一、key
v-for绑定key值,为什么不建议使用index作为key值?
如果只是展示列表数据,key值可以是索引;如果列表中的数据会经常发生变化,特别是列表数据的位置会发生变化,这时候key一定要设置为对象身上的唯一属性,比如:学号、工号、身份证号、手机号等等。目的是:当列表更新时,会大大提高列表重新渲染的性能损耗。
因为vue在渲染数据时,先将数据生成一份虚拟DOM,再将虚拟DOM生成对应的真实DOM挂载到页面中。当vue中的数据修改后,会重新生成一份虚拟DOM,并跟之前的虚拟DOM进行匹配,如果两份虚拟DOM中的key和key对应的值完全相同,不会重新生成对应的真实DOM;只有key和key对应的值不同的虚拟DOM,才会生成新的真实DOM并挂载的页面中。
<div class="home">
<button @click="add">添加</button>
<ul>
<!-- 如果key是索引,当位置发生变化时,所有数据都会重新渲染 -->
<!-- <li v-for="(item, index) in list" :key="index">{{ item }}</li> -->
<!-- 如果id是索引,当位置发生变化时,只会渲染更新的数据 -->
<li v-for="item in list" :key="item.id">{{ item }}</li>
</ul>
</div>
data() {
return {
list: [
{
id: 1001,
name: "张学友",
age: 21,
sex: "男",
},
{
id: 1002,
name: "郭富城",
age: 22,
sex: "男",
},
{
id: 1003,
name: "黎明",
age: 24,
sex: "男",
},
{
id: 1004,
name: "周润发",
age: 26,
sex: "男",
},
],
};
},
methods: {
// 添加员工的方法
add() {
let em = {
id: Date.now(),
name: "蔡依林",
age: 22,
sex: "女",
};
this.list.unshift(em);
},
}
二、$nextTick()
$nextTick():需要传一个回调函数。将回调函数里面的代码延迟到DOM渲染完毕后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
<input type="text" v-model="carName" />
<button @click="addCar">添加汽车</button>
<ul ref="list">
<li v-for="item in list" :key="item.id">
<input type="text" :value="item.name" />
</li>
</ul>
data() {
return {
// 汽车名称
carName: "",
// 汽车数组
list: [
{
id: 1001,
name: "宝马",
},
{
id: 1002,
name: "玛莎拉蒂",
},
]
};
},
methods: {
addCar() {
let car = {
id: Date.now(),
name: this.carName,
};
this.list.push(car);
this.carName = "";
// $nextTick方法,需要传一个回调函数。回调函数里面的代码在DOM更新完成后执行。
this.$nextTick(() => {
// 让最后一个li元素里面的input元素获取焦点
// focus()方法用于为元素设置焦点。
this.$refs.list.lastChild.lastChild.focus();
});
}
}

三、$forceUpdate()
$forceUpdate():进行强制更新。调用这个方法会更新视图和数据,触发updated生命周期。
<button @click="person.name = '张三'">修改姓名</button>
<button @click="addSex">添加性别</button>
<div>{{ person }}</div>
data() {
return {
person: {
name: "张学友",
age: 20,
}
};
},
methods: {
addSex() {
// 添加响应式属性
// this.$set(this.person,"sex","男")
// 直接添加的属性,不具备响应式
this.person.sex = "男";
// 通过$forceUpdate()方法,迫使vue实例重新渲染
this.$forceUpdate();
}
}


四、自定义指令
自定义指令就是一个方法,方法的第一个参数传递的是指令所在的DOM元素,方法的第二个参数是给指令绑定的数据。
1、局部指令
(1)定义指令
data() {
return {
car:'<h2>保时捷卡宴真好看</h2>'
}
},
// 定义局部指令,所有的指令背后都是在操作DOM,我们将这种功能称之为:造轮子。
directives:{
// 注册一个局部自定义指令 'v-red',设置字体颜色为红色
red:function(el){
el.style.color="red"
},
// 注册一个局部自定义指令 'v-myhtml',渲染html标签数据
myhtml(el,bind){
el.innerHTML = bind.value
}
}
(2)使用指令
<div v-red>好好学习</div>
<div v-myhtml="car"></div>

2、全局指令
(1)定义指令
// 定义全局自定义指令
import Vue from 'vue'
Vue.directive('mycolor',function(el,bind){
el.style.color = bind.value
})
(2)main.js文件中导入指令
// 导入全局自定义指令
import './directives'
(3)使用指令
<divv-color="'red'">好好学习Vue</div>
五、自定义插件
1、定义插件
定义一个插件,插件就是将给Vue添加的全局成员,归类到一起去,这样做利于后期维护。
插件本质上就是一个对象,该对象中必须包含一个install方法,方法的第一个参数是Vue,第二个参数是配置对象。install()方法,会在use的时候执行。Vue.use(插件),这里的Vue会作为install方法的第一个参数。
// 插件本质上就是一个对象
export default {
// 该对象中必须包含一个install()方法
install:function(Vue,options){
// 可以直接给Vue添加成员
Vue.sayHi = function(){
console.log('大家好!我是Vue');
},
Vue.msg = "欢迎使用插件",
// 可以在Vue的原型上扩展成员
Vue.prototype.sayHello = function(){
console.log('哈哈!我是Vue原型上的方法');
},
// 给Vue混入成员
Vue.mixin({
data() {
return {
plane:{
name:'奔驰',
price:'100W'
}
}
},
methods: {
showPlane(){
console.log(this.plane.name,this.plane.price);
}
},
}),
// 注册全局组件
Vue.component('b-box', {
// 在脚手架环境中,只能通过渲染函数定义全局组件
render(h) {
return h('div',this.$slots.default)
},
}),
// 注册全局指令
Vue.directive('bgcolor', function(el,bind){
el.style.backgroundColor = bind.value
})
}
}
2、导入插件
// 导入自定义插件
import myPlugin from './plugins'
// 注意:一定要use
Vue.use(myPlugin)
3、使用插件
<!-- 调用插件中定义的vue原型上的方法 -->
<button @click="sayhello">sayHello</button>
<!-- 调用插件中定义的vue方法 -->
<button @click="sayHi">sayHello</button>
<!-- 调用插件中定义的混入成员 -->
<button @click="showPlane">showPlane</button>
<div v-bgcolor="'lightblue'">我是淡蓝色</div>
<b-box>哈哈</b-box>
网友评论