美文网首页
vue typescript

vue typescript

作者: 栗子daisy | 来源:发表于2020-03-03 21:40 被阅读0次

    Typescript

    操作
    新建一个基于ts的vue项目 自定义选项 - Manually select features;添加ts支持 - TypeScript;基于类的组件 - y; tslint
    在已存在项目中安装typescript vue add @vue/typescript

    类型注解和编译时类型检查
    变量后面通过冒号+类型来做类型注解
    // test.ts

    let title1: string; // 类型注解
    title1 = "title1"; // 正确
    title1 = 2; // 错误
    let title2 = "xx"; // 类型推论
    title2 = 2;// 错误
    

    数组类型

    let names: string[];
    names = ['Tom'];//或Array<string>
    

    任意类型

    let foo:any;
    foo = 'xx'
    foo = 3
    //any类型也可用于数组
    let list: any[];
    list = [1, true, "free"];
    list[1] = 100;
    

    函数中使用类型

    function greeting(person: string): string {
     return 'Hello, ' + person;
    }
    //void类型,常用于没有返回值的函数
    function warnUser(): void { alert("This is my warning message"); }
    

    例子,HelloWorld.vue

    <template>
     <div>
      <input type="text" placeholder="输入新科目" @keyup.enter="addSubject">
      <ul>
       <li v-for="subject in subjects" :key="subject">{{subject}}</li>
      </ul>
     </div>
    </template>
    <script lang='ts'>
    import { Component, Vue } from "vue-property-decorator";
    @Component
    export default class Hello extends Vue {
     subjects: string[];
     constructor() {
      super();
      this.subjects = ["语文", "数学"];
    }
     private addSubject(event: any) {
      console.log(event);
      this.subjects.push(event.target.value);
      event.target.value = '';
    }
    }
    </script>
    

    ts中的类和es6中大体相同,重点关注ts带来的特性

    class MyComp extends Parent {
     // 访问修饰符
     private _foo = 'foo'; // 私有属性,不能在类的外部访问
     protected bar = 'bar';// 保护属性,还可以在派生类中访问
     readonly mua = 'mua'; // 只读属性必须在声明时或构造函数里初始化
     // 构造函数:初始化成员变量
     // 参数加上修饰符,能够定义并初始化一个属性
     constructor ( private tua = 'tua') {
      super();
    }
     
     // 方法也有修饰符
     private someMethod() {}
     // 存取器:暴露存取数据时可添加额外逻辑;在vue里面可以用作计算属性
     get foo() { return this._foo }
     set foo(val) { this._foo = val }
    }
    const comp = new MyComp()
    comp.foo
    

    例子:利用getter设置计算属性

    <template>
    <li>特性数量:{{count}}</li>
    </template>
    <script lang="ts">
      export default class HelloWorld extends Vue {
        // 定义getter作为计算属性
        get count() {
          return this. subjects.length;
       }
     }
    </script>
    

    接口

    接口仅约束结构,不要求实现,使用更简单

    interface Person {
     firstName: string;
     lastName: string;
    }
    function greeting(person: Person) {
     return 'Hello, ' + person.firstName + ' ' + person.lastName;
    }
    const user = {firstName: 'Jane', lastName: 'User'};
    console.log(greeting(user));
    

    例子:声明接口类型约束数据结构,HelloWorld.vue

    <template>
      <div>
        <input type="text" placeholder="输入新科目" @keyup.enter="addSubject" />
        <ul>
          <li v-for="subject in subjects" :key="subject.id">{{subject.name}}</li>
        </ul>
      </div>
    </template>
    <script lang="ts">
    import { Component, Vue } from "vue-property-decorator"; 
    interface Subject {
      id: number;
      name: string;
    } 
    @Component
    export default class HelloWorld extends Vue {
      private subjects: Subject[];
      constructor() {
        super();
        this.subjects = [
          { id: 1, name: "语文" },
          { id: 2, name: "数学" }
        ];
      }
      private addSubject(event: any) {
        console.log(event);
        this.subjects.push({ id:this.subjects.length + 1, name: event.target.value });
        event.target.value = "";
      }
    }
    </script>
    

    泛型

    泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定
    类型的一种特性。

    // 不用泛型
    // interface Result {
    //  data: Feature[];
    // }
    // 使用泛型
    interface Result<T> {
    data: T;
    }
    

    例子:使用泛型约束接口返回类型

    function getData<T>(): Result<T> {
     const data: any = [
     { id: 1, name: "类型注解", version: "2.0" },
     { id: 2, name: "编译型语言", version: "1.0" }
    ];
     return { data };
    }
    

    使用接口

    constructor() {
     this.features = getData<Feature[]>().data;
    }
    

    甚至返回Promise

    function getData<T>(): Promise<Result<T>> {
     const data: any = [
     { id: 1, name: "类型注解", version: "2.0" },
     { id: 2, name: "编译型语言", version: "1.0" }
    ];
     return Promise.resolve<Result<T>>({ data });
    }
    

    使用

    async mounted() {
      this.features = (await getData<Feature[]>()).data;
    }
    

    装饰器

    装饰器用于扩展类或者它的属性和方法。
    属性声明:@Prop
    除了在@Component中声明,还可以采用@Prop的方式声明组件属性

    export default class HelloWorld extends Vue {
     // Props()参数是为vue提供属性选项
     // !称为明确赋值断言,它是提供给ts的
     @Prop({type: String, required: true})
     private msg!: string;
    }
    

    事件处理:@Emit
    新增特性时派发事件通知,Hello.vue

    // 通知父类新增事件,若未指定事件名则函数名作为事件名(羊肉串形式)
    @Emit()
    private addFeature(event: any) {// 若没有返回值形参将作为事件参数
      const feature = { name: event.target.value, id: this.features.length + 1 };
      this.features.push(feature);
      event.target.value = "";
      return feature;// 若有返回值则返回值作为事件参数
    }
    

    变更监测:@Watch

    @Watch('msg')
    onRouteChange(val:string, oldVal:any){
      console.log(val, oldVal);
    }
    
    装饰器原理

    装饰器本质是工厂函数,修改传入的类、方法、属性等
    类装饰器

    //类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。
    function log(target: Function) {
      // target是构造函数
      console.log(target === Foo); // true
      target.prototype.log = function() {
       console.log(this.bar);
     }
      // 如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。
    }
    @log
    class Foo {
     bar = 'bar'
    }
    const foo = new Foo();
    // @ts-ignore
    foo.log();
    

    Component例子,新建Decor.vue

    <template>
     <div>{{msg}}</div>
    </template>
    <script lang='ts'>
    import { Vue } from "vue-property-decorator";
    function Component(options: any) {
     return function(target: any) {
      return Vue.extend(options);
    };
    }
    @Component({
     props: {
      msg: {
       type: String,
       default: ""
     }
    }
    })
    export default class Decor extends Vue {}
    </script>
    

    相关文章

      网友评论

          本文标题:vue typescript

          本文链接:https://www.haomeiwen.com/subject/rxvllhtx.html