前端开发一起交流QQ群:740034288

0. Vue的定义:渐进式技术栈,足以应付任何规模的应用,包括比较高级的功能,如解耦视图和数据,可复用组件,前端路由,状态管理,虚拟DOM。Vue官网:https://cn.vuejs.org/v2/guide/

1. MVVM模式:vue的使用模式MVVM,有MVC衍生而来。即V(view)视图层变化时,会自动更新到viewModel(视图模型),反之亦然,从而建立双向绑定。

2. Vue引入:

      2.1 加载CDN文件:

           〈!一自动识别最新稳定版本的Vue . j s 一〉
             < src = ” https : //unpkg.com/vue/dist/vue.min.js ” ></ scripp
           〈! 一指定某个具体版本的Vue . j s 一〉
             < src= ” https : //unpkg . com/vue@2.1.6/dist/vue . min.j s ” ></ >

      2.2 Vue.cli创建vue项目:参考:https://blog.csdn.net/qq_42231156/article/details/82343793

      2.3 webpack创建vue项目:

3. Vue实例化:

var app=new Vue({
    el:\"\",   //dom的id或者class
    data:{
        a:1
    }
})
console.log(app.a);   //获取实例化对象app里的a的数据。

4. Vue生命周期:

     4.1 beforeCreate在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用,但尚未挂载,$el不可用。

     4.2 created在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

     4.3 beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。

     4.4 mountedel 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。注意 :mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted。

  4.5 beforeUpdate数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

     4.6 updated:当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated。

    4.7 activatedkeep-alive 组件激活时调用。

    4.8 deactivatedkeep-alive 组件停用时调用。

    4.9 beforeDestroy实例销毁之前调用。在这一步,实例仍然完全可用。

    4.10 destroyedVue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    4.11 errorCaptured2.5.0+ 新增,(err: Error, vm: Component, info: string) => ?boolean,当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false以阻止该错误继续向上传播。

5. v-html:能识别标签,只读取标签中文本内容,如v-html=\"data\"  data:\"<a> v-html是读取内容,识别标签a但是不读取</a>\"。

注意:如果将用户产生的内容使用v-html 输出后,有可能导致xss 攻击,所以要在服务端对用户提交的内容进行处理, 一般可将尖括号“< > ”转义。

6 .v-pre:跳过该标签和其子标签的编译。<a v-pre>{{这里的内容不会被编译显示}}</a>。

7. 过滤器:

    过滤器也可以串联,而且可以接收参数,例如:
  〈! 一串联一〉
   { { message I filterA I fil terB } }
 〈!一接收参数一一〉
   {{ message I f 工lterA ( ’ argl ’,’ arg2 ’)}}

8. 计算属性computed:完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。每一个计算属性都包含-个get:function(){} 和一个set:function(newValue){}。在methods 里定义了一个方法实现了相同计算属性的效果,但是计算属性基于它的依赖缓存。一个计算属性所依赖的数据发生变化时,它才会重新取值。

9. v-bind的class和style:

    9.1 class:     

<div class=\"static\" :class=\"{\' active \': isActive,\'error\':isError }\"></div>  
<div class=\"static\" :class=\"{\' active \': isIndex==index}\"></div>  
<div class=\"static\" :class=\"active\"></div>  
<div :class = \"[activeCls , errorCls ] \" ></div>
<div :class = \"[ isActive ? activeCls : \' \', errorCls ]\" ></div>
<div : class =\"[{ \'active\': isActive } , errorCls ]\" ></div>

     9.2 style:

<div :style=\"{\'color\': color, \'fontSize\' : fontSize +\'px\'}\"></div>
<div :style = \"styles\"> </div>
<div :style=\"[styleA,styleB]\"></div>

10. 内置指令: 

    10.1 v-cloak:不需要表达式,它会在Vue 实例结束编译时从绑定的HTML 元素上移除, 经常和css的display: none;配合使用。<div v-cloak></div>,当网速较慢、Vue.js 文件还没加载完时,在页面上会显示{ { message } }的字样,直到Vue 创建实例、编译模板时, DOM 才会被替换,所以这个过程屏幕是有闪动的。只要加一句css 就可以解决这个问题了:[v-cloak]{display:none},在一般情况下, v-cloak 是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用,但是在具有工程化的项目里,比如后面进阶篇将介绍web pack 和vue-router 时,项目的HTML结构只有一个空的div 元素,剩余的内容都是由路由去挂载不同组件完成的,所以不再需要v-cloak。

    10.2 v-once:也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容。<div v-once></div>。

    10.3 v-if,v-else-if,v-else:根据表达式的值在DOM中渲染或销毁元素/组件。

