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 Ajax异步处理Json数据详解
Nov 05 Javascript
JQuery.get提交页面不跳转的解决方法
Jan 13 Javascript
jquery实现简单的无缝滚动
Apr 15 Javascript
PageSwitch插件实现100种不同图片切换效果
Jul 28 Javascript
如何使用AngularJs打造权限管理系统【简易型】
May 09 Javascript
JS中使用apply方法通过不同数量的参数调用函数的方法
May 31 Javascript
Windows系统下安装Node.js的步骤图文详解
Nov 15 Javascript
让Vue也可以使用Redux的方法
May 23 Javascript
在create-react-app中使用sass的方法示例
Oct 01 Javascript
小程序点击图片实现自动播放视频
May 29 Javascript
Vue实现仿iPhone悬浮球的示例代码
Mar 13 Javascript
详解vue父子组件状态同步的最佳方式
Sep 10 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
中国的第一台收音机
2021/03/01 无线电
thinkphp实现数组分页示例
2014/04/13 PHP
PHP多个文件上传到服务器实例
2014/10/29 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
2015/07/06 PHP
PHP PDOStatement::errorInfo讲解
2019/01/31 PHP
javascript定时保存表单数据的代码
2011/03/17 Javascript
jQuery插件的写法分享
2013/06/12 Javascript
jQuery统计指定子元素数量的方法
2015/03/17 Javascript
jQuery插件expander实现图片翻转特效
2015/05/21 Javascript
总结jQuery插件开发中的一些要点
2016/05/16 Javascript
Node.js Sequelize如何实现数据库的读写分离
2016/10/23 Javascript
JavaScript实现图片懒加载(Lazyload)
2016/11/28 Javascript
jQuery基于ajax方式实现用户名存在性检查功能示例
2017/02/10 Javascript
Angularjs+bootstrap+table多选(全选)支持单击行选中实现编辑、删除功能
2017/03/27 Javascript
BootStrap 导航条实例代码
2017/05/18 Javascript
vue.js删除动态绑定的radio的指定项
2017/06/02 Javascript
JavaScript反弹动画效果的实现代码
2017/07/13 Javascript
通俗易懂地解释JS中的闭包
2017/10/23 Javascript
jQuery除指定区域外点击任何地方隐藏DIV功能
2017/11/13 jQuery
JavaScript检查数据中是否存在相同的元素(两种方法)
2018/10/07 Javascript
vue实现移动端返回顶部
2020/10/12 Javascript
Python使用MYSQLDB实现从数据库中导出XML文件的方法
2015/05/11 Python
Python基于FTP模块实现ftp文件上传操作示例
2018/04/23 Python
对python读写文件去重、RE、set的使用详解
2018/12/11 Python
Python3.6.2调用ffmpeg的方法
2019/01/10 Python
Boden美国官网:英伦原创时装品牌
2017/07/03 全球购物
澳大利亚手表品牌:Time IV Change
2018/10/06 全球购物
职业生涯规划书基本格式
2014/01/06 职场文书
开展读书活动总结
2014/06/30 职场文书
镇政府副镇长群众路线专题民主生活会对照检查材料
2014/09/19 职场文书
员工离职感谢信
2015/01/22 职场文书
2015年小学英语教师工作总结
2015/05/12 职场文书
公务员学习中国梦心得体会
2016/01/05 职场文书
企业内部管理控制:银行存款控制制度范本
2020/01/10 职场文书
Redis keys命令的具体使用
2022/06/05 Redis
pd.drop_duplicates删除重复行的方法实现
2022/06/16 Python