【VUE3】vue3.0項目配置

vue3 + vite + TS + vue-router + vuex + less + 組合式API + 多語言vue-i18n

vue3安裝

安裝最新穩(wěn)定版

$ npm install vue@next

用vite創(chuàng)建項目

vite不需要單獨安裝

npm init vite-app my_project
cd my_project
npm install 
npm run dev
// 瀏覽器中打開localhost:3000,即可看到啟動的項目

TypeScript配置

vue3+vite+ts在配置過程中會報錯买乃,找不到App.vue模塊相應的類型聲明剪验,等配置完成即可解決功戚。

  1. /src/main.js啸臀,重命名為/src/main.ts
  2. /src/index.html烁落,引入的main.js伤塌,改成main.ts
  3. /src/App.vue每聪,<script> 修改為 <script lang="ts">
  4. 安裝TypeScript
$ npm install -D typescript

根目錄創(chuàng)建ts配置文件:tsconfig.json齿风,并修改配置為

{
    "compilerOptions": {
        // TypeScript 默認會把代碼編譯為 ECMAScript 3
        // esnext 表示僅僅校驗轉換 TypeScript 類型,不進行語法編譯
        "target": "esnext",
        "module": "esnext",
        // 開啟嚴格模式真屯,這使得對“this”的數(shù)據(jù)屬性進行更嚴格的推斷成為可能
        "strict": true,
        "jsx": "preserve",
        "moduleResolution": "node",
        "paths": {
            "/@/*": [
                "./src/*"
            ]
        },
        "lib": [
            "esnext",
            "dom",
            "dom.iterable",
            "scripthost"
        ]
    },
    "include": [
        "src/**/*.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "src/types/images.d.ts",
        "tests/**/*.ts",
        "tests/**/*.tsx"
    ],
    "exclude": [
        "node_modules"
    ]
}
  1. 添加類型聲明文件
    用來解決前面所說的報錯
    創(chuàng)建文件:/src/shims-vue.d.ts讨跟,并修改配置
// /src/shims-vue.d.ts
declare module '*.vue' {
    // Vue 3
    import { defineComponent } from 'vue'
    const Component: ReturnType<typeof defineComponent>
    export default Component
}

6 build時添加tsc校驗
/package.json茶袒,修改scripts.build的值為tsc --noEmit && vite build

"build": "tsc --noEmit && vite build"

ts配置完成

路徑別名設置

根目錄vite配置文件,

// vite.config.js
import {resolve} from "path";

