Vue组件间数据传递的方式(3种)


Posted in Javascript onJuly 13, 2020

vue中传递数据的方式有哪些

数据流的方式传递数据

通过 props 传递属性

父级给demo2组件绑定一个msg数据

父组件

<template>
 <div class='container'>
 <demo2 :msg="msg" @change="change" />
 </div>
</template>

<script>
import demo2 from './demo2'
export default {
 data(){
 return {
  msg:'这是测试数据'
 }
 },
 methods:{
 change(value){
  this.msg = value
 }
 },
 components: {
 demo2
 }
}
</script>

子组件通过定义props来使用msg,$emit触发外部的函数来改变父级传入的值

子组件

<template>
 <div class='container'>
 {{msg}}
 <button @click="change">点一下</button>
 </div>
</template>

<script>
export default {
 props:['msg'],
 methods:{
 change(){
  this.$emit('change','这是新的数据')
 }
 }
}
</script>

通过 $attrs 来收集属性

$attrs 会收集组件上绑定的属性,对应class和style不会处理。如果与props同用,props的优先级要高于attrs

父组件

<template>
 <div class="container">
 <demo2 class="demo" style="color:red" :msg="msg" />
 </div>
</template>

<script>
import demo2 from "./demo2";
export default {
 data() {
 return {
  msg: "这是测试数据"
 };
 },
 components: {
 demo2
 }
};
</script>

子组件中this.$attrs会收集组件上绑定的属性

子组件

<template>
 <div class="container">{{$attrs.msg}} </div>
</template>

<script>
export default {
 // inheritAttrs:true,
 // 会隐藏行间的属性
 // props:['msg'],
 // 这里props的优先级比$attrs要高,如果设置了props,那么msg会在data上,而$attrs中就没有msg
 created(){
 console.log(this.$attrs)
 // 对象中只有msg一个属性
 }
};
</script>

通过$listeners 来收集方法

$listeners 会收集组件上绑定的方法。 可以通过传递实参的方式改变父组件的值

父组件

<template>
 <div class='container'>
 {{msg}}
 <demo2 class="demo" style="color:red" @msgChange="change"/>
 </div>
</template>

<script>
import demo2 from './demo2'
export default {
 data () {
 return {
  msg: '这是测试数据'
 }
 },
 methods: {
 change(newvalue){
  this.msg = newvalue;
 }
 },
 components: {
 demo2
 }
}
</script>

子组件中this.$listeners会收集绑定在组件上的方法。通过this.$listeners.XXX()可以直接调用,以此可以来修改父组件data中的值

子组件

<template>
 <div class="container">
 <button @click="change">点一下</button>
 </div>

</template>

<script>
export default {
 // inheritAttrs:true,
 created(){
 console.log(this)
 },
 methods:{
 change(){
  // this.$emit('msgChange')
  // this.$parent.change()
  // 与$emit功能相同,$parent也能够实现该效果

  this.$listeners.msgChange('改变后的值')

 }
 }
};
</script>

通过provide提供依赖,inject注入依赖实现数据跨多级子组件传递

通过给父级的 provide 提供一个依赖对象,让其所用子组件都能访问到这个对象


provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

其实也就是说provide 和 inject 绑定本身不做额外的事情(数据绑定之类),只是将提供的数据暴露给子组件。那么暴露出来的数据是不是可相应的就取决与数据本身

父组件

<template>
 <div class='container'>
 <demo2 class="demo" style="color:red" :msg="msg" @msgChange="change"/>
 </div>
</template>

<script>
import demo2 from './demo2'
export default {
 provide(){
 return {
  msg:this.msg,
  msgChange:this.change,
  // 这里this本身就是一个可监听的对象。
  // this也就是当前vue实例本身已完成了数据响应,这里只是将这个实例暴露给了他的所用子组件
  app:this
 }
 },
 data () {
 return {
  msg: '这是测试数据'
 }
 },
 methods: {
 change(){
  this.msg += 1;
 }
 },
 components: {
 demo2
 }
}
</script>

后代的子组件可以通过reject注入相应的依赖

子组件

<template>
 <div class="container">
 <!-- 这个msg的值不会变 -->
 <div>{{msg}} </div>
 <!-- msg的值会变,因为依然指向父组件的vue实例 -->
 <div>{{app.$data.msg}}</div>
 <button @click="msgChange">点一下</button>
 </div>
