Vue组件机制

1.概述

组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue的编译器为它添加特殊功能。在有些情况下,组件也可以表现为用is特性进行了扩展的原生 HTML 元素。组件注册的时候需要为该组件指定各种参数。

2.组件定义 

因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝

        // 1.组件的定义
        let component1={
            //data选项必须是一个函数
            data(){
                return{
                    msg:'我是子组件1'
                }
            },
            //模板
            template:`
                <div>
                    <h3>{{msg}}</h3>
                    <button @click="msg='新数据'">修改数据</button>
                </div>
            `
        }

 3.组件注册

 要想进行组件使用,先进行组件注册

1. 全局注册

可以使用Vue.component(tagName, options) 注册一个全局组件, 注册之后可以用在任何新创建的 Vue 根实例的模板中。

Vue.component('my-com1',component1)

2. 局部注册

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。局部注册的组件只能在当前组件中使用。

let vm=new Vue({
         el:'#app',
         data:{},
         methods:{},
         created(){},
         //局部注册
         components:{
             'my-com2':component2
         }
     })

###完整代码例子

<body>
    <div id="app">
        <my-com1></my-com1>
        <my-com2></my-com2>
    </div>
    <script>
        // 1.组件的定义
        let component1={
            data(){
                return{
                    msg:'我是子组件1'
                }
            },
            template:`
                <div>
                    <h3>{{msg}}</h3>
                    <button @click="msg='新数据'">修改数据</button>
                </div>
            `
        }
        let component2={
            data(){
                return{
                    msg:'我是子组件2'
                }
            },
            template:`
                <div>
                    <h3>{{msg}}</h3>
                    <my-com1></my-com1>
                </div>
            `
        }

        // 2.组件注册
            // 2.1全局注册
        Vue.component('my-com1',component1)

        let vm=new Vue({
            el:'#app',
            data:{},
            methods:{},
            created(){},
            // 2.2局部注册
            components:{
                'my-com2':component2
            }
        })
    </script>
</body>

 ###效果如下:

4.组件交互/通信

组件 A 在它的模板中使用了组件 B。它们之间必然需要相互通信:

父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告知父组件。

在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。

1.子组件内使用父组件数据

   1.父组件传递数据给子组件 (可以传递静态属性 动态属性 )

        <my-com title='' :msg='msg' attr-a=''>

   2.子组件接收并处理数据

        {

           props:['title','msg','attrA],

           template:``

        }

2.父组件内使用子组件的数据

       事件发射 自定义事件

       在子组件内发射 在父组件内接受

子组件发射时机

1.手动按钮发送

2.监听子组件内数据变化,然后发射

    在子组件内监听comMsg的变化,this.$emit('',this.comMsg)
父组件的事件处理程序调用,可以更改父组件数据模型中的数据,同步反映到父组件视图中

   4.1 父组件传递数据给子组件

<body>
    <div id="app">
        <!-- 3.组件使用 -->
        <button @click="attr2.username='tom'">修改父组件数据值</button>
        <my-com :num='1' :attr1="attr1" :parent-data='attr2'></my-com>
        <!-- <my-com :num='1' attr1="hello"></my-com> -->

    </div>
    <script>
        // 1.组件的定义
        let component1={
            // props:['num','attr1','parentData']
            props:{
                num:[Number,String],
                attr1:{
                    type:String,
                    required:true,
                    default:'默认值',
                    validator(value){
                        return value.length>=3
                    }
                },
                parentData:{
                    type:Object,
                    default(){
                        return{
                            username:'李四',
                            age:24
                        }
                    }
                }
            },
            data(){
                return{
                    msg:'子组件1'
                }
            },
            template:`
                <div>
                    <h3>{{msg}}</h3>
                    <h2>父组件传递过来的数据:{{attr1}}-{{parentData}}</h2>
                    <h4>{{num}}-{{typeof num}}</h4>
                </div>
            `
        }
        let vm=new Vue({
            el:'#app',
            data:{
                attr1:'我是父组件数据',
                attr2:{
                    username:'zs',
                    age:22
                },
            },
            methods:{},
            // 2.局部组件注册
            components:{
                'my-com':component1
            }
        })
    </script>
</body>

    4.2 子组件向父组件传递数据

<body>
    <div id="app">
        <h2>父组件</h2>
        <div class="box">
            {{parentData}}
        </div>
        <!-- 父组件 -->
        <my-com v-on:child-event="parentHandler">
            成功按钮
        </my-com>
    </div>
    <script>
        // 1.组件定义
        let component1={
            data(){
                return{
                    childData:'windows 11'
                }
            },
            methods:{
                toEmitHandler(){
                    // $emit方法可以向上发送数据,并且可以携带数据
                    // 子组件
                    this.$emit('child-event',this.childData)
                }
            },
            template:`
                <div>
                    <h3>子组件</h3>
                    <button @click='toEmitHandler'>发送事件</button>
                    <button>
                        <slot></slot>
                    </button>
                </div>
            `
        }
        let vm=new Vue({
            el:'#app',
            data:{
                parentData:'Windows98'
            },
            methods:{
                parentHandler(data){
                    console.log('我知道了',data);
                    //修改父组件数据,由父组件自己来决定
                    this.parentData=data;
                }
            },
            // 2.局部组件注册
            components:{
                'my-com':component1
            }
        })
    </script>
</body>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值