computed:{ 變量:function(){ return 計算好的值 } }
<template> <div class="watch"> <input type="text" v-model="msg" /> <input type="text" v-model="comsg" /> </div> </template> <script> export default { name: "watch", data() { return { msg: "123" }; }, methods: {}, computed: { comsg: function() { return this.msg .split("") .reverse() .join(""); } } }; </script>
效果:
初始有值的時候 就已經計算了,而且監聽數據改變從新計算
計算屬性的getter 和setter:以上咱們舉例的是默認的getter。vue
在你須要時,也能夠提供一個setter 函數, 當手動修改計算屬性的值就像修改一個普通數據那樣時,就會觸發setter 函數,執行一些自定義的操做數組
getter/setter語法緩存
computed: { 變量: { get: function() { return 計算的值; }, set: function(newold) { //當計算的值被改變時調用set console.log(newold); } } }
上面的例子,除了使用計算屬性外,咱們也能夠經過在表達式中調用方法來達到一樣的效果,那麼方法和computed都應該處於什麼場景呢app
computed:計算屬性是基於它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時纔會從新求值。函數
方法:每當觸發從新渲染時,調用方法將總會再次執行函數性能
假設咱們有一個性能開銷比較大的的計算屬性,它須要遍歷一個巨大的數組並作大量的計算。優化
若是沒有緩存,咱們將不可避免的屢次執行 它的 getter!若是你不但願有緩存,請用方法來替代。this
監聽大概能夠分爲三種 spa
上面說到計算屬性的時候 初始化的時候就能夠被監聽到而且計算 可是watch是發生改變的時候纔會觸發:例如 3d
這是基本用法
<template> <div class="watch"> <input type="text" v-model="msg" /> <input type="text" v-model="comsg" /> </div> </template> <script> export default { name: "watch", data() { return { msg: "123", comsg: "" }; }, methods: {}, watch: { msg(newval, old) { console.log(newval, old); this.comsg = this.msg .split("") .reverse() .join(""); } } }; </script>
效果:能夠發現 初始化的時候並無觸發 watch監聽 圖二改變的時候才觸發了watch
handler方法和immediate屬性
若是 父組件向子組件傳值時 這時候值並無發生改變咱們卻想在初始的時候就觸發watch 就須要這個屬性了 immediate 默認爲false 爲true時只初始化能夠被監聽
<template> <div class="watch"> <input type="text" v-model="msg" /> <input type="text" v-model="comsg" /> </div> </template> <script> export default { name: "watch", data() { return { msg: "123", comsg: "" }; }, methods: {}, watch: { msg: { handler(newval, old) { console.log(newval, old); this.comsg = this.msg .split("") .reverse() .join(""); }, immediate: true } } }; </script>
效果:
能夠看到 初始的時候就觸發了watch監聽 old打印爲undefined
注意到了嗎,咱們給 msg 綁定了一個方法,以前咱們寫的 watch 方法其實默認寫的就是這個,Vue.js會去處理這個邏輯,最終編譯出來其實就是這個。handlerhandlerhandlerhandler
watch 裏面還有一個屬性 deep
,默認值是 false
,表明是否深度監聽
語法:用來監聽obj
watch: { obj: { handler(newval, old) { //newval old }, immediate: true, deep: true } }
deep
的意思就是深刻觀察,監聽器會一層層的往下遍歷,給對象的全部屬性都加上這個監聽器,可是這樣性能開銷就會很是大了,任何修改obj
裏面任何一個屬性都會觸發這個監聽器裏的 handler。
若是監聽obj中的屬性 例如obj.a 就能夠優化,使用字符串形式監聽 這樣 vue會一層一層解析,直到碰見a屬性,而後給它設置監聽函數
watch: { 'obj.a': { handler(newval, old) { //newval old }, immediate: true, // deep: true } }
爲何要註銷 watch
?由於咱們的組件是常常要被銷燬的,好比咱們跳一個路由,從一個頁面跳到另一個頁面,那麼原來的頁面的 watch 其實就沒用了,這時候咱們應該註銷掉原來頁面的 watch 的,否則的話可能會致使內置溢出。咱們平時 watch 都是寫在組件的選項中的,會隨着組件的銷燬而銷燬。
若是這種寫法就須要手動註銷watch
const unWatch = app.$watch('text', (newVal, oldVal) => { console.log(`${newVal} : ${oldVal}`); }) unWatch(); // 手動註銷watch
watch: { '$route'(to,from){ console.log(to); //to表示去往的界面 console.log(from); //from表示來自於哪一個界面 if(to.path=="/lifeCycle"){
console.log("生命週期");
} } }