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

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

​ 在 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. Jindent——让intellij idea 像eclipse一样生成模版化的javadoc注释

    插件地址 http://plugins.jetbrains.com/plugin/2170?pr=idea 安装方法参考 http://www.cnblogs.com/nova-/p/3535636. ...

  2. 五校联考R1 Day2T2 矩阵matrix(容斥)

    题目链接 容易想到容斥,但是很恶心,因为要对行和列都容斥,然后行+列又要容斥.. 于是得到\(O(nm\log)\)的做法. 就有70分了: #include <cstdio> #incl ...

  3. DG449 High Voltage Single SPDT Analog Switch in SOT23-8

    DESCRIPTION The DG449 is a dual supply single-pole/double-throw (SPDT) switches. On resistance is 38 ...

  4. A CANBus Tiny Network without Transceiver ICs : STM32F4 Discovery

    Sometimes you have a CAN equipped processor on a low cost board but it has no CAN transceiver chips. ...

  5. Android开发:仿美团下拉列表菜单,帮助类,复用简单

    近期在项目中须要用到下拉菜单.公司比較推崇美团的下拉菜单,于是要实现该功能.想着.这个功能应该是一个常常会用到的.于是何不写一个帮助类,仅仅要往这个类里面传入特定的參数,既能够实现下来菜单,并且还能够 ...

  6. delphi 取得任意程序的命令行

    program GetCommandLineExDemo; uses Windows; constSystemHandleInformation = 16;ProcessBasicInformatio ...

  7. CentOS 安装 nexus (maven 私服)

    原文:https://www.sunjianhua.cn/archives/centos-nexus.html 1.下载 wget http://download.sonatype.com/nexus ...

  8. iPhone开发中从一个视图跳到另一个视图有三种方法:

    iPhone开发中从一个视图跳到另一个视图有三种方法:   1.self.view addSubView:view .self.window addSubView,需要注意的是,这个方法只是把页面加在 ...

  9. WordPress主题开发:循环代码

    have_posts() 有没有文章信息 if...else <?php if( have_posts() ) : while( have_posts() ) : the_post(); ?&g ...

  10. 关于面试总结10-selenium中隐藏元素如何定位?(hidden、display: none)

    前言 面试题:selenium中隐藏元素如何定位?这个是很多面试官喜欢问的一个题,如果单纯的定位的话,隐藏元素和普通不隐藏元素定位没啥区别,用正常定位方法就行了 但是吧~~~很多面试官自己都搞不清楚啥 ...