</template>

<script>
export default {
 inject:['msg','msgChange','app']
};
</script>

直接访问组件实例的方式获取数据

通过 ref 获取组件实例

ref 属性定义在组件上获取的是组件的vue实例,定义在原生标签上获取的是对应的dom

需要等挂载之后才能拿到$refs中的内容

父组件

<template>
 <div class='container'>
 {{msg}}
 <demo2 ref="test"/>
 </div>
</template>

<script>
import demo2 from './demo2'
export default {
 data () {
 return {
  msg: ''
 }
 },
 // 需要等挂载之后才能拿到$refs中的内容。
 // 所用不能在模板中使用
 mounted(){
 this.msg = this.$refs.test.msg
 },
 components: {
 demo2
 }
}
</script>

子组件

<script>
export default {
 data(){
 return {
  msg:'这是子组件的数据'
 }
 }
}
</script>

通过\$parent/$children 获取组件实例

同样的也是必须在mounted之后才能获取对应实例

这里是父组件展示子组件中的msg,子组件展示父组件的msg

父组件通过$children获取子组件实例

父组件

<template>
 <div class='container'>
 {{msg}}
 <demo2/>
 </div>
</template>

<script>
import demo2 from './demo2'
export default {
 data () {
 return {
  msg: '',
  fatherMsg:"这是父组件的内容"
 }
 },
 mounted(){
 console.log(this.$children)
 //获取子组件实例上的sonMsg,$children是个数组需要选择对应的索引
 this.msg = this.$children[0].sonMsg;
 },
 components: {
 demo2
 }
}
</script>

子组件通过$paren获取父组件实例

子组件

<template>
 <div class='container'>
 {{msg}}
 </div>
</template>

<script>
export default {
 data () {
 return {
  msg:'',
  sonMsg: '这是子组件的数据'
 }
 },
 mounted(){
 //获取父组件的实例上的fatherMsg
 this.msg = this.$parent.fatherMsg;
 }
}
</script>

定义一个公共仓库共享数据

定义 eventBus 共享数据

在Vue原型上添加一个$bus为一个新的vue对象,可以在全局的vue实例中通过$bus获取到这个vue对象,从而获取这个对象上的属性和方法。

在main.js中定义

Vue.prototype.$bus = new Vue({
 data:{
 a:1,
 b:2
 },
 methods:{
 log(){
  console.log(this.a)
 }
 }
})

全局Vue实例都能获取到定义在$bus上的属性和方法

通过 Vuex 共享数据

官方给出的跨多组件传递数据的解决方案。

store index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
 state: {
 test:'123123123',
 test2:'123123123',
 },
 mutations: {
 changeTest(state,payload){
  console.log(state,payload)
  state.test = payload.value
 },
 changeTest2(state,payload){
  console.log(state,payload)
  state.test2 = payload.value
 }
 },
 actions: {
 asyncChageTest({commit},payload){
  setTimeout( ()=>{
  commit('changeTest2',payload)
  },2000)
 }
 },
 modules: {
 }
})

在组件中使用

<template>
 <div class='container'>
 {{this.$store.state.test}}
 {{test}}
 {{this.$store.state.test2}}
 {{test2}}
 <button @click="change">点一下</button>
 <button @click="asyncChange">点一下</button>
 </div>
</template>

<script>
// 引入mapState辅助函数改造state数据
import { mapState,mapMutations,mapActions } from 'vuex'
export default {
 data(){
 return {
  msg:'这是测试数据'
 }
 },
 computed:{
 ...mapState(['test','test2'])
 }, 
 methods:{
 // 放异步或者同步的方法引入
 ...mapMutations(['changeTest']),
 ...mapActions(['asyncChageTest']),
 change(){
  // 同步修改state值的两种方法
  this.$store.commit('changeTest',{value:'改变后test的值'});
  // this.changeTest({value:'改变后的值'})
 },
 asyncChange(){
  // 异步修改state值的两种方法
  this.$store.dispatch('asyncChageTest',{value:'改变后test2的值'})
  // this.asyncChageTest({value:'改变后test2的值'})
 }
 },
}
</script>

