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时ie6和ie7,ff的区别
Aug 19 Javascript
Extjs4 Treegrid 使用心得分享(经验篇)
Jul 01 Javascript
新增加的内容是如何将div的scrollbar自动移动最下面
Jan 02 Javascript
JS弹出可拖拽可关闭的div层完整实例
Feb 13 Javascript
JavaScript中使用concat()方法拼接字符串的教程
Jun 06 Javascript
JavaScript脚本判断蜘蛛来源的方法
Sep 22 Javascript
浏览器兼容性问题大汇总
Dec 17 Javascript
node.js实现博客小爬虫的实例代码
Oct 08 Javascript
javascript prototype原型详解(比较基础)
Dec 26 Javascript
基于JS实现html中placeholder属性提示文字效果示例
Apr 19 Javascript
js实现每日签到功能
Nov 29 Javascript
浅谈Three.js截图并下载的大坑
Nov 01 Javascript
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
php各种编码集详解和以及在什么情况下进行使用
2011/09/11 PHP
解析在zend Farmework下如何创立一个FORM表单
2013/06/28 PHP
php define的第二个参数使用方法
2013/11/04 PHP
探寻PHP脚本不报错的原因
2014/06/12 PHP
destoon调用企业会员公司形象图片的实现方法
2014/08/21 PHP
php实现图片压缩处理
2020/09/09 PHP
javascript的函数
2007/01/31 Javascript
ExtJS 2.0实用简明教程 之Border区域布局
2009/04/29 Javascript
jQuery.extend 函数详解
2012/02/03 Javascript
jQuery图片滚动图片的效果(另类实现)
2013/06/02 Javascript
判断滚动条到底部的JS代码
2013/11/04 Javascript
网页实时显示服务器时间和javscript自运行时钟
2014/06/09 Javascript
node.js中的fs.linkSync方法使用说明
2014/12/15 Javascript
jQuery简单实现验证邮箱格式
2015/07/15 Javascript
Three.js学习之文字形状及自定义形状
2016/08/01 Javascript
AngularJS 模块化详解及实例代码
2016/09/14 Javascript
浅谈如何优雅处理JavaScript异步错误
2019/11/12 Javascript
python 输出一个两行字符的变量
2009/02/05 Python
python 字符串split的用法分享
2013/03/23 Python
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
python实现获取Ip归属地等信息
2016/08/27 Python
Python实现MySQL操作的方法小结【安装,连接,增删改查等】
2017/07/12 Python
使用pandas中的DataFrame数据绘制柱状图的方法
2018/04/10 Python
python的pandas工具包,保存.csv文件时不要表头的实例
2018/06/14 Python
python调用c++ ctype list传数组或者返回数组的方法
2019/02/13 Python
Python使用pandas和xlsxwriter读写xlsx文件的方法示例
2019/04/09 Python
如何使用pyinstaller打包32位的exe程序
2019/05/26 Python
Pytest框架之fixture的详细使用教程
2020/04/07 Python
Django ORM判断查询结果是否为空,判断django中的orm为空实例
2020/07/09 Python
Python实现壁纸下载与轮换
2020/10/19 Python
写好自荐信要注意的问题
2013/11/10 职场文书
五好党支部事迹材料
2014/02/06 职场文书
班级体育活动总结
2014/07/05 职场文书
2014年局领导班子自身建设情况汇报
2014/11/21 职场文书
师德培训心得体会2016
2016/01/09 职场文书
React forwardRef的使用方法及注意点
2021/06/13 Javascript