翘哥 發表於 2019-7-24 20:13:00

Vue Cli3 TypeScript 搭建工程

<p>  Vue Cli3出来也一段时间了,我想尝试下Vue结合TypeScript搭建个工程,感受下Vue下用TS...网上有一篇讲的非常详细的教程&nbsp;&nbsp;vue-cli3.0 搭建项目模版教程(ts+vuex+axios)&nbsp;作者:陈小生_1017</p>
<p>  我看完教程后(好长的一篇博文,不得不服作者的用心,赞!),我去博主留的git地址&nbsp;https://github.com/chenfangsheng/vue-cli3-tpl.git&nbsp;克隆一份下来,安装完依赖后,发现好多错误...汗...我在原博客评论区和git issue区均为发现问题的解决办法,我尝试着一番google后,项目能跑起来了,顺便研究了下vuex-class的用法,下面会贴出具体的用法。出现的错误有:</p>
<p>  1.引入scss的路径不对,按照下边改为相对路径就可以了</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue-cli3-tpl/src/components/test/test.vue </span>
<span style="color: rgba(0, 0, 0, 1)">
...
</span>&lt;style lang="scss"&gt;
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">@import "@/assets/scss/variables";</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@import </span>"../../assets/scss/variables"<span style="color: rgba(0, 0, 0, 1)">;

.test</span>-<span style="color: rgba(0, 0, 0, 1)">wrap {
    width: </span>100%<span style="color: rgba(0, 0, 0, 1)">;
    color: $background</span>-<span style="color: rgba(0, 0, 0, 1)">color;
}
</span>&lt;/style&gt;</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 0, 1)">// vue-cli3-tpl/src/assets/scss/variables.scss

$background-color : #4c94f1;</span></pre>
</div>
<p>  为了方便,我们引用scss全局变量,在每一个style标签引入这个公共变量文件太麻烦了,官方有全局引入的方法:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue.config.js</span>
<span style="color: rgba(0, 0, 0, 1)">css: {
    modules: </span><span style="color: rgba(0, 0, 255, 1)">false</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 启用 CSS modules</span>
    extract: <span style="color: rgba(0, 0, 255, 1)">true</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 是否使用css分离插件</span>
    sourceMap: <span style="color: rgba(0, 0, 255, 1)">true</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 开启 CSS source maps?</span>
<span style="color: rgba(0, 0, 0, 1)">    loaderOptions: {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 给 sass-loader 传递选项</span>
<span style="color: rgba(0, 0, 0, 1)">      sass: {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> @/ 是 src/ 的别名</span>
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 所以这里假设你有 `src/assets/scss/variables.scss` 这个文件</span>
      data: `@import "@/assets/scss/variables.scss"<span style="color: rgba(0, 0, 0, 1)">;`
      }
    } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> css预设器配置项</span>
},</pre>
</div>
<p>  2.TS报错:&nbsp;Element&nbsp;implicitly&nbsp;has&nbsp;an&nbsp;'any'&nbsp;type&nbsp;because&nbsp;expression&nbsp;of&nbsp;type&nbsp;'string'&nbsp;can't&nbsp;be&nbsp;used&nbsp;to&nbsp;index&nbsp;type&nbsp;'LoginState'.&nbsp; No&nbsp;index&nbsp;signature&nbsp;with&nbsp;a&nbsp;parameter&nbsp;of&nbsp;type&nbsp;'string'&nbsp;was&nbsp;found&nbsp;on&nbsp;type&nbsp;'LoginState'</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue-cli3-tpl/src/store/module/login.ts</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> 更改state</span>
const mutations: MutationTree&lt;LoginState&gt; =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 更新state都用该方法</span>
<span style="color: rgba(0, 0, 0, 1)">UPDATE_STATE(state: LoginState, data: LoginState) {
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (const key <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> data) {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!data.hasOwnProperty(key)) { <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> }
      state </span>= data <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TS7053错误</span>
<span style="color: rgba(0, 0, 0, 1)">    }
}
}</span></pre>
</div>
<p>  我们在js中访问对象时,[]中的name的类型必须是string,但是在ts中name的隐式类型为any,所以ts发现没有类型是string的的索引标记。。。解决办法:指定对象中key的类型</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue-cli3-tpl/src/types/views/login.interface.ts</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> VUEX login.State 参数类型</span>
<span style="color: rgba(0, 0, 0, 1)">export interface LoginState {
: any
}</span></pre>
</div>
<p>  最后贴下我&nbsp;vuex-class 的使用:<em id="__mceDel" style="font-family: &quot;Courier New&quot;; font-size: 12px"><br></em></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue-cli3-tpl/src/store/index.ts</span>
import Vue from 'vue'<span style="color: rgba(0, 0, 0, 1)">
import Vuex from </span>'vuex'<span style="color: rgba(0, 0, 0, 1)">

