# Prop

# Prop大小写

HTML中元素的特性(属性)是大小写不敏感的,浏览器会把所有大写字符都转为小写。需要注意将驼峰命名转为短横线分隔命名

<!-- 在 HTML 中是 kebab-case 的,如果使用字符串模板,就没有该限制 -->
<blog-post post-title="hello!"></blog-post>

<script>
  Vue.component('blog-post', {
    // 在 JavaScript 中是 camelCase 的
    props: ['postTitle'],
    template: '<h3>{{ postTitle }}</h3>'
  })
</script>

# Prop类型

props除了可以是数组外,还可以是对象,用来指定每个prop的数据类型

// 数组
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

// 对象
props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

# Prop可以传入静态或动态的值

传入的变量,这个变量可以是各种数据类型的。下面主要介绍内嵌的写法:

  • 当内嵌写法,且传入布尔属性true时,可以直接省略赋值
  • 当以内嵌写法传入false、数组、对象时,需要使用v-bind,告知这时一个js表达式而不是一个字符串。
<!-- 1. 传一个布尔值 -->
<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post>

<!-- 即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:is-published="false"></blog-post>

<!-- 2.传入一个数组 -->
<!-- 即便数组是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>

<!-- 3.传入一个对象-->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<!-- 即便对象是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<blog-post
  v-bind:author="{
    name: 'Veronica',
    company: 'Veridian Dynamics'
  }"
></blog-post>

# 单向数据流

父组件prop值的更新会传到子组件,而子组件的prop值更新不会传到父组件,用来防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

注意也有例外:由于在 JS 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。

子组件内部不应该改变prop的值

# Prop验证

子组件接收传值时,可以对传值进行校验,比如数据类型、是否必须传入,主要用于开发可能会被别人用到的组件时会很有帮助

注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data、computed 等) 在 default 或 validator 函数中是不可用的。

Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

# type数据类型检查

除了下面的type之外,还支持自定义的构造函数,如定义了Person对象,检查type也可以是Person

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

# 非props里面的特性(属性)

如果自定义组件元素的特性,不在子组件的props声明里。默认情况下,style、class属性会和子组件属性合并。其他属性会被替代

<!--  <div ma-ma="dd" class="k2 k1"> ... </div>   -->
<div id="app">
  <test-com sec="test" ma-ma="dd" class="k1"></test-com>
</div>
<script>
  Vue.component('test-com', {
    // inheritAttrs: false,
    props: ['sec'],

    /**
     * 注意template里面,只会渲染第一个元素
     * 如果<span>1</spapn><span>2</span> 只会渲染第一个。
     * 内容尽量用一个元素包裹,如div或section
     * inheritAttrs: false 会禁用继承,渲染如下:
     * <div ma-ma="123" class="k2 k1"> ... </div> 
     */
    template: `
      <div class="k2" ma-ma="123">
        <span>str1</span>
        <div>
          <span>str2</span>
          str3
        </div>
        <span>{{ sec }}</span>
      </div>
    `
  })
  var app = new Vue({
    el: '#app',
    data: {
    }
  })
</script>

# 禁用继承,$attrs

  • inheritAttrs: false 会禁用继承
  • $attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
上次更新: 2020/10/29 22:59:19