组件传值,数据双向绑定

一、组件传值

组件间的传值方式

父子传值:props、emit、$parent、$chidren、ref
兄弟之间传值:事件总线(on、emit)、Vuex

传值实例

(1)父组件传到子组件(props)
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

// 父组件



// 子组件接收 ceshi


(2)子组件传到父组件(emit)
子组件通过emit触发事件给父组件,父组件通过on去监听数据的变化。

// 父组件



// 子组件接收 ceshi


二、prop

prop类型

以字符串形式列出:

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

通常我们都需要每个 prop 都有指定的值类型,因此通过对象的形式列出、分别标明prop的名称和类型以及默认值

props: {
   test: String,
   likes: {
       type: Number,
       default: () => []
   },
   isPublished: {
       type: Boolean,
       default: false
   }
}

传递静态或动态 Prop

// 静态传值


// 动态赋予一个变量的值


// 动态赋予一个复杂表达式的值

单向数据流

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

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

需要改变prop时,可以通过

(1)子组件内需要将prop作为本地数据进行使用,可以在data中将这个prop作为初始值

props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}

(2)这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

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

三、自定义事件(v-model)

双向绑定v-model

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:

// 子组件


在父组件使用v-model,通过该语句实现price变量与输入值双向绑定




// 等同于

执行流程:
1、子组件通过通过 prop 接收父组件的数据price
2、当input进行输入时,会触发input事件
3、通过 $emit 提交事件,将值传递给父组件
4、父组件的input事件被触发,将会更新变量price的值
5、父组件在通过props传值给子组件

v-bind 实现单向绑定
v-model 实现双向绑定

.sync修饰符

真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源。因此推荐update:myPropName 的模式触发事件

vue事件名可以updata:prop去定义,用于处理prop传递的新值
组件内部将通过$emit('update:dtitle', val)触发事件,修改title的值

// 子组件


props: ['title'],
updateVal(val) {
    this.$emit('update:dtitle', val)
}
// 父组件

注意事项:
1、 .sync 修饰符的 v-bind 不能和表达式一起使用
2、组件内部需要$emit触发的事件名,格式为update:prop

同时在使用sync的时候,简化了绑定prop和绑定update:prop事件

四、动态组件&异步组件

五、代码实例

你可能感兴趣的