Vue Cli3 TypeScript 搭建工程


  Vue Cli3出來也一段時間了,我想嘗試下Vue結合TypeScript搭建個工程,感受下Vue下用TS...網上有一篇講的非常詳細的教程  vue-cli3.0 搭建項目模版教程(ts+vuex+axios) 作者:陳小生_1017

  我看完教程后(好長的一篇博文,不得不服作者的用心,贊!),我去博主留的git地址 https://github.com/chenfangsheng/vue-cli3-tpl.git 克隆一份下來,安裝完依賴后,發現好多錯誤...汗...我在原博客評論區和git issue區均為發現問題的解決辦法,我嘗試着一番google后,項目能跑起來了,順便研究了下vuex-class的用法,下面會貼出具體的用法。出現的錯誤有:

  1.引入scss的路徑不對,按照下邊改為相對路徑就可以了

// vue-cli3-tpl/src/components/test/test.vue 

...
<style lang="scss">
  /*@import "@/assets/scss/variables";*/
  @import "../../assets/scss/variables";

  .test-wrap {
    width: 100%;
    color: $background-color;
  }
</style>
// vue-cli3-tpl/src/assets/scss/variables.scss

 $background-color : #4c94f1;

  為了方便,我們引用scss全局變量,在每一個style標簽引入這個公共變量文件太麻煩了,官方有全局引入的方法:

// vue.config.js
css: {
    modules: false, // 啟用 CSS modules
    extract: true, // 是否使用css分離插件
    sourceMap: true, // 開啟 CSS source maps?
    loaderOptions: {
      // 給 sass-loader 傳遞選項
      sass: {
        // @/ 是 src/ 的別名
        // 所以這里假設你有 `src/assets/scss/variables.scss` 這個文件
        data: `@import "@/assets/scss/variables.scss";`
      }
    } // css預設器配置項
  },

  2.TS報錯: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'LoginState'.  No index signature with a parameter of type 'string' was found on type 'LoginState'

// vue-cli3-tpl/src/store/module/login.ts
// 更改state
const mutations: MutationTree<LoginState> = {
  // 更新state都用該方法
  UPDATE_STATE(state: LoginState, data: LoginState) {
    for (const key in data) {
      if (!data.hasOwnProperty(key)) { return }
      state[key] = data[key] // TS7053錯誤
    }
  }
}

  我們在js中訪問對象時,[]中的name的類型必須是string,但是在ts中name的隱式類型為any,所以ts發現沒有類型是string的的索引標記。。。解決辦法:指定對象中key的類型

// vue-cli3-tpl/src/types/views/login.interface.ts
// VUEX login.State 參數類型
export interface LoginState {
  [key: string]: any
}

  最后貼下我 vuex-class 的使用:

// vue-cli3-tpl/src/store/index.ts
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// modules
import login from './module/login'
import index from './module/index'

export default new Vuex.Store({
  state: {
    //
  },
  mutations: {
    //
  },
  actions: {
    //
  },
  modules: {
    login,
    index
  }
})
// vue-cli3-tpl/src/store/module/login.ts
import { LoginState } from '@/types/views/login.interface'
import { GetterTree, MutationTree, ActionTree } from 'vuex'
import * as LoginApi from '@/api/login'

const state: LoginState = {
  author: 'edison',
  age: 18,
  obj: null
}

// 強制使用getter獲取state
const getters: GetterTree<LoginState, any> = {
  getAuthor: (state: LoginState) => state.author
}

// 更改state
const mutations: MutationTree<LoginState> = {
  // 更新state都用該方法
  UPDATE_STATE(state: LoginState, data: LoginState) {
    for (const key in data) {
      if (!data.hasOwnProperty(key)) { return }
      state[key] = data[key]
    }
  }
}

const actions: ActionTree<LoginState, any> = {
  UPDATE_STATE_ASYN({ commit, state: LoginState }, data: LoginState) {
    commit('UPDATE_STATE', data)
  },
  async GET_DATA_ASYN({ commit, state: LoginState }) {
    const result = await LoginApi.getData()
    commit('UPDATE_STATE', {'obj': result.data})
    return result.data
  }
}

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}
// vue-cli3-tpl/src/views/login/login.ts
import { Component, Vue } from "vue-property-decorator"
import {Getter, Action, namespace, State} from "vuex-class"
import { LoginData } from '@/types/views/login.interface'
import { Test } from "@/components" // 組件

const LoginModule = namespace('login')

@Component({
  components: {
    Test
  }
})
export default class About extends Vue {
  // Getter
  // @Getter login.author

  // Action
  // 和 @State("author") author 相同
  @LoginModule.State('author') author!: string
  // 直接映射 @State age
  @LoginModule.State age!: number
  @LoginModule.State obj!: any

  /**
   * state映射到組件時,是放在computed下的,因此本身為計算屬性
   * */
  // 只從state獲取
  @LoginModule.State(state => state.author) author1!: string
  // 從 state 和 getters 上獲取
  @LoginModule.State((state, getters) => state.author + getters.getAuthor) author2!: string

  // 內部使用namespace 如果不想在外部使用namespace,可以使用參數傳遞namespace
  @State('author', {namespace: 'login'}) author3!: string

  // Getter
  @Getter("login/getAuthor") getAuthor!:string;
  @Getter("getAuthor",{namespace:"login"}) getAuthor1!:string;
  @LoginModule.Getter('getAuthor') getAuthor2!:string;

  // Action
  @LoginModule.Action GET_DATA_ASYN!: Function
  @LoginModule.Action UPDATE_STATE_ASYN!: Function

  // data
  data: LoginData = {
    pageName: 'login'
  }

  created() {
    this.GET_DATA_ASYN()
      .then((data: any) => {
        console.log('data ', data)
        debugger
      })
    console.log('state用法')
    console.log('this.author ', this.author)
    console.log('this.author1 ', this.author1)
    console.log('this.author2 ', this.author2)
    console.log('this.author3 ', this.author3)
    console.log('getter用法')
    console.log('this.getAuthor ', this.getAuthor)
    console.log('this.getAuthor1 ', this.getAuthor1)
    console.log('this.getAuthor2 ', this.getAuthor2)
    console.log('this.age ', this.age)
    console.log('action用法')
    this.UPDATE_STATE_ASYN(
      {
        author: 'edison modified'
      }
    )
    console.log('modified author ', this.author)
  }

  activated() {
    //
  }

  mounted() {
    //
  }

  // 初始化函數
  init() {
    //
  }

}

  參考博文:如何使用 vue + typescript 編寫頁面 ( vuex裝飾器部分 )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM