Vue的学习成本和难度不高,这除了和框架自己的设计理念有关以外,还和Vue完善的官方文档有着密不可分的关系,相信有不少的开发者和我同样,很长时间没有仔细去看过官方文档了,最近花时间仔细看了一下官方文档,将里面一些容易忽视的点整理出来和你们分享。html
ES6的普及使得箭头函数的使用更加频繁,可是在Vue中不要在选项属性或者回调上使用箭头函数,举个例子:vue
new Vue({ el: '#app', data: { show: true }, created: () => { console.log(this.show) }, })
将created钩子写成箭头函数,这里的this将再也不指向Vue对象,在浏览器中将会指向window对象,这是由于箭头函数并无this,this会做为变量一直向上级词法做用域查找,直到找到为止数组
Vue从2.6.0开始,能够用方括号括起来的JavaScript表达式做为一个指令参数,举个例子:浏览器
<div id="app"> <input v-on:[event] = "doSomething"> <button v-on:click="event = 'focus'">change</button> </div>
new Vue({ el: '#app', data() { return { event: 'input' } }, methods: { doSomething () { console.log('sss') } }, })
这里将input的事件监听设置为一个动态的参数event,默认是监听点击事件,当点击change的时候,改成监听focus事件,动态参数预期会求出一个字符串,异常状况下值为null,null值能够用于移除绑定,任何其余非字符串类型的值都会触发一个警告缓存
methods中提供的方法大多数时候都是用来给其余方法调用的,可是它其实也能够像computed计算属性同样直接写在模版里,举个例子:app
<div id="app">{{reversedMessage('hello')}}</div>
var app = new Vue({ el: '#app', methods: { reversedMessage: function (message) { return message.split('').reverse().join('') } }, })
有了computed计算属性,为何还要用methods呢?计算属性是基于响应式依赖进行缓存的,只在相关依赖发生改变时才会从新求值,而methods每次调用都会从新计算,调用methods时能够传参,进行指定计算,可是computed不行,这在遍历数组时十分有用框架
Vue会尽量高效地渲染元素,一般会复用已有元素而不是从头开始渲染。这么作会使 Vue变得很是快,举个例子:函数
<div id="app"> <template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template> <button @click="change">change</button> </div>
var app = new Vue({ el: '#app', data() { return { loginType: 'username' } }, methods: { change () { this.loginType = this.loginType === 'username' ? 'email' : 'username' } } })
上面代码中切换loginType将不会清除用户已经输入的内容,由于两个模版使用了相同的元素,若是不想复用也很简单,只须要添加一个具备惟一值的key属性便可:性能
<template v-if="loginType === 'username'"> <label>Username</label> <input key="username" placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input key="email" placeholder="Enter your email address"> </template> <button @click="change">change</button>
如今切换,每次都会从新渲染,可是label元素仍是会被复用,由于它没有加惟一key值学习
Vue的风格指南不推荐同时使用v-if与v-for,当项目中的eslint继承了@vue/standard时,同时使用就会编译报错,可是能够经过在模版上加<!-- eslint-disable -->进行忽略,同时当它们处于同一节点,v-for的优先级比v-if更高,这意味着v-if 将分别重复运行于每一个v-for循环中
在Vue中对于已经建立的实例,不容许动态添加根级别的响应式属性,可是咱们知道能够经过Vue.set(object, propertyName, value)方法向嵌套对象添加响应式属性,那若是须要为已有对象赋值多个新属性呢?举个例子:
<div id="app">{{user.name}}-{{user.age}}-{{user.sex}}</div>
var app = new Vue({ el: '#app', data() { return { user: { name: 'xxx' } } }, created() { this.user = Object.assign({}, this.user, { age: 18, sex: 'name' }) }, })
能够用Object.assign为这个对象从新赋值,这样就能添加多个新的响应式属性
有时在模版中调用方法时,咱们须要向方法中传参数,可是同时又要传递原始的DOM事件,怎么处理呢?举个例子:
<div id="app"> <button @click="share('share info', $event)">share</button> </div>
var app = new Vue({ el: '#app', data() { return { user: { name: 'xxx' } } }, methods: { share (info, event) { console.log(info, event) } }, })
如例子所示,能够用特殊变量$event把它传入方法
Vue中提供了多个事件修饰符, once、passive是后面新增的两个,once用于限定事件只触发一次,passive用于修饰的事件发生后当即触发,用于提高移动端性能
在默认状况下,v-model在每次input事件触发后将输入框的值与数据进行同步,能够添加lazy修饰符,从而转变为使用change事件进行同步,举个例子:
<input placeholder="lazy" v-model.lazy="msg" @input="input" @change="change">
若是想自动将用户的输入值转为数值类型,能够给v-model添加number修饰符,这一般颇有用,由于即便在type="number"时,HTML输入元素的值也总会返回字符串。若是这个值没法被 parseFloat()解析,则会返回原始的值,举个例子:
<input placeholder="number" v-model.number="age" @input="input">
若是要自动过滤用户输入的首尾空白字符,能够给v-model添加trim修饰符,举个例子:
<input placeholder="trim" v-model.trim="trim" @input="input">
在Vue中对于绝大多数特性来讲,从外部提供给组件的值会替换掉组件内部设置好的值。因此若是传入type="text"就会替换掉 type="date"并把它破坏!庆幸的是,class和 style特性会稍微智能一些,即两边的值会被合并起来,从而获得最终的值,举个例子:
<div id="app"> <base-input type="text" class="out"></base-input> </div>
Vue.component('base-input', { template: `<input type="date" placeholder="replace" class="default">` }) new Vue({ el: '#app', })
在上例中input的type值为date,class为deafault,在使用子组件时,向子组件中传入type="text" class="out",此时input的type值会被替换为text,class值会被合并为"default out",那么若是想要禁用属性继承怎么办呢?能够在组件的选项中设置inheritAttrs:false,举个例子:
Vue.component('base-input', { inheritAttrs: false, template: `<input type="date" placeholder="replace" class="default">` })
可是inheritAttrs:false选项不会影响style和class的绑定,所以style和class仍是会合并
在有些状况下,可能须要对一个 prop进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,由于子组件能够修改父组件,且在父组件和子组件都没有明显的改动来源,所以Vue提供了sync修饰符,举个例子:
<div id="app"> <span>{{title}}</span> <text-document v-bind:title.sync="title"></text-document> </div>
Vue.component('text-document', { props: ['title'], template: `<button @click="change">change</button>`, methods: { change () { this.$emit('update:title', 'change') } }, }) new Vue({ el: '#app', data() { return { title: 'default' } } })
当调用this.$emit('update:title', 'change'),父组件中的title就会改变
这篇文章对Vue中一些容易忽视的点进行了简单的总结,但愿看完以后能对你们有所帮助。若是有错误或不严谨的地方,欢迎批评指正,若是喜欢,欢迎点赞