项目中,我们经常会遇到自定义组件传值的问题,方法很多种,但是原理很简单,下述文档总结实际项目中使用的传值方式。

父组件传递给子组件某一值,子组件内会修改该值,然后父组件需要获取新值

​ 在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop给子组件下发数据,子组件通过事件给父组件发送消息。

常规prop-event

父组件

<prop-event-value :address="address" @update="val => address = val" key="4"></prop-event-value>

<script>
import propEventValue from './components/prop-event-value.vue'
export default {
name: 'app',
components: {
propEventValue
},
data() {
return {
address: ''
}
}
}
</script>

子组件

<template>
<div>
<p>prop-event</p>
<label for="address">地址</label>
<input type="text" id="address" v-model="tempAddress">
</div>
</template> <script>
export default {
name: 'prop-event',
props: ['address'],
data() {
return {
tempAddress: this.address
}
},
watch: {
tempAddress(newVal) {
this.$emit('update', newVal)
}
}
}
</script>

需要注意:不要直接在子组件内操作父组件的内容

​ 组件实例的作用域是孤立的。每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。如果你这么做了,Vue 会在控制台给出警告。

export default {
name: 'prop-event',
props: ['address'],
watch: {
address(newVal) {
this.$emit('update', newVal)
}
}
}

如将上述代码替换子组件,内容会报错! 

修饰符.sync

父组件

<my-sync-value :address.sync="address" key="5"></my-sync-value>

<script>
import mySyncValue from './components/my-sync-value.vue'
export default {
name: 'app',
components: {
mySyncValue
},
data() {
return {
address: ''
}
}
}
</script>

子组件

<template>
<div>
<p>my-sync</p>
<label for="address">地址</label>
<input type="text" id="address" v-model="tempAddress">
</div>
</template> <script>
export default {
name: 'my-sync',
props: ['address'],
data() {
return {
tempAddress: this.address
}
},
watch: {
tempAddress(newVal) {
// 必须是这个update:address
this.$emit('update:address', newVal)
}
}
}
</script>

prop-update:[prop]语法糖,与prop-event对比的优势:父组件无需监听事件@update="val => address = val",自动监听update:[prop]事件。

双向数据绑定v-model

所以要让组件的 v-model 生效,它应该 (从 2.2.0 起是可配置的):

  • 接受一个 value prop
  • 在有新的值时触发 input 事件并将新值作为参数

父组件

<my-vmodel-value v-model="address" key="6"></my-vmodel-value>

<script>
import myVmodelValue from './components/my-vmodel-value.vue'
export default {
name: 'app',
components: {
myVmodelValue
},
data() {
return {
address: ''
}
}
}
</script>

子组件

<template>
<div>
<p>my-vmodel</p>
<label for="address">姓名</label>
<input type="text" id="address" v-model="tempAddress">
</div>
</template> <script>
export default {
name: 'my-vmodel',
props: ['value'],
data() {
return {
tempAddress: this.value
}
},
watch: {
tempAddress(newVal) {
// 必须是input
this.$emit('input', newVal)
}
}
}
</script>

prop-input语法糖,父组件v-model默认监听input事件 
需要注意,这里必须触发input事件,当然也可以自定v-model属性值和事件,请参照自定义组件的v-model

vuex

通过store传值,这里后续单独讲述vuex。

单向数据流

​ 上述已经提及,在子组件内部改变 prop,Vue会在控制台给出告警。但经常开发周静,我们很容易忍不住修改prop中的数据,如:

  • Prop 作为初始值传入后,子组件想把它当作局部数据来用;
  • Prop 作为原始数据传入,由子组件处理成其它数据输出。

对这两种情况,正确的应对方式是: 
问题1:定义一个局部变量,并用 prop 的值初始化它:

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

问题2:定义一个计算属性,处理 prop 的值并返回:

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

特别需要注意:在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

