成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Vuex? 和 TypeScript 的 Webpack4.+ 嘗鮮

Astrian / 1168人閱讀

摘要:靜態(tài)類(lèi)型系統(tǒng)能幫助你有效防止許多潛在的運(yùn)行時(shí)錯(cuò)誤,而且隨著你的應(yīng)用日漸豐滿(mǎn)會(huì)更加顯著。選擇,會(huì)生成符合規(guī)范的文件,使用,會(huì)生成滿(mǎn)足規(guī)范的文件,使用會(huì)生成使用的的代碼。使用或者是會(huì)生產(chǎn)包含特性的代碼。

靜態(tài)類(lèi)型系統(tǒng)能幫助你有效防止許多潛在的運(yùn)行時(shí)錯(cuò)誤,而且隨著你的應(yīng)用日漸豐滿(mǎn)會(huì)更加顯著。這就是為什么 Vue 不僅僅為 Vue core 提供了針對(duì) TypeScript 的官方類(lèi)型聲明,還為 Vue Router 和 Vuex 也提供了相應(yīng)的聲明文件
TsConfig配置
{
    "compilerOptions": {
      // ts 文件編譯成 js 文件的時(shí)候,同時(shí)生成對(duì)應(yīng)的 map 文件
      "sourceMap": true,
      "strict": true,
      "strictNullChecks": true,
      // 當(dāng)表達(dá)式和申明 類(lèi)型為any時(shí),是否需要發(fā)出警告,設(shè)置true,則不警告
      "noImplicitAny": true,
      // 設(shè)置為true時(shí),如果不是函數(shù)中的所有路徑都有返回值,則提示Error
      "noImplicitReturns": true,
      // module 用于指定模塊的代碼生成規(guī)則,可以使用 commonjs 、 amd 、 umd 、 system 、 es6 、 es2015 、 none 這些選項(xiàng)。
      // 選擇commonJS,會(huì)生成符合commonjs規(guī)范的文件,使用amd,會(huì)生成滿(mǎn)足amd規(guī)范的文件,使用system會(huì)生成使用ES6的
      // system.import的代碼。使用es6或者是es2015會(huì)生產(chǎn)包含ES6特性的代碼。
      "module": "es2015",
      "moduleResolution": "node",
      // 設(shè)置為true時(shí),則允許從沒(méi)有默認(rèn)導(dǎo)出的模塊中默認(rèn)導(dǎo)入(也就是不做檢查)
      "allowSyntheticDefaultImports": true,
      // 設(shè)置為true,則支持ES7的裝飾器特性
      "experimentalDecorators": true,
      // target 用于指定生成代碼的兼容版本,可以從es3,es5,es2015,es6中選擇一個(gè),如果不設(shè)置,默認(rèn)生產(chǎn)的代碼兼容到es3
      "target": "es5"
    },
    "include": [
        "./src/**/*"
    ]
}

配置參考:

官方文檔tsconfig解析

tsconfig的JSON文檔

Webpack的基礎(chǔ)配置一覽

每個(gè)項(xiàng)目最重要的一部分個(gè)人感覺(jué)是webpack的配置,只有配置好webpack部分后續(xù)才能順利進(jìn)行開(kāi)發(fā)

這里webpack使用了4.+的版本,所以算是體驗(yàn)了較為新的webpack,其中和舊版的有些區(qū)別,這里不做介紹

先貼出webpack的配置代碼

const path = require("path")
const webpack = require("webpack")
const VueLoaderPlugin = require("vue-loader/lib/plugin")

module.exports = {
  mode: process.env.NODE_ENV === "production" ? "production" : "development",
  entry: "./src/index.ts",
  output: {
    path: path.resolve(__dirname, "./dist"),
    publicPath: "/dist/",
    filename: "build.js"
  },
  module: {
    rules: [
      {
        test: /.vue$/,
        loader: "vue-loader",
        options: {
          loaders: {
            "scss": "vue-style-loader!css-loader!sass-loader",
            "sass": "vue-style-loader!css-loader!sass-loader?indentedSyntax",
          }
        }
      },
      {
        test: /.tsx?$/,
        loader: "ts-loader",
        exclude: /node_modules/,
        options: {
          transpileOnly: true,
          appendTsSuffixTo: [/.vue$/]
        }
      }
    ]
  },
  resolve: {
    extensions: [".ts", ".js", ".vue", ".josn"],
    alias: {
      "vue$": "vue/dist/vue.esm.js"
    }
  },
  devServer: {
    contentBase: "./public",
    host: "localhost",
    port: "8080",
    open: true,
    hot: true,
    inline: true,
    historyApiFallback: true,
    noInfo: true
  },
  performance: {
    hints: false
  },
  devtool: "#eval-source-map",
  plugins: [
    new VueLoaderPlugin()
  ]
}