Vue.use(Vuex)

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> modules</span>
import login from './module/login'<span style="color: rgba(0, 0, 0, 1)">
import index from </span>'./module/index'<span style="color: rgba(0, 0, 0, 1)">

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Vuex.Store({
state: {
    </span><span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">},
mutations: {
    </span><span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">},
actions: {
    </span><span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">},
modules: {
    login,
    index
}
})</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue-cli3-tpl/src/store/module/login.ts</span>
import { LoginState } from '@/types/views/login.interface'<span style="color: rgba(0, 0, 0, 1)">
import { GetterTree, MutationTree, ActionTree } from </span>'vuex'<span style="color: rgba(0, 0, 0, 1)">
import </span>* as LoginApi from '@/api/login'<span style="color: rgba(0, 0, 0, 1)">

const state: LoginState </span>=<span style="color: rgba(0, 0, 0, 1)"> {
author: </span>'edison'<span style="color: rgba(0, 0, 0, 1)">,
age: </span>18<span style="color: rgba(0, 0, 0, 1)">,
obj: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 强制使用getter获取state</span>
const getters: GetterTree&lt;LoginState, any&gt; =<span style="color: rgba(0, 0, 0, 1)"> {
getAuthor: (state: LoginState) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> state.author
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 更改state</span>
const mutations: MutationTree&lt;LoginState&gt; =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 更新state都用该方法</span>
<span style="color: rgba(0, 0, 0, 1)">UPDATE_STATE(state: LoginState, data: LoginState) {
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (const key <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> data) {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!data.hasOwnProperty(key)) { <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> }
      state </span>=<span style="color: rgba(0, 0, 0, 1)"> data
    }
}
}

const actions: ActionTree</span>&lt;LoginState, any&gt; =<span style="color: rgba(0, 0, 0, 1)"> {
UPDATE_STATE_ASYN({ commit, state: LoginState }, data: LoginState) {
    commit(</span>'UPDATE_STATE'<span style="color: rgba(0, 0, 0, 1)">, data)
},
async GET_DATA_ASYN({ commit, state: LoginState }) {
    const result </span>=<span style="color: rgba(0, 0, 0, 1)"> await LoginApi.getData()
    commit(</span>'UPDATE_STATE', {'obj'<span style="color: rgba(0, 0, 0, 1)">: result.data})
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result.data
}
}

export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
namespaced: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
state,
getters,
mutations,
actions
}</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue-cli3-tpl/src/views/login/login.ts</span>
import { Component, Vue } from "vue-property-decorator"<span style="color: rgba(0, 0, 0, 1)">
import {Getter, Action, namespace, State} from </span>"vuex-class"<span style="color: rgba(0, 0, 0, 1)">
import { LoginData } from </span>'@/types/views/login.interface'<span style="color: rgba(0, 0, 0, 1)">
import { Test } from </span>"@/components" <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 组件</span>
<span style="color: rgba(0, 0, 0, 1)">
const LoginModule </span>= namespace('login'<span style="color: rgba(0, 0, 0, 1)">)

@Component({
components: {
    Test
}
})
export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class About extends Vue {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Getter</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> @Getter login.author</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Action</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 和 @State("author") author 相同</span>
@LoginModule.State('author') author!<span style="color: rgba(0, 0, 0, 1)">: string
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 直接映射 @State age</span>
@LoginModule.State age!<span style="color: rgba(0, 0, 0, 1)">: number
@LoginModule.State obj</span>!<span style="color: rgba(0, 0, 0, 1)">: any

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * state映射到组件时,是放在computed下的,因此本身为计算属性
   * </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 只从state获取</span>
@LoginModule.State(state =&gt; state.author) author1!<span style="color: rgba(0, 0, 0, 1)">: string
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从 state 和 getters 上获取</span>
@LoginModule.State((state, getters) =&gt; state.author + getters.getAuthor) author2!<span style="color: rgba(0, 0, 0, 1)">: string

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 内部使用namespace 如果不想在外部使用namespace,可以使用参数传递namespace</span>
@State('author', {namespace: 'login'}) author3!<span style="color: rgba(0, 0, 0, 1)">: string

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Getter</span>
@Getter("login/getAuthor") getAuthor!<span style="color: rgba(0, 0, 0, 1)">:string;
@Getter(</span>"getAuthor",{namespace:"login"}) getAuthor1!<span style="color: rgba(0, 0, 0, 1)">:string;
@LoginModule.Getter(</span>'getAuthor') getAuthor2!<span style="color: rgba(0, 0, 0, 1)">:string;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Action</span>
@LoginModule.Action GET_DATA_ASYN!<span style="color: rgba(0, 0, 0, 1)">: Function
@LoginModule.Action UPDATE_STATE_ASYN</span>!<span style="color: rgba(0, 0, 0, 1)">: Function

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> data</span>
data: LoginData =<span style="color: rgba(0, 0, 0, 1)"> {
    pageName: </span>'login'<span style="color: rgba(0, 0, 0, 1)">
}

created() {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.GET_DATA_ASYN()
      .then((data: any) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.log(</span>'data '<span style="color: rgba(0, 0, 0, 1)">, data)
      </span><span style="color: rgba(0, 0, 255, 1)">debugger</span><span style="color: rgba(0, 0, 0, 1)">
      })
    console.log(</span>'state用法'<span style="color: rgba(0, 0, 0, 1)">)
    console.log(</span>'this.author ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.author)
    console.log(</span>'this.author1 ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.author1)
    console.log(</span>'this.author2 ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.author2)
    console.log(</span>'this.author3 ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.author3)
    console.log(</span>'getter用法'<span style="color: rgba(0, 0, 0, 1)">)
    console.log(</span>'this.getAuthor ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getAuthor)
    console.log(</span>'this.getAuthor1 ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getAuthor1)
    console.log(</span>'this.getAuthor2 ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getAuthor2)
    console.log(</span>'this.age ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.age)
    console.log(</span>'action用法'<span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.UPDATE_STATE_ASYN(
      {
      author: </span>'edison modified'<span style="color: rgba(0, 0, 0, 1)">
      }
    )
    console.log(</span>'modified author ', <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.author)
}

activated() {
    </span><span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">}

mounted() {
    </span><span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 初始化函数</span>
<span style="color: rgba(0, 0, 0, 1)">init() {
    </span><span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">}

}</span></pre>
</div>
<p>  参考博文:如何使用 vue + typescript 编写页面 ( vuex装饰器部分 )</p><br><br>
来源:https://www.cnblogs.com/hanshuai/p/11240571.html
頁: [1]
查看完整版本: Vue Cli3 TypeScript 搭建工程