Vue自定義指令學(xué)習(xí)及應(yīng)用詳解
除了核心功能默認(rèn)內(nèi)置的指令,Vue.js允許注冊(cè)自定義指令。添加一個(gè)自定義指令,有兩種方式:
(1)通過Vue.directive()函數(shù)注冊(cè)一個(gè)全局的指令
(2)通過組件directives屬性,對(duì)該組件添加一個(gè)局部的指令
一、自定義指令v-mycolor
示例:
<div id="root">
<div v-mycolor="color" id="demo">
{{hello}}
</div>
</div>
<script>
Vue.config.productionTip = false;
Vue.directive('mycolor', function(el, binding, vnode) {
el.style = 'color:' + binding.value;
});
const vm = new Vue({
el: '#root',
data: {
hello:"你好",
color:'red'
},
methods: {
}
})
</script>執(zhí)行結(jié)果:

通過以上示例,可以看到網(wǎng)頁上的"你好"是紅色,說明自定義指令起到了作用。
在自定義指令中,可以傳遞是三個(gè)參數(shù):
el:指令所綁定的元素,可以用來直接操作DOM。
binding:一個(gè)對(duì)象,包含指令的很多信息。
vnode:Vue.js編譯生成的虛擬節(jié)點(diǎn)。
自定義指令生命周期:
(1)bind:只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用,用這個(gè)鉤子函數(shù)可以定義一個(gè)綁定時(shí)執(zhí)行一次的初始化動(dòng)作
(2)nserted:被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用(父節(jié)點(diǎn)存在即可調(diào)用,不必存在與document中)。
(3)update:被綁定于元素所在的模板更新時(shí)調(diào)用,而無論綁定至是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新。
(4)componentUpdated:被綁定元素所在模板完成一次更新周期時(shí)調(diào)用。
(5)unbind:只調(diào)用一次,指令與元素解綁時(shí)調(diào)用
二、使用鉤子函數(shù)的自定義指令
鉤子函數(shù)的參數(shù)如下所示:
el:與上面介紹的一樣,el是指令所綁定的元素,可以用來直接操作DOM;
示例:
<div id="root">
<div v-mycolor="color" id="demo">
{{num}}
</div>
<div>
<button @click="add">Add</button>
</div>
</div>
<script>
Vue.config.productionTip = false;
Vue.directive('mycolor',{
bind:function(){
console.log('1-綁定時(shí)調(diào)用bind');
},
inserted:function(el,binding,vnode){
alert('綁定到節(jié)點(diǎn)時(shí)調(diào)用inserted');
console.log('2-綁定到節(jié)點(diǎn)時(shí)調(diào)用inserted');
el.style='color:'+binding.value;
},
update:function(el,binding,vnode){
alert('3-組件更新時(shí)調(diào)用update');
console.log('3-組件更新時(shí)調(diào)用update');
el.style='color:green';
},
componentUpdated:function(){
console.log('4-組件更新完成時(shí)調(diào)用componentUpdated');
}
})
const vm = new Vue({
el: '#root',
data: {
num:10,
color:'red'
},
methods: {
add:function(){
this.num++;
}
}
})
</script>執(zhí)行結(jié)果:
運(yùn)行后,瀏覽器會(huì)彈出"綁定到節(jié)點(diǎn)時(shí)調(diào)用inserted",這時(shí)文字的顏色會(huì)變成紅色,且瀏覽器的控制中輸出:


當(dāng)點(diǎn)擊"Add"按鈕時(shí),瀏覽器會(huì)彈出"3-組件更新時(shí)調(diào)用update",這時(shí)文字會(huì)由"10"變成11,字體顏色會(huì)變成綠色:


