Skip to content
Shimon's BlogShimon's Blog
主页
杂谈
  • 主页
      • 代码笔记
          • Vue.js
            • TypeScript 组件 Demo
              • Vue 与小程序的异同
                • Vue 单文件组件说明
                  • 在 Vue 中使用 Typescript
                    • 使用 TypeScript 进行 Vue 开发
                      • 用法
                        • @Prop() decorator
                          • @Watch() decorator
                            • @Model() decorator
                              • @Emit() decorator
                                • @Provide() decorator
                                  • TS 组件案例
                                  • 开发环境安装
                                    • 快速上手 Vue.js
                                      • 组件使用说明

                                    在 Vue 中使用 Typescript

                                    Shimon Zhan2022年4月19日
                                    • 基础
                                    • TypeScript
                                    大约 2 分钟

                                    此页内容
                                    • 使用 TypeScript 进行 Vue 开发
                                    • 用法
                                    • @Prop() decorator
                                    • @Watch() decorator
                                    • @Model() decorator
                                    • @Emit() decorator
                                    • @Provide() decorator
                                    • TS 组件案例

                                    # 使用 TypeScript 进行 Vue 开发

                                    在使用 Typescript 进行 Vue2.X 版本开发时,需要引入 vue-property-decorator 这个包进行开发。

                                    本质上就是写法上与 js 有所不同,而且需要额外注明变量的类型。

                                    # 用法

                                    有 7 个装饰器和 1 个功能(Mixin):

                                    • @Emit
                                    • @Inject
                                    • @Model
                                    • @Prop
                                    • @Provide
                                    • @Watch
                                    • @Component(由 vue-class-component 提供)
                                    • Mixins(mixins 由 vue-class-component 提供的辅助函数)

                                    # @Prop() decorator

                                    prop 属性的装饰器

                                    import { Vue, Component, Prop } from "vue-property-decorator";
                                    
                                    @Component
                                    export default class YourComponent extends Vue {
                                      @Prop(Number) private readonly propA!: number;
                                    
                                      @Prop({ default: "default value" }) private readonly propB!: string;
                                    
                                      @Prop([String, Boolean]) private readonly propC!: string | boolean;
                                    }
                                    

                                    相当于

                                    export default {
                                      props: {
                                        propA: {
                                          type: Number,
                                        },
                                        propB: {
                                          default: "default value",
                                        },
                                        propC: {
                                          type: [String, Boolean],
                                        },
                                      },
                                    };
                                    

                                    需要在装饰器的参数中填入 js 写法中对应 prop 的值。

                                    在后方使用 private readonly 标识符表示这是一个私有且只读的属性,它与 props 的性质相同。

                                    在 prop 的名称后面使用 !: <类型> 再次声明该属性的定义类型。

                                    注意:

                                    每个 prop 的默认值需要定义为与上面显示的示例代码相同。

                                    不支持以下的形式:

                                      @Prop() prop = 'default value'
                                    

                                    # @Watch() decorator

                                    watch 属性的装饰器。

                                    import { Vue, Component, Watch } from "vue-property-decorator";
                                    
                                    @Component
                                    export default class YourComponent extends Vue {
                                      @Watch("child")
                                      onChildChanged(val: string, oldVal: string) {}
                                    
                                      @Watch("person", { immediate: true, deep: true })
                                      onPersonChanged1(val: Person, oldVal: Person) {}
                                    
                                      @Watch("person")
                                      onPersonChanged2(val: Person, oldVal: Person) {}
                                    }
                                    

                                    相当于

                                    export default {
                                      watch: {
                                        'child': [
                                          {
                                            handler: 'onChildChanged',
                                            immediate: false,
                                            deep: false
                                          }
                                        ],
                                        'person': [
                                          {
                                            handler: 'onPersonChanged1',
                                            immediate: true,
                                            deep: true
                                          },
                                          {
                                            handler: 'onPersonChanged2',
                                            immediate: false,
                                            deep: false
                                          }
                                        ]
                                      },
                                      methods: {
                                        onChildChanged(val, oldVal) { },
                                        onPersonChanged1(val, oldVal) { }
                                        onPersonChanged2(val, oldVal) { }
                                      }
                                    }
                                    

                                    主要使用以上两个装饰器。


                                    以下装饰器很少使用:

                                    # @Model() decorator

                                    model 属性的装饰器

                                    import { Vue, Component, Model } from "vue-property-decorator";
                                    
                                    @Component
                                    export default class YourComponent extends Vue {
                                      @Model("change", { type: Boolean }) readonly checked!: boolean;
                                    }
                                    

                                    相当于

                                    export default {
                                      model: {
                                        prop: "checked",
                                        event: "change",
                                      },
                                      props: {
                                        checked: {
                                          type: Boolean,
                                        },
                                      },
                                    };
                                    

                                    # @Emit() decorator

                                    由 @Emit $emit 返回值修饰的函数后跟其原始参数。如果返回值是 promise,则在发出之前将其解析。

                                    如果未通过 event 参数提供事件的名称,则使用函数名称。在这种情况下, camelCase 名称将转换为 kebab-case。

                                    import { Vue, Component, Emit } from "vue-property-decorator";
                                    
                                    @Component
                                    export default class YourComponent extends Vue {
                                      count = 0;
                                    
                                      @Emit()
                                      addToCount(n: number) {
                                        this.count += n;
                                      }
                                    
                                      @Emit("reset")
                                      resetCount() {
                                        this.count = 0;
                                      }
                                    
                                      @Emit()
                                      returnValue() {
                                        return 10;
                                      }
                                    
                                      @Emit()
                                      promise() {
                                        return new Promise((resolve) => {
                                          setTimeout(() => {
                                            resolve(20);
                                          }, 0);
                                        });
                                      }
                                    }
                                    

                                    相当于

                                    export default {
                                      data() {
                                        return {
                                          count: 0,
                                        };
                                      },
                                      methods: {
                                        addToCount(n) {
                                          this.count += n;
                                          this.$emit("add-to-count", n);
                                        },
                                        resetCount() {
                                          this.count = 0;
                                          this.$emit("reset");
                                        },
                                        returnValue() {
                                          this.$emit("return-value", 10);
                                        },
                                        promise() {
                                          const promise = new Promise((resolve) => {
                                            setTimeout(() => {
                                              resolve(20);
                                            }, 0);
                                          });
                                    
                                          promise.then((value) => {
                                            this.$emit("promise", value);
                                          });
                                        },
                                      },
                                    };
                                    

                                    # @Provide() decorator

                                    import { Component, Inject, Provide, Vue } from "vue-property-decorator";
                                    
                                    const symbol = Symbol("baz");
                                    
                                    @Component
                                    export class MyComponent extends Vue {
                                      @Inject() readonly foo!: string;
                                      @Inject("bar") readonly bar!: string;
                                      @Inject({ from: "optional", default: "default" }) readonly optional!: string;
                                      @Inject(symbol) readonly baz!: string;
                                    
                                      @Provide() foo = "foo";
                                      @Provide("bar") baz = "bar";
                                    }
                                    

                                    相当于

                                    const symbol = Symbol("baz");
                                    
                                    export const MyComponent = Vue.extend({
                                      inject: {
                                        foo: "foo",
                                        bar: "bar",
                                        optional: { from: "optional", default: "default" },
                                        [symbol]: symbol,
                                      },
                                      data() {
                                        return {
                                          foo: "foo",
                                          baz: "bar",
                                        };
                                      },
                                      provide() {
                                        return {
                                          foo: this.foo,
                                          bar: this.baz,
                                        };
                                      },
                                    });
                                    

                                    # TS 组件案例

                                    • 点击此处
                                    上次编辑于: 2022/4/19 07:13:07
                                    贡献者: ShimonZhan
                                    下一页
                                    开发环境安装
                                    Copyright © 2021-present Shimon Zhan