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 相关文章推荐
Prototype使用指南之hash.js
Jan 10 Javascript
js event事件的传递与冒泡处理
Dec 06 Javascript
JavaScript 计算图片加载数量的代码
Jan 01 Javascript
js实现网站首页图片滚动显示
Feb 04 Javascript
基于jquery实现的文字淡入淡出效果
Nov 14 Javascript
浅析jquery的js图表组件highcharts
Mar 06 Javascript
JavaScript不刷新实现浏览器的前进后退功能
Nov 05 Javascript
javascript实现密码强度显示
Mar 18 Javascript
jQuery实现动态给table赋值的方法示例
Jul 04 jQuery
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
May 07 Javascript
cdn模式下vue的基本用法详解
Oct 07 Javascript
create-react-app使用antd按需加载的样式无效问题的解决
Feb 26 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
重置版游戏视频
2020/04/09 魔兽争霸
在PHP3中实现SESSION的功能(三)
2006/10/09 PHP
PHP 解决utf-8和gb2312编码转换问题
2010/03/18 PHP
基于php iconv函数的使用详解
2013/06/09 PHP
PHP统计目录大小的自定义函数分享
2014/11/18 PHP
PHP获取文件夹内文件数的方法
2015/03/12 PHP
复制本贴标题和地址的js代码
2008/07/01 Javascript
js 实现图片预加载(js操作 Image对象属性complete ,事件onload 异步加载图片)
2011/03/25 Javascript
javascript之typeof、instanceof操作符使用探讨
2013/05/19 Javascript
javascript中new关键字详解
2015/12/14 Javascript
学习JavaScript设计模式之责任链模式
2016/01/18 Javascript
详解js实现线段交点的三种算法
2016/08/09 Javascript
vue2.0父子组件间通信的实现方法
2017/04/19 Javascript
Angularjs实现控制器之间通信方式实例总结
2018/03/27 Javascript
解决eclipse中没有js代码提示的问题
2018/10/10 Javascript
JS数据类型STRING使用实例解析
2019/12/18 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
2020/08/18 Javascript
Vue实现菜单切换功能
2020/11/08 Javascript
[04:09]2018年度DOTA2社区贡献奖-完美盛典
2018/12/16 DOTA
python二叉树的实现实例
2013/11/21 Python
简单介绍Python的Django框架加载模版的方式
2015/07/20 Python
Python实现类似比特币的加密货币区块链的创建与交易实例
2018/03/20 Python
python实现微信自动回复功能
2018/04/11 Python
Python求解任意闭区间的所有素数
2018/06/10 Python
centos7中安装python3.6.4的教程
2019/12/11 Python
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
戴尔荷兰官方网站:Dell荷兰
2020/10/04 全球购物
幼儿如何来做好自我评价
2013/11/05 职场文书
最新奶茶店创业计划书
2014/01/25 职场文书
工商管理专业大学生职业生涯规划范文
2014/03/09 职场文书
商业房地产广告语
2014/03/13 职场文书
小学教师2014年度工作总结
2014/12/03 职场文书
公司感谢信范文
2015/01/22 职场文书
家长反馈意见及建议
2015/06/03 职场文书
html5表单的required属性使用
2021/07/07 HTML / CSS
element tree树形组件回显数据问题解决
2022/08/14 Javascript