以上就是对Vue中组件间数据传递的方式进行了一个总结,在日常的开发中还是需要根据使用的场景采取合适的方式进行数据的传递

到此这篇关于Vue组件间数据传递的方式(3种)的文章就介绍到这了,更多相关Vue组件间数据传递内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Jquery命名冲突解决的五种方案分享
Mar 16 Javascript
深入了解javascript中的prototype与继承
Apr 14 Javascript
如何将一个String和多个String值进行比较思路分析
Apr 22 Javascript
js渐变显示渐变消失示例代码
Aug 01 Javascript
jquery利用ajax调用后台方法实例
Aug 23 Javascript
jQuery满意度星级评价插件特效代码分享
Aug 19 Javascript
Node.js读写文件之批量替换图片的实现方法
Sep 07 Javascript
jQuery事件对象的属性和方法详解
Sep 09 jQuery
javaScript字符串工具类StringUtils详解
Dec 08 Javascript
Vue中Table组件Select的勾选和取消勾选事件详解
Mar 19 Javascript
vue组件化中slot的基本使用方法
May 01 Javascript
layui添加动态菜单与选项卡 AJAX请求的例子
Sep 25 Javascript
vue-cli4项目开启eslint保存时自动格式问题
Jul 13 #Javascript
详解Vue+elementUI build打包部署后字体图标丢失问题
Jul 13 #Javascript
浅谈JavaScript中你可能不知道URL构造函数的属性
Jul 13 #Javascript
Vue3新特性之在Composition API中使用CSS Modules
Jul 13 #Javascript
Threejs实现滴滴官网首页地球动画功能
Jul 13 #Javascript
koa2 数据api中间件设计模型的实现方法
Jul 13 #Javascript
浅析JavaScript 函数防抖和节流
Jul 13 #Javascript
You might like
PHP COOKIE设置为浏览器进程
2009/06/21 PHP
PHP 程序员的调试技术小结
2009/11/15 PHP
PHP的Yii框架中YiiBase入口类的扩展写法示例
2016/03/17 PHP
分享一个漂亮的php验证码类
2016/09/29 PHP
PHP+redis实现的购物车单例类示例
2019/02/02 PHP
js setattribute批量设置css样式
2009/11/26 Javascript
JavaScript获取当前页面上的指定对象示例代码
2014/02/28 Javascript
jQuery源码解读之removeClass()方法分析
2015/02/20 Javascript
javascript实现可拖动变色并关闭层窗口实例
2015/05/15 Javascript
js获取页面description的方法
2015/05/21 Javascript
Node.js重新刷新session过期时间的方法
2016/02/04 Javascript
jQuery实现ToolTip元素定位显示功能示例
2016/11/23 Javascript
vue中如何引入jQuery和Bootstrap
2017/04/10 jQuery
vue.js移动端app之上拉加载以及下拉刷新实战
2017/09/11 Javascript
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
vue实现axios图片上传功能
2019/08/20 Javascript
JavaScript 实现HTML DOM增删改查操作的常见方法详解
2020/01/04 Javascript
Python Socket使用实例
2017/12/18 Python
Python实现合并两个有序链表的方法示例
2019/01/31 Python
Matplotlib使用字符串代替变量绘制散点图的方法
2020/02/17 Python
Python爬虫爬取电影票房数据及图表展示操作示例
2020/03/27 Python
Python实现删除某列中含有空值的行的示例代码
2020/07/20 Python
pycharm配置安装autopep8自动规范代码的实现
2021/03/02 Python
使用CSS3滤镜的filter:blur属性制作毛玻璃模糊效果的方法
2016/07/08 HTML / CSS
印度化妆品购物网站:Nykaa
2018/07/22 全球购物
印尼在线旅游门户网站:NusaTrip
2019/11/01 全球购物
数百万免费的图形资源:Freepik
2020/09/21 全球购物
什么是数据抽象
2016/11/26 面试题
Linux机考试题
2015/07/17 面试题
校庆标语集锦
2014/06/25 职场文书
领导干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
销售合作意向书范本
2015/05/08 职场文书
大学生暑期实践报告
2015/07/13 职场文书
总经理致辞
2015/07/29 职场文书
Python爬虫基础之简单说一下scrapy的框架结构
2021/06/26 Python
Python实现视频自动打码的示例代码
2022/04/08 Python