(1)計算屬性javascript
模板的設計初衷是爲了處理簡單的邏輯(即聲明式邏輯),在模板中加入過多的邏輯會使模板難以閱讀和維護html
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div id="app"> <p>原始字符串:{{ message }}</p> <!-- 好比說,在模板中對 message 進行復雜的字符串反轉操做 --> <p>反轉字符串:{{ message.split('').reverse().join('') }}</p> </div> <script> var vm = new Vue({ el: '#app', data: { message: 'hello' } }) </script> </body> </html>
這時,咱們就應該考慮使用計算屬性,以代替複雜的模板邏輯vue
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div id="app"> <p>原始字符串:{{ message }}</p> <!-- 在模板中直接使用計算屬性 --> <p>反轉字符串:{{ reversedMessage }}</p> </div> <script> var vm = new Vue({ el: '#app', data: { message: 'hello' }, // computed 是 Vue 實例的計算屬性 // 它能夠是一個對象,其中每一項的鍵是計算屬性的名稱,值是計算屬性對應的函數 computed: { // 這裏,咱們聲明計算屬性 reversedMessage,用於儲存反轉以後的字符串 // 所提供的函數默認做爲計算屬性的 getter 函數(事實上還能夠提供 setter 函數) // 這裏的計算屬性 reversedMessage 依賴於 message // 也就是說,當 message 發生變化時,reversedMessage 會自動更新 reversedMessage: function () { return this.message.split('').reverse().join('') } } }) </script> </body> </html>
(2)computed & methodsjava
不知道你們還記不記得,咱們在以前的文章中有一個例子,使用 methods 實現反轉字符串的效果npm
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p>原始字符串:{{ message }}</p> <!-- 在模板中顯示方法的返回結果 --> <p>反轉字符串:{{ reversedMessage() }}</p> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { message: "Hello Vue" }, methods: { // 定義方法 reversedMessage(),返回反轉以後的字符串 reversedMessage: function () { return this.message.split('').reverse().join('') } } }) </script> </body> </html>
能夠看到,使用 computed 和 methods 實現的功能大致相同,可是它們的不一樣之處在於:緩存
對於計算屬性而言,計算結果將會被緩存,若是某個依賴在該實例範疇以外,那麼計算屬性是不會被更新的app
可是對於方法而言,調用方法總會再次執行代碼,咱們能夠從一個簡單的例子看出它們之間的區別:函數
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <!-- 注意,這裏是屬性調用 --> <p>第一次調用 computed:{{ msg_in_computed }}</p> <p>第二次調用 computed:{{ msg_in_computed }}</p> <br/> <!-- 注意,這裏是方法調用 --> <p>第一次調用 methods:{{ msg_in_methods() }}</p> <p>第二次調用 methods:{{ msg_in_methods() }}</p> </div> <script> var cnt_for_computed = 0; var cnt_for_methods = 0; var vm = new Vue({ el: '#app', computed: { // 定義計算屬性 msg_in_computed,屢次調用不會更新數據 // 由於它的依賴 cnt_for_computed 是非響應式屬性,不在實例範疇以內 msg_in_computed: function () { cnt_for_computed += 1; return cnt_for_computed } }, methods: { // 定義方法 msg_in_methods(),每次調用總會執行代碼 msg_in_methods: function () { cnt_for_methods += 1; return cnt_for_methods } } }) </script> </body> </html> <!-- 輸出結果 第一次調用 computed:1 第二次調用 computed:1 第一次調用 methods:1 第二次調用 methods:2 -->
(3)getter & setter學習
計算屬性默認只有 getter 函數this
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p>fullName: {{ fullName }}</p> <p>firstName: {{ firstName }}</p> <p>lastName: {{ lastName }}</p> </div> <script> var vm = new Vue({ el: '#app', data: { firstName: 'Steve', lastName: 'Jobs' }, computed: { // 若爲計算屬性提供一個函數,則該函數默認做爲計算屬性的 getter 函數 fullName: function () { return this.firstName + ' ' + this.lastName } } }) // 修改計算屬性依賴的值時,會自動調用計算屬性的 getter 函數 vm.firstName = 'Stephen' </script> </body> </html> <!-- 輸出結果 fullName: Stephen Jobs firstName: Stephen lastName: Jobs -->
可是,在須要的時候咱們也能夠提供一個 setter 函數
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p>fullName: {{ fullName }}</p> <p>firstName: {{ firstName }}</p> <p>lastName: {{ lastName }}</p> </div> <script> var vm = new Vue({ el: '#app', data: { firstName: 'Steve', lastName: 'Jobs' }, computed: { fullName: { // getter 函數 get: function () { return this.firstName + ' ' + this.lastName }, // setter 函數 set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } }) // 修改計算屬性的值時,會自動調用計算屬性的 setter 函數 vm.fullName = 'Tim Cook' </script> </body> </html> <!-- 輸出結果 fullName: Tim Cook firstName: Tim lastName: Cook -->
偵聽屬性是一個對象,鍵是須要觀察的表達式,值是 對應的回調函數 或者是 包含選項的對象
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <p>計數器: {{ counter }}</p> <button @click="counter++">點我</button> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { counter: 1 }, watch: { // 當 counter 發生變化時,會自動調用其對應的回調函數打印一條信息 counter: function(val, oldVal){ alert('計數器從 ' + val + ' 變爲 ' + oldVal); } } }); </script> </body> </html>
var vm = new Vue({ el: '#app', data: { counter: 1 }, watch: { // 使用對象能夠爲監聽屬性添加更多的配置信息 counter: { handler: function (val, oldVal) { alert('計數器從 ' + val + ' 變爲 ' + oldVal); }, deep: true, // 當監聽對象的屬性發生變化時(無論嵌套的深度),觸發回調 immediate: true // 在偵聽開始以後,當即觸發回調 }, } });
【 閱讀更多 Vue 系列文章,請看 Vue學習筆記 】