非父子組件間的通訊:中央事件總線、父鏈、子組件索引

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="Vue.2.6.10.js"></script>
</head>
<body>
    <div id="app1"> {{ message }} <!-- <component-01 :is="component-01"></component-01>????? -->
        <component-01 ></component-01>
    </div>
    <div id="app2"> {{ message }} <component-02></component-02>
    </div>
    <div id="app3">
        <button @click = "handleRef">A</button>
        <!-- <button @click = "handleRef">B</button> <button @click = "handleRef">C</button> --> {{ message }} <component-a ref="comA" ></component-a>
        <!-- <component-b ref="comB" ></component-b> <component-c ref="comC" ></component-c> -->
    </div>
    <br>
    <!-- 並不能經過上面那種方式動態切換組件 試試這個 -->
    <div id="app4">
        <button @click="com = 'comA'">comA</button>
        <button @click="com = 'comB'">comB</button>
        <button @click="com = 'comC'">comC</button>
        <div :is = "com"></div>
        <component :is="com"></component>
    </div>
</body>
<script>
    //在Vue2.X中,推薦使用一個空的中央事件總線bus,即一箇中介(相似於鏈接租房者與房東的房屋中介)
    var bus = new Vue(); Vue.component('component-01',{ template:'<button @click="handleEvent" >傳遞事件</button>', methods: { handleEvent:function(){ bus.$emit('on-message','該內容來自組件01'); } }, }); // 在app1初始化時,即在生命週期mounted鉤子裏監聽(持續監聽?)來自bus的事件,
    // 而在組件01中點擊按鈕會經過bus將這個事件傳遞出去
    var app1 = new Vue({ el:"#app1", data:{ message:'' }, mounted() { var _this = this;//在一個代碼片斷裏this有可能表明不一樣的對象,而編碼者但願_this表明最初的對象
            //在實例初始化時監聽來自bus實例的事件
 bus.$on('on-message',function(msg){ _this.message = msg; }) }, }); Vue.component('component-02',{ template:'<button @click="handleEvent">經過父鏈直接修改數據</button>', methods:{ handleEvent:function(){ //訪問到父鏈後能夠進行任何操做,包括修改父組件數據等
                this.$parent.message = '來自組件02的內容'; // 雖然這種操做可以實現,但事實上子組件應該避免依賴父組件的數據,更不該該去修改(應該緩存一份?)
                //父子組件最好經過props和$emit來通訊
 console.log(this.$parent);//懂了!是整個Vue(app2)實例!
 } } }); var app2 = new Vue({ el:"#app2", data:{ message:'' }, }); Vue.component('component-a',{ template:'<div>子組件A</div>', data() { return { message:'來自子組件A!' } }, }); var app3 = new Vue({ el:"#app3", data:{ message:'', }, methods:{ handleRef:function(){ console.log( this, this.$refs, this.$refs["comA"], this.$refs["comA"].message //this.$refs.comA是錯誤的寫法 // NaN?
                    //因在組件渲染完成後再填充?
 ); this.message = this.$refs["comA"].message; } }, mounted(){ console.log(this.$children); } }); Vue.component('comA',{ template:'<div>子組件A</div>', }); Vue.component('comB',{ template:'<div>子組件B</div>', }); Vue.component('comC',{ template:'<div>子組件C</div>', }); var app4 = new Vue({ el:"#app4" , data:{ com:'comA' } }); </script>
</html>
相關文章
相關標籤/搜索