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 相关文章推荐
jQuery each()方法的使用方法
Mar 18 Javascript
jQuery动态地获取系统时间实现代码
May 24 Javascript
全面理解面向对象的 JavaScript(来自ibm)
Nov 10 Javascript
JS中BOM相关知识点总结(必看篇)
Nov 22 Javascript
Vue.js实现实例搜索应用功能详细代码
Aug 24 Javascript
JS实现的倒计时恢复按钮点击功能【可用于协议阅读倒计时】
Apr 19 Javascript
vue和webpack项目构建过程常用的npm命令详解
Jun 15 Javascript
JS实现的点击按钮图片上下滚动效果示例
Jan 28 Javascript
图解javascript作用域链
May 27 Javascript
在Vue中用canvas实现二维码和图片合成海报的方法
Jun 10 Javascript
基于Echarts图表在div动态切换时不显示的解决方式
Jul 20 Javascript
原生js滑动轮播封装
Jul 31 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
索尼SONY SRF-S83/84电路分析和打磨
2021/03/02 无线电
PHP日期处理函数 整型日期格式
2011/01/12 PHP
php unset全局变量运用问题的深入解析
2013/06/17 PHP
解析mysql 表中的碎片产生原因以及清理
2013/06/22 PHP
PHP 接入支付宝即时到账功能
2016/09/18 PHP
PHP 文件锁与进程锁的使用示例
2017/08/07 PHP
javascript 表单的友好用户体现
2009/01/07 Javascript
模仿jQuery each函数的链式调用
2009/07/22 Javascript
js实时监听文本框状态的方法
2011/04/26 Javascript
浅谈JS继承_借用构造函数 &amp; 组合式继承
2016/08/16 Javascript
JavaScript实现类似拉勾网的鼠标移入移出效果
2016/10/27 Javascript
JS实现根据用户输入分钟进行倒计时功能
2016/11/14 Javascript
从零开始学习Node.js系列教程六:EventEmitter发送和接收事件的方法示例
2017/04/13 Javascript
JavaScript30 一个月纯 JS 挑战中文指南(英文全集)
2017/07/23 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
2017/10/27 Javascript
vue 引入公共css文件的简单方法(推荐)
2018/01/20 Javascript
jQuery实现的简单图片轮播效果完整示例
2018/02/08 jQuery
vue 实现通过手机发送短信验证码注册功能
2018/04/19 Javascript
解决vue.js this.$router.push无效的问题
2018/09/03 Javascript
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
element-ui 时间选择器限制范围的实现(随动)
2019/01/09 Javascript
JavaScript 处理树数据结构的方法示例
2019/06/16 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
Python编程之string相关操作实例详解
2017/07/22 Python
Python绘制二维曲线的日常应用详解
2019/12/04 Python
window环境pip切换国内源(pip安装异常缓慢的问题)
2019/12/31 Python
pytorch 利用lstm做mnist手写数字识别分类的实例
2020/01/10 Python
Django自关联实现多级联动查询实例
2020/05/19 Python
python三引号如何输入
2020/07/06 Python
HTML5 CSS3给网站设计带来出色效果
2009/07/16 HTML / CSS
美国专业汽车音响和移动电子产品零售商:Car Toys
2019/05/13 全球购物
医学生个人求职信范文
2013/09/24 职场文书
招商经理岗位职责
2013/11/16 职场文书
建筑管理专业求职信
2014/07/28 职场文书
大学班长竞选稿
2015/11/20 职场文书
医生行业员工的辞职信
2019/06/24 职场文书