组件传值
一、基本的组件传值
1、父子组件(是两个组件同时都在页面上展示着(都在内存中))
//父子组件的代码格式(标签的嵌套)
//父组件模板里面有子组件使用
<Son></Son>
1)、父给子
有两种方式:
①、props
②、vuex
使用props实现父传子:
//子组件
<template>
....
</template>
<script>
export default{
props:['name'],//子组件的属性
}
</script>
//父组件
<template>
<Son name="sss" ></Son>
</template>
<script>
export default{
}
</script>
2)、子给父
有两种方式:
①、触发事件: this.$emit();
②、vuex
使用触发事件实现子传父:
子组件
<template>
<div ></div>
</template>
<script>
export default{
updated(){ //钩子函数都行
this.$emit("myClick","hello,我是儿子");//触发子组件的自定义事件,调用父组件的函数,传参
}
}
</script>
//父组件
<template>
<input type="button" v-on:click="fn" />
<Son v-on:myClick="fn" ></Son>
</template>
<script>
export default{
methods:{
fn(str){
}
}
}
</script>
2、兄弟组件(是两个组件同时都在页面上展示着(都在内存中))
//父组件的模板里:
<Son1></Son1>
<Son2></Son2>
有三种方式:
①、事件总线;
②、vuex;
③、共同的父亲 路由
使用事件总线实现:
思路: 使用一个空的vue对象,借助vue对象的 $on 和 $emit。空的vue对象就相当于一个全局对象
代码格式:
//1、新建一个文件夹和文件并创建一个空的vue对象
./utils/vuebus.js
export default new Vue();
//假定Son1给Son2传
//2、在Son2里绑定事件(给事件名绑定一个函数)
<template>
</template>
<script>
import vuebus from "./utils/vuebus"
export default{
created(){ //在created里做是因为能拿到this
vuebus.$on("myClick",(str)=>{
console.log(str);
});
}
}
</script>
//3、在Son1触发Son2里绑定的事件(触发事件,并调用函数)
<template>
<input type="button" value="传" @click="fn" />
<template>
<script>
import vuebus from "./utils/vuebus"
export default{
methods:{
fn(){
vuebus.$emit("myClick","hi,我是你兄弟"); //触发事件,就是在调函数
}
}
}
</script>
3、无关组件(有可能不是同时都在内存中)
①、vuex;
②、路由(由A组件跳到B组件,A组件可能就会销毁(除了keep-alive)即使A组件销毁了 但是值放在路由 B组件拿就行了)
当两个组件不是同时都在内存中存在的话,那么就需要借助于另外 一个对象(如:vuex,vue-router)
二、组合(场景)
1、A组件跳到B组件,B组件里有子组件C
思路:
1)、先在router/index.js里配置A、B组件的路由路径;
2)、A组件到B组件使用路由跳转,query传值:
//A组件
<router-link :to="{path:'/B',query:{id:'001'}"/>
B组件接到A组件传来的:
//在模板使用的话
<p>{$route.query.id}</p>
//在script用的话
created(){
console.log("this.$route.query.id",this.$route.query.id);
}
3)、B组件里面有C组件,需要import引入C组件 同时注册componentsC组件 B组件的值传给C使用props,父给子传。
//在模板中使用
<p>从A获取到id是:{{id}}</p>
//在script中需要声明一个属性
export default {
name:"C",
props:["id"]
}
2、A组件跳到B组件,B组件里有子组件C,C组件路由到D组件传值
思路:
1)、先配置D组件的路由,使用路由在C组件中点击跳转到D组件,利用query传值给D(同A传B)
//C组件
<router -link :to="{path:'/D',query:{id:'001'}">
2)、D组件接到C组件传来的(同B接A):
//在模板使用的话
<p>{$route.query.id}</p>
//在script用的话
created(){
console.log("this.$route.query.id",this.$route.query.id);
}
3、A组件跳到B组件,B组件里有子组件C,C组件路由到D组件,D里有E和F互为兄弟
思路:
可以使用事件总线、或者利用共同的父亲D组件。
事件总线:
1)、先在D里面注册事件,引入E、F组件
2)、再在src中创建文件夹utils,再在utils里创建文件vuebus.js,里面创建一个空的Vue对象(是公共对象)
import Vue from "vue";
export default new Vue();
3)、在E、F中引入公共的vuebus
import vuebus from "../utils/vuebus";
4)、假设:E传给F,需要在F中绑定事件,在E中触发F的事件
//F组件
created(){
vuebus.$on("myclick",(str)=>{//这里不用this绑定,是因为this只能在F中用,找不到E,所以只能绑在公共对象vuebus
console.log("str",str);
})
}
在E中触发有很多情况,可以根据不同的时机来触发事件(比如:点击按钮触发、发送请求数据回来之后传给F等)
//E组件
//模板中
<input type="button" value="传" @click="fn"/>
<script>
import vuebus from "../utils/vuebus";
export default {
name:"E",
methods:{
fn(){
vuebus.$emit("myclick","hi,我是E");
}
}
}
</script>