vue的通信传值方式

本文介绍了Vue中组件间通信的多种方式,包括路由传值、sessionStorage本地缓存、prop、$parent、$emit、$children、provide/inject以及eventBus和vuex。详细阐述了如何在父子组件、孙组件与祖先组件之间以及不相关组件之间进行数据传递和状态管理。

一、路由通信传值

路由通信是通过路由跳转用query把参数带过去,也是vue常用的通信手段。
eg:list.vue跳转到update.vue,需要传递id

list.vue
this.$router.push({ path:"/update" , query:{ id:“213” } })
update.vue
let id = this.$route.query.id

list.vue

<template>
 <div>
  xxxxx
 </div>
</template>
<script>
export default {
 name: 'list',
 data () {
	 return {
	 }
 },
 mounted(){
 },
 methods:{
	 edit(){
	  this.$router.push({ path:"/update" , query:{ id:"213" } }) //路由跳转,并用query带过去参数
	 }
 }
}
</script>

update.vue

xxxxx
<script>
export default {
 name: 'update',
 data () {
	 return {
	 	id:'',
	 }
 },
 mounted(){
 	this.id = this.$route.query.id//在生命周期中接收传过来的数据
 },
 methods:{
	 findById(){
	  	//通过id查询数据即可。
	 }
 }
}
</script>

二、sessionStorage本地缓存通信

下边就是简写了。
A.vue

 var message = "哈哈哈"
 sessionStorage.setItem('text', message) //创建缓存

B.vue

mounted(){
 this.message = sessionStorage.getItem("text") //读取缓存
 },

三、组件之间的传值

在这里插入图片描述

1. 父传子

prop

父组件通过prop给子组件下发数据,如果传递的参数很多,可使用json数组{}的形式。
父组件 list.vue

<template>
 <div>
  <update :text=message :stepShow="stepShow"></update> //将message和stepShow两个参数传给子组件
 </div>
</template>

<script>
import update from '@/components/update.vue'	//引用组件
export default {
 name: 'list',
 components:{	//引用组件
	update
 },
 data () {
	 return {
	   message : "哈哈哈",
	   stepShow:false,
	 }
 },
 mounted(){
 
 },
 methods:{
 
 }
}
</script>

自组件update.vue

<template>
 <div>
  <p>我是关于页:{{ message }}</p>
  <p v-if="this.stepShow">我是否要显示这些内容</p>
 </div>
</template>

<script>
export default {
 name: 'list',
 props: ['message','stepShow'],
//props:{
//	'text':[String] //子组件接受数据,[]里面可以写传入类型,如果不符合会报错
// }
 data () {
	 return { 
	 }
 },
 mounted(){
 
 },
 methods:{
 
 }
}
</script>

$parent

父组件

<template>
  <div>
    <h1>父组件</h1>
    <h-child></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    components: {
      HChild
    },
    data () {
      return {
        msg: 'data from parent'
      }
    },
    methods: {
      fun () {
        console.log('parent fun')
      }
    }
  }
</script>

子组件

<template>
  <div>
    <h1>子组件</h1>
    <button @click="showParent">调用父组件的数据和方法</button>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    methods: {
      showParent () {
        // 获取到所有的子组件
        console.log(this.$parent)
        // 获取指定子组件中的指定数据
        console.log(this.$parent.msg)
        // 调用子组件的方法
        this.$parent.fun()
      }
    }
  }
</script>

2. 子传父

$emit

子组件可以通过 $emit 触发父组件的自定义事件。vm.$emit(event,arg) 用于触发当前实例上的事件;
子组件

<template>
  <div>
    子组件:
    <span>{{childValue}}</span>
    <!-- 定义一个子组件传值的方法 -->
    <input type="button" value="点击触发" @click="childClick">
  </div>
</template>
<script>
  export default {
    data () {
      return {
        childValue: '我是子组件的数据'
      }
    },
    methods: {
      childClick () {
        // childByValue是在父组件on监听的方法
        // 第二个参数this.childValue是需要传的值
        this.$emit('childByValue', this.childValue)  
      }
    }
  }
</script>

父组件

<template>
  <div>
    父组件:
    <span>{{name}}</span>
    <br>
    <br>
    <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
    <child v-on:childByValue="childByValue"></child>
  </div>
</template>
<script>
  import child from './child'
  export default {
    components: {
      child
    },
    data () {
      return {
        name: ''
      }
    },
    methods: {
      childByValue: function (childValue) {
        // childValue就是子组件传过来的值
        this.name = childValue
      }
    }
  }
