Vue笔记

来源:互联网 发布:网络优化工作美篇 编辑:程序博客网 时间:2024/06/05 15:33

Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动组件化的思想构建的。

MVVM模式

它是将“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应到View上。
这里写图片描述
ViewModel是Vue.js的核心,它是一个Vue实例
这里写图片描述

使用Vue的过程就是定义MVVM各个组成部分的过程的过程。

  1. 定义View
  2. 定义Model
  3. 创建一个Vue实例或”ViewModel”,它用于连接View和Model

选项对象的
el属性指向View,el: ‘#app’表示该Vue实例将挂载到< div id=”app”>…这个元素;
data属性指向Model,data: exampleData表示我们的Model是exampleData对象。

Vue.js有多种数据绑定的语法

最基础的形式是文本插值,使用一对大括号语法,在运行时{{ msg }}会被数据对象的msg属性替换,所以页面上会输出”Hello World!”。

MVVM模式本身是实现了双向绑定的,在Vue.js中可以使用v-model指令在表单元素上创建双向数据绑定。
这里写图片描述

Vue.js的指令

是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。
这里写图片描述

  • v-if

是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:v-if=”expression”
v-if指令是根据条件表达式的值来执行元素的插入或者删除行为

  • v- show

也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性。

  • v- else

    可以用v-else指令为v-if或v-show添加一个“else块”。v-else元素必须立即跟在v-if或v-show元素的后面——否则它不能被识别。
    (可是我自己试了一下,好像对v-show不起作用)
    这里写图片描述

  • v- for

v-for指令基于一个数组渲染一个列表,它和JavaScript的遍历语法相似:

v-for=”item in items”
这里写图片描述

  • v-bind
    可以在其名称后面带一个参数,中间放一个冒号隔
    一、对象语法:

我们可以给v-bind:class 一个对象,以动态地切换class。
注意:v-bind:class指令可以与普通的class特性共存:
v-bind:class“ {‘ class名 ’:Boolean值 }
//请注意,有个双引号,在一对花括号,class名在单引号里面,还有个冒号!

