Vue自定義指令學習及應用詳解
除了核心功能默認內(nèi)置的指令,Vue.js允許注冊自定義指令。添加一個自定義指令,有兩種方式:
(1)通過Vue.directive()函數(shù)注冊一個全局的指令
(2)通過組件directives屬性,對該組件添加一個局部的指令
一、自定義指令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í)行結果:
通過以上示例,可以看到網(wǎng)頁上的"你好"是紅色,說明自定義指令起到了作用。
在自定義指令中,可以傳遞是三個參數(shù):
el:指令所綁定的元素,可以用來直接操作DOM。
binding:一個對象,包含指令的很多信息。
vnode:Vue.js編譯生成的虛擬節(jié)點。
自定義指令生命周期:
(1)bind:只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數(shù)可以定義一個綁定時執(zhí)行一次的初始化動作
(2)nserted:被綁定元素插入父節(jié)點時調用(父節(jié)點存在即可調用,不必存在與document中)。
(3)update:被綁定于元素所在的模板更新時調用,而無論綁定至是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新。
(4)componentUpdated:被綁定元素所在模板完成一次更新周期時調用。
(5)unbind:只調用一次,指令與元素解綁時調用
二、使用鉤子函數(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-綁定時調用bind'); }, inserted:function(el,binding,vnode){ alert('綁定到節(jié)點時調用inserted'); console.log('2-綁定到節(jié)點時調用inserted'); el.style='color:'+binding.value; }, update:function(el,binding,vnode){ alert('3-組件更新時調用update'); console.log('3-組件更新時調用update'); el.style='color:green'; }, componentUpdated:function(){ console.log('4-組件更新完成時調用componentUpdated'); } }) const vm = new Vue({ el: '#root', data: { num:10, color:'red' }, methods: { add:function(){ this.num++; } } }) </script>
執(zhí)行結果:
運行后,瀏覽器會彈出"綁定到節(jié)點時調用inserted",這時文字的顏色會變成紅色,且瀏覽器的控制中輸出:
當點擊"Add"按鈕時,瀏覽器會彈出"3-組件更新時調用update",這時文字會由"10"變成11,字體顏色會變成綠色:
三、Vue實現(xiàn)簡單的學生信息管理系統(tǒng)
實現(xià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>學生信息管理系統(tǒng)</h2> <div> <h2>添加信息</h2><br> <div> <input type="text" placeholder="請輸入學號" v-model="id"> <input type="text" placeholder="請輸入姓名" v-model="name"> <input type="text" placeholder="請輸入性別" v-model="sex"> <input type="text" placeholder="請輸入年齡" v-model="age"> <button v-on:click="add">提交</button> </div><br> <div> <h2>查詢信息</h2><br> <input type="text" placeholder="請輸入要查詢的姓名" v-model.lazy="keyword"> <button @click="search()">查詢</button> </div> </div><br> <div> <table> <tr> <th>序號</th> <th>學號</th> <th>姓名</th> <th>性別</th> <th>年齡</th> <th>創(chuàng)建時間</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">共計 {{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>當前是第{{ currentPage }}頁 / 總共{{ totalPages }}頁</span> </div> <br> <div v-show="flag"> <h2>修改信息</h2> <br><br> <label>學號:<input type="text" placeholder="請輸入學號" v-model="id2"></label> <label>姓名:<input type="text" placeholder="請輸入姓名" v-model="name2"></label> <br><br> <label>性別:<input type="text" placeholder="請輸入性別" v-model="sex2"></label> <label>年齡:<input type="text" placeholder="請輸入年齡" 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表示窗口關閉 id: "", name: "", sex: "", age: "", id2: "", name2: "", sex2: "", age2: "", keyword: "", time: "", sortType: 0,//0表示原順序,1表示降序,2表示升序 editIndex: null, // 保存正在編輯的對象的索引,初始值不能為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,//當前頁數(shù),默認為1 pageSize: 5,//每頁顯示數(shù)量 }, computed: { //計算有幾組學生信息 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); }, //計算總頁數(shù) totalPages() { return Math.ceil(this.count / this.pageSize) || 1; }, //對學生信息進行排序 fillPersons() { // 找到第一個滿足條件的元素就終止過濾操作 const arr = this.students.filter((p) => { return p.name.indexOf(this.keyword) !== -1; }); //對學生信息進行升序降序和原順序排序 if (this.sortType) { arr.sort((p1, p2) => { return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age; }); } return arr; } }, methods: { //更改每頁顯示的記錄數(shù)時更新當前頁碼,以確保在更改每頁記錄數(shù)后, // 用戶仍然可以看到正確的記錄列表。 changePageSize() { this.currentPage = 1; }, //首頁 firstPage() { this.currentPage = 1; }, //上一頁 previousPage() { this.currentPage -= 1; }, //下一頁 nextPage() { this.currentPage += 1; }, //尾頁 lastPage() { this.currentPage = this.totalPages; }, //添加操作 add() { //添加進對應的學生信息 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ù)下標刪除對應的學生信息 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("請輸入要查找的姓名"); } }, // 修改操作 toEdit(id) { //定位索引 this.editIndex = id; // flag 調成 true,調出修改操作窗口 this.flag = true; // filter 操作:找到第一個滿足條件的元素就終止過濾操作 let student = this.students.filter(stu => { // 注意:此時的返回值 student 是一個對象 return stu.id == id; }); // 此時在文本框中顯示的是:已經(jīng)選中的學生信息 this.id2 = student[0].id; this.name2 = student[0].name; this.sex2 = student[0].sex; this.age2 = student[0].age; }, // 修改保存操作 add2(editIndex) { // flag 調成 false,就表示是關閉修改操作窗口 this.flag = false; //查找需要修改的的下標 var index = this.students.findIndex((item) => { if (item.id == this.editIndex) { return true; } }) //刪除對應下標的學生信息 this.students.splice(index, 1); // //把最最新的學生信息重新添加 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í)行結果:
上圖只展示了主界面,其他功能請自行復制粘貼到vscode中執(zhí)行修改!
到此這篇關于Vue自定義指令學習及應用詳解的文章就介紹到這了,更多相關Vue自定義指令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vant的Loading加載動畫組件的使用(通過接口拿數(shù)據(jù)時顯示加載狀態(tài))
這篇文章主要介紹了vant的Loading加載動畫組件的使用,通過接口拿數(shù)據(jù)時顯示加載狀態(tài),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01vue2 如何實現(xiàn)div contenteditable=“true”(類似于v-model)的效果
這篇文章主要給大家介紹了利用vue2如何實現(xiàn)div contenteditable="true",就是類似于v-model的效果,文中給出了兩種解決的思路,對大家具有一定的參考價值,有需要的朋友們下面來一起看看吧。2017-02-02vue vuex vue-rouert后臺項目——權限路由(適合初學)
這篇文章主要介紹了vue vuex vue-rouert后臺項目——權限路由,通過本文可以很清除的捋清楚vue+vuex+vue-router的關系,本版本非常簡單,適合初學者,需要的朋友可以參考下2017-12-12Vue?圖片監(jiān)聽鼠標滑輪滾動實現(xiàn)圖片縮小放大功能(實現(xiàn)思路)
其實想要實現(xiàn)功能很簡單,就是在一張圖片上監(jiān)聽鼠標滑輪滾動的事件,然后根據(jù)上滾還是下滾實現(xiàn)圖片的縮放,這篇文章主要介紹了Vue?實現(xiàn)圖片監(jiān)聽鼠標滑輪滾動實現(xiàn)圖片縮小放大功能,需要的朋友可以參考下2023-03-03vue-vuex中使用commit提交mutation來修改state的方法詳解
今天小編就為大家分享一篇vue-vuex中使用commit提交mutation來修改state的方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09