在Vue的框架开发的项目过程中,经常会用到组件来管理不同的功能,有一些公共的组件会被提取出来。这时必然会产生一些疑问和需求?比如一个组件调用另一个组件作为自己的子组件,那么我们如何进行给子组件进行传值呢?如果是电商网站系统的开发,还会涉及到购物车的选项,这时候就会涉及到非父子组件传值的情况。当然你也可以用Vuex状态管理工具来实现,这部分我们后续会单独介绍。我先给大家介绍Vue开发中常用的三种传值方式。
Vue常用的三种传值方式有:
- 父传子
- 子传父
- 非父子传值
引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示:!
接下来,我们通过实例来看可能会更明白一些:
1 父组件向子组件进行传值
父组件:
<template>
<div id="app">
<!-- element 测试 -->
<form-test :title="titleVar"></form-test>
<k-button @lalala="handleClick"></k-button>
</div>
</template>
<script>
import FormTest from './components/FormTest.vue';
export default {
name: "app",
components: {
FormTest,
},
data() {
return {
titleVar:'element表单,rules校验规则',
}
},
methods: {
handleClick(obj){
console.log(obj);
}
}
};
</script>
子组件FormTest:
<template>
<div>
<h3>{{title}}</h3>
</div>
</template>
<script>
export default {
props: {
title: { type: String, required: true }
},
data() {
return {
}
},
methods: {
}
};
</script>
这样子组件里就可以拿到父组件传过来的title的值‘element表单,rules校验规则
2 子组件向父组件进行传值(通过handleClick 函数)
父组件:
<template>
<div id="app">
<k-button @lalala="handleClick"></k-button>
</div>
</template>
<script>
import KButton from './components/Button.vue';
export default {
name: "app",
components: {
KButton,
},
data() {
return {
}
},
methods: {
handleClick(obj){
console.log(obj); //从子组件传过来的值 {msg:'hello'}
}
}
};
</script>
子组件KButton:
<template>
<button @click="handleClick">子组件button</button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$emit('lalala', {msg:'hello'})
}
},
}
</script>
这样父组件里就可以拿到子组件传过来的msg对象的值 {msg:'hello'}
3\这样父组件里就可以拿到子组件传过来的msg对象的值 {msg:'hello'}
非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。
- 3.1方式一,也是我自己使用的方式(推荐使用,简单)
大概思路是 :在main.js,也就是入口文件中,我们在vue的原型上添加一个bus对象;
具体实现方式如下:
面的组件A和组件B可以是项目中任意两个组件
下面的组件A和组件B可以是项目中任意两个组件
- 3.2 方式二:稍微有点麻烦,但也很容易理解
大概的实现思路: 新建一个bus.js文件, 在这个文件里实例化一下vue;然后在组件A和组件B中分别引入这个bus.js文件,将事件监听和事件触发都挂到bus.js这个实例上,这样就可以实现全局的监听与触发了
公共bus.js文件
//bus.js
import Vue from 'vue'
export default new Vue()
组件A:
<template>
<div>
A组件:
<span>{{elementValue}}</span>
<input type="button" value="点击触发" @click="elementByValue">
</div>
</template>
<script>
// 引入公共的bus,来做为中间传达的工具
import Bus from './bus.js'
export default {
data () {
return {
elementValue: 4
}
},
methods: {
elementByValue: function () {
Bus.$emit('val', this.elementValue)
}
}
}
</script>
组件B:
<template>
<div>
B组件:
<input type="button" value="点击触发" @click="getData">
<span>{{name}}</span>
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
name: 0
}
},
mounted: function () {
var vm = this
// 用$on事件来接收参数
Bus.$on('val', (data) => {
console.log(data)
vm.name = data
})
},
methods: {
getData: function () {
this.name++
}
}
}
</script>