• Component (组件) 进阶
    • Component 命名规则
    • Prop 命名规则
    • Prop 可以有多种类型。
    • 可以动态为 prop 赋值
    • 使用Object来为Prop赋值
    • 单向的数据流
    • Prop的验证
    • Non Prop (非Prop) 的属性
    • 对于Attribute的合并和替换
    • 避免 子组件的attribute 被父页面 所影响

    Component (组件) 进阶

    Component 是非常常见的,在我们的Web开发中,只要是生产环境的项目,就一定会有Component.

    下面就是我们的一个实际项目中的例子, 这个项目我们只做了两个月,里面就发展到了32个component. 如下图所示:

    实际项目中的component

    很多时候,我们甚至会看到 一个 component 中嵌套着另一个, 这个component再嵌套另外5个….

    例如:

    popup-picker 这个component中,看起来是这样的:

    1. <template>
    2. <div>
    3. <popup
    4. class="vux-popup-picker"
    5. :id="`vux-popup-picker-${uuid}`"
    6. @on-hide="onPopupHide"
    7. @on-show="onPopupShow">
    8. <picker
    9. v-model="tempValue"
    10. @on-change="onPickerChange"
    11. :columns="columns"
    12. :fixed-columns="fixedColumns"
    13. :container="'#vux-popup-picker-'+uuid"
    14. :column-width="columnWidth">
    15. </picker>
    16. </popup>
    17. </div>
    18. </template>
    19. <script>
    20. import Picker from '../picker'
    21. import Popup from '../popup'
    22. ...
    23. </script>

    可以看到,这个component中,还包含了另外两个,一个是popup, 一个是 picker.

    这个时候,新人往往会眼花缭乱。 如果看到 this.$emit , 就更晕了。

    所以,要做好实际项目,同学们一定要学好本章。

    Component 命名规则

    每个component 的命名,官方建议使用 小写字母 + 横线的形式,例如:

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

    这个是符合W3C的规范的。

    也可以定义为:

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

    这个时候,可以使用 <MyComponentName/> 来调用,也可以使用 <my-component-name/> 来调用。

    Prop 命名规则

    同 component, 建议使用 小写字母 + ‘-‘ 连接。

    Prop 可以有多种类型。

    下面是一个例子,可以看出,一个component的 prop 可以有多种类型, 包括: 字符串,数字,bool, 数组,和 Object.

    1. props: {
    2. title: "Triple Body",
    3. likes: 38444,
    4. isPublished: true,
    5. commentIds: [30, 54, 118, 76],
    6. author: {
    7. name: "Liu Cixin",
    8. sex: "male"
    9. }
    10. }

    可以动态为 prop 赋值

    例如,这是个静态的赋值:

    1. <blog-post title="Vuejs的学习笔记"></blog-post>

    这是个动态的赋值:

    1. // 1. 在script中定义
    2. post = {
    3. title: 'Triple body',
    4. author: {
    5. name: "Big Liu",
    6. sex: 'male'
    7. }
    8. }
    9. // 2. 在模板中使用。
    10. <blog-post v-bind:title="post.title + 'by' + post.author.name"></blog-post>

    赋值的时候,只要是符合标准的类型,都可以传入(包括String, bool, array 等).

    使用Object来为Prop赋值

    假设,我们定义有:

    1. post = {
    2. author: {
    3. name: "Big Liu",
    4. sex: 'male'
    5. }
    6. }

    那么,下面的代码:

    1. <blog-post v-bind:author></blog-post>

    等价于:

    1. <blog-post v-bind:name="author.name" v-bind:sex="author.sex"></blog-post>

    单向的数据流

    当“父页面” 引用一个“子组件”时, 如果父页面中的变量发生了变化,那么对应的“子组件”也会发生页面的更新。

    反之则不行。

    Prop的验证

    Vuejs 的组件的Prop , 是可以被验证的。 如果验证不匹配,浏览器的 console就会弹出警告(warning). 这个对于我们的开发非常有利。

    我们下面的代码:

    1. Vue.component('my-component', {
    2. props: {
    3. name: String,
    4. sexandheight: [String, Number],
    5. weight: Number,
    6. sex: {
    7. type: String,
    8. default: 'male'
    9. }
    10. }
    11. })

    可以看得出,

    name: 必须是字符串sexandheight: 必须是个数组。 第一个元素是String, 第二个元素是Numberweight: 必须是Numbersex: 是个String, 默认值是 ‘male’

    支持的类型有:

    • String
    • Number
    • Boolean
    • Array
    • Object
    • Date
    • Function
    • Symbol

    Non Prop (非Prop) 的属性

    很多时候,component的作者无法预见到应该用哪些属性, 所以Vuejs在设计的时候,就支持让 component接受一些没有预先定义的 prop. 例如:

    1. Vue.component('my-component', {
    2. props: ['title']
    3. })
    4. <my-component title='三体' second-title='第二册: 黑暗森林'></my-component>

    上面的 title 就是预先定义的 “Prop”, second-title 就是“非Prop”

    我们想传递一个 non-pro, 非常简单, prop 怎么传, non-prop 就怎么传。

    对于Attribute的合并和替换

    如果component中定义了一个 attribute, 例如:

    1. <template>
    2. <div color="red">我的最终颜色是蓝色</div>
    3. </template>

    如果在引用了这个“子组件”的“父页面”中,也定义了同样的attribute, 例如:

    1. <div>
    2. <my-component color="blue"></my-component>
    3. </div>

    那么,父页面传递进来的 color="blue" 就会替换子组件中的 color="red"

    但是,对于 classstyle 是例外的。 对于上面的例子, 如果attribute换成 class, 那么最终component中的class的值,就是 “red blue” (发生了合并)

    避免 子组件的attribute 被父页面 所影响

    根据上面的小结, 我们知道了 “父页面”的值总会“替换” “子组件”中的同名attribute .

    如果不希望有这样的情况的话,我们就可以在定义 component的时候, 这样做:

    1. Vue.component('my-component', {
    2. inheritAttrs: false,
    3. // ...
    4. })