export default {
    alias: {
        '/@/': resolve(__dirname, 'src'),
        '/@styles/': resolve(__dirname, 'src/assets/styles'),
        '/@components/': resolve(__dirname, 'src/components'),
        '/@pages/': resolve(__dirname, 'src/pages'),
        '/@store/': resolve(__dirname, 'src/store'),

    },
};
// tsconfig.json
{
    "compilerOptions": {
        /* Visit https://aka.ms/tsconfig.json to read more about this file */

        /* Basic Options */
        // "incremental": true,                         /* Enable incremental compilation */
        "target": "es5",
        /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
        "module": "commonjs",
        /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
        // "lib": [],                                   /* Specify library files to be included in the compilation. */
        // "allowJs": true,                             /* Allow javascript files to be compiled. */
        // "checkJs": true,                             /* Report errors in .js files. */
        // "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
        // "declaration": true,                         /* Generates corresponding '.d.ts' file. */
        // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
        // "sourceMap": true,                           /* Generates corresponding '.map' file. */
        // "outFile": "./",                             /* Concatenate and emit output to single file. */
        // "outDir": "./",                              /* Redirect output structure to the directory. */
        // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
        // "composite": true,                           /* Enable project compilation */
        // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
        // "removeComments": true,                      /* Do not emit comments to output. */
        // "noEmit": true,                              /* Do not emit outputs. */
        // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
        // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
        // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

        /* Strict Type-Checking Options */
        "strict": true,
        /* Enable all strict type-checking options. */
        // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */
        // "strictNullChecks": true,                    /* Enable strict null checks. */
        // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */
        // "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
        // "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */
        // "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */
        // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */

        /* Additional Checks */
        // "noUnusedLocals": true,                      /* Report errors on unused locals. */
        // "noUnusedParameters": true,                  /* Report errors on unused parameters. */
        // "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */
        // "noFallthroughCasesInSwitch": true,          /* Report errors for fallthrough cases in switch statement. */
        // "noUncheckedIndexedAccess": true,            /* Include 'undefined' in index signature results */
        // "noImplicitOverride": true,                  /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
        // "noPropertyAccessFromIndexSignature": true,  /* Require undeclared properties from index signatures to use element accesses. */

        /* Module Resolution Options */
        // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
        "baseUrl": "./",
        /* Base directory to resolve non-absolute module names. */
        "paths": {
            "/@/*": [
                "src/*"
            ],
            "/@styles/*": [
                "src/assets/styles/*"
            ],
            "/@pages/*": [
                "src/pages/*"
            ],
            "/@components/*": [
                "src/components/*"
            ],
            "/@store/*": [
                "src/store/*"
            ]
        },
        /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
        // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */
        // "typeRoots": [],                             /* List of folders to include type definitions from. */
        // "types": [],                                 /* Type declaration files to be included in compilation. */
        // "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
        "esModuleInterop": true,
        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
        // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */
        // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */

        /* Source Map Options */
        // "sourceRoot": "",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */
        // "mapRoot": "",                               /* Specify the location where debugger should locate map files instead of generated locations. */
        // "inlineSourceMap": true,                     /* Emit a single file with source maps instead of having a separate file. */
        // "inlineSources": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

        /* Experimental Options */
        // "experimentalDecorators": true,              /* Enables experimental support for ES7 decorators. */
        // "emitDecoratorMetadata": true,               /* Enables experimental support for emitting type metadata for decorators. */

        /* Advanced Options */
        "skipLibCheck": true,
        /* Skip type checking of declaration files. */
        "forceConsistentCasingInFileNames": true
        /* Disallow inconsistently-cased references to the same file. */
    },
    "include": [
        "src/**/*.ts",
        "src/**/*.d.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "src/**/*.less"
    ],
    "exclude": [
        "node_modules"
    ]
}

路由配置vue-router

采用模塊化路由配置

  1. 安裝路由
npm install vue-router@4
  1. 創(chuàng)建頁面目錄pages與頁面文件a.vue嗦董,b.vue
    script中加入lang='ts'
// a.vue
<template>
    <div>page-a</div>
</template>

<script lang="ts">
    export default {
        name: "a"
    }
</script>

<style scoped>

</style>
// b.vue
<template>
    <div>page-a</div>
</template>

<script lang="ts">
    export default {
        name: "b"
    }
</script>

<style scoped>

</style>
  1. 創(chuàng)建路由文件/router.ts
import {createRouter, createWebHistory} from "vue-router";

// 懶加載:component的值是函數(shù)
const routes = [
  {path: '/', component: () => import('./pages/a.vue')},
  {path: '/b', component: () => import('./pages/b.vue')}
]

const router = createRouter({
  history: createWebHistory(),
  routes,
  // 切換頁面后奇唤,返回頂部
  scrollBehavior() {
      return {top: 0}
  }
});

// 權限檢查
function canUserAccess(){
  return new Promise(resolve => {
      return resolve(true)
  })
}

router.beforeEach(async (to, from,next) => {
  // 獲取菜單咬扇、用戶信息廊勃、調用store等異步操作

  // 檢查權限,true繼續(xù)梭灿,false進入登錄
  let isAllow = await canUserAccess()
  isAllow ? next() : next({name:'login'})
})


export default router;
  1. 掛載到vue
    修改/main.ts
import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import './index.css'

const app = createApp(App);
app.use(router)
app.mount('#app')

狀態(tài)管理器配置vuex

  1. 安裝
npm install vuex@next
  1. 創(chuàng)建文件
  • /src/store/index.ts
    */src/store/modules/users.store.ts

````js
// /src/store/index.ts
import {createStore, useStore as baseUseStore, Store} from "vuex";
import {InjectionKey} from 'vue'

export interface State {
    count: number,
    name: string
}

export const key: InjectionKey<Store<State>> = Symbol();


const state = {
    count: 0,
    name: 'cq'
}

const getters = {
    name1(state: State) {
        return state.name
    }
}

const mutations = {
    increase(state:State){
        state.count++
    }
}

const actions = {
    // @ts-ignore
    add({commit}){
        commit('increase');
    }
}

