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-01vue+element-ui實(shí)現(xiàn)主題切換功能
這篇文章主要介紹了vue+element-ui實(shí)現(xiàn)主題切換功能,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06vue2 如何實(shí)現(xiàn)div contenteditable=“true”(類似于v-model)的效果
這篇文章主要給大家介紹了利用vue2如何實(shí)現(xiàn)div contenteditable="true",就是類似于v-model的效果,文中給出了兩種解決的思路,對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。2017-02-02vue 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-12Vue?圖片監(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-03vue-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