<p v-if=\"status === 1\" >当status 为1 时显示该行</p>
<p v-else-\'if=\" status === 2 \"〉当status 为2 时显示该行</ p>
<p v-else >否则显示该行</ p>

     10.4 v-show:v-show 的用法与v-if 基本一致,只不过v -show 是改变元素的css 属性di splay 。当v-show 表达式的值为false 时, 元素会隐藏,查看DOM 结构会看到元素上加载了内联样式display : none。v-show 不能用在<template></template>上。

     10.5 v-for:遍历循环渲染。数组更新,当我们修改数组时, Vue 会检测到数据变化,所以用v-for 渲染的视图也会立即更新。Vue 包含了一组观察数组变异的方法,使用它们改变数组也会触发视图更新,这些数组API包括:push(),pop(),shift(),unshift(),splice(),sort(),reverse()。但是不会触发视图更新的数组API包括:fliter(),concat(),slice()。

     10.6 v-on:事件,修饰符(.stop(阻止冒泡),.prevent(阻止渗透),.capture(添加事件侦听器时使用事件捕获模),.self(只当事件在该元素本身(而不是子元素) 触发时触发回调),.once(只触发一次,组件同样适用)),< !一只有在keyCode 是13 时调用vm . submit ()一〉,<input @keyup.13 =“ submit ”〉,也可以自己配置具体按键:Vue . config .keyCodes .fl = 112;
全局定义后,就可以使用自keyup. fl。

    10.7 v-model:在input标签中相当于 <input  v-model=\"\"/>   => <input value=\"\" @input=\"valueHandle\"/>,v-model.number=\"\",表示将输入框的值转换为数值,v-model.trim=\"\',表示将输入框的字符串去掉首尾空格。

11. 组件:

    11.1 父组件向子组件传值props:props 中声明的数据与组件data 函数return 的数据主要区别就是props 的来自父级,而data 中的是组件自己的数据,作用域是组件本身,这两种数据都可以在模板template 及计算属性computed和方法methods 中使用。由于html 特性不区分大小写,当使用DOM 模板时,驼峰命名的props 名称要转为短横分隔命名,如inputLists  =>  input-lists。

