一篇文章帶你使用Typescript封裝一個(gè)Vue組件

一、搭建項(xiàng)目以及初始化配置

vue create ts_vue_btn

 

這里使用了vue CLI3自定義選擇的服務(wù),我選擇了ts、stylus等工具。然后創(chuàng)建完項(xiàng)目之后,進(jìn)入項(xiàng)目。使用快捷命令code .進(jìn)入Vs code編輯器(如果沒有code .,需要將編輯器的bin文件目錄地址放到環(huán)境變量的path中)。然后,我進(jìn)入編輯器之后,進(jìn)入設(shè)置工作區(qū),隨便設(shè)置一個(gè)參數(shù),這里比如推薦設(shè)置字號(hào),點(diǎn)下。這里是為了生成.vscode文件夾,里面有個(gè)json文件。
 

我們?cè)陂_發(fā)項(xiàng)目的時(shí)候,項(xiàng)目文件夾內(nèi)的文件很多,會(huì)有時(shí)影響視覺。那么這個(gè)文件就是設(shè)置什么文件隱藏,注意只是隱藏,而不是刪除!下面是我自己寫的,在Vue cli3生成的項(xiàng)目需要隱藏的文件參數(shù)。

{
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "**/README.md": true,
        "**/node_modules":true,
        "**/shims-tsx.d.ts": true,
        "**/shims-vue.d.ts": true,
        "**/.browserslistrc": true,
        ".eslintrc.js": true,
        "babel.config.js": true,
        "package-lock.json": true,
        ".gitignore": true,
        "tsconfig.json": true
    }
}

以下就是所看到的文件目錄,我把一些無關(guān)緊要的文件跟文件夾隱藏或者刪除后所看到的。


















文件解讀(從上往下):



二、開發(fā)實(shí)踐

下圖為所需要?jiǎng)?chuàng)建的項(xiàng)目文件目錄,這里我們開發(fā)一個(gè)Vue按鈕組件。









如下圖所示,這就是我們要用Typescript開發(fā)的組件。


開始編輯:
1、App.vue

<template>
  <div id="app">
   <Home></Home>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';// 編寫類樣式組件所需要的一些類或者是裝飾器
import Home from "@/Home.vue"; // 引入頁(yè)面組件

// 這里我們需要使用Component裝飾器,這個(gè)裝飾器是注冊(cè)組件用的,里面的參數(shù)是一個(gè)對(duì)象,內(nèi)有一個(gè)components屬性,值為引入的組件名
@Component({
  components:{
    Home
  }
})
export default class App extends Vue {}
</script>

<style lang="stylus">

</style>

 

2、UIBtn.vue

<template>
  <!-- v-on="$listeners" 可以使用,在本類不再監(jiān)聽,在其他地方監(jiān)聽,可以不用$emit(),但是我們這里不用它 -->
  <button
    class="ui-btn"
    @click="onBtnclick('success!')"
    :class="{
    'ui-btn-xsmall':xsmall,
    'ui-btn-small':small,
    'ui-btn-large':large,
    'ui-btn-xlarge':xlarge
  }"
  >
    <slot>Button</slot>
  </button>
</template>

<script lang="ts">
import { Component, Vue, Emit, Prop } from "vue-property-decorator"; // 編寫類樣式組件所需要的一些類或者是裝飾器
@Component
export default class UIBtn extends Vue {
  @Prop(Boolean) private xsmall: boolean | undefined;
  @Prop(Boolean) private small: boolean | undefined;
  @Prop(Boolean) private large: boolean | undefined;
  @Prop(Boolean) private xlarge: boolean | undefined;
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  @Emit("click") private emitclick(x: string) {}
  private mounted() {
    console.log(this.large);
  }
  private onBtnclick(x: string) {
    this.emitclick(x);
  }
}
</script>

<style scoped lang="stylus" >
resize(a, b, c)
  padding a b
  font-size  c
.ui-btn
  resize(12px, 20px, 14px)
  border 0 solid #000
  border-radius 4px
  outline none
  font-weight 500;
  letter-spacing 0.09em
  background-color #409eff
  color #fff
  cursor pointer
  user-select none
  &:hover
    filter brightness(120%)
  &:active
    filter brightness(80%)
  &.ui-btn-xsmall
    resize(5px, 15px, 14px)
  &.ui-btn-small
    resize(8px, 18px, 14px)
  &.ui-btn-large
    resize(14px, 22px, 14px)
  &.ui-btn-xlarge
    resize(16px, 24px, 14px)
</style>

 

3、Home.vue

<template>
  <div class="home-con">
      <div class="btn-group">
           <UIBtn class="btn" @click="resize('xsmall')">超小</UIBtn>
           <UIBtn class="btn" @click="resize('small')">小</UIBtn>
           <UIBtn class="btn" @click="resize('normal')">正常</UIBtn>
           <UIBtn class="btn" @click="resize('large')">大</UIBtn>
           <UIBtn class="btn" @click="resize('xlarge')">超大</UIBtn>
      </div>
      <div class="btn-con">
           <UIBtn @click='onClick'
           :xlarge="xlarge"
           :large="large"
           :small="small"
           :xsmall="xsmall"
           >主要按鈕</UIBtn>
      </div>
      <div class="btn-pro">
            <UIBtn large >樣式按鈕</UIBtn>
      </div>    
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'; // 編寫類樣式組件所需要的一些類或者是裝飾器
import UIBtn from '@/components/UIBtn.vue';
@Component({
    components:{
      UIBtn
    }
})
export default class Home extends Vue {
   // eslint-disable-next-line @typescript-eslint/no-inferrable-types
   private xlarge: boolean = false;
    // eslint-disable-next-line @typescript-eslint/no-inferrable-types
   private large: boolean = false;
    // eslint-disable-next-line @typescript-eslint/no-inferrable-types
   private xsmall: boolean = false;
    // eslint-disable-next-line @typescript-eslint/no-inferrable-types
   private small: boolean = false;
   private resize (name: string){
       console.log(name)
       switch (name) {
           case 'xsmall':
               this.xsmall=true;
               this.small=false;
               this.large=false;
               this.xlarge=false;
               break;
           case 'small':
               this.xsmall=false;
               this.small=true;
               this.large=false;
               this.xlarge=false;
               break;
           case 'normal':
               this.xsmall=false;
               this.small=false;
               this.large=false;
               this.xlarge=false;
               break;
           case 'large':
               this.xsmall=false;
               this.small=false;
               this.large=true;
               this.xlarge=false;
               break;
           case 'xlarge':
               this.xsmall=false;
               this.small=false;
               this.large=false;
               this.xlarge=true;
               break;
       }
   }
   private onClick(x: string) {
       console.log(x)
    }
}
</script>

<style lang="stylus" scoped>
.btn-group
    margin 50px 0
.btn
    margin 6px
.btn-pro
    margin-top 50px
</style>
 

作者:Vam的金豆之路

主要領(lǐng)域:前端開發(fā)

我的微信:maomin9761

微信公眾號(hào):前端歷劫之路