#搭建Vue+TypeScript项目(七)
2020-12-29 本文已影响0人
风轻云淡小小木
梳理vue常用知识,自用
最好的行为是看官方文档,比我全
组件间消息传递
1.父组件->子组件
#父组件传递消息给子组件
##父组件
<topView ref="topView" :data="flag"></topView>
##子组件
@Prop({ default: 1, type: Number })
flag!: number;
#父组件使用子组件变量
(this.$refs.topView as any).data
2.子组件->父组件
#父组件
<topView @change="changeFun" ref="topView" :data="flag"></topView>
changeFun(send:any){
console.log(send);
}
#子组件合适的时机触发
this.$emit('change',996)
3.同级组件传递
#通过共同父级传递的情况
#组件1
<div @click="change">点击我触发另一个组件事件</div>
change(){
this.$parent.$emit('change',996)
}
#组件2
mounted() {
this.$parent.$on("change", (data: any) => {
console.log(data);
});
}
#通过公共bus类来实现
class Bus {
callback: any = {};
constructor() {
this.callback = {};
}
$on(name: string, fn: Function) {
this.callback[name] = this.callback[name] || [];
this.callback[name].push(fn);
}
$emit(name: string, argus: object) {
this.callback[name].forEach((element: Function) => {
element(argus);
});
}
}
export default Bus;
##使用
###在main.ts
Vue.prototype.$bus = new Bus();
####
#ts需要增加types
#在根目录下新建types文件夹。新建vue.d.ts文件
import Vue from "vue";
declare module "vue/types/vue" {
interface Vue {
$bus: any;
}
}
###在组件a中
<div @click="change">点击我触发另一个组件事件</div>
change() {
this.$bus.$emit("change", { name: "小小木" });
}
###在组件b中
mounted() {
this.$bus.$on("change", (data: object) => {
console.log(data);
});
}
4.祖先组件与后代组件
#祖先给后代组件传值
祖先
@Provide()
flag = "ggsmd";
后代
@Inject()
flag:any
##注意不是动态改变的,但是对象指向同一个内存地址,可以改变
#后代给祖先传值
#后代
<div @click="dispatch('change', '996福报')">点击我给祖先传值</div>
dispatch(eventName: string, argus: any) {
let parent = this.$parent;
while (parent) {
parent.$emit(eventName, argus);
parent = parent.$parent;
}
}
#祖先
async mounted() {
this.$on("change", (data: any) => {
console.log(data);
});
}
5.插槽
#匿名插槽
#父组件
<son>我是插槽数据</son>
#子组件
<div class="son">
<slot></slot>
</div>
#具名插槽及插槽传值
#父组件
<son>
<template v-slot:default> <div>我是默认插槽</div> </template>
<template v-slot:content> <div>我是content插槽</div> </template>
</son>
#子组件
<div class="son">
<slot></slot>
<slot name="content"></slot>
</div>
#传值
#父组件
<son><template v-slot:content="flag">
<div>{{ flag.data.name }}</div>
</template></son>
#子组件
<slot name="content" :data="data"></slot>
data: object = {
name: "996福报",
};
5.v-model和.sync
#简单实现一个input组件
#父组件
<son :value="value" @input="inputFun"></son>
value: any = "";
inputFun(value: any) {
this.value = value;
}
#子组件
<div class="son">
<input type="text" :value="value" @input="inputFun" />
</div>
@Prop()
value: any;
inputFun(e: any) {
this.$emit("input", e.target.value);
}
##使用v-model简化代码
#父组件
<son v-model="value"></son>
value: any = "";
#子组件
<div class="son">
<input type="text" :value="value" @input="inputFun" />
</div>
@Prop()
value: any;
inputFun(e: any) {
this.$emit("input", e.target.value);
}
##还可以通过model更改默认事件,假设是checkbox,不是input
#父组件
<son v-model="value"></son>
value: any = "";
#子组件
<input type="checkbox" @change="checked" :checked="checked" />
@Model("change", { type: Boolean })
checked!: boolean;
#类似于
//类似于
export default {
model: {
prop: 'checked',
event: 'change',
},
props: {
checked: {
type: Boolean,
},
},
}
#sync 操作符
sync修饰符类似于v-model,它能用于修改传递到子组件的属性,如果像下面这样写
<Input :value.sync="username">
等效于下面这行,那么和v-model的区别只有事件名称的变化
<Input :value="username" @update:value="username=$event">
这里绑定属性名称可以随意更改,相应的属性名也会变化
<Input :foo="username" @update:foo="username=$event">
// 所以sync修饰符的控制能力都在父级,事件名称也相对固定update:xx
##例子
#父组件
<son :username.sync="value"></son>
value: any = "默认value";
#子组件
<div class="son">
<div>{{ username }}</div>
<div @click="changename">点击更改username</div>
</div>
@Prop()
username: any;
changename() {
this.$emit("update:username", "1231");
}