//1. props数组传值。
props:[\'propA\',\'propB\',\'propC\']


//2. props对象传值。
props:{
    propA:Number, //必须是数字类型
    propB:[String,Number],//必须是数值或字符串
    propC:{
        type:Boolean,
        default:true
    },
    propD:{    //数字,且必传
        type:Number,
        required:true
    },
    propE:{    
        type:Array,
        default:()=>([])
    },
     propF:{    
        type: ,
        default:()=>{}
    },
     propG:{     //自定义一个验证函数
       validator:(value)=>{
            return value >10
        }
    }
}

     11.2 组件通信:<my-component v-on:click.native= ” handleClick” ></my - component>  ,.native监听一个原生事件,监听的是该组件的组件。

     11.3 bus传值,状态管理:bus即空的vue实例,如用于简单场景下的兄弟组件之间传值。
          a. src下创建bus/index.js文件。
               import Vue from \"vue\"
               const Bus=new Vue()
               export default Bus
          b. 在main.js引入bus,并添加到vue的原型对象里,然后在任何地方都可以不需要在引入,直接使用this.$bus.
              import Bus from \'./bus/index.js\'
              Vue.prototype.$bus=Bus
          c. 从兄弟组件A传值给兄弟组件B:
              A组件:
                   this.$bus.$emit(\"myHandle\",val)
              B组件:
                  mouted(){
                        this.$bus.$on(\"myHandle\",(val)=>{  //监听自定义事件myHandle 在这里处理接收到B组件传递过来的值
                        })
                  }

        11.4 子组件主动调用父组件的方法/变量:this.$parent.方法/变量名。

        11.5 子组件向父组件的传递方法事件值:this.$emit。

        11.6 父组件调用子组件的方法/变量:this.$children(不推荐),或者this.$refs.refDom(推荐)。但是$refs 只是渲染完成后才填元,并且它是非响应式的. 它仅仅作为一个直接访问子组件的应急方案,应当避免在模板或计算属性中使用$refs。

12. slot插槽:

         12.1 单个插槽slot: <slot></slot>。

         12.2 具名插槽:<slot name=\"email\"></slot>,   <div slot =\"email\"></div>。

         12.3 插槽的scope传值:即类似props传值,<template slot =\"email\" scope=\"props\">{props.book}</template >。然后接收插槽传值即            

  props:{

    book:{
        type:Number,
        default:1
    }
}

      12.4 访问slot:<div slot =\"email\"></div>,this.$slot.email。this . $slots.default 包括了所有没有被包含在具名slot 中的节
点。

      12.5 递归组件:组件在它的模板内可以递归地调用自己, 只要给组件设置name 的选项就可以了。

<div id= \" app \" >
    <child-component : count= \" 1 \" ></ child- component>
</div>
< >
Vue.component ( \' child- component \', {
    name :\'child-component \',
    props : {
        count: {
            type : Number ,
            default : 1
        } ,
    template : \' \\<div class= \"child\" >\\<child-component\\:count=\"count + 1 \" \\
                v-if= \" count < 3 \" ></ child- component>\\</div>\' ,
)};
var app =new Vue({
    el :\'#app\'
})
</ >

     12.6 $nextTick:页面渲染完才执行。

13. render:

     13.1 render的createElement:

<div id=\"app\">
    <anchor :l evel = \'2\'   = \'特性\'></anchor>
</div>
< >
    Vue.component ( \'anchor\',{
        props:{
            level:{
                type:Number,
                required:true
            },
             :{
                type:String,
                default:\"\"
            }
        },
        render:function (createElement) {
            var  a=\"123\";
            return createElement(     //三个参数,分别是
                \'h\'+this.level,    //第一个该参数是{String |   | Function),必须Return     上述其中一个,一个HTML 标签,组件选项,或一个函数。
                {     //第二个参数{ ),一个对应属性的数据对象,样式,dom.....,可选

                    \'class\':{   //和v-bind:class一样
                    
                    },
                    style:{   //和v-bind:style一样
                    
                    },
                    attrs:{   //正常的html属性,如src,href, ,alt......
                    
                    },
                    props:{   //组件props
                    
                    },
                    domProps:{ //DOM属性,如innerHTML
                    
                    },
                    on:{    //自定义事件监听器on,不支持如v-on :keyup.enter 的修饰器,需要动匹配keyCode。
                    
                    },

                    nativeOn:{  //仅对于组件,用于监听原生事件,而不是组件使用vm. $emit 触发的自定义事件。

                    },
                    directives:{   //自定义指令

                    },

                    scopedSlots: {   //slot默认插槽
                        default: props => h ( \' span \', props .text);  //默认没有slot的name。              

                    },   
                    slot:\"email\" ,  //slot具名插槽
                    key:\"myemail\",  //key值
                    ref:\"myemail\"   //ref值
                [],   //第三个参数{String | Array)子节点,或innerHTML内容,可选。   
            )
        })
    })
</ >

     13.2 render的JSX:

new Vue({
    el:\"#app\",
    render(h){
        return (
            <Anchor level={l}>
                < span >一级</ span >标题
            </Anchor >
        )
    }
})

14. webpack:在安装最新node和npm的前提下。

    14.1 webpack基础配置:

          步骤1:创建一个目录,如demo,npm init初始化。

                       在demo命令行下:npm init。生成一个package.json文件。

          步骤2:本地安装webpack。

                       在demo命令行下:npm install webpack --save -dev。完成在package.json文件中配置devDependencies。

          步骤3:接着需要安装webpack-dev-server,它可以在开发环境中提供很多服务,比如启动一个服务器、热更新、接口代理等,配置起来也很简单。

                       在demo命令行下:npm install webpack-dev-server  --save-dev。最终完善package.json文件配置。

           步骤4: 在demo下创建webpack.config.js ,井初始化它的内容:

var  config={

}
module.exports=config    //如果支持es6,可以用es6语法。

          步骤5: 在package. json 的 s 里增加一个快速启动webpack-dev-server 服务的脚本:

{
    \" s\":{
        \"test\":\"echo \\\"Error: no test specified\\\"&& exit l \",
        \"dev\":\"webpack-dev-server--open--config webpack.config.js \",  //默认端口是127.0.0.1 :8080
//      \"dev\":\"webpack-dev-server --host 172.172.172.1 --port 8888 --open--config webpack.config.js \"   //配置自定义端口
     }  
}

         步骤6:在demo下新建main.js文件作为入口的文件,然后在webpack.config. 中进行入口和输出的配置:

