vue+TypeScript構建第一個項目

安裝項目

因爲本機vue腳手架是2.0,webpack3.0版本所以本文只適用vue/cli2.0版本。

//新建項目
vue init webpack vue-ts


後面一系列路由,測試單元配置忽略。

 

//新建項目後我們安裝ts
npm install typescript ts-loader --save-dev
//安裝一下官方插件
npm i vue-class-component vue-property-decorator --save

vue-class-component:強化 Vue 組件,使用 TypeScript/裝飾器 增強 Vue 組件
vue-property-decorator:在 vue-class-component 上增強更多的結合 Vue 特性的裝飾器
ts-loader:TypeScript 爲 Webpack 提供了 ts-loader,其實就是爲了讓webpack識別 .ts .tsx文件   !重點ts-loader安裝3.1.1版本配合webpack3.0版本使用否則無法兼容!

 在項目根目錄下新建tsconfig.json文件

//這是我的文件配置
{
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules"
  ],
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "allowJs": true,
    "module": "esnext",
    "target": "es5",
    "moduleResolution": "node",
    "isolatedModules": true,
    "lib": [
      "dom",
      "es5",
      "es2015.promise"
    ],
    "sourceMap": true,
    "pretty": true
  }
}

在src目錄下新建vue-shim.d.ts,內容如下

//這段代碼主要用於 TypeScript 識別.vue 文件,Ts 默認並不支持導入 vue 文件
declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}

在build目錄下找到webpack.base.conf.js,將入口文件改成main.ts,

entry: { 
  app: './src/main.ts'     //'./src/main.js'
},


//在module.rules下添加如下代碼

{
  test: /\.tsx?$/,
  loader: 'ts-loader',
  exclude: /node_modules/,
  options: {
    appendTsSuffixTo: [/\.vue$/],
  }
},

將src目錄下的main.js改成main.ts,內容不變

啓動項目

npm run dev

 

 

在vue項目使用ts時,裝飾器有以下幾種,下面爲這些裝飾器的具體用法並且有和js中寫法的對比:

  1. @Component
  2. @Emit
  3. @Prop
  4. @Watch
  5. @Model
  6. @Inject / @Provide
  7. Mixins

下面爲具體代碼:

data聲明

ts中的data聲明

import { Component, Prop, Vue, Watch } from 'vue-property-decorator';

@Component
export default class Test extends Vue {
  private name: string;
}


/*
*這裏解釋一下private 修飾符

* 在ts中有三種修飾符,分別是public、private、protected 

* public聲明的屬性和方法在類的內部和外部均能訪問到

* protected聲明的方法和屬性只能在類的內部和其子類能訪問

* private聲明的方法和屬性只能在其類的內部訪問
*/

js中的data聲明,上面代碼等同於

data(){
  return{
    name:""
  }
}

@Component

ts中引入組件components寫在@Component中,如下:

<template>
    <div class="parent">
        parent組件--{{title}}
        <hr>
        <Home v-model="title"></Home>
        <About v-model="title"></About>
    </div>
</template>

<script lang='ts'>
    import Home from './Home.vue'
    import About from './About.vue'
    import { Component, Vue } from 'vue-property-decorator';
    @Component({
        components: {
            Home,
            About
        }
    })
    export default class  extends Vue {
        private title: string = '父組件中的值'
    }
</script>
複製代碼

下面爲在js中引入組件components的寫法,與上面ts的代碼效果一樣:

<script>
import Home from './Home.vue'
import About from './About.vue'
export default {
    data() {
        return {
            title: '父組件中的值'
        }
    },
    components: {
        Home,
        About
    }
}
</script>
複製代碼

@Emit

ts中@Emit的用法如下:

<template>
  <div class="home">
    vue+ts項目vue-property-decorator用法
    <hr>
    <button @click="triggerEmit('qqq')">觸發emit</button>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Emit } from 'vue-property-decorator';

@Component({})
export default class Home extends Vue {

  private mounted() {
    this.$on('demo-log', (data: any): void => {
      alert(data)
    })
  }

  @Emit('demo-log')
  triggerEmit(n: any) {
    console.log('hhh')
  }
}
</script>
複製代碼

下面爲@Emit的另一種寫法,$on位置使用 - 鏈接,@Emit位置直接使用駝峯命名,則可以省略括號中的名稱:”

export default class Home extends Vue {
  private mounted() {
    this.$on('trigger-emit', (data: any): void => {
      alert(data)
    })
  }
  @Emit()
  triggerEmit(n: any) {
    console.log('hhh')
  }
}
複製代碼

下面爲$Emit在js中的寫法,與上面ts的代碼效果一樣:

export default {
  data() {
    return {}
  },
  mounted() {
    this.$on('trigger-emit', data => {
      alert(data)
    })
  },
  methods: {
    triggerEmit(val) {
      this.$emit('trigger-emit', val)
    }
  }
}
複製代碼

@Prop

ts中@Prop的用法如下:

<template>
  <div class="home">
    vue+ts項目vue-property-decorator用法
    <hr>
    <p>這是從父組件中傳過來的值: {{title}}</p>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';

@Component({})
export default class Home extends Vue {
  @Prop() title!: string;
  // prop的類型和默認值 
  // @Prop({type: String, default: 'default value'}) title!: string;

  //!: 表示一定存在,?: 表示可能不存在。這兩種在語法上叫賦值斷言
}
</script>
複製代碼

下面爲prop在js中的寫法,與上面ts的代碼效果一樣:

export default {
  data() {
    return {}
  },
  props: ['title'],
  // props: {
  //   title: {
  //     style: String,
  //     default: 'default value'
  //   }
  // }
}
複製代碼

