【VUE3】vue3.0项目配置

vue3 + vite + TS + vue-router + vuex + less + 组合式API + 多语言vue-i18n

vue3安装

安装最新稳定版

$ npm install vue@next

用vite创建项目

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

根目录创建ts配置文件:tsconfig.json,并修改配置为

{
    "compilerOptions": {
        // TypeScript 默认会把代码编译为 ECMAScript 3
        // esnext 表示仅仅校验转换 TypeScript 类型,不进行语法编译
        "target": "esnext",
        "module": "esnext",
        // 开启严格模式,这使得对“this”的数据属性进行更严格的推断成为可能
        "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. 添加类型声明文件
    用来解决前面所说的报错
    创建文件:/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. 创建页面目录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. 创建路由文件/router.ts
import {createRouter, createWebHistory} from "vue-router";

// 懒加载:component的值是函数
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继续,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')

状态管理器配置vuex

  1. 安装
npm install vuex@next
  1. 创建文件
  • /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. 创建目录、文件

  • /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>

多语言配置完成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容