組件通信一 —— props和$emit
props和$emit
父組件 向 子組件 傳遞數據 用 props
子組件 向 父組件 傳遞數據 用 $emit
父組件給子組件傳值
父給子
- 先給父組件中綁定自定義屬性,使用v-bind綁定要傳輸的數據
- 在子組件中使用 props 接受父組件傳遞的數據
Vue.component("",{
template:``,
props:[''],//接受父組件傳遞的數據,然後就可以直接使用
});
例如:
<div id="app"></div>
<script>
var Child = {
template :"<div> 我是子組件 {{msg}} </div>",
props:['msg'],
}
var Parent = {
data(){
return {
msg : "輸入 child",
}
},
components:{
Child,
},
template:`<div >我是父組件<Child :msg="msg"/><input type='text' v-model="msg"></div>`,
}
new Vue({
el :"#app",
components:{
Parent,
},
template:'<Parent />',
});
</script>
子給父
將組件的
- 在父組件綁定 自定義的事件
methods:{
reciveChild(val){
this.childVal = val;
}
},
teplate:`<div>我是父組件{{childVal}}<Child @reciveChild="reciveChild"/></div>`,
- 在子組件中是聲明一個事件,在函數中使用 this.$emit 觸發 父組件 自定義的 事件
this.$emit(父元素中自定義的事件名,需要傳給父元素的數據)
template :`<div> 我是子組件 <br><input type='text' @input='valChange' v-model:value="sendVal"></div>`,
methods:{
valChange(){
this.$emit('reciveChild',this.sendVal)
}
},
<div id="app"></div>
<script>
var Child = {
data(){
return{
msg:"",
}
},
template :`<div> 我是子組件 <br><input type='text' @input="inputs" v-model="msg"> </div>`,
methods:{
inputs(val){
this.$emit("recive",val.target.value);
}
}
}
var Parent = {
data(){
return {
val : "",
}
},
components:{
Child,
},
methods:{
recive(val){
this.val = val;
}
},
template:`<div>我是父組件:{{val}}<Child @recive='recive'/></div>`,
}
new Vue({
el :"#app",
components:{
Parent,
},
template:'<Parent />',
});
</script>
組件通信二 —— $attrs 和 $listeners
$ attrs 和 $listeners
多組件傳值的問題
父組件 與 子孫組件 相互傳值
父傳子孫
- 給每一個子孫組件賦予
v-bind="$attrs" v-on ="$listeners"
子組件綁定需要傳遞數據
:msg="msg"
- 到指定的子元素,使用
{{$attrs.要傳的值}}
<div id="app">
<App :msg="msg" >
<A v-bind="$attrs" v-on="$listeners" ></A>
</App>
</div>
<script>
Vue.component("App",{
template:`<div>{{$attrs.msg}}6</div>`,
})
Vue.component("A",{
template:`<div></div>`,
})
var vm = new Vue({
el:"#app",
data:{
msg:"hello",
demo:"world"
},
})
</script>
子孫傳父
- 父組件聲明函數,並綁定到子元素上
methods:{
get(val){
this.msg = val
}
}
<App @get="get"></App>
- 子孫元素每個都綁定
v-bind="$attrs" v-on ="$listeners"
- 設置觸發函數,使用$emit
methods:{
change(val){
this.$emit("get",val.target.value)
}
}
例子:
<div id="app"></div>
<script>
//$ attrs 和 $listeners
var C = {
data(){
return {
thePut:"",
}
},
template:'<div name="C"><input type="text" @input="GoodVal" v-model="thePut">來自祖組件:{{$attrs.good}}</div>',
methods:{
GoodVal(value){
this.$emit("goodC",this.thePut);
}
},
}
var B = {
components:{
C,
},
template:'<div name="B"><p>我是子孫組件<C v-bind="$attrs" v-on ="$listeners" /></p></div>',
}
var A = {
components:{
B,
},
template:'<div name="A"><p>我是子組件</p><B v-bind="$attrs" v-on ="$listeners" /></div>',
}
var Parent = {
data(){
return {
good:"helloworld!",
v_val:""
}
},
components:{
A,
},
template:'<div name="Parent"><p>我是父組件{{good}} ,來自子孫組件:{{v_val}}</p><A :good="good" @goodC="goodC" /></div>',
methods:{
goodC(val){
this.v_val = val;
}
}
}
new Vue({
el : "#app",
components:{
Parent,
},
template:'<Parent />',
});
</script>
組件通信三 —— 不同組件傳值
中央事件總線
不同組件之間的傳值
我的值可以傳過來,但是添加到頁面時不會顯示,還有就是用bus.bMsg或者this.bMsg都可以獲取值,this.on
遇到的問題
使用官網下載的vue.js是會報錯,而引用官網的鏈接則沒事
方法:
- 創建總線
var bus = new Vue({});
- 數據源
數據源觸發事件
此處的事件(){
bus.$emit("數據接收位置聲明的事件",要傳遞的值);
}
- 數據接收
數據接收位置,添加事件,爲全局事件,需要用到mountend(){}
使用$on創建事件,
mounted(){
bus.$on("事件名",處理函數);
}
例子:
<div id="app"></div>
<script>
var bus = new Vue({
data(){
return{
msg:"",
}
}
});
var A = {
template:`
<div>
這是A組件
<b>{{bus.msg}}</b>
</div>
`,
mounted(){
bus.$on("get",(val)=>{
bus.msg = val;
});
}
};
var B = {
data(){
return{
B_msg:""
}
},
template:`
<div>
這是B組件<input type="text" @input="input_B" v-model="B_msg">
</div>
`,
methods:{
input_B(){
bus.$emit("get",this.B_msg)
}
},
};
new Vue({
el:"#app",
components:{
A,B,
},
template:`
<div>
<A /><B />
</div>
`
});
</script>
組件通信四 —— provide和inject
父組件給傳子孫組件傳值
出現的問題:
傳遞數據無效,格式沒有問題,原因子組件沒有被父組件包含
傳遞的值不支持熱更新,只會傳遞一次,正如接收數據使用的created,組件創建只會進行一次
- 傳值
使用provide傳值
兩種格式
provide:{
傳遞的數據名:對應的數據值
}
provide(){
return {
傳遞的數據名:對應的數據值
}
}
- 接收
使用inject[''],接收傳遞的值,使用created將接收的數據傳遞到組件內部展示出來
inject:['msg'],
created(){
//將傳遞
},
例子:
<div id="app"></div>
<script>
var Children = {
data(){
return{
parentVal:""
}
},
template:`
<div>這子子組件<b>{{parentVal}}</b></div>
`,
inject:['msg'],
created(){
this.parentVal = this.msg;
},
}
var Child = {
data(){
return{
parentVal:""
}
},
template:`
<div :val="getVal">這子組件<b>{{parentVal}}</b></div>
`,
inject:['msg'],
created(){
this.parentVal = this.msg;
},
}
var Parent = {
data(){
return{
msg:"000"
}
},
components:{
Child,
Children
},
template:`
<div>這是父組件<input type="text" @input="inputs" v-model="msg"><Child /><Children /></div>
`,
provide(){
return{
msg:this.msg,
}
},
}
new Vue({
el:"#app",
components:{
Parent,
},
template:`<Parent />`,
})
</script>
組件通信五 —— $parent和$children
子傳父
$parent可以在子元素中調用父元素data中的參數,通過賦值獲取數據
getval(){
this.$parent.pval = this.children
}
因此在子元素中使用函數去觸發賦值
<script>
Vue.component("Child",{
data(){
return{
children:""
}
},
template:`
<div>這是子組件<input type="text" v-model="children" @input="getval"></div>
`,
methods:{
getval(){
this.$parent.pval = this.children
}
}
})
Vue.component("Parent",{
data(){
return{
pval:""
}
},
template:`
<div>這是父組件; 來自子組件的值:{{pval}}<br><Child /></div>
`,
})
new Vue({
el :"#app",
template:'<Parent />',
});
</script>
父傳子
$children可以在父元素中調用子元素data中的參數,通過賦值獲取數據
因此在父元素中使用函數去觸發賦值
getval(){
this.$children[0].children = this.pval
}
值得注意的是,當父元素的子元素有多個,使用數組的形式,通過索引獲取相應需要的子元素
<script>
Vue.component("Child",{
data(){
return{
children:""
}
},
template:`
<div>這是子組件;來自父組件的值:{{children}}</div>
`,
})
Vue.component("Parent",{
data(){
return{
pval:""
}
},
template:`
<div>這是父組件 <input type="text" v-model="pval" @input="getval"><br><Child /></div>
`,
methods:{
getval(){
this.$children[0].children = this.pval
}
}
})
new Vue({
el :"#app",
template:'<Parent />',
});
</script>
組件通信六 —— Vuex
Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式
採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
詳細內容可參考: Vuex 官方文檔