export const store = createStore<State>({
    state,
    getters,
    mutations,
    actions,
})

export function useStore() {
    return baseUseStore(key)
}
// /src/store/modules/users.store.ts
interface IState {}

const state:IState = {}
const getters = {}

const mutations = {}

const  actions = {}

export default {
    state,
    getters,
    mutations,
    actions
}

  1. 修改main

import { createApp } from 'vue'
import router from './router'
import {store,key} from './store/index'
import App from './App.vue'
import './index.css'

const app = createApp(App);
app.use(router)
app.use(store,key)
app.mount('#app')

Less

  1. 安裝
npm install less less-loader --dev
  1. style標簽加入lang=less
<style lang='less'></style>

未解決的問題:
同一個文件使用@import導入兩個文件,第二個失效

多語言vue-i18n

1. 安裝

npm install vue-i18n@next

2. 創(chuàng)建目錄涕蚤、文件

  • /src/language/zh.language/index.ts 中文語言包的輸出文件
  • /src/language/zh.language/modules/home-page.language.ts 將內容通過模塊劃分万栅,一個模塊一個文件
  • /src/language/en.language/index.ts
  • /src/language/en.language/modules/home-page.language.ts
  • /src/language/index.ts 整個語言包的輸出文件
// /src/language/zh.language/index.ts
import home_page from './modules/home-page.language'

export default {
    example: '語言包示例',
    home_page
}
// /src/language/zh.language/modules/home-page.language.ts
export default {
    title:'首頁',
    // 一個component一個對象
    navs:{
        list:[],
        name:'nav list'
    },

}
// /src/language/zh.language/modules/home-page.language.ts
import home_page from './modules/home-page.language'
export default {
    example: 'language package example',
    home_page
}
// /src/language/en.language/modules/home-page.language.ts
export default {
    title:'home page',
    navs:{
        list:[],
        name:'nav list'
    }
}
// /src/language/index.ts
import {createI18n} from "vue-i18n";

import zh from './zh.language/index'
import en from './en.language/index'

const messages = {zh, en}

// 判斷當前瀏覽器是哪種語言
const language = (
    (navigator.language
        ? navigator.language
        // @ts-ignore
        : navigator.userLanguage)
    || 'zh'
).toLowerCase();

const i18n = createI18n({
    fallbackLocale: 'zh',
    globalInjection: true,
    legacy: false,
    locale: language.split("-")[0] || 'zh',
    messages
})

export default i18n;

3. 引入vue

在mian.ts中引入語言包

import i18n from "/@/language/index";
app.use(i18n);

4. vue頁面中使用

<div>
{{$t(`example`)}} 
{{$t(`home_page.title`)}}
</div>

多語言配置完成

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末代赁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子徒役,更是在濱河造成了極大的恐慌忧勿,老刑警劉巖瞻讽,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晌砾,死亡現(xiàn)場離奇詭異烦磁,居然都是意外死亡,警方通過查閱死者的電腦和手機乖寒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門楣嘁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逐虚,“玉大人叭爱,你說我怎么就攤上這事÷蛭恚” “怎么了漓穿?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵晃危,是天一觀的道長僚饭。 經(jīng)常有香客問我鳍鸵,道長,這世上最難降的妖魔是什么钓简? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮古掏,結果婚禮上槽唾,老公的妹妹穿的比我還像新娘。我一直安慰自己拧烦,他們只是感情好恋博,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布债沮。 她就那樣靜靜地躺著疫衩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荣德。 梳的紋絲不亂的頭發(fā)上闷煤,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天童芹,我揣著相機與錄音,去河邊找鬼鲤拿。 笑死辐脖,一個胖子當著我的面吹牛,可吹牛的內容都是我干的皆愉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼艇抠,長吁一口氣:“原來是場噩夢啊……” “哼幕庐!你這毒婦竟也來了?” 一聲冷哼從身側響起家淤,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎督怜,沒想到半個月后丰歌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眼溶,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡宵蕉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了讳窟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情遥诉,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布惫霸,位于F島的核電站猜丹,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜艾疟,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柑司,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽悠垛。三九已至纱皆,卻和暖如春搀缠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勿侯。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人葱轩。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像偎窘,于是被迫代替她去往敵國和親纵诞。 傳聞我的和親對象是個殘疾皇子籽腕,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內容