vue中传参方式(路由、组件、插槽和vuex)
1.路由传参(query和params)
r o u t e r 和 router和 router和route的区别,前者是全局路由对象,后者是当前路由。
1.1 params,参数显示在url,刷新数据依旧保留,适合用作不重要的参数
// router的配置
{
path: "/two/:id/:data", // 跳转的路由后加上/:id,多个参数继续按格式添加,数据按顺序对应
name: "two",
component: two
}
// 跳转,这里message为123
this.$router.push({
path: `/two/${this.message}/456` // 直接把数据拼接在path后面
});
// 接收
created() {
this.msg1=this.$route.params.id // 123
this.msg2=this.$route.params.data // 456
}
// url显示,数据显示在url,所以这种方式传递数据仅限于一些不那么重要的参数
/two/123/456
1.2 params,参数不显示在url,刷新页面数据消失
//传参
{
name: `two`, // 这里只能是name,对应路由
params: { id: this.message, data: 456 }
}
//接参数
this.msg1=this.$route.params.id // 123
this.msg2=this.$route.params.data // 456
// url显示,数据不显示在url
/two
1.3 query,刷新数据依旧保留,参数显示在url
//传参
{
path: `/two`,// 这里可以是path也可以是name(如果是name,name:'two'),对应路由
query: { id: this.message, data: 456 }
}
// 接收参数
this.msg1=this.$route.query.id // 123
this.msg2=this.$route.query.data // 456
// url显示,数据显示在url
/two?id=123&data=456
2. 组件传值
2.1父传子
//父组件
<template>
<div>
<!-- 1.传递:data1为动态参数msg的参数名,名字自定义,与子组件接收参数名同名
data2为静态参数的参数名,名字自定义,与子组件接收参数名同名 -->
<child :data1="msg" data2="777"></child>
</div>
</template>
<script>
import child from "./child";
export default {
data() {
return {
msg:"666"
}
},
components: {
child
}
}
</script>
//子组件
<template>
<div>
<div>接受的父组件动态参数:{{ data1 }}</div>
<div>接受的父组件静态参数:{{ data2 }}</div>
<div>接受的父组件参数:{{ data }}</div>
</div>
</template>
<script>
export default {
// 2.接收:props接收父组件参数,data1与data2为传递参数的参数名,与父组件内同名
props: ["data1", "data2"],
data() {
return {
data: "默认值"
};
},
// 3.使用:直接用this调用
mounted() {
this.data = this.data1;
}
};
</script>
注意,父组件所传递参数如果是需要在生命周期中获取赋值,就不能绑定在mounted中,否则子组件方法中this调用不会成功。生命周期顺序:父beforeMount->子beforeCreate……子mounted->父mounted
2.2子传父($emit)可传引用数据和原始数据
<!-- 子组件child.vue -->
<template>
<div>
<div>这里是child组件</div>
<!-- 这里就是接收的父组件参数 -->
<input type="button" value="点击向父组件传参" @click="toFather">
</div>
</template>
<script>
export default {
data(){
return{
cmsg1:'我是子组件的参数1',
cmsg2:'我是子组件的参数2',
}
},
methods: {
toFather(){
// 1.子组件触发父组件方法
// $emit第一个参数为所要触发的父组件函数,函数名可自定义但要与父组件中对应自定义事件名同名
// $emit第二个参数就是子组件向父组件传递的参数
this.$emit('receive',this.cmsg1,this.cmsg2);
}
},
};
</script>
<!-- father.vue -->
<template>
<div>
<div>这里是father组件</div>
<div>接收子组件参数:{{fmsg}}</div>
<!-- 2.在对应子组件上绑定函数,这里“receive”是函数名,可自定义但要与子组件触发函数同名 -->
<child @receive="fromChild"></child>
</div>
</template>
<script>
import child from "./child";
export default {
data() {
return {
fmsg:''
};
},
methods: {
// 接收子组件参数,赋值
fromChild(data1,data2){
this.fmsg=data1;
}
},
components: {
child
}
};
</script>
2.3 兄弟组件(EventBus)
提示:eventBus的使用还是非常便捷的,但是如果是中大型项目,通信比较复杂,还是建议大家直接使用vuex。
2.3.1使用 eventBus 首先我们创建一个 bus.js 文件,里面的内容如下:
import Vue from 'vue';
const bus = new Vue();
export default bus;
2.3.2在需要使用 eventBus 的组件中引入上面创建的 bus.js 文件。
import Bus from 'common/js/bus.js';
2.3.3发布Bus消息的组件
Bus.$emit('getTarget', params1,params2);
2.3.4 接收Bus消息的组件(一般写在 created 或者是 mounted 钩子)
Bus.$on('getTarget', (data1,data2) => {
console.log(data1,data2);
});
2.3.5在vue页面销毁时,同时移除EventBus事件监听。
beforeDestroy () {
//取消订阅事件
Bus.$off('getTarget');
}
2.4 爷孙组件(provide和inject,不受组件层级影响)
注意:provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
<!-- grandpa.vue -->
data() {
return {
msg: 'A'
}
},
provide() {
return {
message: this.msg
}
}
<!-- father.vue -->
components:{child},
inject:['message'],
<!-- child.vue -->
inject: ['message'],
created() {
console.log(this.message) // A
},
2.5 获取任意组件的属性和方法
2.4.1 获取当前父组件的子组件数据
注意:读取子组件数据,$children子组件的排序是不安全的
this.$children[0].cmsg.code
2.5.2 获取当前子组件的父组件数据
this.$parent.data
2.5.3 使用 this.$refs查找命名子组件。
注意:ref被用来给元素或子组件注册引用信息。引用信息将会注册在父元素的$refs对象上。
如果在普通的DOM元素上使用,引用的就是DOM元素;如果用在子组件上,引用就指向组件实例
<template>
<div class="game">
<LOL ref="lol"></LOL>
<DNF ref="dnf"></DNF>
</div>
</template>
<script>
import LOL from '@/components/game/LOL'
import DNF from '@/components/game/DNF'
export default {
name: 'game',
components: {
LOL,
DNF
},
mounted(){ //注意 mounted
//读取命名子组件数据,组件必须添加ref属性
console.log(this.$refs.dnf.gameMsg);//DNF->Game
}
</script>
2.5.4 从根组件向下查找组件数据
this.$root.$children[0].$children[0].$children[0].msg
3. 插槽传参(slot)
//child.vue
<div class="child">
<slot name="slotName" :argName1="arg1" :argName2="arg2"></slot>
</div>
data(){
return{
arg1:'实参1',
arg2:'实参2',
}
}
//father.vue
<Child>
//scope可以换成任意名称
<template v-slot:slotName="scope">{{scope}}</template>>
</Child>
//scope是child组件传过来的值
scope = {
argName1:'实参1',
argName2:'实参2'
}