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