组件通信一 —— props和$emit
props和$emit
父组件 向 子组件 传递数据 用 props
子组件 向 父组件 传递数据 用 $emit
父组件给子组件传值
父给子
- 先给父组件中绑定自定义属性,使用v-bind绑定要传输的数据
- 在子组件中使用 props 接受父组件传递的数据
Vue.component("",{
template:``,
props:[''],//接受父组件传递的数据,然后就可以直接使用
});
例如:
<div id="app"></div>
<script>
var Child = {
template :"<div> 我是子组件 {{msg}} </div>",
props:['msg'],
}
var Parent = {
data(){
return {
msg : "输入 child",
}
},
components:{
Child,
},
template:`<div >我是父组件<Child :msg="msg"/><input type='text' v-model="msg"></div>`,
}
new Vue({
el :"#app",
components:{
Parent,
},
template:'<Parent />',
});
</script>
子给父
将组件的
- 在父组件绑定 自定义的事件
methods:{
reciveChild(val){
this.childVal = val;
}
},
teplate:`<div>我是父组件{{childVal}}<Child @reciveChild="reciveChild"/></div>`,
- 在子组件中是声明一个事件,在函数中使用 this.$emit 触发 父组件 自定义的 事件
this.$emit(父元素中自定义的事件名,需要传给父元素的数据)
template :`<div> 我是子组件 <br><input type='text' @input='valChange' v-model:value="sendVal"></div>`,
methods:{
valChange(){
this.$emit('reciveChild',this.sendVal)
}
},
<div id="app"></div>
<script>
var Child = {
data(){
return{
msg:"",
}
},
template :`<div> 我是子组件 <br><input type='text' @input="inputs" v-model="msg"> </div>`,
methods:{
inputs(val){
this.$emit("recive",val.target.value);
}
}
}
var Parent = {
data(){
return {
val : "",
}
},
components:{
Child,
},
methods:{
recive(val){
this.val = val;
}
},
template:`<div>我是父组件:{{val}}<Child @recive='recive'/></div>`,
}
new Vue({
el :"#app",
components:{
Parent,
},
template:'<Parent />',
});
</script>
组件通信二 —— $attrs 和 $listeners
$ attrs 和 $listeners
多组件传值的问题
父组件 与 子孙组件 相互传值
父传子孙
- 给每一个子孙组件赋予
v-bind="$attrs" v-on ="$listeners"
子组件绑定需要传递数据
:msg="msg"
- 到指定的子元素,使用
{{$attrs.要传的值}}
<div id="app">
<App :msg="msg" >
<A v-bind="$attrs" v-on="$listeners" ></A>
</App>
</div>
<script>
Vue.component("App",{
template:`<div>{{$attrs.msg}}6</div>`,
})
Vue.component("A",{
template:`<div></div>`,
})
var vm = new Vue({
el:"#app",
data:{
msg:"hello",
demo:"world"
},
})
</script>
子孙传父
- 父组件声明函数,并绑定到子元素上
methods:{
get(val){
this.msg = val
}
}
<App @get="get"></App>
- 子孙元素每个都绑定
v-bind="$attrs" v-on ="$listeners"
- 设置触发函数,使用$emit
methods:{
change(val){
this.$emit("get",val.target.value)
}
}
例子:
<div id="app"></div>
<script>
//$ attrs 和 $listeners
var C = {
data(){
return {
thePut:"",
}
},
template:'<div name="C"><input type="text" @input="GoodVal" v-model="thePut">来自祖组件:{{$attrs.good}}</div>',
methods:{
GoodVal(value){
this.$emit("goodC",this.thePut);
}
},
}
var B = {
components:{
C,
},
template:'<div name="B"><p>我是子孙组件<C v-bind="$attrs" v-on ="$listeners" /></p></div>',
}
var A = {
components:{
B,
},
template:'<div name="A"><p>我是子组件</p><B v-bind="$attrs" v-on ="$listeners" /></div>',
}
var Parent = {
data(){
return {
good:"helloworld!",
v_val:""
}
},
components:{
A,
},
template:'<div name="Parent"><p>我是父组件{{good}} ,来自子孙组件:{{v_val}}</p><A :good="good" @goodC="goodC" /></div>',
methods:{
goodC(val){
this.v_val = val;
}
}
}
new Vue({
el : "#app",
components:{
Parent,
},
template:'<Parent />',
});
</script>
组件通信三 —— 不同组件传值
中央事件总线
不同组件之间的传值
我的值可以传过来,但是添加到页面时不会显示,还有就是用bus.bMsg或者this.bMsg都可以获取值,this.on
遇到的问题
使用官网下载的vue.js是会报错,而引用官网的链接则没事
方法:
- 创建总线
var bus = new Vue({});
- 数据源
数据源触发事件
此处的事件(){
bus.$emit("数据接收位置声明的事件",要传递的值);
}
- 数据接收
数据接收位置,添加事件,为全局事件,需要用到mountend(){}
使用$on创建事件,
mounted(){
bus.$on("事件名",处理函数);
}
例子:
<div id="app"></div>
<script>
var bus = new Vue({
data(){
return{
msg:"",
}
}
});
var A = {
template:`
<div>
这是A组件
<b>{{bus.msg}}</b>
</div>
`,
mounted(){
bus.$on("get",(val)=>{
bus.msg = val;
});
}
};
var B = {
data(){
return{
B_msg:""
}
},
template:`
<div>
这是B组件<input type="text" @input="input_B" v-model="B_msg">
</div>
`,
methods:{
input_B(){
bus.$emit("get",this.B_msg)
}
},
};
new Vue({
el:"#app",
components:{
A,B,
},
template:`
<div>
<A /><B />
</div>
`
});
</script>
组件通信四 —— provide和inject
父组件给传子孙组件传值
出现的问题:
传递数据无效,格式没有问题,原因子组件没有被父组件包含
传递的值不支持热更新,只会传递一次,正如接收数据使用的created,组件创建只会进行一次
- 传值
使用provide传值
两种格式
provide:{
传递的数据名:对应的数据值
}
provide(){
return {
传递的数据名:对应的数据值
}
}
- 接收
使用inject[''],接收传递的值,使用created将接收的数据传递到组件内部展示出来
inject:['msg'],
created(){
//将传递
},
例子:
<div id="app"></div>
<script>
var Children = {
data(){
return{
parentVal:""
}
},
template:`
<div>这子子组件<b>{{parentVal}}</b></div>
`,
inject:['msg'],
created(){
this.parentVal = this.msg;
},
}
var Child = {
data(){
return{
parentVal:""
}
},
template:`
<div :val="getVal">这子组件<b>{{parentVal}}</b></div>
`,
inject:['msg'],
created(){
this.parentVal = this.msg;
},
}
var Parent = {
data(){
return{
msg:"000"
}
},
components:{
Child,
Children
},
template:`
<div>这是父组件<input type="text" @input="inputs" v-model="msg"><Child /><Children /></div>
`,
provide(){
return{
msg:this.msg,
}
},
}
new Vue({
el:"#app",
components:{
Parent,
},
template:`<Parent />`,
})
</script>
组件通信五 —— $parent和$children
子传父
$parent可以在子元素中调用父元素data中的参数,通过赋值获取数据
getval(){
this.$parent.pval = this.children
}
因此在子元素中使用函数去触发赋值
<script>
Vue.component("Child",{
data(){
return{
children:""
}
},
template:`
<div>这是子组件<input type="text" v-model="children" @input="getval"></div>
`,
methods:{
getval(){
this.$parent.pval = this.children
}
}
})
Vue.component("Parent",{
data(){
return{
pval:""
}
},
template:`
<div>这是父组件; 来自子组件的值:{{pval}}<br><Child /></div>
`,
})
new Vue({
el :"#app",
template:'<Parent />',
});
</script>
父传子
$children可以在父元素中调用子元素data中的参数,通过赋值获取数据
因此在父元素中使用函数去触发赋值
getval(){
this.$children[0].children = this.pval
}
值得注意的是,当父元素的子元素有多个,使用数组的形式,通过索引获取相应需要的子元素
<script>
Vue.component("Child",{
data(){
return{
children:""
}
},
template:`
<div>这是子组件;来自父组件的值:{{children}}</div>
`,
})
Vue.component("Parent",{
data(){
return{
pval:""
}
},
template:`
<div>这是父组件 <input type="text" v-model="pval" @input="getval"><br><Child /></div>
`,
methods:{
getval(){
this.$children[0].children = this.pval
}
}
})
new Vue({
el :"#app",
template:'<Parent />',
});
</script>
组件通信六 —— Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
详细内容可参考: Vuex 官方文档