上一篇:父子組件間傳值
在上一篇中講解了父子組件之間是如何傳值的桐汤,如果子組件需要改變傳過來的數(shù)據(jù)供自己使用而克,或者想在子組件中改變傳過來的數(shù)據(jù)并同步到父組件,那么直接改肯定是不行的怔毛,如果你這么做了员萍,Vue 會(huì)在控制臺(tái)給出警告。
對(duì)應(yīng)這兩種情況拣度,解決方式如下:
先創(chuàng)建項(xiàng)目并運(yùn)行
vue init webpack-simple template
cd template
npm i
npm run dev
一碎绎、 子組件需要改變傳過來的數(shù)據(jù)供自己使用
1. 定義一個(gè)局部變量,并用 props 的值來初始化它
在 App.vue 中
<template>
<div class="hello">
<h3>我是 App 父組件</h3>
<h4>訪問自己的數(shù)據(jù):{{msg}},{{name}},{{user.id}}</h4>
<hr>
<!-- 1. 在調(diào)用子組件時(shí)抗果,綁定想要獲取的父組件中的數(shù)據(jù) -->
<Hello :message="msg"></Hello>
</div>
</template>
<script>
// 引入 Hello 組件
import Hello from './assets/components/Hello.vue'
export default {
data(){
return {
msg:'父組件',
name:'tom',
age:'22',
user:{
id:1234,
userName:'Jack'
}
}
},
// 注冊(cè) Hello 組件
components:{
Hello
}
}
</script>
在 Hello.vue 中
<template>
<div class="hello">
<h3>我是 hello 子組件</h3>
<!-- 在頁(yè)面中直接渲染即可 -->
<h4>訪問父組件中的數(shù)據(jù): {{msg}}</h4>
<button @click="change">改變父組件的數(shù)據(jù)</button>
</div>
</template>
<script>
export default {
// 2. 在子組件內(nèi)部筋帖,使用 props 選項(xiàng)聲明獲取的數(shù)據(jù),即接收來自父組件中的數(shù)據(jù)
props:['message'],
data(){
return {
// 定義一個(gè)局部變量冤馏,并用 props 的值來初始化它
msg:this.message
}
},
methods:{
// 定義一個(gè)方法日麸,來觸發(fā)改變父組件的數(shù)據(jù)
change(){
this.msg = '我改變了父組件的數(shù)據(jù)'
}
}
}
</script>
效果圖:
2. 定義一個(gè)計(jì)算屬性,處理 prop 的值并返回:
在 Hello.vue 中改動(dòng)
<script>
export default {
// 2. 在子組件內(nèi)部宿接,使用 props 選項(xiàng)聲明獲取的數(shù)據(jù)赘淮,即接收來自父組件中的數(shù)據(jù)
props:['message'],
data(){
return {
// 定義一個(gè)局部變量,并用 props 的值來初始化它
msg:this.message
}
},
computed:{
// 定義一個(gè)方法睦霎,來觸發(fā)改變父組件的數(shù)據(jù)
change(){
return this.msg = '我改變了父組件的數(shù)據(jù)'
}
}
}
</script>
當(dāng)頁(yè)面渲染成功自動(dòng)完成計(jì)算
二、子組件中改變傳過來的數(shù)據(jù)并同步到父組件
1. 使用 sync 修飾符走诞,它會(huì)被擴(kuò)展為一個(gè)自動(dòng)更新父組件屬性的 v-on 監(jiān)聽器
在 App.vue 中把 template 的內(nèi)容更改為
<template>
<div class="hello">
<h3>我是 App 父組件</h3>
<h4>訪問自己的數(shù)據(jù):{{msg}}</h4>
<hr>
<!-- 1. 在調(diào)用子組件時(shí)副女,綁定想要獲取的父組件中的數(shù)據(jù) -->
<!-- .sync 會(huì)被擴(kuò)展為一個(gè)自動(dòng)更新父組件屬性的 v-on 監(jiān)聽器 -->
<Hello :message.sync="msg"></Hello>
</div>
</template>
在 Hello.vue 中更改為
<template>
<div class="hello">
<h3>我是 hello 子組件</h3>
<!-- 在頁(yè)面中直接渲染即可 -->
<h4>訪問父組件中的數(shù)據(jù): {{message}}</h4>
<button @click="change">改變父組件的數(shù)據(jù)</button>
</div>
</template>
<script>
export default {
// 2. 在子組件內(nèi)部,使用 props 選項(xiàng)聲明獲取的數(shù)據(jù)蚣旱,即接收來自父組件中的數(shù)據(jù)
props:['message'],
methods:{
change(){
// 使用 .sync 時(shí)碑幅,需要顯式的觸發(fā)一個(gè)更新事件
// update 為固定寫法戴陡,后面跟將要被改變的數(shù)據(jù)對(duì)象,接著寫替換的數(shù)據(jù)
this.$emit('update:message','我改變了父組件的數(shù)據(jù)')
}
}
}
</script>
效果為:
2. 可以將父組件中的數(shù)據(jù)包裝成對(duì)象或數(shù)組沟涨,然后在子組件中修改對(duì)象的屬性
在 App.vue 中
<template>
<div class="hello">
<h3>我是 App 父組件</h3>
<h4>訪問自己的數(shù)據(jù):{{user.userName}}</h4>
<hr>
<!-- 2. 在調(diào)用子組件時(shí)恤批,綁定想要獲取的父組件中的數(shù)據(jù) -->
<Hello :user="user"></Hello>
</div>
</template>
<script>
// 引入 Hello 組件
import Hello from './assets/components/Hello.vue'
export default {
data(){
return {
// 1. 在父組件中把數(shù)據(jù)寫成對(duì)象的形式
user:{
id:1234,
userName:'Jack'
}
}
},
// 注冊(cè) Hello 組件
components:{
Hello
}
}
</script>
在 Hello.vue 中
<template>
<div class="hello">
<h3>我是 hello 子組件</h3>
<!-- 5. 在頁(yè)面中直接渲染即可 -->
<h4>訪問父組件中的數(shù)據(jù): {{user.userName}}</h4>
<button @click="change">改變父組件的數(shù)據(jù)</button>
</div>
</template>
<script>
export default {
// 3. 在子組件內(nèi)部,使用 props 選項(xiàng)聲明獲取的數(shù)據(jù)裹赴,即接收來自父組件中的數(shù)據(jù)
props:['message','user'],
methods:{
// 4.直接修改 user 對(duì)象中的數(shù)據(jù)
change(){
this.user.userName = 'Tom'
}
}
}
</script>
效果如下:
我們是不允許直接修改父組件傳過來的數(shù)據(jù)或?qū)ο蟮南才樱@種方法更改的是對(duì)象中的屬性,因?yàn)閷?duì)象是引用類型棋返,指向同一內(nèi)存空間延都,所以可以實(shí)現(xiàn)此效果。推薦使用該方式