美文网首页
第3章 vue组件开发

第3章 vue组件开发

作者: yangsg | 来源:发表于2019-12-05 16:07 被阅读0次

    1. 组件开发

    在vue中,组件是最重要的组合部分,官方中定义组件为可复用的vue实例,分为全局组件和局部组件。

    1.1 全局组件

    使用全局组件的步骤如下:

    • 调用vue.extend()创建一个组件构造器,该构造器中有一个选项对象的template属性可以用来定义组件要渲染的HTML
    • 使用vue.component()注册组件,需要提供2个参数:组件的标签和组件构造器。vue.component()内部会调用组件构造器,创建一个组件实例
    • 将组建挂载到某个vue实例下

    因为组件是可复用的vue实例,所以它们也能接收data、computed、watch、methods以及生命周期钩子等选项

    <div id="demo">
        <haha></haha>
    </div>
    <script type="text/javascript">
        var red = Vue.extend({
            template: "<span style='color: red;'>全局组件</span>"
        });
        Vue.component('haha',red);
        var demo = new Vue({
            el: "#demo"
        })
    </script>
    

    1.2 局部组件

    调用Vue.component()注册组件时,组件的注册是全局的,这意味着该组件可以在任意Vue示例下使用。 如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的components属性实现局部注册。

    <div id="demo">
        <haha></haha>
    </div>
    <script type="text/javascript">
        var red = Vue.extend({
            template: "<span style='color: red;'>局部组件</span>"
        });
        var demo = new Vue({
            el: "#demo",
            components:{
                haha:red
            }
        })
    </script>
    

    虽然上面的组件是在某个具体的vue实例下注册的,但是组件构造器还是全局的,这个并不是完全意义上的局部组件,下面这种组件才是真正意义上的局部组件。

    <div id="demo">
        <haha></haha>
    </div>
    <script type="text/javascript">
        var demo = new Vue({
            el: "#demo",
            components:{
                haha:{
                    template:'<span style="color: red;">局部组件</span>'
                }
            }
        })
    </script>
    

    1.3 组件模板

    可以通过<template>标记声明组件,再通过全局或局部注册组件来使用。
    组件中data不是属性,是方法,需要将数据通过返回值进行返回

    <div id="demo">
        <haha></haha>
    </div>
    <template id="abc">
        <div @click="test1" style="cursor: pointer;">{{message}}</div>
    </template>
    <script type="text/javascript">
        var demo = new Vue({
            el: "#demo",
            components:{
                haha:{
                    data(){
                        return {
                            message: 'init info'
                        }
                    },
                    methods:{
                        test1(){
                            if(this.message == 'init info'){
                                this.message = 'click info'
                            }else{
                                this.message = 'init info'
                            }   
                        }
                    },
                    template:"#abc"
                }
            }
        })
    </script>
    

    2. 组件通信

    2.1 父子组件

    当继续在组件中写组件,形成组件嵌套的时候,就是所谓的父子组件。

    <div id="demo">
        <haha></haha>
    </div>
    
    <template id="haha">
        <div>
            <h2>{{message}}</h2>
            <xixi></xixi>
        </div>
    </template>
    
    <template id="xixi">
        <div>
            <h3>{{info}}</h3>
        </div>
    </template>
    
    <script type="text/javascript">
        var demo = new Vue({
            el: "#demo",
            components:{
                haha:{
                    data(){
                        return {
                            message: '父组件'
                        }
                    },
                    template:"#haha",
                    components:{
                        xixi:{
                            data(){
                                return {
                                    info:'子组件'
                                }
                            },
                            template: "#xixi"
                        }
                        
                    }
                }
            }
        })
    </script>
    

    2.2 子组件获取父组件的数据

    在vue中,组件实例的作用域是孤立的,默认情况下,父子组件的数据是不能共享的,也就是说,子组件是不能直接访问父组件的数据的。为此,vue给我们提供了一个数据传递的选项prop,用来将父组件的数据传递给子组件。

    1. 父组件template中,调用子组件位置通过:msg="message"表示将父组件中的data:message传递给子组件,名字为msg
    2. 子组件components中通过props声明['msg']表示接收父组件推送的数据,子组件template直接{{msg}}进行调用
    <div id="demo">
        <haha></haha>
    </div>
    
    <template id="haha">
        <div>
            <h2>{{message}}</h2>
            <xixi :msg="message"></xixi>
        </div>
    </template>
    
    <template id="xixi">
        <div>
            <h3>{{info}} -> {{msg}}</h3>
        </div>
    </template>
    
    <script type="text/javascript">
        var demo = new Vue({
            el: "#demo",
            components:{
                haha:{
                    data(){
                        return {
                            message: '父组件'
                        }
                    },
                    template:"#haha",
                    components:{
                        xixi:{
                            data(){
                                return {
                                    info:'子组件'
                                }
                            },
                            props:['msg'],
                            template: "#xixi"
                        }
                        
                    }
                }
            }
        })
    </script>
    

    2.3 父组件获取子组件的数据

    父组件获取子组件需要子组件事件驱动,通过触发一个事件将自身的数据发送给父组件。
    步骤:
    1.在子组件的methods中编写send方法,其中通过emit函数将需要传递的数据绑定一个名字“child-msg”
    2.在父组件的template中调用子组件的标记处,通过@child-msg指向父组件的绑定函数"getMsg"
    3.在父组件的methods中编写getMsg函数,通过方法参数接收传递过来的数据,并将其赋值给某个data(cmsg)
    4.通过使用cmsg来使用子组件的数据。

    <div id="demo">
        <haha></haha>
    </div>
    
    <template id="haha">
        <div>
            <h2>{{message}}</h2>
            <xixi :msg="message" @child-msg="getMsg"></xixi>
            <div>{{cmsg}}</div>
        </div>
    </template>
    
    <template id="xixi">
        <div @click="send">
            <h3>{{info}} -> {{msg}}</h3>
        </div>
    </template>
    
    <script type="text/javascript">
        var demo = new Vue({
            el: "#demo",
            components:{
                haha:{
                    data(){
                        return {
                            message: '父组件',
                            cmsg:''
                        }
                    },
                    methods:{
                        getMsg(msg){
                            this.cmsg = msg;
                        }
                    },
                    template:"#haha",
                    components:{
                        xixi:{
                            data(){
                                return {
                                    info:'子组件数据'
                                }
                            },
                            props:['msg'],
                            template: "#xixi",
                            methods:{
                                send(){
                                    this.$emit('child-msg',this.info);
                                }
                            }
                        }
                        
                    }
                }
            }
        })
    </script>
    

    需要强调的是,父子组件数据时单向更新的

    • 当父组件数据变化时,子组件中的显示会实时更新。
    • 当子组件数据变化时,需要触发事件来驱动父组件数据更新。

    2.4 $children和$ref

    当一个父组件中存在多个子组件时,可以通过$children来访问其下所有子组件,它会返回一个包含所有子组件的数组

    <div id="count">
        <button @click="showmsg">
          显示两个组件的信息
        </button>
        <child1></child1>
        <child2></child2>
        </div>
    <template id="child1">
      <div>
        {{ msg }}
      </div>
    </template>
    <template id="child2">
      <div>
        {{ msg }}
      </div>
    </template>
    <script>
        Vue.component('child1', {
          template: '#child1',
          data () {
            return {
              msg: '这是子组件1的信息'
            }
          }
        })
        Vue.component('child2', {
          template: '#child2',
          data () {
            return {
              msg: '这是子组件2的信息'
            }
          }
        })
        new Vue({
          el: '#count',
          data: {
    
          },
          methods: {
            showmsg () {
                for(var i = 0; i < this.$children.length; i++) {
                alert(this.$children[i].msg)
              }
            }
          }
        })
    </script>
    

    有时候组件过多的话,就很记清各个组件的顺序与位置,所以通过给子组件一个索引ID来进行快速定位

    <div id="count">
        <button @click="showmsg">
          显示两个组件的信息
        </button>
       <child1 ref='c1'></child1>
        <child2 ref='c2'></child2>
        </div>
    <template id="child1">
      <div>
        {{ msg }}
      </div>
    </template>
    <template id="child2">
      <div>
        {{ msg }}
      </div>
    </template>
    <script>
        Vue.component('child1', {
          template: '#child1',
          data () {
            return {
              msg: '这是子组件1的信息'
            }
          }
        })
        Vue.component('child2', {
          template: '#child2',
          data () {
            return {
              msg: '这是子组件2的信息'
            }
          }
        })
        new Vue({
          el: '#count',
          data: {
    
          },
          methods: {
            showmsg () {
                alert(this.$refs.c1.msg)
              alert(this.$refs.c2.msg)
            }
          }
        })
    </script>
    

    2.5 $parent和$root

    子组件通过访问$parent获得其父组件的实例对象

    <div id="count">
        父组件中的msg: {{ msg }}
        <child1 ref='c1'></child1>
        <child2 ref='c2'></child2>
    </div>
    <template id="child1">
      <div>
        {{ msg }}
        <button @click="showpmsg">
          显示父组件msg
        </button>
      </div>
    </template>
    <template id="child2">
      <div>
        {{ msg }}
      </div>
    </template>
    <script>
        Vue.component('child1', {
          template: '#child1',
          data () {
            return {
              msg: '这是子组件1的信息'
            }
          },
          methods: {
            showpmsg () {
                    alert(this.$parent.msg)
            }
          }
        })
        Vue.component('child2', {
          template: '#child2',
          data () {
            return {
              msg: '这是子组件2的信息'
            }
          }
        })
        new Vue({
          el: '#count',
          data: {
            msg: 'hello parent'
          }
        })
    </script>
    

    子组件访问根组件 $root 当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自已。

    <div id="count">
        父组件中的msg: {{ msg }}
            <child1 ref='c1'></child1>
        <child2 ref='c2'></child2>
        </div>
    <template id="child1">
      <div>
        {{ msg }}
        <cchild></cchild>
      </div>
    </template>
    <template id="child2">
      <div>
        {{ msg }}
      </div>
    </template>
    <template id="cchild">
      <div>
        <button @click="showroot">
          showrootmsg
        </button>
      </div>
    </template>
    <script>
        Vue.component('child1', {
          template: '#child1',
          data () {
            return {
              msg: '这是子组件1的信息'
            }
          },
          methods: {
            showpmsg () {
                    alert(this.$parent.msg)
            }
          }
        })
        Vue.component('child2', {
          template: '#child2',
          data () {
            return {
              msg: '这是子组件2的信息'
            }
          }
        })
        Vue.component('cchild', {
          template: '#cchild',
          data () {
            return {
              msg: '这是子组件1的信息'
            }
          },
          methods: {
            showroot () {
                    alert(this.$root.msg)
            }
          }
        })
        new Vue({
          el: '#count',
          data: {
            msg: 'hello root'
          }
        })
    </script>
    

    相关文章

      网友评论

          本文标题:第3章 vue组件开发

          本文链接:https://www.haomeiwen.com/subject/skcwuctx.html