vue学习(三) vue组件

组件

一个大的对象;

定义代码:

    <div id="box">
        <bc></bc>   
    </div>
    <hr>
    <script>
        var aaa = Vue.extend({
            template: 'This is a vue 全局组件。'
        })
        Vue.component('bc',aaa);
        new Vue({
            el: '#box',
            data: {

            },
            methods: {

            }
        })
    </script>

效果:

这里写图片描述

全局组件

全局下定义的组件

通过Vue.extend({})来定义组件的模板,再通过vue.component(‘name’,module)来绑定,在html中就可以直接使用

可以直接通过vue.component('name',obj)的方式来声明 方式二的声明方式

ps: **component不能使用实例的data ,但是可以在component 使用data 声明变量,data的使用只能使用函数形式数据的翻译形式只能是json的格式**
    <div id="box">
        <qj1></qj1>
        <hr>
        <qj2></qj2> 
        <hr>
        <qj3></qj3>
    </div>
    <hr><br><br>
    <div id="box2">
        <qj3></qj3>
    </div>

    <!--这里是不会有显示的,因为并没有挂载vue。 正确理解全局的含义 -->
    <qj3></qj3>
    <script>
        var aaa = Vue.extend({
            template: 'This is a vue 全局组件1。'
        })
        Vue.component('qj1',aaa);

        var bbb = Vue.extend({
            template: '{{msg}}',
            //component不能使用实例的data ,但是可以在component 使用data 声明变量,data的使用只能使用函数形式
            // 数据的翻译形式只能是json的格式
            data: function (){
                return {
                    msg: '全局组件2,数据由data返回。'
                }
            }
        })
        Vue.component('qj2',bbb)

        Vue.component('qj3',{
            template: 'This is a vue 全局组件3.{{msg}}',
            //component不能使用实例的data ,但是可以在component 使用data 声明变量,data的使用只能使用函数形式
            // 数据的翻译形式只能是json的格式
            data: function(){
                return {
                    msg: '数据来自与自定义的数据,由data返回,data必须是函数。'
                }
            }
        })

        new Vue({
            el: '#box',
            data: {
            },
            methods: {
            }
        })

        new Vue({
            el: '#box2',
            data: {
            },
            methods: {
            }
        })
    </script>
正确理解全局的意思。 只有在挂载了vue的地方,去使用组件,都是ok的。

局部组件

局部组件,声明方式和全局类似,只是定义在了一个vue实例对象里面
    <div id="jb1">
        <jb1></jb1><br><hr>
        <jb2></jb2><br><hr>
        <jb3></jb3>
    </div>

    <script>
        var jb1 = Vue.extend({
            template: 'This is 局部组件. <strong>{{msg}}</strong>',
            data: function (){
                return {
                    msg: '局部组件,数据信息1。'
                }
            }
        })
        var jb2 = Vue.extend({
            template: 'This is 局部组件. <strong>{{msg}}</strong>',
            data: function (){
                return {
                    msg: '局部组件,数据信息2。'
                }
            }
        })

        new Vue({
            el: '#jb1',
            components: {
                'jb1': jb1,
                'jb2': jb2,
                'jb3': {
                    template: '局部组件3.{{msg}}',
                    data: function (){
                        return {
                            msg: '数据信息3'
                        }
                    }
                }
            }
        })

    </script>

配合模板使用

如果template里面的内容过多的话,可以使用模板来进行调用。为template设置一个id值绑定到模板

模板的创建方式有两种:
    1:通过 script+id+type  <script type="x-template" id="zjmb1">xxx</script>
    2:通过 template标签+id  <template id='aaa'>xxx</template>
    <div id="zjmb">
        <zjmb1></zjmb1>
        <br><br><hr>
        <zjmb2></zjmb2>

    </div>

    <script type="x-template" id="zjmb1">
        <h1>组件配合模板使用</h1>
        <p>{{msg}}</p>
        <button @click="show()">clickMe</button>
    </script>

    <template id="zjmb2">
        <h1>组件配合模板使用2</h1>
        <p>{{msg}}</p>
        <button @click="show()">clickMe</button>
    </template>
    <script>
        new Vue({
            el: '#zjmb',
            components: {
                zjmb1: {
                    template: '#zjmb1',
                    data(){
                        return {
                            msg: '数据是组件模板的数据。'
                        }
                    },
                    methods: {
                        show(){
                            alert('组件配合模板使用。')
                        }
                    }
                },
                zjmb2: {
                    template: '#zjmb2',
                    data(){
                        return {
                            msg: '组件配合模板使用2。另外一种方式创建'
                        }
                    },
                    methods: {
                        show(){
                            alert('组件配合模板使用2。另外一种方式创建')
                        }
                    }
                }
            }
        })
    </script>

