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 相关文章推荐
再谈ie和firefox下的document.all属性
Oct 21 Javascript
javascipt基础内容--需要注意的细节
Apr 10 Javascript
JavaScript中的包装对象介绍
Jan 27 Javascript
javascript对象的创建和访问
Mar 08 Javascript
Javascript中的迭代、归并方法详解
Jun 14 Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
Sep 14 Javascript
js获取腾讯视频ID的方法
Oct 03 Javascript
vue中的非父子间的通讯问题简单的实例代码
Jul 19 Javascript
vue实现在表格里,取每行的id的方法
Mar 09 Javascript
浅谈Fetch 数据交互方式
Dec 20 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
Mar 20 jQuery
封装 axios+promise通用请求函数操作
Aug 11 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的宝库目录--PEAR
2006/10/09 PHP
解析php函数method_exists()与is_callable()的区别
2013/06/21 PHP
ueditor 1.2.6 使用方法说明
2013/07/24 PHP
php实现的树形结构数据存取类实例
2014/11/29 PHP
JQuery跨Iframe选择实现代码
2010/08/19 Javascript
js猜数字小游戏的简单实现代码
2013/07/02 Javascript
js 获取页面高度和宽度兼容 ie firefox chrome等
2014/05/14 Javascript
javascript面向对象特性代码实例
2014/06/12 Javascript
JavaScript实现将数组数据添加到Select下拉框的方法
2015/08/21 Javascript
分享15个大家都熟知的jquery小技巧
2015/12/02 Javascript
Bootstrap3 多选和单选框(checkbox)
2016/12/29 Javascript
es6中的解构赋值、扩展运算符和rest参数使用详解
2017/09/28 Javascript
layer.open关闭父窗口 以及调用父页面的方法
2018/08/17 Javascript
JavaScript函数、闭包、原型、面向对象学习笔记
2018/09/06 Javascript
Vue使用Clipboard.JS在h5页面中复制内容实例详解
2019/09/03 Javascript
mui js控制开关状态、修改switch开关的值方法
2019/09/03 Javascript
[01:20]DOTA2上海特级锦标赛现场采访:谁的ID最受青睐
2016/03/25 DOTA
python图像处理之反色实现方法
2015/05/30 Python
python提取字典key列表的方法
2015/07/11 Python
把JSON数据格式转换为Python的类对象方法详解(两种方法)
2019/06/04 Python
python绘制无向图度分布曲线示例
2019/11/22 Python
如何更改 pandas dataframe 中两列的位置
2019/12/27 Python
Python实现疫情通定时自动填写功能(附代码)
2020/05/27 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
HTML5 UTF-8 中文乱码的解决方法
2013/11/18 HTML / CSS
TripAdvisor土耳其网站:全球知名旅行社区,真实旅客评论
2017/04/17 全球购物
人力资源专业推荐信
2013/11/29 职场文书
会议开场欢迎词
2014/01/15 职场文书
九年级历史教学反思
2014/01/27 职场文书
技能竞赛活动方案
2014/02/21 职场文书
2015世界地球日活动总结
2015/02/09 职场文书
学生不参加考试检讨书
2015/02/19 职场文书
《猴王出世》教学反思
2016/02/23 职场文书
干货:如何写好观后感 !
2019/05/21 职场文书
关于python类SortedList详解
2021/09/04 Python
Eclipse+Java+Swing+Mysql实现电影购票系统(详细代码)
2022/01/18 Java/Android