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 EasyUI API 中文文档 - MenuButton菜单按钮使用介绍
Oct 06 Javascript
使用AngularJS来实现HTML页面嵌套的方法
Jun 17 Javascript
使用AngularJS处理单选框和复选框的简单方法
Jun 19 Javascript
详解javascript数组去重问题
Nov 06 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
Mar 31 Javascript
JavaScript几种数组去掉重复值的方法推荐
Apr 12 Javascript
JavaScript中实现键值对应的字典与哈希表结构的示例
Jun 12 Javascript
浅谈js中字符和数组一些基本算法题
Aug 15 Javascript
PHP捕捉异常中断的方法
Oct 24 Javascript
解决vue中对象属性改变视图不更新的问题
Feb 23 Javascript
Postman的下载及安装教程详解
Oct 16 Javascript
vue解决花括号数据绑定不成功的问题
Oct 30 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生成静态HTML速度快类库
2007/03/18 PHP
Codeigniter通过SimpleXML将xml转换成对象的方法
2015/03/19 PHP
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
Laravel5.1框架路由分组用法实例分析
2020/01/04 PHP
Javascript中匿名函数的多种调用方式总结
2013/12/06 Javascript
JavaScript中实现map功能代码分享
2015/06/11 Javascript
javascript字符串循环匹配实例分析
2015/07/17 Javascript
实例讲解javascript注册事件处理函数
2016/01/09 Javascript
Extjs 点击复选框在表格中增加相关信息行
2016/07/12 Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
2017/03/01 Javascript
Async Validator 异步验证使用说明
2017/07/03 Javascript
JavaScript无操作后屏保功能的实现方法
2017/07/04 Javascript
关于vue.js组件数据流的问题
2017/07/26 Javascript
微信小程序上传图片功能(附后端代码)
2020/06/19 Javascript
jsonp跨域及实现百度首页联想功能的方法
2018/08/30 Javascript
JavaScript实现密码强度实时验证
2020/03/18 Javascript
[05:02][DOTA2]DOTA进化论 第一期
2013/09/27 DOTA
python变量不能以数字打头详解
2016/07/06 Python
浅谈Django的缓存机制
2018/08/23 Python
python微信好友数据分析详解
2018/11/19 Python
Python、 Pycharm、Django安装详细教程(图文)
2019/04/12 Python
Python异常处理例题整理
2019/07/07 Python
python实现基于朴素贝叶斯的垃圾分类算法
2019/07/09 Python
CSS3中伪元素::before和::after的用法示例
2017/09/18 HTML / CSS
The Hut美国/加拿大:英国领先的豪华在线百货商店
2019/03/26 全球购物
用缩写的指针比较"if(p)" 检查空指针是否可靠?如果空指针的内部表达不是0会怎么样?
2014/01/05 面试题
学校对教师的评语
2014/04/28 职场文书
代领毕业证委托书
2014/08/02 职场文书
高中国旗下的演讲稿
2014/08/28 职场文书
小学生迎国庆演讲稿
2014/09/05 职场文书
2015年助理政工师工作总结
2015/05/26 职场文书
如何写观后感
2015/06/19 职场文书
找规律教学反思
2016/02/23 职场文书
职场新人知识:如何制定一份合理的工作计划?
2019/09/11 职场文书
vue使用refs获取嵌套组件中的值过程
2022/03/31 Vue.js
一文搞懂PHP中的抽象类和接口
2022/05/25 PHP