Vue組建通信的幾種方法

組件通信一 —— props和$emit

props和$emit

父組件 向 子組件 傳遞數據 用 props

子組件 向 父組件 傳遞數據 用 $emit

父組件給子組件傳值

父給子

  1. 先給父組件中綁定自定義屬性,使用v-bind綁定要傳輸的數據
  1. 在子組件中使用 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>

子給父

將組件的

  1. 在父組件綁定 自定義的事件
methods:{
    reciveChild(val){
        this.childVal = val;
    }
},
teplate:`<div>我是父組件{{childVal}}<Child @reciveChild="reciveChild"/></div>`,
  1. 在子組件中是聲明一個事件,在函數中使用 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

多組件傳值的問題

父組件 與 子孫組件 相互傳值

父傳子孫

  1. 給每一個子孫組件賦予
v-bind="$attrs" v-on ="$listeners"

子組件綁定需要傳遞數據

:msg="msg"
  1. 到指定的子元素,使用
{{$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>

子孫傳父

  1. 父組件聲明函數,並綁定到子元素上
methods:{
    get(val){
        this.msg = val
    }
}

<App @get="get"></App>
  1. 子孫元素每個都綁定
v-bind="$attrs" v-on ="$listeners"
  1. 設置觸發函數,使用$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沒用,需要用bus.on

遇到的問題

使用官網下載的vue.js是會報錯,而引用官網的鏈接則沒事

方法:

  1. 創建總線
var bus = new Vue({});
  1. 數據源

數據源觸發事件

    此處的事件(){
        bus.$emit("數據接收位置聲明的事件",要傳遞的值);
    }
  1. 數據接收

數據接收位置,添加事件,爲全局事件,需要用到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,組件創建只會進行一次

  1. 傳值

使用provide傳值

兩種格式
provide:{
    傳遞的數據名:對應的數據值
}

provide(){
    return {
        傳遞的數據名:對應的數據值
    }
}
  1. 接收

使用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 官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章