web前端 -- vue -- vue 中非父子組件通訊辦法

根據千峯教育學習視頻所練習的筆記 | 學習一段時間,我也有寫一點東西的必要了···html

vue中除了父子組件外,還能遇到非父子組件的通訊,有如下兩種方法能解決。

1. 空實例與自定義事件

  • 我先在<div>裏面寫兩個組件,<dear-feifei><dear-zhangliuping>,這兩個組件就是非父子組件的關係。如今我想在在<dear-zhangliuping>進行了一些操做,怎樣能將數據傳入到<dear-feifei>當中。

1.1. 先來康康大體的代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue 非父子組件通訊</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <dear-feifei></dear-feifei>
    <dear-zhangliuping></dear-zhangliuping>
</div>
<script>
    var vm = new Vue({
        el:'#app',
        components:{
            'dear-feifei':{
                template:'<h2>{{message}}</h2>',
                data:function () {
                    return{
                        message:'hello feifei'
                    };
                },
            },
            'dear-zhangliuping':{
                template:'<ul><li v-for="item in list">{{item}}</li></ul>',
                data:function () {
                    return{
                        list:['哈哈','呵呵','吼吼']
                    };
                },
            }
        }
    });
</script>
</body>
</html>

1.2. 接着咱們來看如何來交互

  • 我須要到<dear-zhangliuping>組件中添加一個事件:
template:'<ul><li @click="getContent" v-for="item in list">{{item}}</li></ul>',
  • 而後咱們到下邊寫個methods添加剛纔寫的 getContent 方法。咱們要用這個方法獲得內容,並想辦法傳入到<dear-feifei>裏面。咱們還需在開頭建立一個空實例,就能夠調用這個實例的 $emit 添加自定義事件來進行觸發
var busVm = new Vue(); //定義空實例
<script>
······
'dear-zhangliuping':{
    template:'<ul><li @click="getContent" v-for="item in list">{{item}}</li></ul>',
    data:function () {
        return{
            list:['哈哈','呵呵','吼吼']
        };
    },
    methods:{
        getContent:function (ev) {
            busVm.$emit('changeEvents',ev.target.innerHTML);
        }
    }
    ······
</script>

1.3. 如今已經能夠發佈了,但咱們怎麼在另外一個組件裏訂閱呢?

  • 咱們能夠在<dear-feifei>裏面經過生命週期進行訂閱,用mounted。在裏面用 $on 來接收事件。
<script>
'dear-feifei':{
    template:'<h2>{{message}}</h2>',
    data:function () {
        return{
            message:'hello feifei'
        };
    },
    mounted:function () {//用於接收分發過來的數據
        busVm.$on('changeEvents',function (str) {
            console.log(str);
        });
    }
},
</script>
  • 如今點擊 list 裏的內容,就能看到數據能傳輸了:

  • 咱們如何對 message 進行修改
mounted:function () {
    busVm.$on('changeEvents',function (str) {
        console.log(str);
        this.message = str;
        <!-- this 指向busVM這個對象,要去修正,以指向dear-feifei -->
    }.bind(this));//綁定之後就指向dear-feifei了
}

  • 這樣就完成了非父子組件通訊vue

    1.4. 總結:

  • 咱們先定義一個空實例,而後在想要傳輸數據的位置進行一個 $emit 觸發
  • 在想要接收的位置,用 $on 的方式進行接收,造成一個發佈與訂閱的模式,來實現數據的交互,就完成了非父子組件的通訊vuex

2. vuex 狀態管理

上面的方法能解決簡單的項目,但稍微複雜一點的項目咱們就用vuex的方法了app

  • 我先在<div>容器裏寫兩個組件
<div id="app">
    <div>{{count}}</div>
    <addbtn></addbtn>
    <removebtn></removebtn>
</div>
<script>
    var busVm = new Vue();
    var vm = new Vue({
        el:'#app',
        data:{
            count:0
        },
        components:{
            'addbtn':{
                template:'<button >+</button>',
            },
            'removebtn':{
                template:'<button >-</button>',
            }
        }
    });
</script>

2.1. 渲染結果就是上圖這樣子的啦,如今我想經過點擊按鈕來實現加減的處理

  • 能夠發現這兩個組件是共享這個 count,這個時候就涉及到非父子組件的通訊了。我能夠利用 props 傳輸數據,而後在組件裏掛載,使數據既能夠傳到 addbtn 中又能傳到 removebtn 這兩個組件中。而後再去 props 中接收 key 值
<div id="app">
    <addbtn :count="count"></addbtn>
    <removebtn :count="count"></removebtn>
</div>
<script>
components:{
    ·····
    'addbtn':{
        template:'<button >+</button>',
        props:['count'],
</script>

2.2. 那我能夠添加一個方法到組件中,使得點擊的時候觸發一下,接着把發佈功能完善

<script>
    ······
        components:{
            'addbtn':{
                template:'<button @click="setCount">+</button>',
                props:['count'],
                methods:{
                    setCount:function () {
                        busVm.$emit('changeEvents',this.count+1);
                    }
                }
            },
            'removebtn':{
                template:'<button @click="setCount">-</button>',
                props:['count'],
                methods:{
                    setCount:function () {
                        busVm.$emit('changeEvents',this.count-1);
                    }
                }
            }
        }
    });
</script>

2.3. 發佈已經寫好了,咱們仍是用 mounted 進行訂閱

var busVm = new Vue(); //定義空實例
    var vm = new Vue({
        el:'#app',
        data:{
            count:0
        },
        mounted:function(){
            busVm.$on('changeEvents',function (num) {
                this.count = num;
            }.bind(this));
        },
  • 如今就已經完成了
相關文章
相關標籤/搜索