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字符串插入、删除、替换函数使用示例
Jul 25 Javascript
jquery实现图片随机排列的方法
May 04 Javascript
浅析AngularJs HTTP响应拦截器
Dec 28 Javascript
js判断所有表单项不为空则提交表单的实现方法
Sep 09 Javascript
jQuery中弹出iframe内嵌页面元素到父页面并全屏化的实例代码
Dec 27 Javascript
jQuery实现鼠标悬停3d菜单展开动画效果
Jan 19 Javascript
完美解决axios跨域请求出错的问题
Feb 05 Javascript
聊聊JS动画库 Velocity.js的使用
Mar 13 Javascript
vue-cli项目无法用本机IP访问的解决方法
Sep 20 Javascript
js 判断当前时间是否处于某个一个时间段内
Sep 19 Javascript
vue在响应头response中获取自定义headers操作
Jul 24 Javascript
Vite和Vue CLI的优劣
Jan 30 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
海河写的 Discuz论坛帖子调用js的php代码
2007/08/23 PHP
ThinkPHP文件上传实例教程
2014/08/22 PHP
php计算给定日期所在周的开始日期和结束日期示例
2017/02/06 PHP
PHP中include和require的区别实例分析
2017/05/07 PHP
详解cookie验证的php应用的一种SSO解决办法
2017/10/20 PHP
JavaScript实现关键字高亮功能
2014/11/12 Javascript
AngularJS入门教程之链接与图片模板详解
2016/08/19 Javascript
springMVC + easyui + $.ajaxFileUpload实现文件上传注意事项
2017/04/23 Javascript
AngularJs 常用的过滤器
2017/05/15 Javascript
给vue项目添加ESLint的详细步骤
2017/09/29 Javascript
vuejs数据超出单行显示更多,点击展开剩余数据实例
2019/05/05 Javascript
Angular2实现的秒表及改良版示例
2019/05/10 Javascript
简单了解微信小程序的目录结构
2019/07/01 Javascript
微信小程序中如何使用flyio封装网络请求
2019/07/03 Javascript
详解Python中for循环的使用
2015/04/14 Python
深入解析Python中的list列表及其切片和迭代操作
2016/03/13 Python
基于Django filter中用contains和icontains的区别(详解)
2017/12/12 Python
《与孩子一起学编程》python自测题
2018/05/27 Python
修复 Django migration 时遇到的问题解决
2018/06/14 Python
Python检查ping终端的方法
2019/01/26 Python
python安装gdal的两种方法
2019/10/29 Python
Python如何使用内置库matplotlib绘制折线图
2020/02/24 Python
基于zepto的插件之移动端无缝向上滚动并上下触摸滑动实例代码
2016/12/20 HTML / CSS
西班牙香水和化妆品网上商店:Douglas
2017/10/29 全球购物
泰国折扣酒店预订:Hotels2Thailand
2018/03/20 全球购物
大学生个人简历自我评价
2013/11/16 职场文书
乡镇信息公开实施方案
2014/03/23 职场文书
《小鹰学飞》教学反思
2014/04/23 职场文书
医院义诊活动总结
2014/07/04 职场文书
2014年民主评议党员工作总结
2014/12/02 职场文书
成事在人观后感
2015/06/16 职场文书
环保守法证明
2015/06/24 职场文书
2016优秀护士求职自荐信
2016/01/28 职场文书
2016年教师师德师风承诺书
2016/03/25 职场文书
如何在Python中创建二叉树
2021/03/30 Python
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python