• vue-typescript入门


    原文链接:https://www.jianshu.com/p/8ba2cdbfabd7

    这里主要讲下vue cli 3.x 的typescript集成

    一、起步

    1、安装

    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli
    

    2、创建项目

    安装的时候要自定义配置,选择typescript相关

    3、集成开发环境

    建议使用vscode编辑器,因为vscode集成了typescript,可以开箱即用

    二、相关依赖介绍

    Vue TypeScript支持:https://cn.vuejs.org/v2/guide/typescript.html

    package.json

    "dependencies": {
        "core-js": "^2.6.5",
        "vue": "^2.6.10",
        "vue-class-component": "^7.0.2",
        "vue-property-decorator": "^8.1.0",
        "vue-router": "^3.0.3",
        "vuex": "^3.0.1"
    }
    

    vue、vue-router、vuex就不讲了,大家也都了解,重点讲下

    • core-js
    • vue-class-component
    • vue-property-decorator

    1、 core-js

    JavaScript的模块化标准库。包括ECMAScript到2019年的polyfills:promises, symbols, collections, iterators, typed arrays许多其他功能、ECMAScript proposals、一些跨平台的WHATWG / W3C功能和建议,比如URL。您可以只加载所需的特性,或者使用它而不污染全局名称空间。

    2、 vue-class-component

    vue-class-component是vue作者尤大推出的一个支持使用class方式来开发vue单文件组件的库

    示例:

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <p>{{ word }}</p>
      </div>
    </template>
    
    <script lang="ts">
    import Vue from 'vue';
    import Component from 'vue-class-component';
    @Component
    export default class About extends Vue {
      word: string = "天涯共此时";
    }
    </script>
    

    3、 vue-property-decorator

    vue-property-decorator依赖于vue-class-component并且扩展了其他功能,如下:

    • @Prop
    • @Model
    • @Watch
    • @Emit
    • @Inject
    • @Provide
    • @Component (provided by vue-class-component)
    • Mixins(在vue-class-component中定义)

    1) @Prop

    HelloWorld.vue

    <template>
      <div>
        {{ msg }}
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Prop, Vue } from 'vue-property-decorator';
    
    @Component
    export default class HelloWorld extends Vue {
      @Prop() private msg!: string;
    }  
    </script>
    

    !是和?相对的,是typescript的语法,表示强制解析(也就是告诉typescript编译器,我这里一定有值)。你写?的时候再调用,typescript会提示可能为undefined

    Home.vue

    <template>
      <div>
        <HelloWorld msg="hello vue typscript"/>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    import HelloWorld from '@/components/HelloWorld.vue';
    
    @Component({
      components: {
        HelloWorld
      }
    })
    export default class Home extends Vue {}
    </script>
    

    2) @Model

    components/Test.vue

    <template>
      <div>
          <input type="checkbox" :checked="checked"/>
      </div>
    </template>
    
    <script lang="ts">
    import { Vue, Component, Model} from 'vue-property-decorator';
    
    @Component
    export default class Test extends Vue {
        @Model ('change', {type: Boolean})  checked!: boolean;
    }
    </script>
    

    views/Home.vue

    <template>
      <div>
        <Test v-model="isChecked"/>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    import Test from '@/components/Test.vue';
    
    @Component({
      components: {
        Test
      }
    })
    export default class Home extends Vue {
      isChecked: boolean = true;
    }
    </script>
    

    3) @Watch

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <p>{{ msg }}</p>
      </div>
    </template>
    
    <script lang="ts">
    import {Vue, Component, Watch} from 'vue-property-decorator';
    @Component
    export default class About extends Vue {
      msg: string = 'hello';
    
      @Watch('msg')
      onChangeValue(newV: string, oldV: string){
        console.log(newV, oldV); // world hello
      }
    
      mounted(): void {
        // 1.5秒后改变msg值
        setTimeout(() => {
          this.msg = 'world';
        }, 1500);
      }
    }
    </script>
    

    4) @Emit示例

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <p>{{ count }}</p>
        <button type="button" @click="handleClick">点击</button>
      </div>
    </template>
    
    <script lang="ts">
    import { Vue, Component, Emit } from 'vue-property-decorator'
    @Component
    export default class About extends Vue {
      count: number = 0;
    
      @Emit()
      addToCount(n: number) {
        // return n+1; // 这里可以做数据劫持,把传的1变成n+1
        // console.log(n); 
      }
    
      private handleClick(): void {
        this.addToCount(1); // 相当于 this.$emit('addToCount', 1)
      }
    
      private mounted(): void {
        this.$on('add-to-count', (n: number) => { // 相当于 this.$on('add-to-count', (n) => { // ... })
          this.count += n;
        });
      }
    }
    </script>
    

    在子父组件使用示例:

    parent.vue

    <template>
      <div>
        <Children @customClick="handleCustomClick"></Children>
        {{ count }}
      </div>
    </template>  
    
    <script lang="ts">
    import { Component, Vue } from 'vue-property -decorator'
    import Children from '@/components/Children.vue';
    
    @Component({
      components: {
        Children
      }
    })
    export class Parent extends Vue {
      count: number = 1;
      handleCustomClick(payload) {
         this.count += payload;
      }
    }
    </script>  
    

    children.vue

    <template>
      <div>
        <button type="button" @click="handleClick"></button>  
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue } from 'vue-property -decorator'
    
    @Component
    export class Children extends Vue {
      @Emit('customClick')
      handleClick() {
        return 1;
      }
    }
    </script>  
    

    5/6) @Inject和@Provide

    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
        }
      }
    })
    

    7) @Component

    其实上面的示例已经有了,这里再简写一下

    <script lang="ts">
    import {Vue, Component} from 'vue-property-decorator';
    @Component
    export default class About extends Vue {
      // ...
    }
    </script>
    

    8) mixin

    方式一:

    components/mixin.ts

    import Vue from 'vue';
    import  Component  from 'vue-class-component';
    
    @Component
    export default class myMixins extends Vue {
      value: string = 'Hello';
    }
    

    view/About.vue

    <template>
      <div class="about">
        <h1>This is an about page</h1>
      </div>
    </template>
    
    <script lang="ts">
    // 引入
    import  Component, {mixins}  from 'vue-class-component';
    import myMixins from '../components/mixin';
    
    @Component
    export default class About extends mixins(myMixins) {
      created() {
        console.log(this.value); // => Hello
      }
    }
    </script>
    

    方式二:

    components/mixin.ts

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

    view/About.vue

    <template>
      <div class="about">
        <h1>This is an about page</h1>
      </div>
    </template>
    
    <script lang="ts">
    import { Vue, Component, Prop } from 'vue-property-decorator';
    import myMixins from '../components/mixin';
    
    @Component({
      mixins: [myMixins]
    })
    export default class myComponent extends Vue{
      created(){
        console.log(this.value) // => Hello
      }
    }
    </script>
    

    三、computed和methods

    1、computed

    <template>
      <div>
         {{ cName }}
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    
    @Component
    export default class HelloWorld extends Vue {
      name = 'tom';
      get cName() {
        return this.name + '123';
      }
    }  
    </script>
    

    2、methods

    <template>
      <div>
        <button type="button" @click="say">点击</button>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    
    @Component
    export default class HelloWorld extends Vue {
      say() {
        console.log('hello'); 
      }
    }  
    </script>
    

    四、如何使用vuex

    安装

    $ npm install --save vuex-class
    # or 
    $ yarn add vuex-class
    

    示例:

    import Vue from 'vue'
    import Component from 'vue-class-component'
    import {
      State,
      Getter,
      Action,
      Mutation,
      namespace
    } from 'vuex-class'
     
    const someModule = namespace('path/to/module')
     
    @Component
    export class MyComp extends Vue {
      @State('foo') stateFoo
      @State(state => state.bar) stateBar
      @Getter('foo') getterFoo
      @Action('foo') actionFoo
      @Mutation('foo') mutationFoo
      @someModule.Getter('foo') moduleGetterFoo
     
      // If the argument is omitted, use the property name
      // for each state/getter/action/mutation type
      @State foo
      @Getter bar
      @Action baz
      @Mutation qux
     
      created () {
        this.stateFoo // -> store.state.foo
        this.stateBar // -> store.state.bar
        this.getterFoo // -> store.getters.foo
        this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
        this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
        this.moduleGetterFoo // -> store.getters['path/to/module/foo']
      }
    }
    

    参考连接:



    作者:webStyle_虎_
    链接:https://www.jianshu.com/p/8ba2cdbfabd7
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    阿里注册中心 Nacos 启动报错 Unable to start web server
    微服务监控中心springbootadmin 配置登录密码
    flowable 三种方式部署流程
    【IMU/VIOSLAM易混淆知识点】IMU坐标系和其他坐标系关系梳理以及SLAM中BA优化概念
    【C++】【初三知识我忘了。。】三维点最小二乘法拟合平面并求平面和轴的夹角
    米尔嵌入式CPU模组亮相工业控制技术研讨会
    有奖试用,车规级国产工业CPU平台,米尔MYCYT507开发板等你体验
    扎实的基础知识+正确的方法是快速阅读源码的关键
    同一项目、不同版本之间源码的阅读
    .NET MAUI 简介
  • 原文地址:https://www.cnblogs.com/yimai-series/p/14084165.html
Copyright © 2020-2023  润新知