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

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

​ 在 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. java string 替换img标签 正则表达式 任意多个字符

    正则表达式 任意多个字符 (.*)  正则表达式中,“.”(点符号)匹配的是除了换行符“\n”以外的所有字符 要匹配包括 '\n' 在内的任何字符,([\s\S]*) 也可以用 “([\d\D]*)” ...

  2. HDU 3802Ipad,IPhone

    前两块可以看成是不是二次剩余,快速幂计算即可. 后半部分可以看成x1=a+b+2ab,x2=a+b-2ab为特征方程x^2-px-qx=0的两根 然后可以通过韦达定理求出p和q,因此递推式为A(n+2 ...

  3. hdu 5194 组合数学or暴力

    直接凑了个公式带入,没想到直接ac了,至于题解中的期望可加性可以参考概率论相关知识 #include<cstdio> #include<iostream> #include&l ...

  4. Linux学习笔记08—如何关闭防火墙

    Linux系统下面自带了防火墙iptables,iptables可以设置很多安全规则.但是如果配置错误很容易导致各种网络问题,那么如果要关闭禁用防火墙怎么操作呢,咗嚛本经验以centos系统为例演示如 ...

  5. 在windows下安装配置python开发环境及Ulipad开发工具(转)

    最近开始学习Python,在网上寻找一下比较好的IDE.因为以前用C#做开发的,用Visual Studio作为IDE,鉴于用惯了VS这么强大的IDE,所以对IDE有一定的依赖性. Python的ID ...

  6. 设置Azure WebSite黑白名单

    Azure WebSite服务默认是不提供黑白名单,也就是说任何Internet用户都可以访问Azure WebSite,那么我们如何来给我们的网站设置黑白名单? 这里有一种方式,可以通过配置网站的配 ...

  7. Redis "MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk"问题的解决(转)

    今天第二次遇到Redis “MISCONF Redis is configured to save RDB snapshots, but is currently not able to persis ...

  8. OFbiz--简单介绍

    一.简单介绍 OFBiz是一个很著名的电子商务平台,是一个很著名的开源项目,提供了创建基于最新J2EE/XML规范和技术标准,构建大中型企业级.跨平台.跨数据库.跨应用server的多层.分布式电子商 ...

  9. GoDaddy Linux主机支持机房的更换

    GoDaddy Linux主机支持机房的更换 http://godaddy.idcspy.com/godaddy-change-data-center GoDaddy推出中文界面后,小编发现虚拟主机有 ...

  10. [Winform]检测exe是否已经运行,并将其置顶

    摘要 在很多pc应用中,基本上都需要有这样的判断,保证在一个终端只运行一个winform的client.并且如果最小化了,用户再次双击桌面图标的时候,将client置顶显示. 解决方案 需要使用win ...