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 应用 JQuery.groupTable.js
Dec 15 Javascript
控制页面按钮在后台执行期间不重复提交的JS方法
Jun 24 Javascript
浅析Node.js查找字符串功能
Sep 03 Javascript
Javascript进制转换实例分析
May 14 Javascript
javascript随机显示背景图片的方法
Jun 18 Javascript
分享纯手写漂亮的表单验证
Nov 19 Javascript
Vue官网todoMVC示例代码
Jan 29 Javascript
如何用RxJS实现Redux Form
Dec 29 Javascript
laypage.js分页插件使用方法详解
Jul 27 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
Nov 01 Javascript
解决js中的setInterval清空定时器不管用问题
Nov 17 Javascript
Promise静态四兄弟实现示例详解
Jul 07 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写MySQL数据 实现代码
2009/06/15 PHP
php获取post中的json数据的实现方法
2011/06/08 PHP
php采用session实现防止页面重复刷新
2015/12/24 PHP
Yii CGridView用法实例详解
2016/07/12 PHP
PHP弱类型的安全问题详细总结
2016/09/25 PHP
总结PHP内存释放以及垃圾回收
2018/03/29 PHP
jquery禁用右键单击功能屏蔽F5刷新
2014/03/17 Javascript
Node.js 制作实时多人游戏框架
2015/01/08 Javascript
jQuery插件制作之参数用法实例分析
2015/06/01 Javascript
js+html5绘制图片到canvas的方法
2015/06/05 Javascript
深入理解jquery跨域请求方法
2016/05/18 Javascript
javascript中对Date类型的常用操作小结
2016/05/19 Javascript
原生js获取元素样式的简单方法
2016/08/06 Javascript
微信小程序 前端源码逻辑和工作流详解
2016/10/08 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
微信小程序 input输入及动态设置按钮的实现
2017/10/27 Javascript
利用nodeJs anywhere搭建本地服务器环境的方法
2018/05/12 NodeJs
[04:22]DSPL第二期精彩集锦:残血反杀!
2014/12/10 DOTA
[02:00]最后,我终于出了辉耀
2018/03/27 DOTA
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
Python爬虫利用cookie实现模拟登陆实例详解
2017/01/12 Python
python matplotlib中文显示参数设置解析
2017/12/15 Python
python 一个figure上显示多个图像的实例
2019/07/08 Python
Python线程条件变量Condition原理解析
2020/01/20 Python
Jupyter 无法下载文件夹如何实现曲线救国
2020/04/22 Python
Python datetime模块使用方法小结
2020/06/18 Python
倩碧香港官方网站:Clinique香港
2017/11/13 全球购物
Elemental Herbology官网:英国美容品牌
2019/04/27 全球购物
Notino希腊:购买香水和美容产品
2019/07/25 全球购物
交通违章检讨书
2014/09/21 职场文书
文体活动总结
2015/02/04 职场文书
交心谈心活动总结
2015/05/11 职场文书
JS不要再到处使用绝对等于运算符了
2021/04/30 Javascript
OpenCV全景图像拼接的实现示例
2021/06/05 Python
Python学习之异常中的finally使用详解
2022/03/16 Python
MySQL去除密码登录告警的方法
2022/04/20 MySQL