zoukankan      html  css  js  c++  java
  • vue.js原生组件化开发(二)——父子组件

    前言

    在了解父子组件之前应先掌握组件开发基础。在实际开发过程中,组件之间可以嵌套,也因此生成父子组件。

    父子组件创建流程

    1.构建父子组件

    1.1 全局注册

    (1)构建注册子组件

     1  
     2 //构建子组件child
     3  
     4 var child = Vue.extend({
     5  
     6 template: '<div>这是子组件</div>'
     7  
     8 });
     9  
    10 //注册名为'child'的组件
    11  
    12 Vue.component('child',child);

    (2)构建注册父组件

     1 //构建父组件parent,在其中嵌套child组件
     2  
     3 var parent = Vue.extend({
     4  
     5 template: '<div>这是父组件<child></child></div>'
     6  
     7 });
     8  
     9  
    10  
    11 Vue.component('parent',parent);

    (3)定义vue实例

    1 var app = new Vue({
    2  
    3 el: '#app'
    4  
    5 })

    (4)使用父组件

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

    打开浏览器查看

    1.2 局部注册

    (1)构建子组件

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

    (2)构建父组件
    在父组件中局部注册子组件

     1 var parent = Vue.extend({
     2  
     3 template: '<div>这是父组件<child></child></div>',
     4  
     5 components:{
     6  
     7 'child':child
     8  
     9 }
    10  
    11 });

    (3)定义vue实例

    在vue实例中局部注册父组件

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

    (4)使用父组件

    1 <div id="app">
    2  
    3 <parent></parent>
    4  
    5 </div>

    2.父子组件间通信

    2.1 父传子

    父组件传消息到子组件使用props,并且这传递是单向的,只能由父组件传到子组件。我们将上面例子中的父组件增加一个数据传递到子组件中渲染显示。如果父组件需要传多个数据给子组件,依次在后面加即可。
    (1)在父组件中增加data,并绑定到子组件上

     1 var parent = Vue.extend({
     2  
     3 template: '<div>这是父组件<child :pdata=data></child></div>',
     4  
     5 data(){
     6  
     7 return{
     8  
     9 data:'这是父组件传来的数据'
    10  
    11 }
    12  
    13 },
    14  
    15 components:{
    16  
    17 'child':child
    18  
    19 }
    20  
    21 });

    其中<child :pdata=data></child>:pdatav-bind:pdata的缩写,pdata是自定义传递数据的命名,子组件中也是用该名字获取数据,data是父组件中数据的命名。

    (2)在子组件中通过props获取数据,并渲染出来

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

    查看浏览器

    父组件中数据发生变化,子组件中自动更新
    子组件不可直接修改通过props获取到的父组件中的数据

    下面我们通过一个例子更好的理解上面两句话
    (1)使用<template>标签创建子组件
    为方便书写,我们使用<template>标签创建组件

    <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>

    这里使用v-model指令来双向绑定从父组件中获取到的数据

    (2)使用<template>标签创建父组件、

     1 <template id="parent">
     2  
     3 <div>
     4  
     5 <p>这是父组件</p>
     6  
     7 <table>
     8  
     9 <tr>
    10  
    11 <td>name</td>
    12  
    13 <td>{{name}}</td>
    14  
    15 <td><input type="text" v-model="name"></td>
    16  
    17 </tr>
    18  
    19 <tr>
    20  
    21 <td>age</td>
    22  
    23 <td>{{age}}</td>
    24  
    25 <td><input type="text" v-model="age"></td>
    26  
    27 </tr>
    28  
    29 </table>
    30  
    31 //给子组件传递2个数据
    32  
    33 <child :name="name" :age="age"></child>
    34  
    35 </div>
    36  
    37 </template>

    (3)构建子组件

    1 var child = Vue.extend({
    2  
    3 template: '#child',
    4  
    5 props:['name','age']
    6  
    7 });

    (4)构建父组件

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

    查看浏览器


    接着,我们在父组件中修改输入框的值,这会引起v-model绑定的值变化,同时也会改变子组件中的值


    然后我们试着修改子组件中输入框的值,vue会警告不能直接修改父组件传过来的值。


    如果我们需要修改从父组件中props传过来的值,最好一开始把这个值赋给另外一个data。


     1 var child = Vue.extend({
     2  
     3 template: '#child',
     4  
     5 props:['name','age'],
     6  
     7 data(){
     8  
     9 return{
    10  
    11 name1: '',
    12  
    13 age1: ''
    14  
    15 }
    16  
    17 },
    18  
    19 //页面挂载时将props的值赋给子组件中的data
    20  
    21 mounted:function(){
    22  
    23 this.name1 = this.name
    24  
    25 this.age1 = this.age
    26  
    27 },
    28  
    29 //同时增加监听,当props的值发生变化时,也立即赋值给子组件的data
    30  
    31 watch:{
    32  
    33 name:function(val){
    34  
    35 this.name1 = this.name
    36  
    37 },
    38  
    39 age:function(val){
    40  
    41 this.age1 = this.name
    42  
    43 }
    44  
    45 }
    46  
    47 });

    同时修改v-model绑定的name值为name1ageage1
    现在修改子组件中的值,就不会报错了,这是因为子组件中修改的是name1,并不是props传递过来的name

    2.1 子传父

    子组件给父组件传值通过emit。父组件需在子组件标签上绑定emit事件。
    例子:
    (1)构建子组件

     1 var child = Vue.extend({
     2  
     3 template: '<div><button @click="change">点击给父组件传值</button></div>',
     4  
     5 methods:{
     6  
     7 change: function(){
     8  
     9 this.$emit('posttoparent',10)
    10  
    11 }
    12  
    13 }
    14  
    15 });

    子组件按钮绑定了一个click事件,当点击按钮执行change方法,该方法触发emit事件,事件名为posttoparent,并且带了一个参数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方法名="父组件方法"

    父组件将接收到的参数赋值给datafromchild
    查看浏览器

    3.兄弟组件间通信

    兄弟组件间通信也是用的emit。但原生vue.js需要新建一个空的vue实例来当桥梁。
    下面直接贴代码

     
     1 //新建一个空的vue实例bus
     2  
     3 var bus = new Vue();
     4  
     5  
     6  
     7 var myCom1 = Vue.extend({
     8  
     9 template: '<div><button @click="change">点击给兄弟组件传值</button></div>',
    10  
    11 methods:{
    12  
    13 change: function(){
    14  
    15 //通过空实例去触发emit
    16  
    17 bus.$emit('posttobro',10)
    18  
    19 }
    20  
    21 }
    22  
    23 });
    24  
    25  
    26  
    27 var myCom2 = Vue.extend({
    28  
    29 template: '<div>来自兄弟组件的值为:{{datafrombro}}</div>',
    30  
    31 data(){
    32  
    33 return{
    34  
    35 datafrombro:''
    36  
    37 }
    38  
    39 },
    40  
    41 mounted:function(){
    42  
    43 //接收emit事件
    44  
    45 bus.$on('posttobro',function(val){
    46  
    47 this.datafrombro = val
    48  
    49 }.bind(this))
    50  
    51 }
    52  
    53 });
    54  
    55  
    56  
    57 Vue.component('my-com1',myCom1);
    58  
    59 Vue.component('my-com2',myCom2);
    60  
    61  
    62  
    63 var app = new Vue({
    64  
    65 el: '#app'
    66  
    67 });
     

    使用组件

     
    1 <div id="app">
    2  
    3 <my-com1></my-com1>
    4  
    5 <my-com2></my-com2>
    6  
    7 </div>
     

    查看浏览器

  • 相关阅读:
    HyperV创建NAT网络
    Win10
    ConEmu
    ffmpeg的centos、msys2、msvc编译
    7z压缩gopath的src的批处理
    VS2015自带v120的Platform Toolset
    Putty配置
    第一章:HTML5的基础
    java的错题整理
    第十四章:类的带参方法
  • 原文地址:https://www.cnblogs.com/weifeng123/p/9872524.html
Copyright © 2011-2022 走看看