vue中子組件如何間接修改父組件傳遞過來的值問題
一、前言
Vue中遵循單向數(shù)據(jù)流,所有的 props 都遵循著單向綁定原則,props 因父組件的更新而變化,自然地將新的狀態(tài)向下流往子組件,而不會逆向傳遞。
這避免了子組件意外修改父組件的狀態(tài)的情況,不然應(yīng)用的數(shù)據(jù)流將很容易變得混亂而難以理解。
但是項目中總是有需求讓我們來修改子組件內(nèi)部傳入的prop,所以才有了這篇文章,其實我們可以間接修改數(shù)據(jù)。
二、使用背景
父組件傳遞給子組件一個名為count數(shù)據(jù),但是現(xiàn)在要在子組件中修改它的值并且實時更新頁面,直接this.count是不能直接修改他的值的,控制臺會報錯,報錯如下。
所以我采用了下面兩種方式間接更改。
三、解決方法
方法1
子組件通過computed計算屬性來間接修改父組件傳遞的值
父組件傳值
<GoodsBasic :renderObj='renderBasic' :count='count'></GoodsBasic>
子組件更改傳入的值
<template> <div class='goodsBasic'> <div>{{ incrementCount}}</div> <button @click='changeCount'>增加次數(shù)</button> </div> </template> <script> export default { props: { renderObj: { type: Object, default () { return {} } }, count:{ type: Number, default:0 } }, data () { return { increment: this.count //新定義一個變量,并把prop傳進來的值作為初始值 } }, computed:{ incrementCount(){ //當新定義的變量變更時,計算屬性也會自動更新 return this.increment } }, methods: { changeCount(){ this.increment++ } } } </script>
方法2
子組件data中重新定義個局部數(shù)據(jù),把父組件prop傳來的數(shù)據(jù)作為初始值使用。
父組件傳值
<GoodsBasic :renderObj='renderBasic' :count='count'></GoodsBasic>
子組件更改傳入的值
<template> <div class='goodsBasic'> <div>{{ increment }}</div> <button @click='changeCount'>增加次數(shù)</button> </div> </template> export default { props: { renderObj: { type: Object, default () { return {} } }, count:{ type: Number, default:0 } }, data () { return { increment: this.count //作為初始值使用,這樣做就使prop和后續(xù)更新無關(guān)了 } }, methods: { changeCount(){ this.increment++ } } } </script>
四、更改對象 / 數(shù)組類型的 props
經(jīng)過個人測試發(fā)現(xiàn),當傳入的prop為Object類型的時候,修改組件內(nèi)部的prop可以對應(yīng)的改變父組件中的值。
如果傳入的prop為簡單類型(例如String,Number等)時,瀏覽器會報錯,提示子組件不能修改prop的值。
比如上文例子更改 renderBasic.price
控制臺就不會報錯。
個人感覺當傳入的prop為引用類型時,子組件能直接修改父組件值,是因為在堆內(nèi)存中公用同一個內(nèi)存地址;修改的話只是改了它的值,而內(nèi)存地址并沒變,所以不報錯;
基本數(shù)據(jù)類型修改會報錯,原因是指向的內(nèi)存地址要被迫修改,所以控制臺報錯。
另外Vue官方文檔也說了:
- 當對象或數(shù)組作為 props 被傳入時,雖然子組件無法更改 props 綁定,但仍然可以更改對象或數(shù)組內(nèi)部的值。
- 這是因為 JavaScript 的對象和數(shù)組是按引用傳遞,而對 Vue 來說,禁止這樣的改動,雖然可能生效,但有很大的性能損耗,比較得不償失。
- 這種更改的主要缺陷是它允許了子組件以某種不明顯的方式影響父組件的狀態(tài),可能會使數(shù)據(jù)流在將來變得更難以理解。在最佳實踐中,你應(yīng)該盡可能避免這樣的更改,除非父子組件在設(shè)計上本來就需要緊密耦合。
- 在大多數(shù)場景下,子組件應(yīng)該拋出一個事件來通知父組件做出改變。
目前我們公司有個項目就是就是因為父子組件數(shù)據(jù)需要緊密耦合的,所以直接在子組件更改了數(shù)據(jù);
上面文檔說的子組件應(yīng)該拋出一個事件來通知父組件做出改變,意思就是子組件調(diào)用$emit
拋出一個事件名,去通知父組件,值要改變了,在父組件寫一個事件做后續(xù)處理。
想繼續(xù)深入vue傳值的問題,也可以去看我之前關(guān)于vue中傳值方法的文章。
vue組件之間的傳值方法(父子傳值,兄弟傳值,跨級傳值,vuex)
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3中實現(xiàn)拖拽和縮放自定義看板 vue-grid-layout的方法
這篇文章主要介紹了Vue3中實現(xiàn)拖拽和縮放自定義看板 vue-grid-layout的方法,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03mockjs+vue頁面直接展示數(shù)據(jù)的方法
這篇文章主要介紹了mockjs+vue頁面直接展示數(shù)據(jù)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12vue-element-admin如何轉(zhuǎn)換成中文
這篇文章主要介紹了vue-element-admin如何轉(zhuǎn)換成中文問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03vuex?mutations的兩種調(diào)用方法小結(jié)
這篇文章主要介紹了vuex?mutations的兩種調(diào)用方法小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03基于ant-design-vue實現(xiàn)表格操作按鈕組件
這篇文章主要為大家介紹了基于ant-design-vue實現(xiàn)表格操作按鈕組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06