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 相关文章推荐
select标记美化--JS式插件、后期加载
Apr 01 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
Nov 21 Javascript
拥Bootstrap入怀——导航栏篇
May 30 Javascript
批量下载对路网图片并生成html的实现方法
Jun 07 Javascript
在localStorage中存储对象数组并读取的方法
Sep 24 Javascript
Vue实战教程之仿肯德基宅急送App
Jul 19 Javascript
vue 框架下自定义滚动条(easyscroll)实现方法
Aug 29 Javascript
微信公众号开发之微信支付代码记录的实现
Oct 16 Javascript
微信小程序实现侧边分类栏
Oct 21 Javascript
Js视频播放器插件Video.js使用方法详解
Feb 04 Javascript
原生javascript单例模式的应用实例分析
Feb 23 Javascript
基于javascript canvas实现五子棋游戏
Jul 08 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
Uncaught exception com_exception with message Failed to create COM object
2012/01/11 PHP
PHP计算2点经纬度之间的距离代码
2013/08/12 PHP
php实现字符串翻转的方法
2015/03/27 PHP
PHP结合Vue实现滚动底部加载效果
2017/12/17 PHP
实例讲解通过​PHP创建数据库
2019/01/20 PHP
PHP连接及操作PostgreSQL数据库的方法详解
2019/01/30 PHP
jquery选择器之基本过滤选择器详解
2014/01/27 Javascript
用jquery实现的一个超级简单的下拉菜单
2014/05/18 Javascript
node.js中的fs.readSync方法使用说明
2014/12/17 Javascript
jQuery的text()方法用法分析
2014/12/20 Javascript
NodeJs基本语法和类型
2015/02/13 NodeJs
快速掌握Node.js事件驱动模型
2016/03/21 Javascript
浅谈Angular中ngModel的$render
2016/10/24 Javascript
HTML5canvas 绘制一个圆环形的进度表示实例
2016/12/16 Javascript
JavaScript限定范围拖拽及自定义滚动条应用(3)
2017/05/17 Javascript
js中less常用的方法小结
2017/08/09 Javascript
checkbox:click事件触发span元素内容改变的方法
2017/09/11 Javascript
ES6中Array.copyWithin()函数的用法实例详解
2017/09/16 Javascript
jquery动态添加带有样式的HTML标签元素方法
2018/02/24 jQuery
小程序实现带年月选取效果的日历
2018/06/27 Javascript
原生js实现获取form表单数据代码实例
2019/03/27 Javascript
微信小程序实现分享商品海报功能
2019/09/30 Javascript
layui table表格数据的新增,修改,删除,查询,双击获取行数据方式
2019/11/14 Javascript
windows下python之mysqldb模块安装方法
2017/09/07 Python
Python 单元测试(unittest)的使用小结
2018/11/14 Python
Django框架 查询Extra功能实现解析
2019/09/04 Python
python十进制转二进制的详解
2020/02/07 Python
如何使用css3实现一个类在线直播的队列动画的示例代码
2020/06/17 HTML / CSS
美国伊甸园兄弟种子公司:Eden Brothers
2018/07/01 全球购物
运行时异常与一般异常有何异同?
2014/01/05 面试题
如何开发安全的AJAX应用
2014/03/26 面试题
特色冷饮店创业计划书
2014/01/28 职场文书
公司财务人员岗位职责
2015/04/14 职场文书
医院合作意向书范本
2015/05/08 职场文书
幼儿园春季开学通知
2015/07/16 职场文书
话题作文之财富(600字)
2019/12/03 职场文书