三、Vue實(shí)現(xiàn)簡(jiǎn)單的學(xué)生信息管理系統(tǒng)
實(shí)現(xiàn)學(xué)生信息的增刪改查和分頁功能,及按照學(xué)生年齡進(jìn)行降序排序,升序排序和原順序
全部源代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue-2.7.14.js"></script>
<style>
* {
margin: 0px;
padding: 0px;
}
#root {
margin: 0px auto;
width: 900px;
height: auto;
background-color: orange;
}
div {
margin: 0px auto;
border: 2px solid black;
width: 98%;
text-align: center;
padding-top: 10px;
padding-bottom: 10px;
}
table {
width: 98%;
margin: 1px auto;
border: 2px solid black;
border-collapse: collapse;
}
th,
td {
border: 2px solid black;
padding: 5px;
}
label {
margin-left: 10px;
}
input {
height: 30px;
}
button {
width: 100px;
height: 30px;
}
span {
margin-left: 50px;
margin-right: 50px;
}
</style>
</head>
<body>
<div id="root">
<div>
<h2>學(xué)生信息管理系統(tǒng)</h2>
<div>
<h2>添加信息</h2><br>
<div>
<input type="text" placeholder="請(qǐng)輸入學(xué)號(hào)" v-model="id">
<input type="text" placeholder="請(qǐng)輸入姓名" v-model="name">
<input type="text" placeholder="請(qǐng)輸入性別" v-model="sex">
<input type="text" placeholder="請(qǐng)輸入年齡" v-model="age">
<button v-on:click="add">提交</button>
</div><br>
<div>
<h2>查詢信息</h2><br>
<input type="text" placeholder="請(qǐng)輸入要查詢的姓名" v-model.lazy="keyword">
<button @click="search()">查詢</button>
</div>
</div><br>
<div>
<table>
<tr>
<th>序號(hào)</th>
<th>學(xué)號(hào)</th>
<th>姓名</th>
<th>性別</th>
<th>年齡</th>
<th>創(chuàng)建時(shí)間</th>
<th>操作</th>
</tr>
<tr v-for="(student,index) in dataShow" :key="student.id">
<td>{{index+1}}</td>
<td>{{student.id}}</td>
<td>{{student.name}}</td>
<td>{{student.sex}}</td>
<td>{{student.age}}</td>
<td>{{student.ctime | newTime}}</td>
<td>
<button @click.prevent='toEdit(student.id)'>修改</button>
<button @click.prevent="del(index)">刪除</button>
</td>
</tr>
<tr>
<td align="right" colspan="7">共計(jì) {{count}} 人</td>
</tr>
</table>
</div><br>
<div>
<select v-model="pageSize" v-on:change="changePageSize">
<option value="5">5頁</option>
<option value="10">10頁</option>
<option value="15">15頁</option>
<option value="20">20頁</option>
</select>
<button v-on:click="firstPage" :disabled="currentPage === 1">首頁</button>
<button v-on:click="previousPage" :disabled="currentPage === 1">上一頁</button>
<button v-on:click="nextPage" :disabled="currentPage === totalPages">下一頁</button>
<button v-on:click="lastPage" :disabled="currentPage === totalPages">尾頁</button>
<span>當(dāng)前是第{{ currentPage }}頁 / 總共{{ totalPages }}頁</span>
</div>
<br>
<div v-show="flag">
<h2>修改信息</h2>
<br><br>
<label>學(xué)號(hào):<input type="text" placeholder="請(qǐng)輸入學(xué)號(hào)" v-model="id2"></label>
<label>姓名:<input type="text" placeholder="請(qǐng)輸入姓名" v-model="name2"></label>
<br><br>
<label>性別:<input type="text" placeholder="請(qǐng)輸入性別" v-model="sex2"></label>
<label>年齡:<input type="text" placeholder="請(qǐng)輸入年齡" v-model="age2"></label>
<br><br>
<button @click="add2(editIndex)">保存</button>
</div>
<div>
<span><button style="width: 150px;" v-on:click="sortType=2">按年齡升序</button></span>
<span><button style="width: 150px;" v-on:click="sortType=1">按年齡降序</button></span>
<span><button style="width: 150px;" v-on:click="sortType=0">原順序</button></span>
</div>
</div>
</div>
<script>
Vue.config.productionTip = false;
Vue.filter("newTime", (value) => {
year = value.getFullYear();
month = value.getMonth() + 1;
day = value.getDate();
return `${year}年${month}月${day}日`;
// return year + "年" + month + "月" + day + "日"
})
const vm = new Vue({
el: '#root',
data: {
flag: false,//true表示修改窗口展開,false表示窗口關(guān)閉
id: "",
name: "",
sex: "",
age: "",
id2: "",
name2: "",
sex2: "",
age2: "",
keyword: "",
time: "",
sortType: 0,//0表示原順序,1表示降序,2表示升序
editIndex: null, // 保存正在編輯的對(duì)象的索引,初始值不能為0及0以上的數(shù)
students: [
{ id: "00001", name: "張三", sex: "男", age: 20, ctime: new Date() },
{ id: "00002", name: "李四", sex: "女", age: 19, ctime: new Date() },
{ id: "00003", name: "王五", sex: "男", age: 18, ctime: new Date() },
{ id: "00004", name: "趙六", sex: "男", age: 19, ctime: new Date() },
{ id: "00005", name: "李力", sex: "男", age: 21, ctime: new Date() },
{ id: "00006", name: "二狗", sex: "男", age: 17, ctime: new Date() },
{ id: "00007", name: "狗蛋", sex: "女", age: 20, ctime: new Date() },
{ id: "00008", name: "三炮", sex: "男", age: 19, ctime: new Date() },
{ id: "00009", name: "劉仁", sex: "女", age: 19, ctime: new Date() },
{ id: "00010", name: "四兒", sex: "男", age: 22, ctime: new Date() }
],
newStudents: [],
currentPage: 1,//當(dāng)前頁數(shù),默認(rèn)為1
pageSize: 5,//每頁顯示數(shù)量
},
computed: {
//計(jì)算有幾組學(xué)生信息
count() {
return this.fillPersons.length;
},
dataShow() {
let start = (this.currentPage - 1) * this.pageSize;
let end = Math.min((this.currentPage) * this.pageSize, this.count);
return this.fillPersons.slice(start, end);
},
//計(jì)算總頁數(shù)
totalPages() {
return Math.ceil(this.count / this.pageSize) || 1;
},
//對(duì)學(xué)生信息進(jìn)行排序
fillPersons() {
// 找到第一個(gè)滿足條件的元素就終止過濾操作
const arr = this.students.filter((p) => {
return p.name.indexOf(this.keyword) !== -1;
});
//對(duì)學(xué)生信息進(jìn)行升序降序和原順序排序
if (this.sortType) {
arr.sort((p1, p2) => {
return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age;
});
}
return arr;
}
},
methods: {
//更改每頁顯示的記錄數(shù)時(shí)更新當(dāng)前頁碼,以確保在更改每頁記錄數(shù)后,
// 用戶仍然可以看到正確的記錄列表。
changePageSize() {
this.currentPage = 1;
},
//首頁
firstPage() {
this.currentPage = 1;
},
//上一頁
previousPage() {
this.currentPage -= 1;
},
//下一頁
nextPage() {
this.currentPage += 1;
},
//尾頁
lastPage() {
this.currentPage = this.totalPages;
},
//添加操作
add() {
//添加進(jìn)對(duì)應(yīng)的學(xué)生信息
this.students.push({
id: this.id,
name: this.name,
sex: this.sex,
age: this.age,
ctime: new Date()
});
//重新賦空值
this.id = "",
this.name = "",
this.sex = "",
this.age = ""
},
//刪除操作
del(index) {
//根據(jù)下標(biāo)刪除對(duì)應(yīng)的學(xué)生信息
this.students.splice(index, 1);
},
//查詢操作
search() {
//判斷是否輸入查詢內(nèi)容
if (this.keyword) {
// this.students = this.newStudents;
//找到滿足條件的元素并賦值
var list = this.students.filter(item => item.name.indexOf(this.keyword) > -1);
if (list.length != 0) {
alert("查詢成功");
this.students = list;
} else {
alert("查詢失敗");
this.students = [];
}
this.keyword = ''
} else {
alert("請(qǐng)輸入要查找的姓名");
}
},
// 修改操作
toEdit(id) {
//定位索引
this.editIndex = id;
// flag 調(diào)成 true,調(diào)出修改操作窗口
this.flag = true;
// filter 操作:找到第一個(gè)滿足條件的元素就終止過濾操作
let student = this.students.filter(stu => {
// 注意:此時(shí)的返回值 student 是一個(gè)對(duì)象
return stu.id == id;
});
// 此時(shí)在文本框中顯示的是:已經(jīng)選中的學(xué)生信息
this.id2 = student[0].id;
this.name2 = student[0].name;
this.sex2 = student[0].sex;
this.age2 = student[0].age;
},
// 修改保存操作
add2(editIndex) {
// flag 調(diào)成 false,就表示是關(guān)閉修改操作窗口
this.flag = false;
//查找需要修改的的下標(biāo)
var index = this.students.findIndex((item) => {
if (item.id == this.editIndex) {
return true;
}
})
//刪除對(duì)應(yīng)下標(biāo)的學(xué)生信息
this.students.splice(index, 1);
// //把最最新的學(xué)生信息重新添加
this.students.push({
id: this.id2,
name: this.name2,
sex: this.sex2,
age: this.age2,
ctime: new Date()
});
// //重新賦空值
this.id2 = "",
this.name2 = "",
this.sex2 = "",
this.age2 = ""
},
}
})
</script>
</body>
</html>執(zhí)行結(jié)果:

上圖只展示了主界面,其他功能請(qǐng)自行復(fù)制粘貼到vscode中執(zhí)行修改!
到此這篇關(guān)于Vue自定義指令學(xué)習(xí)及應(yīng)用詳解的文章就介紹到這了,更多相關(guān)Vue自定義指令內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vant的Loading加載動(dòng)畫組件的使用(通過接口拿數(shù)據(jù)時(shí)顯示加載狀態(tài))
這篇文章主要介紹了vant的Loading加載動(dòng)畫組件的使用,通過接口拿數(shù)據(jù)時(shí)顯示加載狀態(tài),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
vue+element-ui實(shí)現(xiàn)主題切換功能
這篇文章主要介紹了vue+element-ui實(shí)現(xiàn)主題切換功能,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
vue2 如何實(shí)現(xiàn)div contenteditable=“true”(類似于v-model)的效果
這篇文章主要給大家介紹了利用vue2如何實(shí)現(xiàn)div contenteditable="true",就是類似于v-model的效果,文中給出了兩種解決的思路,對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。2017-02-02
vue vuex vue-rouert后臺(tái)項(xiàng)目——權(quán)限路由(適合初學(xué))
這篇文章主要介紹了vue vuex vue-rouert后臺(tái)項(xiàng)目——權(quán)限路由,通過本文可以很清除的捋清楚vue+vuex+vue-router的關(guān)系,本版本非常簡(jiǎn)單,適合初學(xué)者,需要的朋友可以參考下2017-12-12
Vue?圖片監(jiān)聽鼠標(biāo)滑輪滾動(dòng)實(shí)現(xiàn)圖片縮小放大功能(實(shí)現(xiàn)思路)
其實(shí)想要實(shí)現(xiàn)功能很簡(jiǎn)單,就是在一張圖片上監(jiān)聽鼠標(biāo)滑輪滾動(dòng)的事件,然后根據(jù)上滾還是下滾實(shí)現(xiàn)圖片的縮放,這篇文章主要介紹了Vue?實(shí)現(xiàn)圖片監(jiān)聽鼠標(biāo)滑輪滾動(dòng)實(shí)現(xiàn)圖片縮小放大功能,需要的朋友可以參考下2023-03-03
vue-vuex中使用commit提交mutation來修改state的方法詳解
今天小編就為大家分享一篇vue-vuex中使用commit提交mutation來修改state的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09
在vue里面設(shè)置全局變量或數(shù)據(jù)的方法
下面小編就為大家分享一篇在vue里面設(shè)置全局變量或數(shù)據(jù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03