动态组件

    格式:  <component :is="组件名称"></component>
    通过点击button来改变aaa,进而根据aaa的不同,实现组件更换
    <div id="dtzj">
        <input type="button" value="dtzj1" @click="aaa='dtzj1'" />
        <input type="button" value="dtzj2" @click="aaa='dtzj2'" />
        <componemt :is='aaa'></componemt>
    </div>
    <template id='dtzj1'>
        <h1>动态组件1</h1>
        <p>{{msg}}</p>
    </template>
    <script>
        new Vue({
            el:'#dtzj',
            data:{
                aaa:'dtzj1'
            },
            components:{
                'dtzj1':{
                    template:'#dtzj1',
                    data(){
                        return {
                            msg: '动态组件数据',
                        }
                    },
                    methods:{
                        show(){
                            alert('动态组件方法')
                        }
                    }
                },
                'dtzj2':{
                    template:'<h1>动态组件2</h1>',
                }
            }
        })
    </script>

父子组件

即组件里面套组件
    <div id="fzzj">
        <fzzj1></fzzj1>
    </div>
    <template id='fzzj1'>
        <h1>父子组件1</h1>
        <p>This is 父子组件。</p>
        <hr>
        <fzzjchild></fzzjchild>
    </template>
    <script>
        //父子组件
        new Vue({
            el: '#fzzj',
            data: {
            },
            components: {
                'fzzj1': {
                    template:'#fzzj1',
                    components: {
                        'fzzjchild': {
                            template: '<h2>父子组件的子组件</h2>'
                        }
                    }
                }
            }
        })
    </script>

效果:

这里写图片描述

子组件无法获取父组件数据,需要经过处理才能获取到
    <!--这里子组件是不能获取到父组件的数据的-->
    <div id="fzzj">
        <fzzj1></fzzj1>
    </div>
    <template id='fzzj1'>
        <h1>父子组件1</h1>
        <p>This is 父子组件。</p>
        <p>{{msgF}}</p>
        <hr>
        <fzzjchild></fzzjchild>
    </template>
    <script>
        //父子组件
        new Vue({
            el: '#fzzj',
            data: {
            },
            components: {
                'fzzj1': {
                    template:'#fzzj1',
                    data(){
                        return {
                            msgF: "这是父组件的数据。"
                        }
                    },
                    components: {
                        'fzzjchild': {
                            template: '<h2>父子组件的子组件</h2><p>{{msgZ}}</p><p>父组件数据:{{msgF}}</p>',
                            data(){
                                return {
                                    msgZ: "这是子组件的数据。"
                                }
                            },
                        }
                    }
                }
            }
        })
    </script>

这里写图片描述

处理:
    在调用子组件:    <bbb :m="数据"></bbb>
    子组件之内:
                    props:['m','myMsg']   // 多个数据,用逗号隔开就好
                    props:{               // 如果以对象的形式,这种表示 ‘数据’:数据类型
                        'm':String,
                        'myMsg':Number
                    }
    <div id="fzzj">
        <fzzj1></fzzj1>
    </div>
    <template id='fzzj1'>
        <h1>父子组件1</h1>
        <p>This is 父子组件。</p>
        <p>{{msgF}}</p>
        <hr>
        <fzzjchild :msg='msgF' :msg2='msgF2' :my-msg='msgF3'></fzzjchild>
    </template>
    <script>
        //父子组件
        new Vue({
            el: '#fzzj',
            data: {
            },
            components: {
                'fzzj1': {
                    template:'#fzzj1',
                    data(){
                        return {
                            msgF: "这是父组件的数据。",
                            msgF2: '父组件数据2.',
                            msgF3: 333
                        }
                    },
                    components: {
                        'fzzjchild': {
                            // props: ['msg','msg2'], // 有多条数据的或,用逗号隔开。
                            // 如果是以对象的实行,则后面的表示数据类型
                            props: {
                                'msg': String,
                                'msg2': String,
                                'myMsg': Number,
                            },
                            template: '<h2>父子组件的子组件</h2><p>{{msgZ}}</p><p>父组件数据:{{msg}}</p><p>父组件数据2:{{msg2}}</p><p>父组件数据3:{{myMsg}}</p>',
                            data(){
                                return {
                                    msgZ: "这是子组件的数据。"
                                }
                            },
                        }
                    }
                }
            }
        })
    </script>

