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 相关文章推荐
javascript 简单抽屉效果的实现代码
Mar 09 Javascript
jQuery如何实现点击页面获得当前点击元素的id或其他信息
Jan 09 Javascript
js编写贪吃蛇的小游戏
Aug 24 Javascript
JavaScript setTimeout使用闭包功能实现定时打印数值
Dec 18 Javascript
快速获取/设置iframe内对象元素的几种js实现方法
May 20 Javascript
AngularJS基础 ng-mouseleave 指令详解
Aug 02 Javascript
使用开源工具制作网页验证码的方法
Oct 17 Javascript
JavaScript中return用法示例
Nov 29 Javascript
微信小程序实现倒计时调用相机自动拍照功能
Jun 10 Javascript
Vue.js实现可排序的表格组件功能示例
Feb 19 Javascript
理解Proxy及使用Proxy实现vue数据双向绑定操作
Jul 18 Javascript
深入讲解Vue中父子组件通信与事件触发
Mar 22 Vue.js
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
深入了解 register_globals (附register_globals=off 网站打不开的解决方法)
2012/06/27 PHP
php实现设计模式中的单例模式详解
2014/10/11 PHP
Laravel 5.4.36中session没有保存成功问题的解决
2018/02/19 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
DIV+CSS+JS不间断横向滚动实现代码
2013/03/19 Javascript
Javascript 多浏览器兼容总结(实战经验)
2013/10/30 Javascript
js四舍五入数学函数round使用实例
2014/05/09 Javascript
搭建pomelo 开发环境
2014/06/24 Javascript
提高NodeJS中SSL服务的性能
2014/07/15 NodeJs
轻松学习Javascript闭包函数
2015/12/15 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
2016/05/30 Javascript
简单实现js浮动框
2016/12/13 Javascript
jquery实现用户登陆界面(示例讲解)
2017/09/06 jQuery
无限循环轮播图之运动框架(原生JS实现)
2017/10/01 Javascript
详解Vue Elememt-UI构建管理后台
2018/02/27 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
2018/11/08 Javascript
nodejs基础之多进程实例详解
2018/12/27 NodeJs
多个vue子路由文件自动化合并的方法
2019/09/03 Javascript
layer弹窗在键盘按回车将反复刷新的实现方法
2019/09/25 Javascript
vue $set 给数据赋值的实例
2019/11/09 Javascript
[04:37]DOTA2英雄梦之声Vol20发条
2014/06/20 DOTA
python实现名片管理系统项目
2019/04/26 Python
Python3简单实现串口通信的方法
2019/06/12 Python
python实现代码统计器
2019/09/19 Python
关于HTML5的22个初级技巧(图文教程)
2012/06/21 HTML / CSS
html5如何及时更新缓存文件(js、css或图片)
2013/06/24 HTML / CSS
浅谈html5之sse服务器发送事件EventSource介绍
2017/08/28 HTML / CSS
印度购买眼镜和太阳镜网站:Coolwinks
2018/09/26 全球购物
如何开启linux的ssh服务
2013/06/03 面试题
幼儿园秋游活动方案
2014/01/21 职场文书
本科生自荐信
2014/06/18 职场文书
初中学校对照检查材料
2014/08/19 职场文书
幼儿教师暑期培训方案
2014/08/27 职场文书
2014年营销工作总结
2014/11/22 职场文书
中秋节感想
2015/08/10 职场文书
大学宣传委员竞选稿
2015/11/19 职场文书