Vue2.0学习-2-深入了解组件--2--Prop

(day9-2)

Prop的大小写、Prop类型、传递一个静态或动态Prop

单向数据流、Prop验证、非Prop的Attribute

一、Prop的大小写、Prop类型、传递一个静态或动态Prop

 1、Prop的大小写(camelCase vs kebab-case)

camelCase(驼峰命名法)、kebab-case(短横线分隔命名)

在JavaScript中是驼峰命名,在HTML中将会是kebab-case。(因为浏览器会把所有的大写字符解释为小写字符)

2、Prop类型

# 通常看到的以字符串形式列出的prop:

props:['title','likes','isPublished','commentIds','author']

# 以对象的形式列出prop,这些property 的名称和值分别是 这些props各自的名称和类型

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

这样写可以为你组件的Prop提供文档,并且这种写法可以用在类型检查以及其他Prop验证,后面会讲到。

3、传递静态或动态Prop

# 静态赋值:直接给事先定义好的prop传入一个静态的值:

<blog-post title="My journey with Vue"><blog-post>

# 动态赋值:通过 v-bind 动态赋值:

<!--动态的赋予一个变量值-->
<blog-post v-bind:title="post.title"></blog-post>

<!--动态的的赋予一个复杂表达式的值-->
<blog-post v-bind:title="post.id + 'by' + post.author.name"></blog-post>

# 上述的传递给prop 的是字符串,实际上任何类型的值都可以传递给prop

数字、布尔值、数组、对象、传入一个对象的所有property。

# 数字:

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

<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:likes="post.likes"></blog-post>

# 布尔值:(注意下面的第一个情况)

<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post>

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

<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:is-published="post.isPublished"></blog-post>

# 数组:

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

<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:comment-ids="post.commentIds"></blog-post>

# 对象:

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

<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:author="post.author"></blog-post>

# 一个对象的所有property:

post: {
  id: 1,
  title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>

<!--上面的写法等价于-->
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

二、单向数据流、 Prop验证、非Prop的Attribute

1、单向数据流

对于所有的prop,父子prop之间会形成一个单向下行绑定父级prop的更新会向下流动到子组件中,但是反过来则不行。(这样可以防止子组件意外变更父组件的状态,从而导致你的数据流向难以理解)

(有点类似于复制变量值,子组件复制父组件的变量值,子组件的改变不会影响父组件的值,父组件的改变会赋值给子组件从而导致子组件的跟随父组件变化)

 每次父级组件的发生变更,子组件中所有的prop都将会刷新为最新的值。
这意味着你不应该在一个子组件内部改变prop。(如果做了,Vue会在浏览器的控制台发出警告)

 两种常见的试图变更一个prop 的情形

# 这个prop用来传递一个初始值;这个子组件接下来希望将其作为一个本地的prop数据来使用

//在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:
props:['initialCounter'],
data:function(){
    return {
        counter:this.initialCounter
    }
}

 # 这个prop以一种原始的值传入且需要进行转换

//在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

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

 2、Prop验证

# 验证

也就是在 props 中的值提供一个带有验证需求的对象,而不是字符串数组。如:

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
      }
    }
  }
})

基础检查、多可能的类型、必填(required:true)、默认值(default:String/Object)、自定义验证函数(validator:function(){})

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

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

 # 类型检查

type 可以是原生构造函数中的一个:

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

额外的,type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。例如,

function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}


//使用下面,来验证 author prop 的值是否是通过 new Person 创建的。
Vue.component('blog-post', {
  props: {
    author: Person
  }
})

3、非Prop的Attribute

一个非 prop 的 attribute 是指传向一个组件,但是该组件并没有相应 prop 定义的 attribute。

 就是指一个Attibute,它传给了一个组件,但这个组件的props中没有定义这个Attirbute,那么这个Attribute就是 非Prop的Attribute。

因为显式定义的 prop 适用于向一个子组件传入信息,然而组件库的作者并不总能预见组件会被用于怎样的场景。这也是为什么组件可以接受任意的 attribute而这些 attribute 会被添加到这个组件的根元素上

  替换/合并已有的Attribute

<!--<bootstrap-date-input> 的模板是这样的:-->
<input type="date" class="form-control">
<!--应用模板时-->
<!--为了给我们的日期选择器插件定制一个主题,我们可能需要像这样添加一个特别的类名-->
<bootstrap-date-input
  data-date-picker="activated"
  class="date-picker-theme-dark"
></bootstrap-date-input>

在这种情况下,我们定义了两个不同的 class 的值:

  • form-control,这是在组件的模板内设置好的
  • date-picker-theme-dark,这是从组件的父级传入的

对于绝大多数 attribute 来说,从外部提供给组件的值会替换掉组件内部设置好的值。
所以如果传入 type="text" 就会替换掉 type="date" 并把它破坏!

庆幸的是,class 和 style attribute 会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:form-control date-picker-theme-dark

 # 禁用Attribute继承

inheritAttrs: false ——不希望组件的根元素继承 attribute。

这尤其适合配合实例的 $attrs property 使用。

有了 inheritAttrs: false 和 $attrs,你就可以手动决定这些 attribute 会被赋予哪个元素。

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on:input="$emit('input', $event.target.value)"
      >
    </label>
  `
})

 这个模式允许你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素:

<base-input
  label="Username:"
  v-model="username"
  required
  placeholder="Enter your username"
></base-input>

注意 inheritAttrs: false 选项不会影响 style  class 的绑定。

 # vm.$attrs 

  • 类型:{ [key: string]: string }
  • 只读
  • 详细:
    包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值