天天看點

vue——元件間通信方式

元件間通信:(父子、兄弟元件資料的傳遞方式)

一、父元件向子元件傳遞:

1、常見方式:利用屬性傳遞資料

$attrs表示元件中未被注冊的屬性;可以利用其進行傳值;配合v-bind可以将所有屬性傳遞給另一個元件;

vue——元件間通信方式
//根資料傳給元件,通過父元件傳給子元件:

   var vm = new Vue({ 
        el: "#app",
        data: {
            content: '我是内容',
            title: '我是标題'
        },
        components: {
            myContent: {
                // props: ['title', 'content'], //這種方法注冊的'content'隻是用來傳值,沒用實際作用
                props: ['title'],
                created () {//$attrs表示元件中未被注冊的屬性;可以利用其進行傳值;
                    console.log(this.$attrs)
                },
                inheritAttrs: false,     //設為false,沒有被注冊的屬性不會顯示在行間;(本身有的不會消除)
          
  // template: `<div>
            //                 <h3>{{ title }}</h3>
            //                 <my-p :content="content"></my-p>
            //             </div>`,
             template: `<div>
                            <h3>{{ title }}</h3>
                            <my-p v-bind="$attrs"></my-p>
                        </div>`,
            components: {
                myP: {
                    props: ['content'],
                    template: `<p>{{ content }}</p>`
                }
            }
        }
    }
})
           

2、$attrs、

$children:

一般情況下能不用不用,應急時使用(傳遞較麻煩)

vue——元件間通信方式
//根資料直接父元件用一部分、子元件用一部分:
        var vm1 = new Vue({
            el: "#app1",
            data: {
                content: '我是内容',
                title: '我是标題'
            },
            components: {
                myContent: {
                    created () {                    //$parent表示父元件的執行個體;
                        console.log(this.$parent);
                        this.title = this.$parent.title
                    },
                    mounted () {                  //$childre表示子元件的執行個體;
                        console.log(this.$children)
                    },
                     template: `<div>
                                    <h3>{{ title }}</h3>
                                    <my-p> {{ title }}</my-p>
                                </div>`,
                    components: {
                        myP: {
                            created () {
                                this.content = this.$parent.$parent.content;
                            },
                            template: `<p>{{ content }}</p>`
                        }
                    }
                }
            }
        })
           

3、provide:{}提供值,inject:[]接收值;(一般不用)

vue——元件間通信方式
//父元件提供值,子元件可以取到;
        var vm2 = new Vue({
            el: "#app2",
            provide: {
                content: '我是内容',
                title: '我是标題'
            },
            components: {
                myContent: {
                    inject: ['title'],
                     template: `<div>
                                    <h3>{{ title }}</h3>
                                    <my-p> {{ title }}</my-p>
                                </div>`,
                    components: {
                        myP: {
                            inject: ['content'],
                            template: `<p>{{ content }}</p>`
                        }
                    }
                }
            }
        })
           

二、子向父傳遞:

1、$children 方式擷取到子元件的執行個體,進行操作(不推薦)

2、$refs:拿到子元件的引用;可以dom上,也可以放到元件上;

vue——元件間通信方式
const vm3 = new Vue({
        el: "#app3",
        mounted  () {
            console.log(this.$refs.dom); //放到dom上;
            //這裡的dom元素如果初始時有多個且一樣,隻會列印最後一個;v-for生成的dom會全不列印在[]中;
            console.log(this.$refs.cmp); //放到元件上;this.$refs.cmp拿到子元件裡的執行個體;再拿到裡面的資料;
            console.log(this.$refs.cmp.msg);
            this.$refs.cmp.cmpFunc()
        },
        components: {
            myCmp: {
                data () {
                    return {
                        msg: 'hello'
                    }
                },
                methods: {
                    cmpFunc () {
                        console.log('cmp')
                    }
                },
                template: `<div> i am a cmp </div>`
            }
        }
    })
           

3、傳遞函數方式:通過在子元件中執行父元件的函數,向父元件傳遞資料

方法一:将父元件中的函數當做屬性傳給子元件執行;

方法二:利用 l i s t e n e r s : 能 夠 把 通 過 v − o n 綁 定 的 事 件 放 到 listeners:能夠把通過v-on綁定的事件放到 listeners:能夠把通過v−on綁定的事件放到listeners裡面來;

方法三:利用$emit(’’, );主動觸發元件v-on綁定的事件;第二個值可傳參用;

//注意:
//當事件綁定很多時,利用v-on給元件内某個dom綁定事件監聽(注意通過v-on方法不能傳參)
//$listeners與$attrs相似有一個v-on屬性,可以将該元件通過v-on綁定的事件傳遞給另一個元件;
//$listeners和$emit()不僅能觸發系統自帶的事件,也可以觸發自定義事件; 
           
vue——元件間通信方式
const vm4 = new Vue({
        el: "#app4",
        methods: {
            func (data) {
                console.log(data);
            },
            down (){
                console.log('down')
            }
        },
        components: {
            myCmp: {
                // props: ['func'],  //方法一
                data () {
                    return {
                        msg: 'hello'
                    }
                },
                methods: {
                    cmpFunc () {
                        console.log('cmp');
                    },
                    handleClick () {
                        // this.func(this.msg);  //方法一;
                        // this.$listeners.click(this.msg);  //方法二;
                        this.$emit('click', this.msg);    //方法三;
                    },
                    handleMouse () {
                        this.$emit('mousedown', 4545);
                    }
                },
                template: `<div> i am a cmp
                            <button @click="handleClick" @mousedown="handleMouse">點選</button>
                            <button v-on="$listeners"> click </button>
                            </div>`
            }
        }
    })
           

三、兄弟傳遞:

enent bus 事件總線: 一個兄弟組觸發新的vue執行個體事件并将資料傳參,另一個兄弟元件監聽該vue執行個體事件并取值;

this.bus. $emit(’’, )觸發事件;

this.bus. $on(’’, data => {})監聽事件;

vue——元件間通信方式
Vue.prototype.bus = new Vue();  //vue原型上增加屬性為一個新的vue執行個體;
    const vm5 = new Vue({
        el: "#app5",
        components: {
             myContent1: {      //一個兄弟組觸發新的vue執行個體事件并将資料傳參,
                data () {
                    return {
                        content: '我有值'
                    }
                },
                methods: {
                    handleClick () {
                        console.log(this)
                        this.bus.$emit('myClick', this.content); //觸發新vue執行個體的事件
                    }
                },
                template: `<div> {{ content }}
                            <button @click="handleClick">送出</button>
                          </div>`
            },
            myContent: {        //另一個兄弟元件監聽該vue執行個體事件并取值;
                data () {
                    return {
                        msg: 123
                    }
                },
                created () {
                    this.bus.$on('myClick', data => {    //監聽vue執行個體的事件
                         this.msg = data;
                    })
                },
                template: `<div> {{ msg }}</div>`
            },
        }})