读Vue.js第七章

组件用法

全局注册
  • 组件需要注册后才能使用
  • 注册有全局注册和局部注册两种方式
  <div id="app">
            <my-component></my-component>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>这是一个组件的内容</div>'
            });
           var app = new Vue({
               el:'#app',
               data:{
                   selected:''
               }
           });

        </script>
  • template的DOM结构必需被一个元素包含

局部注册
  • 使用component可以局部注册组件,注册后只能在该实例作用域下有效,使组件可以嵌套
 <div id="app">
            <my-component></my-component>
            <my-components></my-components>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>这是一个组件的内容</div>'
            });
            var Child = {
                template:'<div>这是一个局部注册组件的内容</div>'
            };
           var app = new Vue({
               el:'#app',
               data:{
                   selected:''
               },
               components:{
                'my-components': Child
               }
           });

        </script>
 - Vue模板在某种情况下会受到HTML的限制,比如<table>中只能出现<tbody>这些元素,如果直接使用是无效的,这种情况可以使用特殊的属性is来挂载组件;
<div id="app">

            <table>
                <tbody is="my-component"></tbody>
            </table>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>这是一个组件的内容</div>'
            });
            var Child = {
                template:'<div>这是一个局部注册组件的内容</div>'
            };
           var app = new Vue({
               el:'#app',
               data:{
                   selected:''
               },
               components:{
                'my-components': Child
               }
           });

        </script>
  • 在组件中除了使用template外也可以使用data,computer,methods等使用data时有区别;
<div id="app">

            <table>
                <tbody is="my-component"></tbody>
            </table>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>{{ message }}</div>',
                data: function () {
                    return{
                        message:'组件内容'
                    }
                }
            });
            var Child = {
                template:'<div>这是一个局部注册组件的内容</div>'
            };
           var app = new Vue({
               el:'#app',
               data:{
                   selected:''
               },
               components:{
                'my-components': Child
               }
           });

        </script>
  • 如果使用data时return出的对象是外部对象,那这个对象就是共享的,修改任何一方都会同步;
 <div id="app">
            <my-component></my-component>
            <my-component></my-component>
            <my-component></my-component>

        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            var data = {
                counter:0
            }
            Vue.component('my-component',{
                template:'<button @click="counter++">{{counter}}</button>',
                data: function () {
                    return data;
                }
            });
           var app = new Vue({
               el:'#app'
           });

        </script>
  • 我们需要让它独立,而不是同时变动,就需要组件返回一个新的对象

 <div id="app">
            <my-component></my-component>
            <my-component></my-component>
            <my-component></my-component>

        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<button @click="counter++">{{counter}}</button>',
                data: function () {
                    return {
                        counter:0
                    }
                }
            });
           var app = new Vue({
               el:'#app'
           });

        </script>
  • 这样点击三个按钮就不会互相影响了


使用props传递数据####
  • 概念:组件不仅可以复用,更重要的是组件跟组件之间还可以进行通信,通常父组件的模板中含子组件,父组件正向的向子组件传递数据或参数,子组件接收到后根据参数的不同来渲染不同的内容和执行操作。这个正向传递数据的过程就是通过props[prɑps]来实现的;
  • 在组件中,使用props来声明需要从父级接收的数据,props的值可以是两种,一种是字符串组,一种是对象;
      <my-component message="来自父组件的数据"></my-component>

        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>{{ message }}</div>',
                props:['message']
            });
           var app = new Vue({
               el:'#app'
           });

        </script>

由于html特性不区分大小写,当使用DOM模块时,驼峰命名的props名称要转为短横分隔命名:

 <div id="app">
            <my-component warning-text="来自父组件的数据"></my-component>

        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>{{ warningText }}</div>',
                props:['warningText']
            });
           var app = new Vue({
               el:'#app'
           });

        </script>

有的时候数据并不是写死的,而是来自父级的动态数据,这时可以使用命令V-bind来动态绑定props的值,当父组件的数据变化时,也会传递给子组件:

 <div id="app">
            <input type="text" v-model="parentMessage">
            <my-component :message="parentMessage"></my-component>

        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>{{ message }}</div>',
                props:['message']
            });
           var app = new Vue({
               el:'#app',
               data:{
                parentMessage:''
               }
           });

        </script>