if (process.env.NODE_ENV === "production") {
  module.exports.devtool = "#source-map"
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: ""production""
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
} else {
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.HotModuleReplacementPlugin()
  ])
}

注意點(diǎn):

vue-loader v15需要在webpack插件中添加VueLoaderPlugin插件

webpack4.+需要指定mode,開(kāi)發(fā)模式還是生產(chǎn)模式

注意ts-loader的配置

這里只是簡(jiǎn)單進(jìn)行webpack配置,沒(méi)有太完整地根據(jù)完整的項(xiàng)目來(lái)進(jìn)行配置,只是簡(jiǎn)單配置了生產(chǎn)環(huán)境下的代碼混淆壓縮,以及對(duì)應(yīng)的開(kāi)發(fā)服務(wù)器和熱更新等,有需要其他功能擴(kuò)展的自行配置。

Vue環(huán)境搭建配置 vue-shims.d.ts的添加

這個(gè)是比較重要的一個(gè)配置,該文件需要放到vue的入口文件中,具體的d.ts代碼如下:

declare module "*.vue" {
  import Vue from "vue"
  export default Vue
}

目的是讓ts能夠識(shí)別到vue的靜態(tài)類(lèi)型

vue的入口文件

index.ts:

import Vue from "vue"
import App from "./App.vue"
// vuex部分
import store from "./store"

new Vue({
  el: "#app",
  store,
  render: h => h(App),
})

入口文件跟普通的js寫(xiě)法沒(méi)有太多的區(qū)別,只是文件類(lèi)型為ts。

開(kāi)始寫(xiě)vue的單文件頁(yè)面和組件 單文件頁(yè)面模板




主要是在script項(xiàng)中把lang寫(xiě)為ts類(lèi)型

使用裝飾器來(lái)實(shí)現(xiàn)組件和頁(yè)面

這里我們主要使用兩個(gè)裝飾器庫(kù)vue-property-decorator 和 vuex-class, vue-property-decorator其是基于vue-class-得component的基礎(chǔ)擴(kuò)展修改的。

大致了解一下vue-property-decorator的裝飾器的用法

一共有七個(gè)裝飾器:

@Emit

@Inject

@Model

@Prop

@Provide

@Watch

@Component (exported from vue-class-component)

這里使用vue-property-decorator的例子來(lái)做解析

import { Component, Emit, Inject, Model, Prop, Provide, Vue, Watch } from "vue-property-decorator"

const s = Symbol("baz")

@Component
export class MyComponent extends Vue {
  
  @Emit()
  addToCount(n: number){ this.count += n }

  @Emit("reset")
  resetCount(){ this.count = 0 }

  @Inject() foo: string
  @Inject("bar") bar: string
  @Inject({from: "optional", default: "default"}) optional: string
  @Inject(s) baz: string

  @Model("change") checked: boolean

  @Prop()
  propA: number

  @Prop({ default: "default value" })
  propB: string

  @Prop([String, Boolean])
  propC: string | boolean

  @Provide() foo = "foo"
  @Provide("bar") baz = "bar"

  @Watch("child")
  onChildChanged(val: string, oldVal: string) { }

  @Watch("person", { immediate: true, deep: true })
  onPersonChanged(val: Person, oldVal: Person) { }
}

相當(dāng)于js的寫(xiě)法:

const s = Symbol("baz")