</script>

$children

子组件

<template>
  <div>
    <h1>子组件</h1>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    data () {
      return {
        msg: 'msg from child'
      }
    },
    methods: {
      fun () {
        console.log('child fun')
      }
    }
  }
</script>

父组件

<template>
  <div>
    <h1>父组件</h1>
    <h-child></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    components: {
      HChild
    },
    mounted () {
      // 获取到所有的子组件,结果是一个数组
      console.log(this.$children)
      // 获取指定子组件中的指定数据
      console.log(this.$children[0].msg)
      // 调用子组件的方法
      this.$children[0].fun()
    }
  }
</script>

3.孙组件与祖先组件的通信(provide和inject)

provide:Object | () => Object
inject:Array | { [key: string]: string | Symbol | Object }

provide / inject 以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

使用场景:由于vue有$parent属性可以让子组件访问父组件。但孙组件想要访问祖先组件就比较困难。通过provide/inject可以轻松实现跨级访问祖先组件的数据

一种最常见的用法是刷新vue组件
app.vue

<template>
  <div
    id="app"
  >
    <router-view
      v-if="isRouterAlive"
    />
  </div>
</template>

<script>
export default {
  name: 'App',
  components: {
    MergeTipDialog,
    BreakNetTip
  },
  data () {
    return {
      isShow: false,
      isRouterAlive: true
  },

// 父组件中返回要传给下级的数据
  provide () {
    return {
      reload: this.reload
    }
  },
  methods: {
    reload () {
      this.isRouterAlive = false
      this.$nextTick(() => {
        this.isRouterAlive = true
      })
    }
  }
}
</script>
<template>
  <popup-assign
    :id="id"
    @success="successHandle"
  >
    <div class="confirm-d-tit"><span class="gray-small-btn">{{ name }}</span></div>
    <strong>将被分配给</strong>
    <a
      slot="reference"
      class="unite-btn"
    >
      指派
    </a>
  </popup-assign>
</template>
<script>
import PopupAssign from '../PopupAssign'
export default {
//引用vue reload方法
  inject: ['reload'],
  components: {
    PopupAssign
  },
methods: {
    // ...mapActions(['freshList']),
    async successHandle () {
      this.reload()
    }
  }
}
</script>

下面一个例子祖组件的数据,祖孙元素调取
Ancestor.vue

<template>
    <div id="app">
    </div>
</template>
    <script>
        export default {
            data () {
                    return {
                        datas: [
                            {
                                id: 1,
                                label: '产品一'
                            },
                            {
                                id: 1,
                                label: '产品二'
                            },
                            {
                                id: 1,
                                label: '产品三'
                            }
                        ]
                    }
            },
            provide {
                return {
                    datas: this.datas
                }
            }
        }
    </script>

后代组件

<template>
    <div>
        <ul>
        <li v-for="(item, index) in datas" :key="index">
            {{ item.label }}
        </li>
        </ul>
    </div>
</template>
    <script>
        export default {
            inject: ['datas']
        }
    </script>

后代元素引入被注入数据datas,并在组件内循环输出

4. 不同组件之间传值

通过eventBus(小项目少页面用eventBus,大项目多页面使用 vuex)

4.1 eventBus

$bus主要是解决无关系组件之间的交互问题
这种方法通过一个空的Vue实例作为中央事件总线(事件中心)
实现方式:

    var Event=new Vue();
    Event.$emit(事件名,数据);
    Event.$on(事件名,data => {});

首先在vue实例上绑定一个bus实例(其实就是一个全新的vue实例,此实例拥有vue的全部方法)例子:
main.js

Vue.prototype.$bus = new Vue() // event Bus 用于无关系组件间的通信。

在组件中就可以这样使用
假设有两个不相关的a,b组件
a.vue中

handleEvent(messageList) {
    if (xxxx) {
      this.$bus.$emit('cus')
    }
    if (xxx) {
      this.$bus.$emit('age',this.age)
    }
  },

b.vue中

mounted() {
	// 用$on事件来接收参数
    this.$bus.$on('cus', () => { 
		this.seach();
	});
	this.$bus.$on('age', (data) => { 
		alert(data);	//就是传来的age
	});
   
  },

这里顺嘴提一句:(data)=>{}等同于function(data){}
可以去百度一下VUE中箭头函数的含义

4.2 vuex

未完待续。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值