2020-12-27 补充
1.vue-class-component 和 vue-property-decorator的关系
- 前者是vue官方提供
- 后者是第三方提供
- 后者完全依赖前者,并扩展一系列的装饰器
- 开发时可以直接引用vue-property-decorator
2.用类的形式写vue组件,如何使用mixins
- 可以通过在@Component装饰器中使用常规写法
- 可以通过继承Mixins()
<template>
<div>
<h2>Mixins</h2>
</div>
</template>
<script lang="ts">
import { Vue, Prop,Mixins,Component } from "vue-property-decorator";
import mixins1 from "../mixins/mixins1.vue";
@Component({
// 在@Component中使用mixins选项
// mixins:[mixins1]
})
// 或者在class上继承Mixins();如果采用第一种方式混入,此处不用继承混入,依然默认继承Vue
export default class NAME extends Mixins(mixins1) {
created () {
console.log('main component created...');
}
mounted () {
console.log('main component mounted...');
}
}
</script>
直接上代码,针对每个装饰器都有注释。
<!-- fatner -->
<template>
<div>
<div>我是父组件的: {{models}}</div>
<child :params.sync="params" v-model="models" @emit-test="hanlerEmit1" @emitTestName="handlerEmit2"></child>
</div>
</template>
<script lang="ts">
import {
Vue,
Component,
Prop,
Provide,
Inject,
Ref,
} from "vue-property-decorator";
import child from "../views/child.vue";
@Component({
components: {
child
}
})
export default class NAME extends Vue {
models = "models";
params = "sync props";
// data中的变量
private var = "变量";
// 生命周期
created() {
console.log("created...");
}
mounted() {
console.log("mounted...");
}
beforeDestroy() {}
// methods中的方法
public handler() {
console.log('methods...');
}
hanlerEmit1(val) {
console.log('@emit1: ',val);
}
handlerEmit2(val) {
console.log('@emit2: ', val);
}
}
</script>
<!-- children -->
<template>
<div>
<div>{{ syncParam }}</div>
<button @click="handler" ref="ybutton">修改props的值</button>
<input type="text" :value="checked" @input="handlerInput($event)" />
<div><button @click="emitTest(syncParam)">测试emit1</button></div>
<div><button @click="emitTest2($event)">测试emit2</button></div>
<grandson ref="comp"></grandson>
<div><button @click="getRefs">获取ref</button></div>
</div>
</template>
<script lang="ts">
import {
Vue,
Component,
Prop,
Provide,
Inject,
PropSync,
Model,
Watch,
Emit,
Ref,
} from "vue-property-decorator";
import grandson from "../views/Grandson.vue";
@Component({
/**
* 在@Components()装饰器中声明未提供装饰器的选项
* components/filters/directives;
*
* 也可以声明computed等常规选项
*/
inheritAttrs: false,
components: { grandson },
})
export default class Children extends Vue {
/**
* @Prop(options)
* options三种方式:
* 1. @Prop(String)
* 2. @Prop([String, Number])
* 3. @Prop({type: String, default: "", required: true, validator: function(){}})
*/
// @Prop(String) str1!:string
// @Prop([String, Number]) str2!:string
// @Prop({type: String, default: "str...", required: true}) str3!:string
/**
* @PropSync(name, options)
* 接收两个参数:props传递过来的值;options:同上;
*
* 该装饰器实现了props的双向绑定,在父组件中是要使用 .sync修饰
* <child :params.sync="params"></child>
*/
@PropSync("params", { type: String }) syncParam: string;
/**
* @Model(event, options)
* 允许在组件上自定义v-model
* ?????????????????????
*/
@Model("change", { type: String }) checked: string;
/**
* @Watch(propName, options)
* 接收两个参数:监听的属性名;参数(immediate,deep)
*/
@Watch("syncParam")
valChange() {
console.log("syncParam发生变化");
}
/**
* @Emit(eventName?: string)
* 一个可选参数,如果不存在,则使用函数名,函数名为驼峰则时间名需要使用kebab-case;如果存在则使用设定的值
* 如果没有return,则默认返回函数的参数
*/
@Emit() emitTest(val) {
return val;
}
@Emit("emitTestName") private emitTest2($event) {}
/**
* @Ref(key)
* key为可选参数,如果不存在,则已后边的属性名作为参数
*/
@Ref() ybutton!: HTMLButtonElement;
@Ref("comp") refcomponent!: grandson;
private user = {
name: 'admin',
age: 20
}
/**
* @Provide() 向内传递名formdata的对象(可以是任意类型,这里使用object)
* @Inject() 在任意子组件中可以根据Provide提供的名称进行获取值。
* 隔代组件通信
*/
@Provide() formdata = {
user: this.user
}
@Inject() title!: string
mounted() {
console.log(this.syncParam);
}
handler() {
this.syncParam = "更新props";
}
public handlerInput($event): void {
this.$emit("change", $event.target.value);
}
public getRefs() {
console.log(this.ybutton);
console.log(this.refcomponent);
}
}
</script>