Vue文档3 Prop

Prop

字符串数组形式列出的 prop:

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

prop 各自的名称和类型

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

传递静态或动态 Prop

给 prop 传入一个静态的值

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

prop 可以通过 v-bind 动态赋值

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

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

需要 v-bind 来告诉 Vue 这是一个 JavaScript 表达式而不是一个字符串。

  • 传入数字
  • 传入布尔值
  • 传入数组
  • 传入对象

单向数据流

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

每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你应该在一个子组件内部改变 prop

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

Prop 验证

例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你

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

替换/合并已有的 Attribute]

classstyle attribute 值会被合并起来

禁用 Attribute 继承

如果你希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false。例如:

Vue.component('my-component', {
  inheritAttrs: false,
  // ...
})

自定义事件

事件名不存在自动大小写转换,在v-on事件监听器DOM模板中会自动转化为小写

自定义组件v-model

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件

但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

将原生事件绑定到组件

想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on.native 修饰符:

但元素实际上是一个 <label> 元素的时候监听不到:

包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定

$attrs可以接受上级传递过来的属性

<label>
  {{ label }}
  <input
    v-bind="$attrs"
    v-bind:value="value"
    v-on:input="$emit('input', $event.target.value)"
  >
</label>

Vue 提供了一个 $listeners property,它是一个对象,里面包含了作用在这个组件上的所有监听器

{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}

就可以配合 v-on="$listeners"将所有的事件监听器指向这个组件的某个特定的子元素

.sync 修饰符

真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源

带有 .sync 修饰符的 v-bind 不能和表达式一起使用

例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的

简写双向绑定的语法糖

<child :title.sync="title"> </child>

 <input :value="title" @input="abc" type="text">
    props: {
      title: {
        type: String,
        required: true
      }
    },
      methods: {
      abc(e) {
        console.log(e.target.value);
        this.$emit('update:title', e.target.value);
      }
    }