vue.js原生組件化開發(二)——父子組件 前言 父子組件創建流程

前言

在瞭解父子組件之前應先掌握組件開發基礎。在實際開發過程中,組件之間可以嵌套,也因此生成父子組件。

父子組件創建流程

1.構建父子組件

1.1 全局註冊

(1)構建註冊子組件

//構建子組件child
var child = Vue.extend({
    template: '<div>這是子組件</div>'
});
//註冊名爲'child'的組件
Vue.component('child',child);

(2)構建註冊父組件

//構建父組件parent,在其中嵌套child組件
var parent = Vue.extend({
    template: '<div>這是父組件<child></child></div>'
});

Vue.component('parent',parent);

(3)定義vue實例

var app = new Vue({
    el: '#app'
})

(4)使用父組件

<div id="app">
    <parent></parent>
</div>

打開瀏覽器查看

1.2 局部註冊

(1)構建子組件

var child = Vue.extend({
    template: '<div>這是子組件</div>'
});

(2)構建父組件
在父組件中局部註冊子組件

var parent = Vue.extend({
    template: '<div>這是父組件<child></child></div>',
    components:{
        'child':child
    }
});

(3)定義vue實例
在vue實例中局部註冊父組件

var app = new Vue({
    el: '#app',
    components:{
        'parent':parent
    }
})

(4)使用父組件

<div id="app">
    <parent></parent>
</div>

2.父子組件間通信

2.1 父傳子

父組件傳消息到子組件使用<code>props</code>,並且這傳遞是單向的,只能由父組件傳到子組件。我們將上面例子中的父組件增加一個數據傳遞到子組件中渲染顯示。如果父組件需要傳多個數據給子組件,依次在後面加即可。
(1)在父組件中增加data,並綁定到子組件上

var parent = Vue.extend({
    template: '<div>這是父組件<child :pdata=data></child></div>',
    data(){
        return{
            data:'這是父組件傳來的數據'
        }
    },
    components:{
        'child':child
    }
});

其中<code><child :pdata=data></child></code>,<code>:pdata</code>是<code>v-bind:pdata</code>的縮寫,<code>pdata</code>是自定義傳遞數據的命名,子組件中也是用該名字獲取數據,<code>data</code>是父組件中數據的命名。
(2)在子組件中通過props獲取數據,並渲染出來

var child = Vue.extend({
    template: '<div>這是子組件 {{pdata}}</div>',
    props:['pdata']
});

查看瀏覽器

父組件中數據發生變化,子組件中自動更新
子組件不可直接修改通過<code>props</code>獲取到的父組件中的數據

下面我們通過一個例子更好的理解上面兩句話
(1)使用<code><template></code>標籤創建子組件
爲方便書寫,我們使用<code><template></code>標籤創建組件

<template id="child">
    <div>
        <p>這是子組件</p>
        <table>
            <tr>
                <td>name</td>
                <td>{{name}}</td>
                <td><input type="text" v-model="name"></td>
            </tr>
            <tr>
                <td>age</td>
                <td>{{age}}</td>
                <td><input type="text" v-model="age"></td>
            </tr>
        </table>
    </div>
</template>

這裏使用<code>v-model</code>指令來雙向綁定從父組件中獲取到的數據
(2)使用<code><template></code>標籤創建父組件

<template id="parent">
    <div>
        <p>這是父組件</p>
        <table>
            <tr>
                <td>name</td>
                <td>{{name}}</td>
                <td><input type="text" v-model="name"></td>
            </tr>
            <tr>
                <td>age</td>
                <td>{{age}}</td>
                <td><input type="text" v-model="age"></td>
            </tr>
        </table>
        //給子組件傳遞2個數據
        <child :name="name" :age="age"></child>
    </div>
</template>

(3)構建子組件

var child = Vue.extend({
    template: '#child',
    props:['name','age']
});

(4)構建父組件

var parent = Vue.extend({
    template: '#parent',
    data(){
        return{
            age:16,
            name:'喬巴'
        }
    },
    components:{
        'child':child
    }
});

查看瀏覽器


接着,我們在父組件中修改輸入框的值,這會引起<code>v-model</code>綁定的值變化,同時也會改變子組件中的值



然後我們試着修改子組件中輸入框的值,vue會警告不能直接修改父組件傳過來的值。



如果我們需要修改從父組件中props傳過來的值,最好一開始把這個值賦給另外一個data。
var child = Vue.extend({
    template: '#child',
    props:['name','age'],
    data(){
        return{
            name1: '',
            age1: ''
        }
    },
    //頁面掛載時將props的值賦給子組件中的data
    mounted:function(){
        this.name1 = this.name
        this.age1 = this.age
    },
    //同時增加監聽,當props的值發生變化時,也立即賦值給子組件的data
    watch:{
        name:function(val){
            this.name1 = this.name
        },
        age:function(val){
            this.age1 = this.name
        }
    }
});

同時修改<code>v-model</code>綁定的<code>name</code>值爲<code>name1</code>,<code>age</code>爲<code>age1</code>
現在修改子組件中的值,就不會報錯了,這是因爲子組件中修改的是<code>name1</code>,並不是props傳遞過來的<code>name</code>值


2.1 子傳父

子組件給父組件傳值通過<code>emit</code>。父組件需在子組件標籤上綁定<code>emit</code>事件。
例子:
(1)構建子組件

var child = Vue.extend({
    template: '<div><button @click="change">點擊給父組件傳值</button></div>',
    methods:{
        change: function(){
            this.$emit('posttoparent',10)
        }
    }
});

子組件按鈕綁定了一個<code>click</code>事件,當點擊按鈕執行<code>change</code>方法,該方法觸發<code>emit</code>事件,事件名爲<code>posttoparent</code>,並且帶了一個參數10。
(2)構建父組件

var parent = Vue.extend({
    template: '<div>來自子組件的值爲:{{datafromchild}} <child v-on:posttoparent="getfromchild"></child></div>',
    data(){
        return{
            datafromchild:''
        }
    },
    components:{
        'child':child
    },
    methods: {
        getfromchild: function(val){
            this.datafromchild = val
        }
    }
});

父組件接收emit事件通過v-on指令,格式爲:

v-on:emit方法名="父組件方法"

父組件將接收到的參數賦值給<code>datafromchild </code>
查看瀏覽器


3.兄弟組件間通信

兄弟組件間通信也是用的<code>emit</code>。但原生vue.js需要新建一個空的vue實例來當橋樑。
下面直接貼代碼

//新建一個空的vue實例bus
var bus = new Vue();

var myCom1 = Vue.extend({
    template: '<div><button @click="change">點擊給兄弟組件傳值</button></div>',
    methods:{
        change: function(){
            //通過空實例去觸發emit
            bus.$emit('posttobro',10)
        }
    }
});

var myCom2 = Vue.extend({
    template: '<div>來自兄弟組件的值爲:{{datafrombro}}</div>',
    data(){
        return{
            datafrombro:''
        }
    },
    mounted:function(){
      //接收emit事件
        bus.$on('posttobro',function(val){
            this.datafrombro = val
        }.bind(this))
    }
});

Vue.component('my-com1',myCom1);
Vue.component('my-com2',myCom2);

var app = new Vue({
    el: '#app'
});

使用組件

<div id="app">
    <my-com1></my-com1>
    <my-com2></my-com2>
</div>

查看瀏覽器


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