• TS的一些用法和普通的对比(Vue)


    前言

    TS的一些用法其实官网介绍的很明白了,只不过如何去使用,在项目中如何搭建,

    TS跟正常的Vue项目还是或多或少有不少差距的,js是一门弱类型的语言,
    是在变量赋值时,永远都是给变量直接赋值各种类型值来初始化,
    线上一些隐藏的bug就冷不防会暴露出来。把这种错误扼杀在项目开发编译阶段而非上线阶段,
    所有就有了typescript超集的出现。
     
    ts在Vue项目中的基础用法
    vue-property-decorator

    vue-property-decoratorvue-class-component的基础上增加了更多与Vue相关的装饰器,使Vue组件更好的跟TS结合使用。这两者都是离不开装饰器的,(decorator)装饰器已在ES提案中。Decorator是装饰器模式的实践。装饰器模式呢,它是继承关系的一个替代方案。动态地给对象添加额外的职责。在不改变接口的前提下,增强类的性能。

    vue-property-decorator是这个Vue项目文件中完全依赖的库,它是Vue官方推荐的并且依赖于vue-class-component,先介绍下它在项目中的常见用法。

    • @Component
    • @Emit
    • @Provice @Inject
    • @Prop
    • @Watch
    • @Model
    • @Minxins

    @Component 类装饰器

    首先,Vue页面中的script部分要加一个lang=ts,这样安装好typescript正能引用

    <script lang="ts">
        import {Vue, Component} from 'vue-property-decorator';
        import BaseHeader from '@/components/BaseHeader'; 
        
        //公共头部组件
        @Component({
            components: {
                BaseHeader
            }
        })
        export default class extends Vue {
            private stateA:boolean = true
            private stateB:string = ''
            private stateC:number = 0
            private stateD:any = {}
            stateE:any[] = []
        }
    </script>

    等同于

    <script>
        import Vue from 'vue';
        import BaseHeader from '@/components/BaseHeader'; //公共头部组件
    
        export default {
            components: {
                BaseHeader
            },
            
            data(){
                return {
                    stateA: true,
                    stateB: '',
                    stateC: 0,
                    stateD: {},
                    stateE: []
                }    
            }
        }
    </script>

    vue-property-decorator在项目中的应用最主要是起一个装饰器的作用,差异化的话看对比就非常直观了

    data变量的定义比较多元化,这里区别有加private,不加就是public,当变量标记为private时,它就不能在声明它的类的外部访问。

    @Component装饰器属性名必须得写上

    @Prop

    父子组件之间的属性传值

    export default class extends Vue {
        @Prop({ default: 0 }) private propA!: number
        @Prop({ default: () => [10, 20, 30, 50] }) private propB!: number[]
        @Prop({ default: 'total, sizes, prev, pager, next, jumper' }) private propC!: string
        @Prop({ default: true }) private propD!: boolean,
        @prop([String, Boolean]) propE: string | boolean;
    }    

    等同于

    export default {
      props: {
        propA: {
            type: Number
        },
        propB: {
            type: Array,
            default: [10, 20, 30, 50]
        },
        propC: {
            type: String,
            default: 'total, sizes, prev, pager, next, jumper'
        },
        propD: {
            type: String,
            default: 'total, sizes, prev, pager, next, jumper'
        },
        propE: {
            type: [String, Boolean]
        }
      }
    }

    这里有两个常用修饰符!``?!和可选参数?是相对的, !表示强制解析(也就是告诉typescript编译器,我这里一定有值),

    你写?的时候再调用,typescript会提示可能为undefined

    @Emit

    Component
    export default class YourComponent extends Vue {
      count = 0
    
      @Emit('reset')
      resetCount() {
        this.count = 0
      }
    
      @Emit()
      returnValue() {
        return 10
      }
    
      @Emit()
      onInputChange(e) {
        return e.target.value
      }
    }

    等同于

    export default {
      data() {
        return {
          count: 0
        }
      },
      
      methods: {
        resetCount() {
          this.count = 0
          this.$emit('reset')
        },
        
        returnValue() {
          this.$emit('return-value', 10)
        },
        
        onInputChange(e) {
          this.$emit('on-input-change', e.target.value, e)
        }
      }
    }

    @Emit装饰器的函数会在运行之后触发等同于其函数名(驼峰式会转为横杠式写法)的事件, 并将其函数传递给$emit

    @Emit触发事件有两种写法

    • @Emit()不传参数,那么它触发的事件名就是它所修饰的函数名.
    • @Emit(name: string),里面传递一个字符串,该字符串为要触发的事件名


    @Watch 观察属性装饰器

    @Watch装饰器主要用于替代Vue属性中的watch属性,监听依赖的变量值变化而做一系列的操作

    @Component
    export default class YourComponent extends Vue {
      @Watch('child')
      onChildChanged(val: string, oldVal: string) {}
    
      @Watch('person', { immediate: true, deep: true })
      onPersonChanged(val: Person, oldVal: Person) {}
    }

    等同于

    export default {
      watch: {
        child(val, oldVal) {},
        person: {
            handler(val, oldVal) {},
            immediate: true,
            deep: true
        }
      }
    }

    watch 是一个对象,对象就有键,有值。

    • 第一个handler:其值是一个回调函数。即监听到变化时应该执行的函数。
    • 第二个是deep:其值是true或false;确认是否深入监听。deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器(受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除)
    • 第三个是immediate:其值是true或false;immediate:true代表如果在 wacth 里声明了之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行

    @Watch使用非常简单,接受第一个参数为要监听的属性名, 第二个属性为可选对象。@Watch所装饰的函数即监听到属性变化之后应该执行的函数。

    @Watch装饰的函数的函数名并非如上onStateChanged严格命名,它是多元化的,你可以随心所欲的命名,当然,能按照规范化的命名会使你的代码阅读性更好。

    // myMixin.ts
    
    @Component
    export default class MyMixin extends Vue {
      mixinValue:string = 'Hello World!!!'
    }
    
    // 引用mixins
    import MyMixin from './myMixin.js'
    
    @Component
    export default class extends mixins(MyMixin) {
      created () {
        console.log(this.mixinValue) // -> Hello World!!!
      }
    }

    Minxins

    然后我又偷学到了另外一种mixins写法,记录一下

    先改造一下myMixin.ts,定义vue/type/vue模块,实现Vue接口

    // myMixin.ts
    import { Vue, Component } from 'vue-property-decorator';
    
    
    declare module 'vue/types/vue' {
        interface Vue {
            mixinValue: string;
        }
    }
    
    @Component
    export default class myMixins extends Vue {
        mixinValue: string = 'Hello World!!!'
    }
     

    引用

    import { Vue, Component, Prop } from 'vue-property-decorator';
    import MyMixin from './myMixin.js'
    
    @Component({
        mixins: [MyMixin]
    })
    export default class extends Vue{
        created(){
            console.log(mixinValue) // => Hello World!!!
        }
    }

    两种方式不同在于定义mixins时如果没有定义vue/type/vue模块, 那么在混入的时候就要继承该mixins;

    如果定义vue/type/vue模块,在混入时可以在@Componentmixins直接混入。

    @Provide @Inject

    @Provide 声明一个值 , 在其他地方用 @Inject 接收,在实战项目中用得不多,一般用于不依赖于任何第三方状态管理库(如vuex)的组件编写


    @Ref(refKey?: string)

    @Ref装饰器接收一个可选参数,用来指向元素或子组件的引用信息。如果没有提供这个参数,会使用装饰器后面的属性名充当参数

    import { Vue, Component, Ref } from 'vue-property-decorator'
    import { Form } from 'element-ui'
    
    @Componentexport default class MyComponent extends Vue {
      @Ref() readonly loginForm!: Form
      @Ref('changePasswordForm') readonly passwordForm!: Form
    
      public handleLogin() {
        this.loginForm.validate(valide => {
          if (valide) {
            // login...
          } else {
            // error tips
          }
        })
      }
    }

    等同于

    export default {
      computed: {
        loginForm: {
          cache: false,
          get() {
            return this.$refs.loginForm
          }
        },
        passwordForm: {
          cache: false,
          get() {
            return this.$refs.changePasswordForm
          }
        }
      }
    }

    使用时切记要引入修饰器

    import {
        Vue,
        Component,
        Prop,
        Component,
        Emit,
        Provice,
        Inject,
        Watch,
        Model,
        Minxins,
    } from 'vue-property-decorator'

    钩子函数

    以下的public、private在引入tslint后是必写的,否则会有警告,如果没有引的话是可以不写的

    TsJs说明
    public created() {} created() {} 初始化
    public mounted() {} mounted() {} 挂载完毕
    private _getInitData() {} methods: { _getInitData() {} } 方法
    private get _userName() {} computed: { _userName() {} } 计算属性
    public destroyed() {} destroyed() {} 销毁生命周期
     
    以上就是一些关于TS在vue 里面的一些总结,还是需要多多练习
  • 相关阅读:
    JSP+JDBC+Servlet--基于数据库的登陆验证
    简单的购物车设计
    控制网页的访问时间
    JSP+JavaBean设计模式
    关于doGet和doPost的疑问
    IDEA连接SQL Server
    no sqljdbc_auth in java.library.path com.microsoft.sql 没有为集成身份验证配置驱动程序。
    数组的属性排序
    关于AFNetworking的Assertion failure崩溃
    C++中static关键字作用总结
  • 原文地址:https://www.cnblogs.com/yf-html/p/12877638.html
Copyright © 2020-2023  润新知