@Watch

ts中@Watch的用法如下

<template>
  <div class="home">
    vue+ts項目vue-property-decorator用法
    <hr>
    <input type="text" v-model="inputValue">
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';

@Component({})
export default class Home extends Vue {
  private inputValue: string = ''
  @Watch('inputValue')
  valueChange(newValue: string, oldValue: string) {
    console.log(newValue, oldValue)
  }
  // 對watch的配置爲第二個參數,以對象形式傳入
  // @Watch('inputValue',{ deep: true })
  // valueChange(newValue: string, oldValue: string) {
  //   console.log(newValue, oldValue)
  // }
   
}
</script>
複製代碼

下面爲watch在js中的寫法,與上面ts的代碼效果一樣:

export default {
  data() {
    return {
      inputValue: ''
    }
  },
  watch: {
    inputValue(newValue, oldValue) {
      console.log(newValue, oldValue)
    }
  }
}
複製代碼

@Model

ts中@Model的用法如下

父組件代碼如下

<template>
    <div class="parent">
        parent組件--{{title}}
        <hr>
        <Home v-model="title"></Home>
        <!-- 直接使用v-mode爲以下使用標籤的語法糖,默認子組件使用value接受prop傳值使用emit調用input方法修改值,在使用model參數prop修改如何接受,event修改emit調用哪個方法來修改值 -->
        <!--<Home :value="title" @input="title=$event.target.value"></Home>-->
    </div>
</template>

<script lang='ts'>
    import Home from './Home.vue'
    import { Component, Vue } from 'vue-property-decorator';
    @Component({
        components: {
            Home
        }
    })
    export default class  extends Vue {
        private title: string = '父組件中的值'
    }
</script>
複製代碼

子組件ts代碼如下

<template>
  <div class="home">
    vue+ts項目vue-property-decorator用法
    <hr>
    <input type="text" v-model="inputValue" @input="valueChange($event.target.value)">
  </div>
</template>

<script lang="ts">
import { Component, Vue, Model, Emit, Prop } from 'vue-property-decorator';

@Component({})
export default class Home extends Vue {
  private inputValue: string = ''
  private created() {
    this.inputValue = this.valueFromModel
  }
  @Model ('changeValueFromModel')  valueFromModel !: string;
  @Emit('changeValueFromModel')
  // 參數應該爲輸入框的值,所以上面傳過來的值應該爲value而不能是e
  valueChange(val: string) {}
   
}
</script>
複製代碼

下面爲model在js中的寫法,與上面ts的代碼效果一樣:

export default {
  model:{
    prop: 'valueFromModel',
    event: 'changeValueFromModel'
  },
  props: ['valueFromModel'],
  data() {
    return {
      inputValue: ''
    }
  },
  created() {
    this.inputValue = this.valueFromModel
  },
  methods: {
    valueChange(e) {
      this.$emit('changeValueFromModel', e.target.value)
    }
  }
  
}
複製代碼

@Provide / @Inject

ts中@Provide / @Inject用法如下

父組件

<template>
    <div class="parent">
        parent組件--{{title}}
        <Home></Home>
    </div>
</template>

<script lang='ts'>
    import Home from './Home.vue'
    import { Component, Vue, Provide } from 'vue-property-decorator';
    @Component({
        components: {
            Home
        }
    })
    export default class  extends Vue {
        private title: string = '父組件中的值'
        @Provide()
        pOne = 'oneFromProvide'
        
        @Provide('pTwo')
        two = 'twoFromProvide'
    }
</script>
複製代碼

子組件

<template>
  <div class="home">
    vue+ts項目vue-property-decorator用法
    <hr>
    來自provide中的值--1--{{pOne}}--2--{{pTwo}}
  </div>
</template>

<script lang="ts">
import { Component, Vue, Inject } from 'vue-property-decorator';
import outMixins from './mixins';

@Component({})
export default class Home extends Vue {
  @Inject('pOne')
    pOne!: string;
    
  @Inject({
      from:'pTwo',
      default:'default value'
  })
  pTwo!: string;
}
</script>
複製代碼

下面爲project / inject在js中的寫法,與上面ts的代碼效果一樣:

父組件

<template>
    <div class="parent">
        parent組件
        <About></About>
    </div>
</template>

<script>
import About from './About.vue'
export default {
    components: {
        About
    },
    provide () {
        return {
            pOne: 'oneFromProvide',
            pTwo: 'twoFromProvide'
        }
    }
}
</script>
複製代碼

子組件

<template>
  <div class="home">
    vue+js項目
    <hr>
    來自provide中的值--1--{{pOne}}--2--{{pTwo}}
  </div>
</template>

<script>
export default {
  inject: {
    pOne: 'pOne',
    pTwo: { from: 'pTwo', default: 'default value' }
  }
}
</script>
複製代碼

Mixins

ts中Mixins的用法如下

mixins.ts文件如下

import { Vue, Component } from 'vue-property-decorator';

@Component
export default class myMixins extends Vue {
    valueFromMixins: string = "來自mixins的value"
}
複製代碼

ts代碼如下

<template>
  <div class="home">
    vue+ts項目vue-property-decorator用法
    <hr>
    來自mixins中的變量--{{valueFromMixins}}
  </div>
</template>

<script lang="ts">
import { Component, Vue, Model, Emit, Prop } from 'vue-property-decorator';
import outMixins from './mixins';

@Component({
  mixins: [outMixins]
})
export default class Home extends Vue {}
</script>

複製代碼

下面爲mixins在js中的寫法,與上面ts的代碼效果一樣:

<script>
import {outMixins} from './mixins'
export default {
  mixins:[outMixins]
}
</script>


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章