一、父組件向子組件傳值
1、首先創建父組件(parent)和子組件(child),並在父組件中注冊子組件
2、在父組件調用子組件標簽中添加一個自定義屬性(msg)
// 父組件
<template>
<div class="parent">
<Child :msg="parentMsg"></Child>
</div>
</template>
<script>
import Child from './child.vue';
export default {
data() {
return {
parentMsg: "我是傳給子組件的值"
};
},
components: {
Child
},
}
</script>
3、在子組件的props
中將父組件中自定義屬性(msg)添加進去,則該屬性在子組件中可以像data中定義的屬性一樣使用
// 子組件
<template>
<div class="child">
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
props: {
msg:{
type:String,
default:""
}
}
}
</script>
二、子組件向父組件傳值
1、在子組件中創建一個按鈕,給按鈕綁定一個點擊事件
2、在響應 點擊事件的函數中使用$emit
來發送一個自定義事件(listenChildEvent)給父組件,並傳遞一個參數
<template>
<div class="child">
<p>{{ msg }}</p>
<button @click="sendMsg">向父組件傳值</button>
</div>
</template>
<script>
export default {
props: {
msg:{
type:String,
default:""
}
},
methods:{
sendMsg(){
this.$emit("listenChildEvent","this message is from child");
}
}
}
</script>
3、在父組件調用子組件標簽中,監聽該自定義事件(listenChildEvent)並添加一個響應該事件的處理方法,並接收子組件傳過來的數據
<template>
<div class="parent">
<Child :msg="parentMsg" @listenChildEvent="acceptMsgFromChild"></Child>
</div>
</template>
<script>
import Child from './child.vue';
export default {
data() {
return {
parentMsg: "我是傳給子組件的值"
};
},
components: {
Child
},
methods:{
acceptMsgFromChild(data){
console.log(data);//或者將接受值處理
}
}
}
</script>
三、使用v-model實現父子組件通信
1、v-model
一般用於表單的雙向數據綁定
<template>
<div>
<input type="text"
v-model="msg">
<p>{{msg}}</p>
</div>
</template>
<script>
export default {
data () {
return {
msg: ''
}
}
}
</script>
2、v-model原理
由此看出,v-model是v-bind
和v-on:input
的結合,即監聽了表單的input事件,然后修改value屬性對應的值
<template>
<div>
<input type="text"
:value="msg"
@input="bind">
<p>{{msg}}</p>
</div>
</template>
<script>
export default {
data () {
return {
msg: ''
}
},
methods: {
bind () {
this.msg = event.target.value
}
}
}
</script>
3、v-model
除了在輸入表單上可以使用之外,在組件上也可以使用,以實現父子組件的雙向數據綁定
// -------------------------------父組件
<template>
<div>
<!-- 在父組件中用v-model相當於,v-bind綁定了value,以及執行了v-on:input事件 -->
<child v-model="flag"></child>
<div>{{flag}}</div>
</div>
</template>
<script>
export default {
data () {
return {
flag: ''
}
},
components: {
child
}
}
</script>
// -------------------------------子組件
<template>
<div>
<div class="btn" @click="confirm">確定</div>
</div>
</template>
<script>
export default {
// 用props接收父組件傳遞的value值,從而實現雙向數據綁定
props: {
value: {
type: Boolean,
default: true
}
},
methods: {
// 通過$emit觸發父組件的input事件,並將第二個參數作為值傳遞給父組件
confirm () {
this.$emit('input', false)
}
}
}
</script>
最后,父組件中的flag默認為true,點擊了子組件中的“確定”后,子組件將false傳遞給了父組件的flag
4、v-model添加model
選項
以上這種方式實現的父子組件的v-model通信,限制了popos接收的屬性名必須為value和emit觸發的必須為input,這樣容易有沖突,特別是在表單里面。所以,為了更優雅的使用v-model通信,可以在子組件中使用model
選項
// 子組件
<template>
<div>
<div class="btn" @click="confirm">確定</div>
</div>
</template>
<script>
export default {
// model選項用來避免沖突,prop屬性用來指定props屬性中的哪個值用來接收父組件v-model傳遞的值,例如:這里用props中的flag1來接收父組件傳遞的v-model值;event屬性可以理解為父組件@input的別名,從而避免沖突,即emit時要提交的事件名。
model: {
prop: 'flag1',
event: 'changed'
}
// 用props接收父組件傳遞的value值,從而實現雙向數據綁定
props: {
value: {
type: Boolean,
default: true
}
},
methods: {
// 通過$emit觸發父組件的input事件,並將第二個參數作為值傳遞給父組件
confirm () {
this.$emit('input', false)
}
}
}
</script>
5、v-model實現動態傳值
<template>
<div>
<new-input v-model="name"></new-input>{{name}}
</div>
</template>
<script>
import Vue from 'vue'
Vue.component('new-input', {
props: {
value: {
type: String
}
},
template: '<label><input type="text" v-model="newValue" /> 你的名字:</label>',
computed: {
newValue: {
get: function () {
return this.value
},
set: function (value) {
this.$emit('input', value)
}
}
}
})
export default {
data () {
return {
name: 'nick'
}
}
}
</script>