这里写图片描述

父组件也是无法获取到子组件的数据的,同样需要做处理。

*子组件把自己的数据,发送到父级
                            vm.$emit(事件名,数据);
                            v-on:   @

上面的案例,继续更改,得到父组件可以获取到子组件的数据

<div id="fzzj">
        <fzzj1></fzzj1>
    </div>
    <template id='fzzj1'>
        <h1>父子组件1</h1>
        <p>This is 父子组件。</p>
        <p>{{msgF}}</p>
        <p>子组件的数据: {{msgZ1}}</p>
        <hr>
        <fzzjchild :msg='msgF' :msg2='msgF2' :msg3='msgF3' @msg-z="get"></fzzjchild>
    </template>
    <script>
        //父子组件
        new Vue({
            el: '#fzzj',
            data: {
            },
            components: {
                'fzzj1': {
                    template:'#fzzj1',
                    data(){
                        return {
                            msgF: "这是父组件的数据。",
                            msgF2: '父组件数据2.',
                            msgF3: 333,
                            msgZ1: 111,
                        }
                    },
                    methods: {
                        get(msg) {
                            this.msgZ1 = msg;
                        }
                    },
                    components: {
                        'fzzjchild': {
                            // props: ['msg','msg2'], // 有多条数据的或,用逗号隔开。
                            // 如果是以对象的实行,则后面的表示数据类型
                            props: {
                                'msg': String,
                                'msg2': String,
                                'msg3': Number,
                            },
                            template: '<h2>父子组件的子组件</h2><p>{{msgZ}}</p><p>父组件数据:{{msg}}</p><p>父组件数据2:{{msg2}}</p><p>父组件数据3:{{msg3}}</p><button @click="send()">send</button>',
                            data(){
                                return {
                                    msgZ: "这是子组件的数据。"
                                }
                            },
                            methods: {
                                send(){
                                    this.$emit('msg-z',this.msgZ);
                                }
                            }
                        }
                    }
                }
            }
        })
    </script>
vm.$dispatch(事件名,数据)   子级向父级发送数据
vm.$broadcast(事件名,数据)  父级向子级广播数据
配合: event:{}
在vue2.0里面已经,报废了

slot

作用: 占个位置
类似ng里面 transclude  (指令)

代码解释:

    <div id="box">
        <aaa>
            <ul>
                <li>1111</li>
                <li>2222</li>
                <li>3333</li>
            </ul>
        </aaa>
    </div>

    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                a:'aaa'
            },
            components:{
                'aaa':{
                    template:'<h1>xxxx</h1>'
                }
            }
        });

    </script>
当在使用组件的时候,组件内有其他内容填充,我们可以使用slot来占位,避免组件内的内容缺失不显示,因此我们可以在定义组件的时候,放上一些slot占位
<div id="box">
        <aaa>
            <ul>
                <li>1111</li>
                <li>2222</li>
                <li>3333</li>
            </ul>
        </aaa>
        <hr>
        <aaa>
        </aaa>
    </div>
    <template id="aaa">
        <h1>xxxx</h1>
        <slot>这是默认的情况</slot>
        <p>welcome vue</p>
    </template>

    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                a:'aaa'
            },
            components:{
                'aaa':{
                    template:'#aaa'
                }
            }
        });

    </script>

效果:
这里写图片描述

又有情况会出现,如果组件里的内容过多,怎么确定slot的对应问题呢?
ps: 在组件中,为每一个slot增加一个name,在使用组件的时候,给对应填充的地方的根标签上加上slot=name 就ok
<div id="box">
        <aaa>
            <ul slot="ul-slot">
                <li>1111</li>
                <li>2222</li>
                <li>3333</li>
            </ul>
            <ol slot="ol-slot">
                <li>111</li>
                <li>222</li>
                <li>333</li>
            </ol>
        </aaa>
        <hr>
        <aaa>
        </aaa>
    </div>
    <template id="aaa">
        <h1>xxxx</h1>
        <slot name="ol-slot">这是默认的情况</slot>
        <p>welcome vue</p>
        <slot name="ul-slot">这是默认的情况2</slot>
    </template>

    <script>
        var vm=new Vue({
            el:'#box',
            data:{
                a:'aaa'
            },
            components:{
                'aaa':{
                    template:'#aaa'
                }
            }
        });

    </script>

效果:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值