vue-自定义组件传值的更多相关文章

  1. vue父子组件传值加例子

    例子:http://element-cn.eleme.io/#/zh-CN/component/form         上进行改的 父传子:用prop:子组件能够改变父组件的值,是共享的,和父操作是 ...

  2. vue自定义组件(vue.use(),install)+全局组件+局部组件

    相信大家都用过element-ui.mintui.iview等诸如此类的组件库,具体用法请参考:https://www.cnblogs.com/wangtong111/p/11522520.html ...

  3. 关于Vue父子组件传值(复杂数据类型的值)的细节点

    vue 父子组件传值是很常见的,多数情况下都是父传递给子的值是基础数据类型,如string,number,boolean, 当父组件值被修改时,子组件能够实时的作出改变. 如果父子传值的类型是复杂数据 ...

  4. 一个故事讲懂vue父子组件传值

    作者:李佳明同学链接:https://www.jianshu.com/p/2272b6ca0f0c 一个故事讲懂vue父子组件传值 讲故事前先讲代码 父组件向子组件传值 父组件数据传递给子组件可以通过 ...

  5. Vue自定义组件实现v-model指令

    Tips: 本文所描述的Vue均默认是Vue2版本 在我们初次接触Vue的时候,一定会了解到一个语法糖,那就是v-model指令,它带给我们的第一印象就是它可以实现双向绑定 那么,什么是双向绑定?通俗 ...

  6. vue 自定义组件 v-model双向绑定、 父子组件同步通信

    父子组件通信,都是单项的,很多时候需要双向通信.方法如下: 1.父组件使用:msg.sync="aa"  子组件使用$emit('update:msg', 'msg改变后的值xxx ...

  7. vue.js组件传值

    组件传值有一下几种方式:父子传值(父传子,子传父),非父子传值,vuex,插槽作用域 1.父子传值: (1)父传子: 传值方:当子元素在父元素中当标签使用时,通过给子标签绑定一个自定义属性,属性值为需 ...

  8. vue父子组件传值

    1.父组件向子组件传值 例如app.vue是父组件,v-header.vue是子组件,实现app向v-header传值父组件需要自定义自己的title值, 子组件v-header内容 <temp ...

  9. vue 自定义组件 v-model双向绑定、 父子组件同步通信【转】

    父子组件通信,都是单项的,很多时候需要双向通信.方法如下: 1.父组件使用:msg.sync="aa"  子组件使用$emit('update:msg', 'msg改变后的值xxx ...

  10. vue自定义组件中的v-model简单解释

    在使用iview框架的时候,经常会看到组件用v-model双向绑定数据,与传统步骤父组件通过props传值子组件,子组件发送$emit来修改值相比,这种方式避免操作子组件的同时再操作父组件,显得子组件 ...

随机推荐

  1. windows系统,联系人文件。个性化。

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha ======= 文件下载链接:

  2. ZJOI2019day1退役记

    ZJOI2019day1退役记 每天都在划水,考场上心态炸了,也没什么好说的. 有人催我更退役记,等成绩出来了再更更吧,成绩出来也没心情更了,落差好大,还打不过文化课选手 虽然被卡常数卡到心态爆炸,但 ...

  3. 工具使用-----Jmeter-脚本的录制

    //转载  http://www.cnblogs.com/fnng/archive/2011/08/20/2147082.html 以下是我自己录制的关于这篇文章的视频,有兴趣的可以下载哦 https ...

  4. BZOJ4275 : [ONTAK2015]Badania naukowe

    设f[i][j]为a[1..i]与b[1..j]的LCS,g[i][j]为a[i..n]与b[j..m]的LCS. 若C为0,则ans=f[n][m]. 否则求出d[i]=a中从i开始往右匹配上c串的 ...

  5. Codeforces Round #375 (Div. 2) B. Text Document Analysis 模拟

    B. Text Document Analysis 题目连接: http://codeforces.com/contest/723/problem/B Description Modern text ...

  6. jQuery.fn.extend()和jQuery.extend()

    jQuery.fn.extend( object ) 一个对象的内容合并到jQuery的原型,以提供新的jQuery实例方法. jQuery.fn.extend()方法继承了jQuery原型($.fn ...

  7. 使用 IntraWeb (23) - 基本控件之 TIWTimer、TIWProgressBar、TIWProgressIndicator、TIWTimeEdit

    TIWTimer //和 TTimer 没多大区别, 它的默认事件现在是异步的(OnAsyncTimer), 在网络上使用 OnTimer 肯定是非常糟糕的 TIWProgressBar //进度条 ...

  8. Bootstrap入门学习(三)——简单项目

    此样例来自Bootstrap官网提供的入门级模版.仅仅有主要的东西:引入了预编译版的 CSS 和 JavaScript 文件,页面仅仅包括了一个 container 元素. 引入Bootstrap 创 ...

  9. IIS7.0下 HTTP 错误 404.15 - Not Found 请求筛选模块被配置为拒绝包含的查询字符串过长的请求

    IIS7.0下 HTTP 错误 404.15 - Not Found 请求筛选模块被配置为拒绝包含的查询字符串过长的请求   IIS7.0下查询条件太多时,会报错,因为IIS 7对于Query Str ...

  10. mysql主从同步失败Last_IO_Error: Got fatal error 1236 from master解决方法

    mysql教程主从同步失败Last_IO_Error: Got fatal error 1236 from master解决方法 遇到这样的错误如:“Last_IO_Error: Got fatal ...