vue-自定义组件传值的实例讲解


Posted in Javascript onSeptember 18, 2018

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

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

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

自定义组件传值

vue-自定义组件传值的实例讲解

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

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

vue-自定义组件传值的实例讲解

修饰符.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-自定义组件传值的实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS下高效拼装字符串的几种方法比较与测试代码
Apr 15 Javascript
js中replace的用法总结
Dec 27 Javascript
jQuery实现html表格动态添加新行的方法
May 28 Javascript
针对初学者的jQuery入门指南
Aug 15 Javascript
微信小程序 获取相册照片实例详解
Nov 16 Javascript
浅谈JavaScript的计时器对象
Dec 26 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
Mar 13 Javascript
Angular中的ng-template及angular 使用ngTemplateOutlet 指令的方法
Aug 08 Javascript
小程序实现自定义导航栏适配完美版
Apr 02 Javascript
vue+vant 上传图片需要注意的地方
Jan 03 Vue.js
JS addEventListener()和attachEvent()方法实现注册事件
Jan 11 Javascript
jquery插件实现搜索历史
Apr 24 jQuery
vuex actions传递多参数的处理方法
Sep 18 #Javascript
微信小程序搭建(mpvue+mpvue-weui+fly.js)的详细步骤
Sep 18 #Javascript
详解关于Vue2.0路由开启keep-alive时需要注意的地方
Sep 18 #Javascript
Vue中 key keep-alive的实现原理
Sep 18 #Javascript
vue服务端渲染页面缓存和组件缓存的实例详解
Sep 18 #Javascript
从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法
Sep 18 #Javascript
vue服务端渲染添加缓存的方法
Sep 18 #Javascript
You might like
使用XDebug调试及单元测试覆盖率分析
2011/01/27 PHP
php数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
2011/10/29 PHP
PHP中Memcache操作类及用法实例
2014/12/12 PHP
php自定义加密与解密程序实例
2014/12/31 PHP
yii2.0使用Plupload实现带缩放功能的多图上传
2015/12/22 PHP
php实现多维数组排序的方法示例
2017/03/23 PHP
JavaScript 对象模型 执行模型
2009/12/06 Javascript
JavaScript 存在陷阱 删除某一区域所有节点
2010/05/10 Javascript
json数据的列循环示例
2013/09/06 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
jQuery中next()方法用法实例
2015/01/07 Javascript
JS选项卡动态替换banner图片路径的方法
2015/05/11 Javascript
JS截取与分割字符串常用技巧总结
2015/11/10 Javascript
AngularJS 如何在控制台进行错误调试
2016/06/07 Javascript
解决React Native端口号修改的方法
2017/07/28 Javascript
bootstrap-Treeview实现级联勾选
2017/11/23 Javascript
对vuex中getters计算过滤操作详解
2019/11/06 Javascript
JavaScript装饰者模式原理与用法实例详解
2020/03/09 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
2020/05/15 Javascript
[48:48]完美世界DOTA2联赛PWL S3 Magama vs GXR 第一场 12.19
2020/12/24 DOTA
Python中的pass语句使用方法讲解
2015/05/14 Python
基于Python数据可视化利器Matplotlib,绘图入门篇,Pyplot详解
2017/10/13 Python
Flask web开发处理POST请求实现(登录案例)
2018/07/26 Python
PyCharm在新窗口打开项目的方法
2019/01/17 Python
pytorch 状态字典:state_dict使用详解
2020/01/17 Python
Origins加拿大官网:雅诗兰黛集团高端植物护肤品牌
2017/11/19 全球购物
戴尔美国官方折扣店:Dell Outlet
2018/02/13 全球购物
电子商务专业自我鉴定
2013/12/18 职场文书
自主招生教师推荐信
2014/05/10 职场文书
产品推广策划方案
2014/05/10 职场文书
乡镇综治宣传月活动总结
2014/07/02 职场文书
2015年学校精神文明工作总结
2015/05/27 职场文书
钱学森电影观后感
2015/06/04 职场文书
一篇带你入门Java垃圾回收器
2021/06/16 Java/Android
mysql函数全面总结
2021/11/11 MySQL