也可以绑定一个数据对象;
可以绑定class数组;
可以使用三目运算;
这里写图片描述
-

                                                                                                                                                                                                                                                                                                                                                                 四一、对于VUE的基本认识:Vue.js是当下很火的一个JavaScriptMVVM库,它是以数据驱动和组件化的思想构建的。1、MVVM模式:它是将“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应到View上。                    <-----view<--->view model        model                    ----->1.1、使用Vue的过程就是定义MVVM各个组成部分的过程的过程:定义View定义Model选项对象的el属性指向View,el:‘#app’表示该Vue实例将挂载到<divid=”app”>…这个元素;data属性指向Model,data:exampleData表示我们的Model是exampleData对象。Vue.js有多种数据绑定的语法最基础的形式是文本插值,使用一对大括号语法,在运行时{{msg}}会被数据对象的msg属性替换,所以页面上会输出”HelloWorld!”。MVVM模式本身是实现了双向绑定的,在Vue.js中可以使用v-model指令在表单元素上创建双向数据绑定。2、Vue.js的指令:是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。    2.1、v-if    是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:v-if=”expression”    v-if指令是根据条件表达式的值来执行元素的插入或者删除行为。    2.2、v-show    也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性。    2.3、v-else    可以用v-else指令为v-if或v-show添加一个“else块”。v-else元素必须立即跟在v-if或v-show元素的后面——否则它不能被识别。    (可是我自己试了一下,好像对v-show不起作用)    2.4、v-for    v-for指令基于一个数组渲染一个列表,它和JavaScript的遍历语法相似:    v-for=”item in items”    2.5、v-bind    可以在其名称后面带一个参数,中间放一个冒号隔一、对象语法:    我们可以给v-bind:class一个对象,以动态地切换class。    注意:v-bind:class指令可以与普通的class特性共存:    v-bind:class“{‘class名’:Boolean值}”    //请注意,有个双引号,在一对花括号,class名在单引号里面,还有个冒号!    也可以绑定一个数据对象;    可以绑定class数组;    可以使用三目运算;11.24 星期五学习地址:https://cn.vuejs.org/v2/guide/一、介绍:1、vue是什么?Vue.js (读音 /vjuː/,类似于 view) 是一套构建用户界面的 渐进式框架 。与其他重量级框架不同的是,Vue 采用 自底向上 增量开发的设计。Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供驱动。2、起步:3、声明式渲染:vue.js 的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统:    <div id="app">{{m1}}</div>    var app=new Vue({            el:"#app",            data:{                m1:"这是第一个例子"            }        })    //页面上显示hello;el属性指向View,el:‘#app’表示该Vue实例将挂载到<divid=”app”>…这个元素;data属性指向Model,data:exampleData表示我们的Model是exampleData对象。4、条件与循环:<div id="app3" v-if="seen">你现在能看到第三个例子</div>var app3=new Vue({            el:'#app3',            data:{                seen:true            }        })//页面上回显示“你现在能看到第三个例子”,seen若为falese则看不到v-for 指令可以绑定数组的数据来渲染一个项目列表:<div id="app4"><ol><li v-for="mg in mgs">{{mg.mg}}</li></ol></div>var app4=new Vue({            el:'#app4',            data:{                mgs:[                {mg:'这是第四个例子'},                {mg:'这是第四个例子'}]            }        })//页面上显示: 这是第四个例子                         这是第四个例子5、处理用户输入:为了让用户和你的应用进行互动,我们可以用 v-on 指令绑定一个事件监听器,通过它调用我们 Vue 实例中定义的方法:v-on 指令绑定一个事件监听器,通过它调用我们 Vue 实例中定义的方法:<div id="app5"><p>{{m5}}</p><button v-on:click="fanzhuan">反转</button></div>var app5=new Vue({            el:'#app5',            data:{                m5:'这是第五个例子'            },            methods:{                fanzhuan:function(){                    this.m5=this.m5.split('').reverse().join('');                }            }        })//点击按钮之后,页面上的文字会反转v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。<div id="app6"><p>{{m6}}</p><input type="text" v-model="m6"></div>var app6=new Vue({            el:'#app6',            data:{                m6:'这是第六个例子'            }        })//页面上的文字会因为输入而改变6、组件化应用构建组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。一个组件本质上是一个拥有预定义选项的一个 Vue 实例,在 Vue 中注册组件很简单:子单元通过 props 接口实现了与父单元很好的解耦。<div id="app7"><ol><li7 v-for="p7 in list7" v-bind:a7="p7" v-bind:key="p7.text"></li7></ol></div>        Vue.component('li7',{            props:['a7'],//自定义属性名为a7            template:'<li>{{a7.text}}</li>'        })        var app7=new Vue({            el:'#app7',            data:{                list7:[                {id:0,text:'这是'},                {id:1,text:'第七'},                {id:2,text:'个例子'}]            }        })  6.1与自定义元素的关系:   Vue 组件非常类似于自定义元素——它是 Web 组件规范的一部分,这是因为 Vue 的组件语法部分参考了该规范。11.25星期六:二、Vue实例:1、创建一个Vue实例:每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的:        var vm = new Vue({          // 选项        })所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象即可2、数据与方法:        2.1、当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。        当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。        当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时 data 中存在的属性是响应式的        2.2、要使用Vue实例中的对象,前缀需要加上$                var data = { a: 1 }                var vm = new Vue({                  el: '#example',                  data: data                })                vm.$data === data // => true                vm.$el === document.getElementById('example') // => true3、实例生命周期:   3.1、每个 Vue 实例在被创建之前都要经过一系列的初始化过程。        例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。        同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码。   3.2、 created 钩子可以用来在一个实例被创建之后执行代码:           var b1=new Vue({                el:'b1',                created:function(){                    alert("这是二-1个例子")                }            })//打开网页的时候回弹出“这是二-1例子”三、语法模板:1、插值    1.1、文本:数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:<span>Message: {{ msg }}</span>                通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。                但请留心这会影响到该节点上所有的数据绑定:<span v-once>这个将不会改变: {{ msg }}</span>    1.2、原始 HTML:               双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令:               例子:<p>Using mustaches: {{ rawHtml }}</p>                     <p>Using v-html directive: <span v-html="rawHtml"></span></p>               这个 span 的内容将会被替换成为属性值 rawHtml,直接作为 HTML——会忽略解析属性值中的数据绑定。               不能使用 v-html 来复合局部模板,因为 Vue 不是基于字符串的模板引擎。               注意:站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。                     请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。    1.3、特性:              Mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind 指令:    1.4、使用 JavaScript 表达式:              对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持:                    {{ number + 1 }}基本运算                    {{ ok ? 'YES' : 'NO' }}三目运算                    {{ message.split('').reverse().join('') }}调用函数                    <div v-bind:id="'list-' + id"></div>属性            每个绑定都只能包含单个表达式,所以下面的例子都不会生效:                    {{ var a = 1 }}// 这是语句,不是表达式                    {{ if (ok) { return message } }}//流控制也不会生效,请使用三元表达式            注意:模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date 。不应该在模板表达式中试图访问用户定义的全局变量。2、指令:指令 (Directives) 是带有 v- 前缀的特殊属性。指令属性的值预期是单个 JavaScript 表达式 (v-for 是例外情况)         指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。    2.1、参数:一些指令能够接收一个“参数”,在指令名称之后以冒号表示。              例如,v-bind 指令可以用于响应式地更新 HTML 属性:<a v-bind:href="url">...</a>                    v-on 指令,它用于监听 DOM 事件:<a v-on:click="doSomething">...</a>    2.2、修饰符:修饰符 (Modifiers) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。              例如:.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():<form v-on:submit.prevent="onSubmit">...</form>3、缩写:: 与 @ 对于特性名来说都是合法字符,在所有支持 Vue.js 的浏览器都能被正确地解析。    3.1、v-bind 缩写:                    <a v-bind:href="url">...</a>//完整语法    v-bind:href=“路径”                    <a :href="url">...</a>//缩写语法      :href=“路径”    3.2、v-on 缩写:                    <a v-on:click="doSomething">...</a>//完整写法  v-on:click=“函数名”                    <a @click="doSomething">...</a>//缩写写法       @click=“函数名”四、计算属性和观察者1、计算属性:对于任何复杂逻辑,都应当使用计算属性    1.1、基础例子:                <div id="e1">{{fan}}</div>                var e1=new Vue({                        el:'#e1',                        data:{                            hello:'这是计算机属性的例子'                        },                        computed:{                            fan:function(){                                return this.hello.split('').reverse().join('');                            }                        }                    })//页面上显示“子例性属机算计是这”    1.2、计算属性缓存computed vs 方法methods:计算属性是基于它们的依赖进行缓存的,计算属性只有在它的相关依赖发生改变时才会重新求值                               每当触发重新渲染时,调用方法将总会再次执行函数。    1.3、计算属性 vs 侦听属性watch:Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性                                    通常更好的做法是使用计算属性而不是命令式的 watch 回调    1.4、计算属性的 setter:                        计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :                    // ...                    computed: {                      fullName: {                        // getter                        get: function () {                          return this.firstName + ' ' + this.lastName                        },                        // setter                        set: function (newValue) {                          var names = newValue.split(' ')                          this.firstName = names[0]                          this.lastName = names[names.length - 1]                        }                      }                    }                    // ...2、侦听器:虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。           这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。           当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。11.26、星期日五、Class 与 Style 绑定注意:只要是vue里的属性名,用在html中就不用加‘’;如果是用class里的属性名,或者class名就加‘’1、绑定 HTML Class    1.1、对象语法:                 例如:传给 v-bind:class 一个对象,以动态地切换 class:                       <div v-bind:class=" { ' class名 ': 属性名 } "></div>//class名要加单引号                       上面的语法表示class 存在与否将取决于数据属性的是否为true或false    1.2、数组语法:我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:                 例如:<div v-bind:class=" [ class1, class2 ] "></div>//clas1和clas2是需要在vue实例中的data里的。class1:‘class名’    1.3、用在组件上:也可以自己创建一个组件,然后在组件里绑定class                    Vue.component('zujianming',{template:'<p>用在组件上<p>'})                    <zujiangming v-bind:class="{'class名':bloon}"></zujianming>                    <zujiangming v-bind:class="[class1,class2]"></zujianming>2、绑定内联样式:    2.1、对象语法:            v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。            CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名:            <div v-bind:style="{ color: '颜色名称', fontSize: fontSize + 'px' }"></div>    2.2、数组语法:<div v-bind:style="[baseStyles, overridingStyles]"></div>    2.3、自动添加前缀:当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。    2.4、多重值:            <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>            这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。六、条件渲染1、v-if:是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:v-if=”布尔值”v-if指令是根据条件表达式的值来执行元素的插入或者删除行为。    1.1、在 <template> 元素上使用 v-if 条件渲染分组    1.2、v-else:v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。    1.3、v-else-if:v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。    1.4、用 key 管理可复用的元素:这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可:         例如: <div id="vif">                <button v-on:click="bian">变换</button>                <div v-if=zhen>                <label>请输入if</label>                <input type="text" placeholder="这是if例子" key="if">                </div>                <div v-else>                <label>请输入else</label>                <input type="text" placeholder="这是else例子" key=else>                </div>                </div>                var vif=new Vue({                        el:'#vif',                        data:{                            zhen:false                        },                        methods:{                            bian:function(){                                if (this.zhen==false) {                                    this.zhen=true;                                }                                else this.zhen=false;                            }                        }                    })//当点击按钮是,会切换输入框,然后输入的内容会复用,如果添加key值就不会复用;2、v-show:        <h1 v-show="ok">Hello!</h1>        注意:v-show 不支持 <template> 元素,也不支持 v-else。        不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。3、v-if vs v-show:v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。                   v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。                   v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。                   一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。                   因此,如果需要非常频繁地切换,则使用 v-show 较好;                   如果在运行时条件很少改变,则使用 v-if 较好。4、v-if 与 v-for 一起使用:当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。11.27 星期一七列表渲染1、用 v-for 把一个数组对应为一组元素:    v-for 指令需要使用 item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名。    在 v-for 块中,我们拥有对父作用域属性的完全访问权限。v-for 还支持一个可选的第二个参数为当前项的索引。    也可以用 of 替代 in 作为分隔符,因为它是最接近 JavaScript 迭代器的语法:    <div v-for="item of items"></div>2、一个对象的 v-for:在遍历对象时,是按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下是一致的。                    <div v-for="(value, key, index) in object">                    {{ index }}. {{ key }}: {{ value }}</div>3、key:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。       如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,        而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。       这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。       理想的 key 值是每项都有的且唯一的 id。它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值 (在这里使用简写):                <div v-for="item in items" :key="item.id">                  <!-- 内容 -->                </div>4、数组更新检测    4.1、变异方法:    Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:                    push()                    pop()                    shift()                    unshift()                    splice()                    sort()                    reverse()    4.2、替换数组:    变异方法 (mutation method),顾名思义,会改变被这些方法调用的原始数组。    相比之下,也有非变异 (non-mutating method) 方法,例如:filter(), concat() 和 slice() 。    这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:    ue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的、启发式的方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。    4.3、注意事项:        由于 JavaScript 的限制,Vue 不能检测以下变动的数组:        当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue        当你修改数组的长度时,例如:vm.items.length = newLength        4.3.1、为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:            // Vue.set            Vue.set(example1.items, indexOfItem, newValue)            // Array.prototype.splice            example1.items.splice(indexOfItem, 1, newValue)        4.3.2、为了解决第二类问题,你可以使用 splice:            example1.items.splice(newLength)5、对象更改检测注意事项:      还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:      对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。      有时你可能需要为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()。      在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:            Object.assign(this.对象名, {              age: 27,              favoriteColor: 'Vue Green'            })            你应该这样做:            this.对象名 = Object.assign({}, this.对象名, {              age: 27,              favoriteColor: 'Vue Green'            })6、显示过滤/排序结果:要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性。                <ul id="w"><li v-for=" a in xiao">{{a}}</li></ul>//a in 计算属性的方法                或者<ul id="w"><li v-for=" a in xiao">{{a}}</li></ul>//a in 方法(参数)                var w=new Vue({                            el:'#w',                            data:{                                shuzi:[1,2,3,4,5]                            },                            methods:{                            xx:function(shuzi){                            return this.shuzi.filter(function(shuzi){                                    return shuzi%2==0;                                });                            }                        },                            computed:{                                xiao:function(){                                    return this.shuzi.filter(function(shuzi){                                        return shuzi%2==0;                                    });                                }                            }                        })//页面上显示2、47、一段取值范围的 v-for:v-for 也可以取整数。在这种情况下,它将重复多次模板。            例如:<div>              <span v-for="n in 10">{{ n }} </span>            </div>//页面依次显示1、2、3、4、5、6、7、8、9、108、v-for on a <template>:类似于 v-if,你也可以利用带有 v-for 的 <template> 渲染多个元素。9、v-for with v-if:            当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:            <li v-for="todo in todos" v-if="!todo.isComplete">              {{ todo }}            </li>10一个组件的 v-for:            <my-component v-for="item in items" :key="item.id"></my-component>//当在组件中使用 v-for 时,key 现在是必须的。            注意:注意这里的 is="todo-item" 属性。这种做法在使用 DOM 模板时是十分必要的,因为在 <ul> 元素内只有 <li> 元素会被看作有效内容。这样做实现的效果与 <todo-item> 相同,但是可以避开一些潜在的浏览器解析错误。八、事件处理1、监听事件:可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。//v-on:click="表达式"2、事件处理方法: v-on 还可以接收一个需要调用的方法名称。//v-on:click="methods里的函数名"3、内联处理器中的方法:v-on:click="methods里的函数名(参数)"4、事件修饰符:在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。               尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。               v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。                    .stop                    .prevent                    .capture                    .self                    .once        <a v-on:click.stop="doThis"></a><!-- 阻止单击事件继续传播 -->        <form v-on:submit.prevent="onSubmit"></form><!-- 提交事件不再重载页面 -->        <a v-on:click.stop.prevent="doThat"></a><!-- 修饰符可以串联 -->        <form v-on:submit.prevent></form><!-- 只有修饰符 -->        <div v-on:click.capture="doThis">...</div><!-- 添加事件监听器时使用事件捕获模式 --><!-- 即内部元素触发的事件先在此处处理,然后才交由内部元素自身进行处理 -->        <div v-on:click.self="doThat">...</div><!-- 只当在 event.target 是当前元素自身时触发处理函数 --><!-- 即事件不是从内部元素触发的 -->        <a v-on:click.once="doThis"></a><!-- 点击事件将只会触发一次 -->//此为新增    注意:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。          因此,用 @click.prevent.self 会阻止所有的点击,而 @click.self.prevent 只会阻止对元素自身的点击。5、按键修饰符:Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:                <!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->                <input v-on:keyup.13="submit">    5.1、自动匹配按键修饰符:记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:            <!-- 同上 -->            <input v-on:keyup.enter="submit">            <!-- 缩写语法 -->            <input @keyup.enter="submit">                    全部的按键别名:                    .enter                    .tab                    .delete (捕获“删除”和“退格”键)                    .esc                    .space                    .up                    .down                    .left                    .right            可以通过全局 config.keyCodes 对象自定义按键修饰符别名:            // 可以使用 `v-on:keyup.f1`            Vue.config.keyCodes.f1 = 112            <input @keyup.page-down="onPageDown">           在上面的例子中,处理函数仅在 $event.key === 'PageDown' 时被调用。           有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,它们的内置别名应该是首选。6、系统修饰键:        可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。        .ctrl        .alt        .shift        .meta            例如:            <!-- Alt + C -->            <input @keyup.alt.67="clear">            <!-- Ctrl + Click -->            <div @click.ctrl="doSomething">Do something</div>            请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发keyup.ctrl。而单单释放 ctrl 也不会触发事件。6.1、.exact 修饰符:         .exact 修饰符应与其他系统修饰符组合使用,以指示处理程序只在精确匹配该按键组合时触发。          <!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->        <button @click.ctrl="onClick">A</button>          <!-- 仅在只有 Ctrl 被按下的时候触发 -->        <button @click.ctrl.exact="onCtrlClick">A</button>6.2、鼠标按钮修饰符:        .left        .right        .middle        这些修饰符会限制处理函数仅响应特定的鼠标按钮。7为什么在 HTML 中监听事件?        使用 v-on 有几个好处:        扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。        因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。        当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何自己清理它们。九、表单输入绑定1、基础用法:        v-model 指令在表单控件元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。        尽管有些神奇,但 v-model 本质上不过是语法糖,它负责监听用户的输入事件以更新数据,并特别处理一些极端的例子。        注意:v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值。因为它会选择 Vue 实例数据来作为具体的值。             对于要求 IME (如中文、日语、韩语等) (IME 意为“输入法”)的语言,你会发现 v-model 不会在 ime 输入中得到更新。             如果你也想实现更新,请使用 input 事件。    1.1、文本:例如:<div id="sr"><input v-model="shuru">                    <p >{{shuru}}</p></div>    1.2、多行文本:在文本区域插值 (<textarea></textarea>) 并不会生效,应用 v-model 来代替。    1.3、复选框:单个勾选框,逻辑值:            <input type="checkbox" id="checkbox" v-model="checked">            <label for="checkbox">{{ checked }}</label>//选中哪些就显示哪些    1.4、单选按钮:            <input type="radio" id="radio" v-model="radioed">            <label for="radio">{{radioed }}</label>//选择中哪一个就显示哪一个    1.5、选择列表:            <select v-model="xz">                    <option>这是</option>                    <option>选择</option>                    <option>例子</option>                </select>                <p>{{xz}}</p>//选中哪一个就显示哪一个            注意:如果 v-model 表达初始的值不匹配任何的选项,<select> 元素就会以”未选中”的状态渲染。              new Vue({                  el: '#example-6',                  data: {                    xz: []//表示绑定到一个数组。selec的style要有multiple。若xz:‘’ 表示单选列表                  }                })2、值绑定:        对于单选按钮,勾选框及选择列表选项,v-model 绑定的 value 通常是静态字符串 (对于勾选框是逻辑值):        <!-- 当选中时,`picked` 为字符串 "a" -->        <input type="radio" v-model="picked" value="a">        <!-- `toggle` 为 true 或 false -->        <input type="checkbox" v-model="toggle">        <!-- 当选中时,`selected` 为字符串 "abc" -->        <select v-model="selected">          <option value="abc">ABC</option>        </select>        但是有时我们想绑定 value 到 Vue 实例的一个动态属性上,这时可以用 v-bind 实现,并且这个属性的值可以不是字符串。    2.1、复选框:        <input type="checkbox" v-model="toggle"  v-bind:true-value="a" v-bind:false-value="b">        // 当选中时        vm.toggle === vm.a        // 当没有选中时        vm.toggle === vm.b    2.2、单选按钮:        <input type="radio" v-model="pick" v-bind:value="a">        // 当选中时        vm.pick === vm.a    2.3、选择列表的选项:        <select v-model="selected">        <!-- 内联对象字面量 -->        <option v-bind:value="{ number: 123 }">123</option>        </select>        // 当选中时        typeof vm.selected // => 'object'        vm.selected.number // => 1233修饰符    3.1、.lazy:        在默认情况下,v-model 在 input 事件中同步输入框的值与数据 (除了 上述 IME 部分),但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:        <!-- 在 "change" 而不是 "input" 事件中更新 -->        <input v-model.lazy="msg" >    3.2、.number:         想自动将用户的输入值转为 Number 类型 (如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值:         <input v-model.number="age" type="number">         因为在 type="number" 时 HTML 中输入的值也总是会返回字符串类型。    3.3、.trim:         如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入:         <input v-model.trim="msg">4、v-model 与组件:        Vue 的组件系统允许你创建一个具有自定义行为可复用的 input 类型,这些 input 类型甚至可以和 v-model 一起使用十、组件1、什么是组件?:    组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。    在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。    在有些情况下,组件也可以表现为用 is 特性进行了扩展的原生 HTML 元素。2、使用组件    2.1、全局注册:            创建一个 Vue 实例:            new Vue({              el: '#some-element',              // 选项            })            要注册一个全局组件,可以使用 Vue.component(tagName, options)。例如:            Vue.component('my-component', {              // 选项            })            组件在注册之后,便可以作为自定义元素 <my-component></my-component> 在一个实例的模板中使用。            注意确保在初始化根实例之前注册组件://先注册组件,在实例化vue    2.2、局部注册:            不必把每个组件都注册到全局。你可以通过某个 Vue 实例/组件的实例选项 components 注册仅在其作用域中可用的组件:                例如:var Child = {template: '<div>A custom component!</div>'}                    new Vue({                      // ...                      components: {                        // <my-component> 将只在父组件模板中可用                        'my-component': Child                      }                    })                    这种封装也适用于其它可注册的 Vue 功能,比如指令    2.3、DOM 模板解析注意事项:            当使用 DOM 作为模板时 (例如,使用 el 选项来把 Vue 实例挂载到一个已有内容的元素上),会受到 HTML 本身的一些限制、            因为 Vue 只有在浏览器解析、规范化模板之后才能获取其内容。            尤其要注意,像 <ul><ol><table><select> 这样的元素里允许包含的元素有限制,而另一些像 <option> 这样的元素只能出现在某些特定元素的内部。            在自定义组件中使用这些受限制的元素时会导致一些问题:                     例如:                        <table>                          <my-row>...</my-row>                        </table>                        自定义组件 <my-row> 会被当作无效的内容,因此会导致错误的渲染结果。变通的方案是使用特殊的 is 特性:                        <table>                          <tr is="my-row"></tr>                        </table>            应当注意,如果使用来自以下来源之一的字符串模板,则没有这些限制:            <script type="text/x-template">            JavaScript 内联模板字符串            .vue 组件            因此,请尽可能使用字符串模板。    2.4、data 必须是函数:            构造 Vue 实例时传入的各种选项大多数都可以在组件里使用。只有一个例外:data 必须是函数。实际上,如果你这么做:            Vue.component('my-component', {              template: '<span>{{ message }}</span>',              data: {                message: 'hello'              }            })            那么 Vue 会停止运行,并在控制台发出警告,告诉你在组件实例中 data 必须是一个函数。    2.5、组件组合:    组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件 A 在它的模板中使用了组件 B。它们之间必然需要相互通信:父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告知父组件。然而,通过一个良好定义的接口来尽可能将父子组件解耦也是很重要的。这保证了每个组件的代码可以在相对隔离的环境中书写和理解,从而提高了其可维护性和复用性。在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。3、Prop    3.1、使用 Prop 传递数据:         组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。         父组件的数据需要通过 prop 才能下发到子组件中。子组件要显式地用 props 选项声明它预期的数据:    3.2、camelCase vs. kebab-case:         HTML 特性是不区分大小写的。所以,当使用的不是字符串模板时,camelCase (驼峰式命名) 的 prop 需要转换为相对应的 kebab-case (短横线分隔式命名):            Vue.component('child', {              // 在 JavaScript 中使用 camelCase              props: ['myMessage'],              template: '<span>{{ myMessage }}</span>'            })            <!-- 在 HTML 中使用 kebab-case -->            <child my-message="hello!"></child>            component内:props:【‘xiaoDA’】            html内:xiao-da=“内容”            如果你使用字符串模板,则没有这些限制。    3.3、动态 Prop:与绑定到任何普通的 HTML 特性相类似,我们可以用 v-bind 来动态地将 prop 绑定到父组件的数据。                    每当父组件的数据变化时,该变化也会传导给子组件:    3.4、字面量语法 vs 动态语法:            初学者常犯的一个错误是使用字面量语法传递数值:            <!-- 传递了一个字符串 "1" -->            <comp some-prop="1"></comp>            因为它是一个字面量 prop,它的值是字符串 "1" 而不是一个数值。如果想传递一个真正的 JavaScript 数值,则需要使用 v-bind,从而让它的值被当作 JavaScript 表达式计算:            <!-- 传递真正的数值 -->            <comp v-bind:some-prop="1"></comp>    3.5、单向数据流:    Prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。    每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。    在两种情况下,我们很容易忍不住想去修改 prop 中数据:            1、Prop 作为初始值传入后,子组件想把它当作局部数据来用;            2、Prop 作为原始数据传入,由子组件处理成其它数据输出。            对这两种情况,正确的应对方式是:            1、定义一个局部变量,并用 prop 的值初始化它:            props: ['initialCounter'],            data: function () {              return { counter: this.initialCounter }            }            2、定义一个计算属性,处理 prop 的值并返回:            props: ['size'],            computed: {              normalizedSize: function () {                return this.size.trim().toLowerCase()              }            }    注意:在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。    3.6、Prop 验证:我们可以为组件的 prop 指定验证规则。如果传入的数据不符合要求,Vue 会发出警告。                要指定验证规则,需要用对象的形式来定义 prop,而不能用字符串数组:            Vue.component('example', {              props: {                // 基础类型检测 (`null` 指允许任何类型)                propA: Number,                // 可能是多种类型                propB: [String, Number],                // 必传且是字符串                propC: {                  type: String,                  required: true                },                // 数值且有默认值                propD: {                  type: Number,                  default: 100                },                // 数组/对象的默认值应当由一个工厂函数返回                propE: {                  type: Object,                  default: function () {                    return { message: 'hello' }                  }                },                // 自定义验证函数                propF: {                  validator: function (value) {                    return value > 10                  }                }              }            })            type 可以是下面原生构造器:            String            Number            Boolean            Function            Object            Array            Symbol            type 也可以是一个自定义构造器函数,使用 instanceof 检测。            当 prop 验证失败,Vue 会抛出警告 (如果使用的是开发版本)。注意 prop 会在组件实例创建之前进行校验,所以在 default 或 validator 函数里,诸如 data、computed 或 methods 等实例属性还无法使用。4、非 Prop 特性:所谓非 prop 特性,就是指它可以直接传入组件,而不需要定义相应的 prop。        假设我们使用了第三方组件 bs-date-input,它包含一个 Bootstrap 插件,该插件需要在 input 上添加 data-3d-date-picker 这个特性。这时可以把特性直接添加到组件上 (不需要事先定义 prop):        <bs-date-input data-3d-date-picker="true"></bs-date-input>        添加属性 data-3d-date-picker="true" 之后,它会被自动添加到 bs-date-input 的根元素上。    4.1、替换/合并现有的特性5、自定义事件    5.1、使用 v-on 绑定自定义事件:        每个 Vue 实例都实现了事件接口,即:            使用 $on(自定义事件名1) 监听事件            使用 $emit(自定义事件名2) 触发事件//组件里的函数,在组件里使用,在html中使用时是 v-on:自定义事件名2=“使用实例里的函数名”        注意: $on 和 $emit 并不是addEventListener 和 dispatchEvent 的别名。不能用 $on 侦听子组件释放的事件,而必须在模板里直接用 v-on 绑定    5.2、给组件绑定原生事件:想在某个组件的根元素上监听一个原生事件。可以使用 v-on 的修饰符 .native。                             例如:<my-component v-on:click.native="doTheThing"></my-component>    5.3、.sync 修饰符:        但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。        如下代码        <comp :foo.sync="bar"></comp>        会被扩展为:        <comp :foo="bar" @update:foo="val => bar = val"></comp>        当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:        this.$emit('update:foo', newValue)    5.4、使用自定义事件的表单输入组件:        自定义事件可以用来创建自定义的表单输入组件,使用 v-model 来进行数据双向绑定。要牢记:<input v-model="something">        要让组件的 v-model 生效,它应该 :1、接受一个 value prop2、在有新的值时触发 input 事件并将新值作为参数    5.5、自定义组件的 v-model:        默认情况下,一个组件的 v-model 会使用 value prop 和 input 事件    5.6、非父子组件的通信:        有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线:        var bus = new Vue()        // 触发组件 A 中的事件        bus.$emit('id-selected', 1)        // 在组件 B 创建的钩子中监听事件        bus.$on('id-selected', function (id) {          // ...        })6、使用插槽分发内容:        在使用组件时,我们常常要像这样组合它们:        <app>          <app-header></app-header>          <app-footer></app-footer>        </app>        注意两点:        <app> 组件不知道它会收到什么内容。这是由使用 <app> 的父组件决定的。        <app> 组件很可能有它自己的模板。        为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为内容分发 (即 Angular 用户熟知的“transclusion”)。Vue.js 实现了一个内容分发 API,参照了当前 Web Components 规范草案,使用特殊的 <slot> 元素作为原始内容的插槽。    6.1、编译作用域:        父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。    6.2、单个插槽:        除非子组件模板包含至少一个 <slot> 插口,否则父组件的内容将会被丢弃。当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,并替换掉插槽标签本身。    6.3、具名插槽:        <slot> 元素可以用一个特殊的特性 name 来进一步配置如何分发内容。多个插槽可以有不同的名字。        具名插槽将匹配内容片段中有对应 slot 特性的元素。        仍然可以有一个匿名插槽,它是默认插槽,作为找不到匹配的内容片段的备用插槽。        如果没有默认插槽,这些找不到匹配的内容片段将被抛弃。    6.4、作用域插槽:        作用域插槽是一种特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。        在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样:        <div class="child">          <slot text="hello from child"></slot>        </div>7、动态组件:通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,我们让多个组件可以使用同一个挂载点,并动态切换:    7.1、keep-alive:如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:        <keep-alive>          <component :is="currentView">            <!-- 非活动组件将被缓存! -->          </component>        </keep-alive>8、杂项:    8.1、编写可复用组件:         Vue 组件的 API 来自三部分——prop、事件和插槽:            Prop 允许外部环境传递数据给组件;            事件允许从组件内触发外部环境的副作用;            插槽允许外部环境将额外的内容组合在组件中。    8.2、子组件引用:       尽管有 prop 和事件,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个引用 ID。例如:        <div id="parent">          <user-profile ref="profile"></user-profile>        </div>        var parent = new Vue({ el: '#parent' })        // 访问子组件实例        var child = parent.$refs.profile        当 ref 和 v-for 一起使用时,获取到的引用会是一个数组,包含和循环数据源对应的子组件。        注意:$refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅是一个直接操作子组件的应急方案——应当避免在模板或计算属性中使用 $refs。    8.3、异步组件    8.4、高级异步组件    8.5、组件命名约定:        当注册组件 (或者 prop) 时,可以使用 kebab-case (短横线分隔命名)、camelCase (驼峰式命名) 或 PascalCase (单词首字母大写命名)。        // 在组件定义中        components: {          // 使用 kebab-case 注册          'kebab-cased-component': { /* ... */ },          // 使用 camelCase 注册          'camelCasedComponent': { /* ... */ },          // 使用 PascalCase 注册          'PascalCasedComponent': { /* ... */ }        }    8.6、递归组件:    组件在它的模板内可以递归地调用自己。不过,只有当它有 name 选项时才可以这么做:    name: 'unique-name-of-my-component'    当你利用 Vue.component 全局注册了一个组件,全局的 ID 会被自动设置为组件的 name。    Vue.component('unique-name-of-my-component', {      // ...    })    8.7、组件间的循环引用    8.8、内联模板:    如果子组件有 inline-template 特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板编写起来更灵活。    <my-component inline-template>      <div>        <p>这些将作为组件自身的模板。</p>        <p>而非父组件透传进来的内容。</p>      </div>    </my-component>    但是 inline-template 让模板的作用域难以理解。使用 template 选项在组件内定义模板或者在 .vue 文件中使用 template 元素才是最佳实践。    8.9、X-Template:        在 JavaScript 标签里使用 text/x-template 类型,并且指定一个 id。例如:        <script type="text/x-template" id="hello-world-template">          <p>Hello hello hello</p>        </script>        Vue.component('hello-world', {          template: '#hello-world-template'        })    8.10、对低开销的静态组件使用 v-once:    尽管在 Vue 中渲染 HTML 很快,不过当组件中包含大量静态内容时,可以考虑使用 v-once 将渲染结果缓存起来,就像这样:12.3  星期日 12.4 星期一过渡 & 动画十一、进入/离开 & 列表过渡1、概述:    Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。    包括以下工具:        在 CSS 过渡和动画中自动应用 class        可以配合使用第三方 CSS 动画库,如 Animate.css        在过渡钩子函数中使用 JavaScript 直接操作 DOM        可以配合使用第三方 JavaScript 动画库,如 Velocity.js2、单元素/组件的过渡:    Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加 entering/leaving 过渡        条件渲染 (使用 v-if)        条件展示 (使用 v-show)        动态组件        组件根节点    当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:        自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。        如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。        如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。    2.1、过渡的类名:    在进入/离开的过渡中,会有 6 个 class 切换。        1、v-enter:定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除。        2、v-enter-active:定义过渡的状态。在元素整个过渡过程中作用,在元素被插入时生效,在 transition/animation 完成之后移除。这个类可以被用来定义过渡的过程时间,延迟和曲线函数。        3、v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入一帧后生效 (于此同时 v-enter 被删除),在 transition/animation 完成之后移除。        4、v-leave: 定义离开过渡的开始状态。在离开过渡被触发时生效,在下一个帧移除。        5、v-leave-active:定义过渡的状态。在元素整个过渡过程中作用,在离开过渡被触发后立即生效,在 transition/animation 完成之后移除。这个类可以被用来定义过渡的过程时间,延迟和曲线函数。        6、v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发一帧后生效 (于此同时 v-leave 被删除),在 transition/animation 完成之后移除。        自己实践之后的感悟:在定义离开过渡的时候,最后就只定义class-leave-active的类,class-leave效果不明显。                            css的过渡,就用transition:属性 过渡时间 速度 整个动画时间                            动画的过渡,就用animation:动画名 过渡时间    2.2、CSS 过渡    2.3、CSS 动画:    CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。    2.4、自定义过渡的类名:        我们可以通过以下特性来自定义过渡类名:            enter-class            enter-active-class            enter-to-class (2.1.8+)            leave-class            leave-active-class            leave-to-class (2.1.8+)        他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。    2.5、同时使用过渡和动画:         Vue 为了知道过渡的完成,必须设置相应的事件监听器。它可以是 transitionend 或 animationend ,这取决于给元素应用的 CSS 规则。如果你使用其中任何一种,Vue 能自动识别类型并设置监听。         你需要给同一个元素同时设置两种过渡动效,比如 animation 很快的被触发并完成了,而 transition 效果还没结束。在这种情况中,你就需要使用 type 特性并设置 animation 或 transition 来明确声明你需要 Vue 监听的类型。    2.6、显性的过渡持续时间:在很多情况下,Vue 可以自动得出过渡效果的完成时机。默认情况下,Vue 会等待其在过渡效果的根元素的第一个 transitionend 或 animationend 事件。    在这种情况下你可以用 <transition> 组件上的 duration 属性定制一个显性的过渡持续时间 (以毫秒计):        <transition :duration="1000">...</transition>    你也可以定制进入和移出的持续时间:        <transition :duration="{ enter: 500, leave: 800 }">...</transition>    2.7、JavaScript 钩子:是一种事件劫持机制,也就是说它会比你的事件更早进行执行处理。    注意:当只用 JavaScript 过渡的时候, 在 enter 和 leave 中,回调函数 done 是必须的 。否则,它们会被同步调用,过渡会立即完成。          推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。<transitionv-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter" v-on:enter-cancelled="enterCancelled"v-on:before-leave="beforeLeave" v-on:leave="leave" v-on:after-leave="afterLeave" v-on:leave-cancelled="leaveCancelled"></transition>在methods中添加以下方法:beforeEnter enter afterEnter enterCancelled 它们的参数都是el3、初始渲染的过渡:可以通过 appear 特性设置节点的在初始渲染的过渡,默认和进入和离开过渡一样,同样也可以自定义 CSS 类名。        <transition  appear appear-class="custom-appear-class"  appear-to-class="custom-appear-to-class" (2.1.8+)          appear-active-class="custom-appear-active-class"></transition>4、多个元素的过渡:    <transition name="fade" mode="out-in">//name=“要使用的过渡css样式” 需要加一个过渡模式mode=“过渡模式”            <button v-if="flag" key="save" @click="flag=!flag">save</button>            <button v-else key="edit" @click="flag=!flag">edit</button>     </transition>     //因为切换的是同一个类型的元素,且用到了v-if和v-else。所以都需要加上key,来区别    4.1、过渡模式:    同时生效的进入和离开的过渡不能满足所有要求,所以 Vue 提供了 过渡模式        in-out:新元素先过渡,最后在将旧元素过渡出去;        out-in:旧元素先过渡出去,在过渡新元素;5、多个组件的过渡6、列表过渡:        <transition-group name="list" tag="p">            <span v-for="item in items" v-bind:key="item" class="list-item">              {{ item }}            </span>          </transition-group>不同于 <transition>,它会以一个真实元素呈现:默认为一个 <span>。你也可以通过 tag 特性更换为其他元素。             内部元素 总是需要 提供唯一的 key 属性值    6.1、列表的进入/离开过渡    6.2、列表的排序过渡:    需要注意的是使用 FLIP 过渡的元素不能设置为 display: inline 。作为替代方案,可以设置为 display: inline-block 或者放置于 flex 中    6.3、列表的交错过渡7、可复用的过渡:过渡可以通过 Vue 的组件系统实现复用。要创建一个可复用过渡组件,你需要做的就是将 <transition> 或者 <transition-group> 作为根组件,然后将任何子组件放置在其中就可以了。8、动态过渡:    在 Vue 中即使是过渡也是数据驱动的!动态过渡最基本的例子是通过 name 特性来绑定动态值。    <transition v-bind:name="transitionName">      <!-- ... -->    </transition>12.5星期一十二、状态过渡:Vue 的过渡系统提供了非常多简单的方法设置进入、离开和列表的动效。1、状态动画与观察者:通过观察者我们能监听到任何数值属性的数值更新。2、动态状态过渡3、把过渡放到组件里4、赋予设计以生命:只要一个动画,就可以带来生命。可复用性 & 组合十三、混合1、基础:混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。         以组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。         // 定义一个混合对象        var myMixin = {          created: function () {            this.hello()          },          methods: {            hello: function () {              console.log('hello from mixin!')            }          }        }        // 定义一个使用混合对象的组件        var Component = Vue.extend({          mixins: [myMixin]        })        var component = new Component() // => "hello from mixin!"2、选项合并:当组件和混合对象含有同名选项时,这些选项将以恰当的方式混合。             注意:混合对象的 钩子将在组件自身钩子 之前 调用             值为对象的选项,例如 methods, components 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。             注意:Vue.extend() 也使用同样的策略进行合并。3、全局混合:也可以全局注册混合对象。注意使用! 一旦使用全局混合对象,将会影响到 所有 之后创建的 Vue 实例。使用恰当时,可以为自定义对象注入处理逻辑。            注意:谨慎使用全局混合对象,因为会影响到每个单独创建的 Vue 实例 (包括第三方模板)。大多数情况下,只应当应用于自定义选项,也可以将其用作 Plugins 以避免产生重复应用4、自定义选项合并策略:        自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies 添加一个函数:        Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {          // return mergedVal        }        对于大多数对象选项,可以使用 methods 的合并策略:        var strategies = Vue.config.optionMergeStrategies        strategies.myOption = strategies.methods十四、自定义指令1、简介:    // 注册一个全局自定义指令 `v-focus`    Vue.directive('focus', {      // 当被绑定的元素插入到 DOM 中时……      inserted: function (el) {        // 聚焦元素        el.focus()      }    })2、钩子函数:    一个指令定义对象可以提供如下几个钩子函数 (均为可选):    1、bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。    2、inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。    3、update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。    4、componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。    5、unbind:只调用一次,指令与元素解绑时调用。    接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。3、钩子函数参数:    1、el:指令所绑定的元素,可以用来直接操作 DOM 。    2、binding:一个对象,包含以下属性:        2.1、name:指令名,不包括 v- 前缀。        2.2、value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。        2.3、oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。        2.4、expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。        2.5、arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。        2.6、modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。    3、vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。    4、oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。    注意:除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。4、函数简写5、对象字面量:如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。        <div v-demo="{ color: 'white', text: 'hello!' }"></div>        Vue.directive('demo', function (el, binding) {          console.log(binding.value.color) // => "white"          console.log(binding.value.text)  // => "hello!"        })十五、渲染函数 & JSX1、基础:Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接近编译器。2、节点、树以及虚拟 DOM:    每个元素都是一个节点。每片文字也是一个节点。    甚至注释也都是节点。一个节点就是页面的一个部分。    就像家谱树一样,每个节点都可以有孩子节点        <h1>{{ blogTitle }}</h1>    等同于:    render: function (createElement) {//参数是createElement      return createElement('h1', this.blogTitle)//createElement(‘标签’,‘内容’)    }    2.1、虚拟 DOM:Vue 通过建立一个虚拟 DOM 对真实 DOM 发生的变化保持追踪。    return createElement('h1', this.blogTitle)    createElement 返回的不是一个实际的 DOM 元素。它更准确的名字可能是 createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,及其子节点。我们把这样的节点描述为“虚拟节点 (Virtual Node)”,也常简写它为“VNode”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。3、createElement 参数    3.1、深入 data 对象:正如在模板语法中,v-bind:class 和 v-bind:style ,会被特别对待一样,在 VNode 数据对象中,下列属性名是级别最高的字段。该对象也允许你绑定普通的 HTML 特性,就像 DOM 属性一样,比如 innerHTML (这会取代 v-html 指令)。    3.2、完整示例    3.3、约束:组件树中的所有 VNodes 必须是唯一的。    渲染了 20 个重复的段落:        render: function (createElement) {          return createElement('div',            Array.apply(null, { length: 20 }).map(function () {              return createElement('p', 'hi')            })          )        }4、使用 JavaScript 代替模板功能    4.1、v-if 和 v-for        <ul v-if="items.length">          <li v-for="item in items">{{ item.name }}</li>        </ul>        <p v-else>No items found.</p>    render: function (createElement) {      if (this.items.length) {        return createElement('ul', this.items.map(function (item) {          return createElement('li', item.name)        }))      } else {        return createElement('p', 'No items found.')      }    }    4.2、v-model:render 函数中没有与 v-model 相应的 api - 你必须自己来实现相应的逻辑:    4.3、事件 & 按键修饰符:对于 .passive、.capture 和 .once事件修饰符, Vue 提供了相应的前缀可以用于 on:        Modifier(s)     |Prefix        ________________________        .passive        |&        .capture        |!        .once           |~        .capture.once   |~!        .once.capture   |~!    4.4、插槽:        你可以从 this.$slots 获取 VNodes 列表中的静态内容:        render: function (createElement) {          // `<div><slot></slot></div>`          return createElement('div', this.$slots.default)        }        还可以从 this.$scopedSlots 中获得能用作函数的作用域插槽,这个函数返回 VNodes:        render: function (createElement) {          // `<div><slot :text="msg"></slot></div>`          return createElement('div', [            this.$scopedSlots.default({              text: this.msg            })          ])        }        如果要用渲染函数向子组件中传递作用域插槽,可以利用 VNode 数据中的 scopedSlots 域:        render (createElement) {          return createElement('div', [            createElement('child', {              // pass `scopedSlots` in the data object              // in the form of { name: props => VNode | Array<VNode> }              scopedSlots: {                default: function (props) {                  return createElement('span', props.text)                }              }            })          ])        }5、JSX:      注意:将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的,如果在作用域中 h 失去作用,在应用中会触发报错。6、函数式组件    6.1、slots() 和 children 对比7、模板编译十六、插件1、开发插件:    插件通常会为 Vue 添加全局功能。插件的范围没有限制——一般有下面几种:        1、添加全局方法或者属性,如: vue-custom-element        2、添加全局资源:指令/过滤器/过渡等,如 vue-touch        3、通过全局 mixin 方法添加一些组件选项,如: vue-router        4、添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。        5、一个库,提供自己的 API,同时提供上面提到的一个或多个功能,如 vue-router    Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:        MyPlugin.install = function (Vue, options) {          // 1. 添加全局方法或属性          Vue.myGlobalMethod = function () {// 逻辑...}          // 2. 添加全局资源          Vue.directive('my-directive', {            bind (el, binding, vnode, oldVnode) {// 逻辑... }...})          // 3. 注入组件          Vue.mixin({            created: function () { // 逻辑... }   ...  })          // 4. 添加实例方法          Vue.prototype.$myMethod = function (methodOptions) {// 逻辑... }}2、使用插件    通过全局方法 Vue.use() 使用插件:// 调用 `MyPlugin.install(Vue)`    Vue.use(MyPlugin)    也可以传入一个选项对象:    Vue.use(MyPlugin, { someOption: true })    Vue.use 会自动阻止多次注册相同插件,届时只会注册一次该插件。十七、过滤器Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。1、过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:    <!-- 在双花括号中 -->    {{ message | capitalize }}    <!-- 在 `v-bind` 中 -->    <div v-bind:id="rawId | formatId"></div>2、可以在一个组件的选项中定义本地的过滤器:    filters: {      capitalize: function (value) {        if (!value) return ''//若该值为空,则返回空        value = value.toString()//否则将该值转为字符        return value.charAt(0).toUpperCase() + value.slice(1)//将该值的第一个字符转为大写      }    }3、全局定义过滤器:    Vue.filter('capitalize', function (value) {      if (!value) return ''      value = value.toString()      return value.charAt(0).toUpperCase() + value.slice(1)    })4、过滤器可以串联:    {{ message | filterA | filterB }}//将 filterA 的结果传递到 filterB 中。5、过滤器是 JavaScript 函数,因此可以接收参数:    {{ message | filterA('arg1', arg2) }}    这里,filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。工具十八、生产环境部署1、开启生产环境模式:    开发环境下,Vue 会提供很多警告来帮你对付常见的错误与陷阱。    而在生产环境下,这些警告语句却没有用,反而会增加应用的体积。    此外,有些警告检查还有一些小的运行时开销,这在生产环境模式下是可以避免的。    1.1、不使用构建工具:如果用 Vue 完整独立版本,即直接用 <script> 元素引入 Vue 而不提前进行构建,请记得在生产环境下使用压缩后的版本 (vue.min.js)。    1.2、使用构建工具2、模板预编译3、提取组件的 CSS4、跟踪运行时错误:如果在组件渲染时出现运行错误,错误将会被传递至全局 Vue.config.errorHandler 配置函数 (如果已设置)。利用这个钩子函数来配合错误跟踪服务是个不错的主意。十九、单文件组件1、介绍:在很多 Vue 项目中,我们使用 Vue.component 来定义全局组件,紧接着用 new Vue({ el: '#container '}) 在每个页面内指定一个容器元素。      缺点:全局定义 (Global definitions) ,强制要求每个 component 中的命名不得重复            字符串模板 (String templates) ,缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的            不支持 CSS (No CSS support) ,意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏            没有构建步骤 (No build step) ,限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器    1.1、怎么看待关注点分离?            一个重要的事情值得注意,关注点分离不等于文件类型分离。            我们已经发现相比于把代码库分离成三个大的层次并将其相互交织起来,把它们划分为松散耦合的组件再将其组合起来更合理一些。            在一个组件里,其模板、逻辑和样式是内部耦合的,并且把他们搭配在一起实际上使得组件更加内聚且更可维护。2、起步    2.1、例子沙箱    2.2、针对刚接触 JavaScript 模块开发系统的用户    2.3、针对高级用户
原创粉丝点击