摘要:定義是一個計算屬性類似于過濾器對綁定到的數據進行處理用法不可在里面定義如果定義會報如下圖片的錯誤因為對應的作為計算屬性定義并返回對應的結果給這個變量變量不可被重復定義和賦值和用法回調函數當需要讀取當前屬性值是執行,根據相關數據計算并返回當前
1.computed 1.1 定義
是一個計算屬性,類似于過濾器,對綁定到view的數據進行處理
1.2 get用法data: { firstName: "Foo", lastName: "Bar" }, computed: { fullName: function () { return this.firstName + " " + this.lastName } }
fullName不可在data里面定義,
如果定義會報如下圖片的錯誤,因為對應的computed作為計算屬性定義fullName并返回對應的結果給這個變量,變量不可被重復定義和賦值
data: { firstName: "Foo", lastName: "Bar" }, computed: { fullName:{ get(){//回調函數 當需要讀取當前屬性值是執行,根據相關數據計算并返回當前屬性的值 return this.firstName + " " + this.lastName }, set(val){//監視當前屬性值的變化,當屬性值發生變化時執行,更新相關的屬性數據 //val就是fullName的最新屬性值 console.log(val) const names = val.split(" "); console.log(names) this.firstName = names[0]; this.lastName = names[1]; } } }2. watch 2.1 定義
watch是一個觀察的動作
2.2 示例data: { firstName: "Foo", lastName: "Bar", fullName: "Foo Bar" }, watch: { firstName: function (val) { this.fullName = val + " " + this.lastName }, lastName: function (val) { this.fullName = this.firstName + " " + val } }
上面是監聽firstName和lastName的變化,但是僅限簡單數據類型
2.2 監聽簡單數據類型data(){ return{ "first":2 } }, watch:{ first(){ console.log(this.first) } },2.3 監聽復雜數據類型
1.監聽復雜數據類型需用深度監聽
data(){ return{ "first":{ second:0 } } }, watch:{ secondChange:{ handler(oldVal,newVal){ console.log(oldVal) console.log(newVal) }, deep:true } },
2.console.log打印的結果,發現oldVal和newVal值是一樣的,所以深度監聽雖然可以監聽到對象的變化,但是無法監聽到具體對象里面那個屬性的變化
3.oldVal和newVal值一樣的原因是它們索引同一個對象/數組。Vue 不會保留修改之前值的副本
vm.$watch的深度監聽
4.深度監聽對應的函數名必須為handler,否則無效果,因為watcher里面對應的是對handler的調用
2.4 監聽對象單個屬性方法一:可以直接對用對象.屬性的方法拿到屬性 data(){ return{ "first":{ second:0 } } }, watch:{ first.second:function(newVal,oldVal){ console.log(newVal,oldVal); } },
方法二:watch如果想要監聽對象的單個屬性的變化,必須用computed作為中間件轉化,因為computed可以取到對應的屬性值
data(){ return{ "first":{ second:0 } } }, computed:{ secondChange(){ return this.first.second } }, watch:{ secondChange(){ console.log("second屬性值變化了") } },3 computed和watch的區別 3.1 computed特性
1.是計算值,
2.應用:就是簡化tempalte里面{{}}計算和處理props或$emit的傳值
3.具有緩存性,頁面重新渲染值不變化,計算屬性會立即返回之前的計算結果,而不必再次執行函數
1.是觀察的動作,
2.應用:監聽props,$emit或本組件的值執行異步操作
3.無緩存性,頁面重新渲染時值不變化也會執行
傳入的值想作為局部變量來使用,直接使用會
props:["listShop"], data(){ return{} }, created(){ this.listShop=30 }
報錯
這個錯誤是說的避免直接修改父組件傳入的值,因為會改變父組件的值,貼上官網介紹
3.2 解決方案1簡單數據類型解決方案:
所以可以在data中重新定義一個變量,改變指向,但是也只是針對簡單數據類型,因為復雜數據類型棧存貯的是指針,
props:["listShop"], data(){ return{ listShopChild:this.listShop } }, created(){ this.listShopChild=30 }
這樣就可以愉快的更改傳入的簡單數據類型的數據啦!不會有任何報錯,也不會影響父組件!
3.4 存在的問題復雜數據類型在棧中存貯的是指針,所以賦值給新的變量也會改變原始的變量值.那么應該咋整呢?
1.可以手動深度克隆一個復雜的數據出來,循環或者遞歸都行
數組深度克隆:
var x = [1,2,3]; var y = []; for (var i = 0; i < x.length; i++) { y[i]=x[i]; } console.log(y); //[1,2,3] y.push(4); console.log(y); //[1,2,3,4] console.log(x); //[1,2,3]
對象深度克隆:
var x = {a:1,b:2}; var y = {}; for(var i in x){ y[i] = x[i]; } console.log(y); //Object {a: 1, b: 2} y.c = 3; console.log(y); //Object {a: 1, b: 2, c: 3} console.log(x); //Object {a: 1, b: 2}
函數深度克隆
var x = function(){console.log(1);}; var y = x; y = function(){console.log(2);}; x(); //1 y(); //2
為什么函數可以直接賦值克隆?
由于函數對象克隆之后的對象會多帶帶復制一次并存儲實際數據,因此并不會影響克隆之前的對象。所以采用簡單的復制“=”即可完成克隆。
2.Object.assign
只會對只是一級屬性復制,比淺拷貝多深拷貝了一層而已,所以還是無法達到深度克隆的目的.
詳請請戳
3.強大的JSON.stringify和JSON.parse
const obj1 = JSON.parse(JSON.stringify(obj));
這是ES5新出來的API,先將對象轉化為字符串,就是簡單數據類型賦值,再用JSON.parse轉化
3.5 解決方案2直接用computed改變
computed:{ listShopChild(){ return this.listShop } }3.5 存在的問題
注意:此時用computed時,如果是數組this.$set(arr,1,true)對應的值耶不更新,
這個很坑,這個bug我找個很久
如果傳入的值只是在data定義,并未在methods或生命周期鉤子更改,直接改變也會報錯
所以還是可以先用局部變量接收,再修改,這個坑比較多
監聽本組件計算和監聽
4.2 應用2計算或監聽父傳子的props值
4.3 應用3分為簡單數據類型和復雜數據類型監聽,監聽方法如上watch的使用
4.4 應用4監聽vuex的state或者getters值的變化
computed:{ stateDemo(){ return this.$store.state.demoState; } } watch:{ stateDemo(){ console.log("vuex變化啦") } }5. computed和watch的原理分析
很開心小伙伴們能看到這里,接下來給大家簡單羅列下他們的原理!
5.1 computed的原理深入理解 Vue Computed 計算屬性
5.2 watch的原理分為三個過程:實例化Vue、調用$watch方法、屬性變化,觸發回調
Vue的數據依賴實現原理簡析
vue中$watch源碼閱讀筆記
公共類
function defineReactive(data, key, val, fn) { let subs = [] // 新增 Object.defineProperty(data, key, { configurable: true, enumerable: true, get: function() { // 新增 if (data.$target) { subs.push(data.$target) } return val }, set: function(newVal) { if (newVal === val) return fn && fn(newVal) // 新增 if (subs.length) { // 用 setTimeout 因為此時 this.data 還沒更新 setTimeout(() => { subs.forEach(sub => sub()) }, 0) } val = newVal }, }) }6.1 computed實現
function computed(ctx, obj) { let keys = Object.keys(obj) let dataKeys = Object.keys(ctx.data) dataKeys.forEach(dataKey => { defineReactive(ctx.data, dataKey, ctx.data[dataKey]) }) let firstComputedObj = keys.reduce((prev, next) => { ctx.data.$target = function() { ctx.setData({ [next]: obj[next].call(ctx) }) } prev[next] = obj[next].call(ctx) ctx.data.$target = null return prev }, {}) ctx.setData(firstComputedObj) }6.1 watch實現
function watch(ctx, obj) { Object.keys(obj).forEach(key => { defineReactive(ctx.data, key, ctx.data[key], function(value) { obj[key].call(ctx, value) }) }) }
https://segmentfault.com/a/11...
大家如果發現有什么錯誤,歡迎指正,共同交流。如果覺得篇文章真的對你有點作用。
謝謝親們能看完!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/51721.html
摘要:定義是一個計算屬性類似于過濾器對綁定到的數據進行處理用法不可在里面定義如果定義會報如下圖片的錯誤因為對應的作為計算屬性定義并返回對應的結果給這個變量變量不可被重復定義和賦值和用法回調函數當需要讀取當前屬性值是執行,根據相關數據計算并返回當前 1.computed 1.1 定義 是一個計算屬性,類似于過濾器,對綁定到view的數據進行處理 1.2 get用法 data: { ...
摘要:當某個屬性發生變化,觸發攔截函數,然后調用自身消息訂閱器的方法,遍歷當前中保存著所有訂閱者的數組,并逐個調用的方法,完成響應更新。 編者按:我們會不時邀請工程師談談有意思的技術細節,希望知其所以然能讓大家在面試有更出色表現。也給面試官提供更多思路。 showImg(https://segmentfault.com/img/bVbgYyU?w=1200&h=600); 雖然目前的技術...
摘要:源碼對于計算屬性的理解這是我最近學習源碼的一個個人總結和理解,所以可能并不適合每一位讀者本文的整體脈絡如下,首先盡可能去掉細節,對計算屬性源碼的大致實現有一個了解,然后舉一例子,分別談談計算屬性依賴收集和派發更新的流程。 vue源碼-對于「計算屬性」的理解 這是我最近學習vue源碼的一個個人總結和理解,所以可能并不適合每一位讀者 本文的整體脈絡如下,首先盡可能去掉細節,對計算屬性源碼的...
摘要:當一個組件沒有聲明任何時,這里會包含所有父作用域的綁定和除外,并且可以通過傳入內部組件在創建高級別的組件時非常有用。 寫在前面 組件間的通信是是實際開發中非常常用的一環,如何使用對項目整體設計、開發、規范都有很實際的的作用,我在項目開發中對此深有體會,總結下vue組件間通信的幾種方式,討論下各自的使用場景 文章對相關場景預覽 父->子組件間的數據傳遞 子->父組件間的數據傳遞 兄弟...
摘要:知識點閉包問題執行機制定時器線程理解構造函數內的方法與構造函數屬性上方法的對比中都經歷了什么深入理解中的屬性和特性中的方法詳解為什么編程語言的都要定義數據類型中與的區別輕松理解基本包裝對象中數據類型內置對象包裝類型對象關系基礎之數組中的邏輯 JS知識點 JS hoist JS閉包問題 JS執行機制 JS定時器線程理解 構造函數內的方法與構造函數prototype屬性上方法的對比 JS...
閱讀 3758·2023-04-25 20:00
閱讀 3109·2021-09-22 15:09
閱讀 505·2021-08-25 09:40
閱讀 3412·2021-07-26 23:38
閱讀 2201·2019-08-30 15:53
閱讀 1097·2019-08-30 13:46
閱讀 2788·2019-08-29 16:44
閱讀 2043·2019-08-29 15:32