var path= require (\'path\');   //在下载path前提下引入path
var config ={
    entry:{
        main:\"./main\"     //主入口文件main.js
    },
    output:{   //output 中path选项用来存放打包后文件的输出目录,是必填项。publicPath 指定资源件引用的目录,如果你的资源存放在CDN 上,这里可以填CDN 的网址。filename 用于指定输出文件的名称。因此,这里配置的output 意为打包后的文件会存储为demo/dist/main.js 文件,只要在html 中引入它就可以了。
        path:path.join(_dirname,\'./dist\'),
        publicPath:\'/dist/\',
        filename :\'main.js\'
    }
}
module.exports= config;

         步骤7:在demo下新建一个index.html 作为我们SPA 的入口:

< !DOCTYPE html>
<html>
    <head>
        <  charset=”utf-8 ”>
        < >webpack App</ >
    </head>
    <body>
        <div id=\'app\' >
            Hello World.
        </div>
        <  type =\'text/ \' src =\'/dist/main.js\'></ >
    </body>
</html>

       步骤8:在demo命令行下执行npm run dev启动vue项目,在浏览器中打开localhost:8080(这配置的端口ip)即可。

   14.2 完善webpack高级配置:

       配置加载器(loaders)

       如css模块:

             npm install css-loader --save-dev

             npm install style-loader --save-dev

      然后在webpack.config.js 文件里配置Loader,增加对.css 文件的处理:

var path= require (\'path\');   //在下载path前提下引入path
var config ={
    entry:{
        main:\"./main\"     //主入口文件main.js
    },
    output:{  
        path:path.join(_dirname,\'./dist\'),
        publicPath:\'/dist/\',
        filename :\'main.js\'
    },
    modele:{
        rules:[
            {
                test : /\\.css$/,
                use : [
                    \'style-loader\',
                    \'css-loader\'
                ]
            }
        ]
    }
}
module.exports= config;

          安装extract-text-webpack-plugin 插件:npm ins tall extrac t-text-webpack-plugin --save-dev。

          然后然后在配置文件中导入插件,并改写loader 的配置:

var path= require (\'path\');   //在下载path前提下引入path
var ExtractTextPlugin =re quire ( \'extract-text-webpack-plugin \'); //引入插件
var config ={
    entry:{
        main:\"./main\"     //主入口文件main.js
    },
    output:{  
        path:path.join(_dirname,\'./dist\'),
        publicPath:\'/dist/\',
        filename :\'main.js\'
    },
    modele:{
        rules:[
            {
                test : /\\.css$/,
                use : ExtractTextPlugin.extract({
                   fallback: \'style-loader\',
                   use: \'css-loader\'
                })
            }
        ]
    },
    plugins:[
        new ExtractTextPlugin (\"main.css\")   //重命名提取后的css 丈件
    ]
}
module.exports= config;

         在demo下创建style.css文件,在main.js引入style.css文件import \' ./lstyle css \';

          使用.vue 文件需要先安装vue-loader 、vue-style-loader 等加载器并做配置。因为要使用ES6 语法,还需要安装babel 和bab 巳I-loader 等加载器。使用npm 逐个安装以下依赖:

npm install --save vue
npm install --save-dev vue-loader
npm install --save-dev vue-style-loader
npm install --save-dev vue-template-compiler
npm install --save-dev vue-hot-reload-api
npm install --save-dev babel
npm install --save-dev babel-loader
npm install --save-dev babel-core
npm install --save-dev babel-plugin-transform-runtime
npm install --save-dev babel-preset- es2015
npm install --save-dev babel-runtime

           安装完成后, 修改配置文件webpack.config.js 

var path= require (\'path\');   //在下载path前提下引入path
var ExtractTextPlugin =re quire ( \'extract-text-webpack-plugin \'); //引入插件
var config ={
    entry:{
        main:\"./main\"     //主入口文件main.js
    },
    output:{  
        path:path.join(_dirname,\'./dist\'),
        publicPath:\'/dist/\',
        filename :\'main.js\'
    },
    modele:{
        rules:[
            {
                test : /\\.css$/,
                use : ExtractTextPlugin.extract({
                   fallback: \'style-loader\',
                   use: \'css-loader\'
                })
            },
            {
                test: /\\.vue$/,
                loader:\'vue-1oader\',   
                options : {
                    loaders:{
                        css:ExtractTextPlugin.extract({
                            use:\'css-loader\',
                            fallback:\"vue-style-loader\"
                        })
                    }
                }         
            },
            {
                test : /\\.js$/,
                loader :\'babel - loader \',
                exclude : /node modules/
            }
        ]
    },
    plugins:[
        new ExtractTextPlugin (\"main.css\")   //重命名提取后的css 丈件
    ]
}
module.exports= config;

         在demo下创建.babelrc文件,并写入babel 的配置, webpack 会依赖此配置文件来使用babel 编译ES6 代码:

{
    \"presets\":[\"es2015\"],
    \"plugins\":[\"transform- runtime \"],
    \"comments\": false
}

       在demo下创建app.vue并写入:

<template>
    <div>Hello {{ name }}</div>
</template>
< >
    export default {
        data () {
            return {}
        }
    }
</ >
<style scoped>>

</style>

         在demo下main.js内容被替换成:

import Vue from \'vue\';
import App from \'./app.vue\';
new Vue({
    el : \'#app\',
    render: h => h(App)
})

     最后 npm run dev 启动vue项目,在浏览器中打开localhost:8080(如果有重新配置,就打开重新配置的端口,没有就是这个默认端口)即可。

   14.3 进一步完善webpack高级配置:来支持更多常用的功能,如安装url - loader 和file-loader 来支持图片、字体等文件。

         下载:

         npm install --save-dev url-loader
         npm install --save-dev file-loader

        在webpack.config . js配置:

var path= require (\'path\');   //在下载path前提下引入path
var ExtractTextPlugin =re quire ( \'extract-text-webpack-plugin \'); //引入插件
var config ={
    entry:{
        main:\"./main\"     //主入口文件main.js
    },
    output:{  
        path:path.join(_dirname,\'./dist\'),
        publicPath:\'/dist/\',
        filename :\'main.js\'
    },
    modele:{
        rules:[
            {
                test : /\\.css$/,
                use : ExtractTextPlugin.extract({
                   fallback: \'style-loader\',
                   use: \'css-loader\'
                })
            },
            {
                test: /\\.vue$/,
                loader:\'vue-1oader\',   
                options : {
                    loaders:{
                        css:ExtractTextPlugin.extract({
                            use:\'css-loader\',
                            fallback:\"vue-style-loader\"
                        })
                    }
                }         
            },
            {
                test : /\\.js$/,
                loader :\'babel - loader \',
                exclude : /node modules/
            },
            {
                test :/\\. (gif | jpg | png | woff |svg | eot | ttf)\\??.*$/,
                loader:\'url-loader?limit=1024\'
            }  //表示到.gif、.png 、.ttf 等格式文件时, url-loader 会把它们一起编译到dist 录下,“?limit=1024 ”是指如果这个文件小于lkb ,就以 64 的形式加载,不会生成一个文件。
        ]
    },
    plugins:[
        new ExtractTextPlugin (\"main.css\")   //重命名提取后的css 丈件
    ]
}
module.exports= config;

          打包会用到下面两个依赖,使用NPM 安装:

                  npm install --save-dev webpack-merge
                  npm install --save-dev html-webpack-plugin

          为了方便开发和生产环境的切换,我们在demo 目录下再新建一个用于生产环境的配置文件webpack.prod.config.j s 。

           编译打包,直接执行webpack 命令就可以。在package .json 中, 再加入一个build 的快捷脚本用来打包:

{
    \" s\":{
        \"test\":\"echo \\\"Error: no test specified\\\"&& exit l \",
        \"dev\":\"webpack-dev-server--open--config webpack.config.js \",  //默认端口是127.0.0.1 :8080
//      \"dev\":\"webpack-dev-server --host 172.172.172.1 --port 8888 --open--config webpack.config.js \",  //配置自定义端口
        \"build\":\"webpack --progress --hide-modules --config webpack.prop.config.js\", //打包
     }  
}

         配置webpack.prod.config.js的代码:

var webpack =require (\'webpack\');
var HtmlwebpackPlugin = require (\"html-webpack-plugin\");
var ExtractTextPlugin = require (\"extract-text-webpack-plugin\");
var merge = require (\"webpack-merge\");
var webpack Config =require (\'./webpack.config.js\');
webpack Config .plugins = []; //清空基本配置的插件列表
module.exports = merge(webpack Config , {
    output: {
        publicPath : \'/dist/\',
        filename:\'[name].[hash].js\'
    },  //将入口文件重命名为带有20 位hash 值的唯一文件
    plugins : [
        new ExtractTextPlugin({
            filename:\'[name].[hash].css\',
            allChunks:true
        }),   //提取css , 并重命名为带有20 位hash 值的唯一文件
        new webpack.DefinePlugin({  //定义当前node 环境为生产环境
            \'process.env\': {
                NODE ENV:\"production\"
            }
        }) ,
        new webpack.optimize.UglifyJsPlugin({  //压缩js
            compress : {
                warnings : false
            }
        }),
        new HtmlwebpackPlugin({  //提取模板,并保存入口html 文件
            filename:\"../index_prod.html\",
            template:\"./index.ejs\",
            inject : false
        })
    ],
})

          最终在demo下运行npm run build打包:

 

 

 

 

 

 

 

 

 

收藏 打印