export const MyComponent = Vue.extend({
  name: "MyComponent",
  inject: {
    foo: "foo",
    bar: "bar",
    "optional": { from: "optional", default: "default" },
    [s]: s
  },
  model: {
    prop: "checked",
    event: "change"
  },
  props: {
 ? ?checked: Boolean,
 ? ?propA: Number,
    propB: {
      type: String,
      default: "default value"
    },
    propC: [String, Boolean],
  },
  data () {
    return {
      foo: "foo",
      baz: "bar"
    }
  },
  provide () {
    return {
      foo: this.foo,
      bar: this.baz
    }
  },
  methods: {
    addToCount(n){
      this.count += n
      this.$emit("add-to-count", n)
    },
    resetCount(){
      this.count = 0
      this.$emit("reset")
    },
    onChildChanged(val, oldVal) { },
    onPersonChanged(val, oldVal) { }
  },
  watch: {
    "child": {
      handler: "onChildChanged",
      immediate: false,
      deep: false
    },
    "person": {
      handler: "onPersonChanged",
      immediate: true,
      deep: true
    }
  }
})

相信通過(guò)以上的例子我們很容易就看出各個(gè)裝飾器如何去使用,這里就不再做太多的解釋。

再看一下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

  @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"]
  }
}
Vuex的配置 store的入口
import Vue from "vue"
import Vuex, { StoreOptions } from "vuex"
import { RootState } from "./modules/types"
import { profile } from "./modules/profile"

Vue.use(Vuex)

const store: StoreOptions = {
  state: {
    version: "v1.0.0"
  },
  modules: {
    profile
  }
}

export default new Vuex.Store(store);

這里RootState只是用于留空,目的是為了注入全局的store,區(qū)別于modules的狀態(tài)

vuex的modules的配置

寫(xiě)一個(gè)全局類(lèi)型聲明

export interface RootState {
  version: string;
}

version字段就是我們剛才在RootState中定義的字段

定義模板profile

profile模塊的類(lèi)型聲明:

export interface ProfileState {
  firstName: string
  lastName: string
}

profile的模塊實(shí)現(xiàn):

import { RootState } from "../types"
import { Module } from "vuex"
import { ProfileState } from "./types"
import { GetterTree, ActionTree, MutationTree  } from "vuex"
import axios, { AxiosPromise } from "axios"

const state: ProfileState = {
  firstName: "",
  lastName: ""
}

const getters: GetterTree = {
  firstName(state) : string {
    return state.firstName
  },
  lastName(state) : string {
    return state.lastName
  }
}

const actions: ActionTree = {
  fetchName({ commit }, id: number): AxiosPromise {
    console.log("action:", id)
    return axios.request({
      url: "https://www.apiopen.top/satinCommentApi?id=27610708&page=1"
    }).then(res => {
      commit("setProfile", {
        firstName: "lin",
        lastName: "guangyu"
      })
      return res
    }).catch(err => {
      return err
    })
  }
}

const mutations: MutationTree = {
  setProfile(state, payload: ProfileState) {
    state.firstName = payload.firstName
    state.lastName = payload.lastName
  }
}

const namespaced: boolean = true;

export const profile: Module = {
  namespaced,
  state,
  getters,
  actions,
  mutations
};

這里我們就完成了Vuex的配置了,就可以結(jié)合裝飾器對(duì)vuex進(jìn)行調(diào)用,而且具有靜態(tài)類(lèi)型提示,十分方便。

完成了這一系列的配置我們的嘗試已經(jīng)完成,自己寫(xiě)了個(gè)簡(jiǎn)單的demo,有興趣可以觀看github怎么配置。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95289.html

相關(guān)文章

  • 前方來(lái)報(bào),八月最新資訊--關(guān)于vue2&3最佳文章推薦

    摘要:哪吒別人的看法都是狗屁,你是誰(shuí)只有你自己說(shuō)了才算,這是爹教我的道理。哪吒去他個(gè)鳥(niǎo)命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰(shuí)和你做朋友太乙真人人是否能夠改變命運(yùn),我不曉得。我只曉得,不認(rèn)命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...

    izhuhaodev 評(píng)論0 收藏0
  • 關(guān)于Vue2一些值得推薦文章 -- 五、六月份

    摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥(niǎo)雀呼晴,侵曉窺檐語(yǔ)。葉上初陽(yáng)乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門(mén),久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...

    sutaking 評(píng)論0 收藏0
  • 關(guān)于Vue2一些值得推薦文章 -- 五、六月份

    摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥(niǎo)雀呼晴,侵曉窺檐語(yǔ)。葉上初陽(yáng)乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門(mén),久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...

    khs1994 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<