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中img对象区别的困惑
Dec 27 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
Dec 01 Javascript
老生常谈javascript的面向对象思想
Aug 22 Javascript
JS沙箱模式实例分析
Sep 04 Javascript
基于Vue 2.0的模块化前端 UI 组件库小结
Dec 21 Javascript
webpack4的迁移的使用方法
May 25 Javascript
vue+axios新手实践实现登陆的示例代码
Jun 06 Javascript
深入解析ES6中的promise
Nov 08 Javascript
Makefile/cmake/node-gyp中区分判断不同平台的方法
Dec 18 Javascript
vue实现配置全局访问路径头(axios)
Nov 01 Javascript
详解vue中v-bind:style效果的自定义指令
Jan 21 Javascript
vue 图片裁剪上传组件的实现
Nov 12 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 和 XML: 使用expat函数(三)
2006/10/09 PHP
php获取$_POST同名参数数组的实现介绍
2013/06/30 PHP
php判断正常访问和外部访问的示例
2014/02/10 PHP
php中函数前加&amp;符号的作用分解
2014/07/08 PHP
HTML中嵌入PHP的简单方法
2016/02/16 PHP
Zend Framework框架路由机制代码分析
2016/03/22 PHP
Laravel框架数据库迁移操作实例详解
2020/04/06 PHP
动态控制Table的js代码
2007/03/07 Javascript
Javascript的一种模块模式
2008/03/22 Javascript
CSS常用网站布局实例
2008/04/03 Javascript
EXT中xtype的含义分析
2010/01/07 Javascript
基于jquery实现图片放大功能
2016/05/07 Javascript
Node调用Java的示例代码
2017/09/20 Javascript
vue中导出Excel表格的实现代码
2018/10/18 Javascript
JS实现checkbox互斥(单选)功能示例
2019/05/04 Javascript
利用Electron简单撸一个Markdown编辑器的方法
2019/06/10 Javascript
vue如何使用async、await实现同步请求
2019/12/09 Javascript
python实现爬取千万淘宝商品的方法
2015/06/30 Python
Python对列表中的各项进行关联详解
2017/08/15 Python
python 简单搭建阻塞式单进程,多进程,多线程服务的实例
2017/11/01 Python
20行python代码的入门级小游戏的详解
2019/05/05 Python
python算法题 链表反转详解
2019/07/02 Python
python实现kNN算法识别手写体数字的示例代码
2019/08/16 Python
Python3使用xml.dom.minidom和xml.etree模块儿解析xml文件封装函数的方法
2019/09/23 Python
用CSS3实现背景渐变的方法
2015/07/14 HTML / CSS
详解HTML5中的picture元素响应式处理图片
2018/01/03 HTML / CSS
大女孩胸罩:Big Girls Bras
2016/12/15 全球购物
英国潮流网站:END.(全球免邮)
2017/01/16 全球购物
Etam艾格英国官网:法国著名女装品牌
2019/04/15 全球购物
英国奢侈品牌时尚购物平台:Farfetch(支持中文)
2020/02/18 全球购物
澳大利亚领先的女性运动服品牌:Lorna Jane
2020/06/19 全球购物
大队委竞选演讲稿
2014/04/28 职场文书
保护动物的标语
2014/06/11 职场文书
2014年化验室工作总结
2014/11/21 职场文书
大学生个人简历自我评价
2015/03/11 职场文书
幼儿园大班教育随笔
2015/08/14 职场文书