zoukankan      html  css  js  c++  java
  • vuelearning:25 component 概念定义注册使用命名

    概念

    Vue遵循Web Component规范,提供了自己的组件系统。组件是一段独立的代码,代表页面中某个功能块,拥有自己的数据、JS、样式,以及标签。组件的独立性是指形成自己独立的作用域,不会对其它组件产生任何副作用。

    Vue 组件是可复用 Vue 实例,接受相同的选项option对象 (除了一些根级特有的选项) 和使用相同的生命周期钩子,以及模板调用方式。

    Vue 组件可以嵌套,所以组件之间可以进行引用和通信

    组件定义

    Vue提供了专用的API来定义组件,组件构造器函数: Vue.extend()

        const MyComponent = Vue.extend(option)
        // option跟new Vue(option)时基本相同(除了el/data)
    

    这样,我们就构建好了一个组件,但现在还无法使用这个组件。还需要将这个组件注册到对应的应用中。

    组件的注册

    为了能在模板中使用,这些组件必须注册以便 Vue 能够识别。有两种注册方式:全局注册和局部注册

    全局注册

    使用API:Vue.component就可以完成组件全局注册,全局注册的组件可以被多个Vue实例复用。

    Vue.component('my-component', MyComponent)
    // 组件注册语句必须在new Vue(option)之前
    

    局部注册

    使用Vue实例的components属性注册局部组件,局部注册的组件只在包含它的父组件作用域内有效。

    const MyChild = Vue.extend({
        template: `<p>{{ childMsg }}</p>`
        data: function() {
            return {
                childMsg: 'This is a child component'
            }
        }
    })
    
    const vm = new Vue({
        el: "#app",
        data: {
            msg: 'This is a parent component'
        },
        components: {
            MyChild: MyChild
        }
    })
    

    上述Child组件只在vm实例内有效。在其它新建的实例内无法引用。

    注册语法糖

    Vue对全局注册和局部注册都提供了简写方法,可以在注册的同时定义组件,Vue内部会自动调用extend方法构建组件。

    Vue源码解读之Component组件注册

    // 全局注册
    Vue.component('MyChild', {
        template: `<p>{{ childMsg }}</p>`
        data: function() {
            return {
                childMsg: 'This is a child component'
            }
        }
    })
    
    // 局部注册
    new Vue({
        el: "#app",
        data: {
            msg: 'This is a parent component'
        },
        components: {
            MyChild: {
                template: `<p>{{ childMsg }}</p>`
                data: function() {
                    return {
                        childMsg: 'This is a child component'
                    }
                }
            },
        }
    })
    

    组件的使用

    在注册组件同时,也声明了一个自定义标签,即组件名。在Vue模板需要调用的地方使用组件名作为自定义的标签,直接调用组件。

    <My-Child></My-Child>
    

    注意事项:

    option的区别

    const MyChild = Vue.extend(option)
    const vm = new Vue(option)
    
    • data必须是一个函数
      因为组件是可复用的,如果组件的data是一个对象的直接引用,那复用多个组件将共享一个对象,其中一个组件修改了对象属性,其它组件引用了该对象属性的值也会变化,这是我不希望看到的。而通过函数返回值,将实现每个组件拥有独立的数据对象。
      点击查看官方示例解释
    new Vue({
        el: "#app",
        data: {
            msg: 'This is a parent component'
        },
        components: {
            MyChild: {
                template: `<p>{{ childMsg }}</p>`
                data: function() {
                    return {
                        childMsg: 'This is a child component'
                    }
                }
            },
        }
    })
    

    解析 DOM 模板时的注意事项

    有些 HTML 元素,诸如 <ul><ol><table><select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li><tr><option>,只能出现在其它某些特定的元素内部。

    这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

    <table>
      <blog-post-row></blog-post-row>
    </table>
    

    这个自定义组件 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:

    <table>
      <tr is="blog-post-row"></tr>
    </table>
    

    需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:

    组件的命名规范

    官方组件命名风格指南

    • 在JS域中使用PascalCase,在DOM模板域中使用kebab-case
    • 以父组件或更高级别的单词开头,使用语义完整的单词
    • 由于 HTML 是大小写不敏感的,在 DOM 模板中必须使用 kebab-case
    • 在 JavaScript 中,PascalCase 是类和构造函数 (本质上任何可以产生多份不同实例的东西) 的命名约定,Vue 组件也可以有多份实例,所以同样使用 PascalCase 是有意义的。

    点击查看DEMO

    <div id="app">
        <p>{{ msg }}</p>
        <com-local></com-local>
        <com-global></com-global>
    </div>
    <p>=================================</p>
    <div id="other">
        <p>{{ msg }}</p>
        <com-other-local></com-other-local>
        <com-global></com-global>
    </div>
    
    // 使用构造器函数定义组件
    const ComLocal = Vue.extend({
        data: function() {
            return {
                msg: 'This is a local component'
            }
        },
        template: `<p>{{ msg }} by Vue.extend</p>`
    })
    
    // 全局注册组件,并且必须在new Vue()之前
    Vue.component('ComGlobal', {
        data: () => {
            return {
                msg: 'this is a global component'
            }
        },
        template: `<p>{{ msg }} by Vue.component`
    })
    
    // 创建一个Vue 实例对象vm,调用全局组件和使用extend定义的局部组件
    const vm = new Vue({
        el: "#app",
        data: {
            msg: 'This is a vm'
        },
        components: {
            ComLocal
        }
        
    })
    
    // 创建另一个Vue实例对象otherVm,调用全局组件和使用内部components属性定义的局部组件
    const otherVm = new Vue({
        el: '#other',
        data: {
            msg: 'This is other Vue'
        },
        components: {
            comOtherLocal: {
                template: `<p>This is a local component by components properity</p>`
            }
        }
    })
    
    // 输出
    This is a vm
    This is a local component by Vue.extend
    this is a global component by Vue.component
    =================================
    This is other Vue
    This is a local component by components properity
    this is a global component by Vue.component
    
  • 相关阅读:
    PowerDesigner概念设计模型(CDM)中的3种实体关系
    基于Prototype 1.6.2 框架下的数据分页
    中国地区,北京54坐标系条带号的选
    C#中MessageBox的使用
    C#注册表的读,写,删除,查找 (转)
    C# Tostring() 格式大全 [转]
    Layer features in this layer set, ArcEngine图层标注源码 (转)
    判断点是否在多边形之内的方法
    C#导入Excel到Dataset和导出Excel到DataTable
    Server.MapPath方法的应用方法
  • 原文地址:https://www.cnblogs.com/webxu20180730/p/11031231.html
Copyright © 2011-2022 走看看