如果你要传递数字、布尔值、数组、对象,而且不使用v-bind,传递的是字符串:

 <div id="app">
            <my-component message="[1,2,3]"></my-component>
            <my-component :message="[1,2,3]"></my-component>

        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'<div>{{ message.length }}</div>',
                props:['message']
            });
           var app = new Vue({
               el:'#app',
               data:{
                parentMessage:''
               }
           });

        </script>
  • 单向数据流
    VUE2.0通过prop传递数据是单向的,只能父组件传递给子组件,反过来却不行;

组件通信


  • 自定义事件
    父组件直接在子组件的自定义标签上使用v-on来监听子组件触发的自定义事件,子组件用$emit()来触发事件,注意子组件的监听函数名要小写
<div id="app">
            <p>总数:{{ total }}</p>
            <my-component  v-on:increase = "handlegettotal"
                           v-on:reduce = "handlegettotal">

            </my-component>

        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            Vue.component('my-component',{
                template:'\
                         <div>\
                           <button @click = "handleIncrease">+1</button>\
                           <button @click = "handleReduce">-1</button>\
                        </div>',
                data:function () {
                    return {
                        counter:0
                    }
                },
                methods:{
                    handleIncrease:function () {
                        this.counter++;
                        this.$emit('increase', this.counter);
                        console.log(this.counter);
                    },
                    handleReduce:function () {
                        this.counter--;
                        this.$emit('reduce', this.counter);
                        console.log(this.counter);
                    }
                }
            });
           var app = new Vue({
               el:'#app',
               data:{
                total:0
               },
               methods:{
                   handlegettotal:function (total) {
                    console.log(total);
                    this.total = total;
                }
               }
           });

        </script>
slot内容分发

单个slot用法: 也就是说子组件内使用特殊的slot元素,这个子组件就会开启一个slot,如果一个子组件内插入了内容,那么就会替代slot;

  <div id="app">
            <component-child>
                <p>分发的内容</p>
                <p>更多的分发的内容</p>
            </component-child>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            var bus = new Vue();
            Vue.component('component-child',{
                template:'\
                <div>\
                <slot>\
                <p>如果父组件没有插入内容,我将默认出现</p>\
                </slot>\
                </div>\
                '

            });
           var app = new Vue({
               el:'#app',
               data:{
                showChild: true
               }
           });

        </script>

给slot指定name后可以分发更多的内容,具有slot可以与单个slot共存;

 <div id="app">
            <component-child>
                <h2 slot="header">标题</h2>
                <p>分发的内容</p>
                <p>更多的分发的内容</p>
                <div slot="footer">底部信息</div>
            </component-child>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            var bus = new Vue();
            Vue.component('component-child',{
                template:'\
                <div class="container">\
                   <div class="header">\
                        <slot name="header"></slot>\
                   </div>\
                     <div>\
                        <slot>其实我是出现不了的</slot>\
                    </div>\
                    <div class="footer">\
                        <slot name="footer"></slot>\
                    </div>\
                </div>\
                '

            });
           var app = new Vue({
               el:'#app',
               data:{
                showChild: true
               }
           });

        </script>

组件的高级用法

  • 递归组件
    组件在模板内自己调用自己,只要给组件设置name就可以了,**注意的是要给组件设置递归限制条件;

  • 内联模板
    也就是说在使用组件时,给组件标签使用inline-template特性,组件就会把它的内容当做模板;

  • 动态组件
    用特殊的元素component用来动态挂载不同的组件,使用is特性来选择需要挂载的组件;

  • nextTickVueDOM nextTick就是用来知道什么时候DOM更新完成的;

  • X-template
    X-template是定义模板的另一种方式,可以在script标签中书写HTML代码

<script type='text/x-template' id='my-component'>
        <div>这是一个模板内容</div>   //模板内容
</script>        

end


实例


Vue中html中如果有标点符号的错误,Vue是检测不出来的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值