Vue:計算屬性、內容分發、自定義事件
什么是計算屬性
計算屬性的重點突出在 屬性
兩個字上(屬性是名詞),首先它是個 屬性
其次這個屬性有 計算
的能力(計算是動詞),這里的 計算
就是個函數;簡單點說,它就是一個能夠將計算結果緩存起來的屬性(將行為轉化成了靜態的屬性),僅此而已;可以想象為緩存!
上代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>狂神說Java</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script> </head> <body> <div id="vue"> <!--注意,一個是方法,一個是屬性--> <p>調用當前時間的方法:{{currentTime1()}}</p> <p>當前時間的計算屬性:{{currentTime2}}</p> </div> <script type="text/javascript"> var vm = new Vue({ el: '#vue', data: { message: 'Hello Vue' }, methods: { currentTime1: function () { return Date.now(); } }, computed: { //currentTime2 ,這是一個屬性!不是方法 currentTime2: function () { this.message; return Date.now(); } } }); </script> </body> </html>
注意:methods 和 computed 里的東西不能重名
說明:
- methods:定義方法,調用方法使用 currentTime1(),需要帶括號
- computed:定義計算屬性,調用屬性使用 currentTime2,不需要帶括號;this.message 是為了能夠讓 currentTime2 觀察到數據變化而變化
- 如何在方法中的值發生了變化,則緩存就會刷新!可以在控制台使用
vm.message="qinjiang"
,改變下數據的值,再次測試觀察效果!
結論:
調用方法時,每次都需要進行計算,既然有計算過程則必定產生系統開銷,那如果這個結果是不經常變化的呢?此時就可以考慮將這個結果緩存起來,采用計算屬性可以很方便的做到這一點,計算屬性的主要特性就是為了將不經常變化的計算結果進行緩存,以節約我們的系統開銷;
內容分發
在 Vue.js
中我們使用 <slot>
元素作為承載分發內容的出口,作者稱其為 插槽,可以應用在組合組件的場景中;
測試
比如准備制作一個待辦事項組件(todo),該組件由待辦標題(todo-title)和待辦內容(todo-items)組成,但這三個組件又是相互獨立的,該如何操作呢?
第一步: 定義一個待辦事項的組件
<div id="vue"> <todo></todo> </div> <script type="text/javascript"> Vue.component('todo', { template: '<div>\ <div>待辦事項</div>\ <ul>\ <li>學習狂神說Java</li>\ </ul>\ </div>' }); </script>
第二步: 我們需要讓,待辦事項的標題和值實現動態綁定,怎么做呢? 我們可以留出一個插槽!
1-將上面的代碼留出一個插槽,即 slot
Vue.component('todo', { template: '<div>\ <slot name="todo-title"></slot>\ <ul>\ <slot name="todo-items"></slot>\ </ul>\ </div>' });
2-定義一個名為 todo-title 的待辦標題組件 和 todo-items 的待辦內容組件
Vue.component('todo-title', { props: ['title'], template: '<div>{{title}}</div>' });
//這里的index,就是數組的下標,使用for循環遍歷的時候,可以循環出來! Vue.component('todo-items', { props: ['item', 'index'], template: '<li>{{index + 1}}. {{item}}</li>' });
3-實例化 Vue 並初始化數據
var vm = new Vue({ el: '#vue', data: { todoItems: ['狂神說Java', '狂神說運維', '狂神說前端'] } });
4-將這些值,通過插槽插入
<div id="vue"> <todo> <todo-title slot="todo-title" title="秦老師系列課程"></todo-title> <todo-items slot="todo-items" v-for="(item, index) in todoItems" v-bind:item="item" v-bind:index="index" :key="index"></todo-items> </todo> </div>
說明:我們的 todo-title 和 todo-items 組件分別被分發到了 todo 組件的 todo-title 和 todo-items 插槽中
自定義事件
通過以上代碼不難發現,數據項在 Vue 的實例中,但刪除操作要在組件中完成,那么組件如何才能刪除 Vue 實例中的數據呢?此時就涉及到參數傳遞與事件分發了,Vue 為我們提供了自定義事件的功能很好的幫助我們解決了這個問題;使用 this.$emit('自定義事件名', 參數),操作過程如下:
1-在vue的實例中,增加了 methods 對象並定義了一個名為 removeTodoItems 的方法
var vm = new Vue({ el: '#vue', data: { title: "秦老師系列課程1", todoItems: ['狂神說Java', '狂神說運維', '狂神說前端'] }, methods: { // 該方法可以被模板中自定義事件觸發 removeTodoItems: function (index) { console.log("刪除 " + this.todoItems[index] + " 成功"); // splice() 方法向/從數組中添加/刪除項目,然后返回被刪除的項目,其中 index 為添加/刪除項目的位置,1 表示刪除的數量 this.todoItems.splice(index, 1); } } });
2-修改 todo-items 待辦內容組件的代碼,增加一個刪除按鈕,並且綁定事件!
Vue.component('todo-items', { props: ['item', 'index'], template: '<li>{{index + 1}}. {{item}} <button @click="remove_component">刪除</button></li>', methods: { remove_component: function (index) { // 這里的 remove 是自定義事件的名稱,需要在 HTML 中使用 v-on:remove 的方式指派 this.$emit('remove', index); } } });
3-修改 todo-items 待辦內容組件的 HTML 代碼,增加一個自定義事件,比如叫 remove,可以和組件的方法綁定,然后綁定到vue的方法中!
<!--增加了 v-on:remove="removeTodoItems(index)" 自定義事件,該事件會調用 Vue 實例中定義的名為 removeTodoItems 的方法--> <todo-items slot="todo-items" v-for="(item, index) in todoItems" v-bind:item="item" v-bind:index="index" :key="index" v-on:remove="removeTodoItems(index)"></todo-items>
邏輯理解
Vue 入門小結
核心 : 數據驅動 , 組件化
優點 : 借鑒了 AngulaJS 的模塊化開發 和 React 的虛擬Dom , 虛擬Dom就是把Dom操作放到內存中執行;
常用的屬性:
- v-if
- v-else-if
- v-else
- v-for
- v-on 綁定事件 , 簡寫
@
- v-model 數據雙向綁定
- v-bind 給組件綁定參數,簡寫
:
組件化:
- 組合組件 slot 插槽
- 組件內部綁定事件需要使用到
this.$emit("事件名",參數)
; - 計算屬性的特色,緩存計算數據
遵循SoC 關注度分離原則,Vue是純粹的視圖框架,並不包含,比如Ajax之類的通信功能,為了解決通信問題,我們需要使用Axios 框架做異步通信;
說明
Vue的開發都是要基於NodeJS, 實際開發采用 vue-cli腳手架開發,vue-router 路由,vuex做狀態管理; Vue UI,界面我們一般使用 ElementUI(餓了么出品),或者ICE(阿里巴巴出品!)來快速搭建前端項目~
官網: