vue.js组件

为什么使用组件?

  组件就是一个个的Vue实例,可以重复使用。

组件的构成?

//tagName:是组件名
//options:是组件的配置
Vue.component(tagName, options)

  如Vue.filter(参数1,参数2)过滤器本质也是一个组件,参数一是组件的标签(即名字);参数二:是组件的构造器。

组件的基础知识

  1. 组件分为:全局组件Vue.component()
    和 局部组件Vue.components();
  2. 因为组件是Vue实例,因此组件中也可以包含data、method、watch等标签;

  3. 组件的data标签与往常的Vue中的data使用不同,组件中的data必须是一个函数,该函数返回一个对象,

    如:data:function(){return msg:"我是一个组件!"}

  4. Vue.extend():组件构造器,无法直接使用,相当于vue.component()中的第二个参数。如:

    // 创建构造器
    var au = Vue.extend({
      template: "<p><a :href='url'>{{ author }}</a></p>",
      data : function() {
        return {
          author : 'Li',
          url : 'http://www.baidu.com'
        }
      }
    });
    // 创建组件
    Vue.component('au',au);
    // 注册
    new Vue({
      el:"#app"
    })
    //也可以创建构造器实例,并将其挂载到一个元素上
    new au().$mount('#app');
  5. 在component组件中可以定义子组件components();

  6. 在Vue中组件实例的作用域是独立的,默认情况下,父子组件之间的数据是不共享的。

  7. 子组件获取父组件数据:在子组件中声明props,然后在子组件的模板中进行数据绑定:

    <div id="app">
        <div>
          <input v-model="parentMsg">
          //将子组件中props声明的message与父组件中的属性parentMsg绑定
          <child v-bind:message="parentMsg"></child>
        </div>
    </div>
     
    <script>
    // 注册
    Vue.component('child', {
      // 声明 props
      props: ['message'],
      // 同样也可以在 vm 实例中像 "this.message" 这样使用
      template: '<span>{{ message }}</span>'
    })
    // 创建根实例
    new Vue({
      el: '#app',
      data: {
        parentMsg: '父组件内容'
      }
    })
    </script>
  8. props中可以传入任意数量的prop,props可以是数组也可以是对象
    <div id="app">
        <ol>
        <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
          </ol>
    </div>
     
    <script>
    Vue.component('todo-item', {
      props: ['todo'],
      template: '<li>{{ todo.text }}</li>'
    })
    new Vue({
      el: '#app',
      data: {
        sites: [
          { text: 'Runoob' },
          { text: 'Google' },
          { text: 'Taobao' }
        ]
      }
    })
    </script>

    注意:这种传递方式是单向的,使用prosps子组件只能接收父组件的信息,而不能反过来传递给父组件。

  9. 父组件获取子组件的数据,需要子组件定义一个发送数据的事件,例如:

    
    

     //准备一个空的实例对象

    var Event=new Vue();

    //
    定义A组件 var A={ template:` <div> <span>我是A组件</span> -> {{a}} <input type="button" value="把A数据给父组件" @click="send"> </div> `, methods:{ send(){ Event.$emit('a-msg',this.a); } }, data(){ return { a:'我是a数据' } } }; //父组件接收A组件数据 { template:` <div> <span>接收过来的A的数据为: {{a}}</span> </div> `, data(){ return { a:'' } }, mounted(){ var _this = this; //接收A组件的数据 Event.$on('a-msg',function(a){ _this.a=a; }); //另一种方式接收 Event.$on('a-msg',function(a){ this.a=a; }.bind(this)); } };

    //步骤总结:
    • 准备一个空的实例对象 var Event=new Vue();
    • 发送数据 Event.$emit(事件名称, 数据)
    • 接收数据 Event.$on(事件名称,function(data){ }.bind(this));
    
    

     

  10. 父子组件之间数据传递结论:父向子组件传递数据,是通过属性绑定的形式,父数据改变,子也会随之改变;

    而子向父传递数据是通过emit的方法,需要事件驱动,若没有触发事件,则子数据改变,父组件的数据并不会有变化(事件驱动的通信方式适合爷孙、兄弟组件之间的通信)。

  11. 通过对象引用的方式,也可以实现子组件的改变同步到父组件
    <body>
         <template id="child">
            <div>
                <span>我是子组件</span>
                <input type="button" value="按钮" @click="change">
                <strong>{{msg.a}}</strong>
            </div>
        </template>
        <div id="box">
            父级: ->{{giveData.a}}
            <child-com :msg="giveData"></child-com>
        </div>
        <script>
            new Vue({
                    el:'#box',
                    data:{
                        giveData:{
                            a:'我是父组件数据'
                        }
                    },
                    components:{
                        'child-com':{
       //这里msg与父组件的giveData对象完成了绑定 props:[
    'msg'], template:'#child', methods:{ change(){ this.msg.a='被改了'; } } } } }); </script> </body> 
  12. 父组件访问子组件使用 $children或$ref
    //$children返回所有子组件的实例,是一个数组
    new Vue({
          el: '#count',
          data: {},
          methods: {
            showmsg () {
                for(var i = 0; i < this.$children.length; i++) {
                alert(this.$children[i].msg)
              }
            }
          }
        })

    $ref :有时候组件过多的话,就很记清各个组件的顺序与位置,所以通过给子组件一个索引ID

    <div id="count">
        <button @click="showmsg">
          显示两个组件的信息
        </button>
    //给组件加索引
            <child1 ref='c1'></child1>
            <child2 ref='c2'></child2>
    </div>
    
    new Vue({
          el: '#count',
          data: {},
          methods: {
            showmsg () {
                alert(this.$refs.c1.msg)
              alert(this.$refs.c2.msg)
            }
          }
        })

     

  13. 子组件访问父组件 $parent

    Vue.component('child1', {
          template: '#child1',
          data () {
            return {
              msg: '这是子组件1的信息'
                    }
          },
          methods: {
            showpmsg () {
                   //访问父组件的msg属性
                    alert(this.$parent.msg)
            }
          }
        })        
  14. 子组件访问根组件 $root

     methods: {
            showroot () {
                //访问跟组件的msg属性
                    alert(this.$root.msg)
            }
          }
        })    
  15. 当在父组件的template中编写子组件的数据时,该内容是默认消失的,例如;

    <template id="aaa">
            <div class="parent">
                <p>父组件</p>
                <bbb>
                    <p>测试内容1</p>
                    <p>测试内容2</p>
                    <p>测试内容3</p>
                </bbb>
              </div>
        </template>
    
    //bbb组件中的内容是不会显示的

    要想保存该部分内容,需要使用插槽标签slot,这样在父组件中的子组件信息都想插入到子组件中定义插槽的位置。

    注意:该匿名slot标签只能使用有一次,多个slot会导致程序错误。

  16. 除了匿名slot,还有实名slot
    <template id="aaa">
            <div class="parent">
                <p>父组件</p>
                <bbb>
                    <p slot="my-header">我是头部</p>
                    <p slot="my-footer">我是尾部</p>
                    <p>我是主体</p>
                </bbb>
              </div>
        </template>
    
    //可以在子组件中定义实名slot
    <slot name="my-header">头部默认值</slot>
    <slot name="my-body">主体默认值</slot>
    <slot name="my-footer">尾部默认值</slot>

     

posted @ 2022-02-10 17:10  干了这瓶老干妈  阅读(53)  评论(0编辑  收藏  举报
Live2D