一、key
v-for綁定key值刘急,為什么不建議使用index作為key值?
如果只是展示列表數(shù)據(jù)棚菊,key值可以是索引;如果列表中的數(shù)據(jù)會(huì)經(jīng)常發(fā)生變化叔汁,特別是列表數(shù)據(jù)的位置會(huì)發(fā)生變化统求,這時(shí)候key一定要設(shè)置為對(duì)象身上的唯一屬性检碗,比如:學(xué)號(hào)、工號(hào)球订、身份證號(hào)后裸、手機(jī)號(hào)等等。目的是:當(dāng)列表更新時(shí)冒滩,會(huì)大大提高列表重新渲染的性能損耗微驶。
因?yàn)関ue在渲染數(shù)據(jù)時(shí),先將數(shù)據(jù)生成一份虛擬DOM开睡,再將虛擬DOM生成對(duì)應(yīng)的真實(shí)DOM掛載到頁面中因苹。當(dāng)vue中的數(shù)據(jù)修改后,會(huì)重新生成一份虛擬DOM篇恒,并跟之前的虛擬DOM進(jìn)行匹配扶檐,如果兩份虛擬DOM中的key和key對(duì)應(yīng)的值完全相同,不會(huì)重新生成對(duì)應(yīng)的真實(shí)DOM胁艰;只有key和key對(duì)應(yīng)的值不同的虛擬DOM款筑,才會(huì)生成新的真實(shí)DOM并掛載的頁面中。
<div class="home">
<button @click="add">添加</button>
<ul>
<!-- 如果key是索引腾么,當(dāng)位置發(fā)生變化時(shí)奈梳,所有數(shù)據(jù)都會(huì)重新渲染 -->
<!-- <li v-for="(item, index) in list" :key="index">{{ item }}</li> -->
<!-- 如果id是索引,當(dāng)位置發(fā)生變化時(shí)解虱,只會(huì)渲染更新的數(shù)據(jù) -->
<li v-for="item in list" :key="item.id">{{ item }}</li>
</ul>
</div>
data() {
return {
list: [
{
id: 1001,
name: "張學(xué)友",
age: 21,
sex: "男",
},
{
id: 1002,
name: "郭富城",
age: 22,
sex: "男",
},
{
id: 1003,
name: "黎明",
age: 24,
sex: "男",
},
{
id: 1004,
name: "周潤發(fā)",
age: 26,
sex: "男",
},
],
};
},
methods: {
// 添加員工的方法
add() {
let em = {
id: Date.now(),
name: "蔡依林",
age: 22,
sex: "女",
};
this.list.unshift(em);
},
}
二攘须、$nextTick()
$nextTick():需要傳一個(gè)回調(diào)函數(shù)。將回調(diào)函數(shù)里面的代碼延遲到DOM渲染完畢后執(zhí)行殴泰。在修改數(shù)據(jù)之后立即使用它于宙,然后等待 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: "",
// 汽車數(shù)組
list: [
{
id: 1001,
name: "寶馬",
},
{
id: 1002,
name: "瑪莎拉蒂",
},
]
};
},
methods: {
addCar() {
let car = {
id: Date.now(),
name: this.carName,
};
this.list.push(car);
this.carName = "";
// $nextTick方法悍汛,需要傳一個(gè)回調(diào)函數(shù)捞魁。回調(diào)函數(shù)里面的代碼在DOM更新完成后執(zhí)行离咐。
this.$nextTick(() => {
// 讓最后一個(gè)li元素里面的input元素獲取焦點(diǎn)
// focus()方法用于為元素設(shè)置焦點(diǎn)署驻。
this.$refs.list.lastChild.lastChild.focus();
});
}
}
三、$forceUpdate()
$forceUpdate():進(jìn)行強(qiáng)制更新健霹。調(diào)用這個(gè)方法會(huì)更新視圖和數(shù)據(jù),觸發(fā)updated生命周期瓶蚂。
<button @click="person.name = '張三'">修改姓名</button>
<button @click="addSex">添加性別</button>
<div>{{ person }}</div>
data() {
return {
person: {
name: "張學(xué)友",
age: 20,
}
};
},
methods: {
addSex() {
// 添加響應(yīng)式屬性
// this.$set(this.person,"sex","男")
// 直接添加的屬性糖埋,不具備響應(yīng)式
this.person.sex = "男";
// 通過$forceUpdate()方法,迫使vue實(shí)例重新渲染
this.$forceUpdate();
}
}
四窃这、自定義指令
自定義指令就是一個(gè)方法瞳别,方法的第一個(gè)參數(shù)傳遞的是指令所在的DOM元素,方法的第二個(gè)參數(shù)是給指令綁定的數(shù)據(jù)。
1祟敛、局部指令
(1)定義指令
data() {
return {
car:'<h2>保時(shí)捷卡宴真好看</h2>'
}
},
// 定義局部指令疤坝,所有的指令背后都是在操作DOM,我們將這種功能稱之為:造輪子馆铁。
directives:{
// 注冊(cè)一個(gè)局部自定義指令 'v-red'跑揉,設(shè)置字體顏色為紅色
red:function(el){
el.style.color="red"
},
// 注冊(cè)一個(gè)局部自定義指令 'v-myhtml',渲染html標(biāo)簽數(shù)據(jù)
myhtml(el,bind){
el.innerHTML = bind.value
}
}
(2)使用指令
<div v-red>好好學(xué)習(xí)</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文件中導(dǎo)入指令
// 導(dǎo)入全局自定義指令
import './directives'
(3)使用指令
<divv-color="'red'">好好學(xué)習(xí)Vue</div>
五历谍、自定義插件
1、定義插件
定義一個(gè)插件辣垒,插件就是將給Vue添加的全局成員望侈,歸類到一起去,這樣做利于后期維護(hù)勋桶。
插件本質(zhì)上就是一個(gè)對(duì)象脱衙,該對(duì)象中必須包含一個(gè)install方法,方法的第一個(gè)參數(shù)是Vue例驹,第二個(gè)參數(shù)是配置對(duì)象捐韩。install()方法,會(huì)在use的時(shí)候執(zhí)行眠饮。Vue.use(插件)奥帘,這里的Vue會(huì)作為install方法的第一個(gè)參數(shù)。
// 插件本質(zhì)上就是一個(gè)對(duì)象
export default {
// 該對(duì)象中必須包含一個(gè)install()方法
install:function(Vue,options){
// 可以直接給Vue添加成員
Vue.sayHi = function(){
console.log('大家好仪召!我是Vue');
},
Vue.msg = "歡迎使用插件",
// 可以在Vue的原型上擴(kuò)展成員
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);
}
},
}),
// 注冊(cè)全局組件
Vue.component('b-box', {
// 在腳手架環(huán)境中,只能通過渲染函數(shù)定義全局組件
render(h) {
return h('div',this.$slots.default)
},
}),
// 注冊(cè)全局指令
Vue.directive('bgcolor', function(el,bind){
el.style.backgroundColor = bind.value
})
}
}
2扔茅、導(dǎo)入插件
// 導(dǎo)入自定義插件
import myPlugin from './plugins'
// 注意:一定要use
Vue.use(myPlugin)
3已旧、使用插件
<!-- 調(diào)用插件中定義的vue原型上的方法 -->
<button @click="sayhello">sayHello</button>
<!-- 調(diào)用插件中定義的vue方法 -->
<button @click="sayHi">sayHello</button>
<!-- 調(diào)用插件中定義的混入成員 -->
<button @click="showPlane">showPlane</button>
<div v-bgcolor="'lightblue'">我是淡藍(lán)色</div>
<b-box>哈哈</b-box>