深入了解组件- -- 组件注册

gitHub地址:https://github.com/huangpna/vue_learn/example里面的lesson07

一 定义组件

1、 组件名:

在注册组件的时候我们始终需要给它一个名字,比如在全局注册的时候我们已经看到了。

 Vue.component('my-component-name',{
        /**/
    });

 该组件名就是 Vue.component 的第一个参数。

规范:我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符),这会帮助你避免和当前以及未来的 HTML 元素相冲突。

2、组件名大小写:

定义组件名的方式有两种:

使用kebab-case

Vue.component('my-component-name', { /* ... */ })

当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

使用 PascalCase

Vue.component('MyComponentName', { /* ... */ })

当使用 PascalCase (驼峰式命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name> 和 <MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

kebab-case和PascalCase的具体区别还是有些不太明白,除了书写方式的不同外;之后会再写一遍文章重新整理。

二 全局注册

举例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index1</title>
</head>
<body>
    <div id="app1">
        <my-component-name1></my-component-name1>
        <my-component-name2></my-component-name2>
        <my-component-name3></my-component-name3>
    </div>
</body>
<script src="../js/vue.min.js"></script>
<script>
    Vue.component('my-component-name1', {template:'<div>组件一</div>'});
    Vue.component('my-component-name2', {template:'<div>组件二</div>'});
    Vue.component('my-component-name3', {template:'<div>组件三</div>'});
    new Vue({
        el:'#app1'
    })
</script>
</html>

这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。

注意:在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。

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

三 局部注册

举例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index2</title>
</head>
<body>
    <div id="app2">
        <component-a></component-a>
        <component-b></component-b>
    </div>
</body>
<script src="../js/vue.min.js"></script>
<script>
    var componentA = {
        template:'<div>组件1</div>'
    };
    var componentB = {
        template:'<div>组件2</div>'
    };
    new Vue({
        el:'#app2',
        components:{   //通过components来定义你想到的组件
            'component-a':componentA,  // 属性名:自定义元素的名字   属性值:组件的选项对象
            'component-b':componentB
        }
    })
</script>
</html>

注意:局部注册的组件在其子组件中不可用,例如:如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:

    var componentA = {
        template:'<div>组件1</div>'
    };
    var componentB = {
        template:'<div>组件2</div>',
        components:{
            'component-a':componentA
        }
    };
    new Vue({
        el:'#app2',
        components:{
            'component-b':componentB
        }
    })

或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:

import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  },
  // ...
}

注意:在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写

三 模块系统

1、在模块系统中局部注册

如果你使用了诸如 Babel 和 webpack 的模块系统,在这些情况下,我们推荐创建一个 components 目录,并将每个组件放置在其各自的文件中。

然后你需要在局部注册之前导入每个你想使用的组件。例如,在一个假设的 ComponentB.js 或 ComponentB.vue 文件中:

import ComponentA from './ComponentA'
import ComponentC from './ComponentC'

export default {
  components: {
    ComponentA,
    ComponentC
  },
  // ...
}

2、基础组件的自动化全局注册

可以你的很多组件都只包含了一个输入框或者按钮的元素,是相对通用的,我们有时候会把它们称为基础组件,它们会在各个组件中被频繁的用到。

所以会导致很多组件里都会有一个包含基础组件的长列表:

import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'

export default {
  components: {
    BaseButton,
    BaseIcon,
    BaseInput
  }
}

而只是用于模板中的一小部分:

<BaseInput
  v-model="searchText"
  @keydown.enter="search"
/>
<BaseButton @click="search">
  <BaseIcon name="search"/>
</BaseButton>

幸好如果你使用了 webpack (或在内部使用了 webpack 的 Vue CLI 3+),那么就可以使用 require.context 只全局注册这些非常通用的基础组件。这里有一份可以让你在应用入口文件 (比如 src/main.js) 中全局导入基础组件的示例代码:

import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'

const requireComponent = require.context(
  // 其组件目录的相对路径
  './components',
  // 是否查询其子目录
  false,
  // 匹配基础组件文件名的正则表达式
  /Base[A-Z]w+.(vue|js)$/
)

requireComponent.keys().forEach(fileName => {
  // 获取组件配置
  const componentConfig = requireComponent(fileName)

  // 获取组件的 PascalCase 命名
  const componentName = upperFirst(
    camelCase(
      // 剥去文件名开头的 `./` 和结尾的扩展名
      fileName.replace(/^./(.*).w+$/, '$1')
    )
  )

  // 全局注册组件
  Vue.component(
    componentName,
    // 如果这个组件选项是通过 `export default` 导出的,
    // 那么就会优先使用 `.default`,
    // 否则回退到使用模块的根。
    componentConfig.default || componentConfig
  )
})

记住全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生。

先这样,还有一些不明白的,但是因为现在没有搭建vue+webpack框架,暂时无法验证,后续搭建之后一一验证。

原文地址:https://www.cnblogs.com/1156063074hp/p/10065478.html