1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Vite2 + Vue3 + TypeScript + Pinia 搭建一套企業(yè)級的開發(fā)腳手架

        共 34757字,需瀏覽 70分鐘

         ·

        2021-12-16 21:11


        前端學(xué)習(xí)路線一條龍【內(nèi)含入門到進階到高級精選資源】無套路獲?。。?!

        前端小菜雞之菜雞互啄,公眾號:前端開發(fā)愛好者xy哥怒肝,前端學(xué)習(xí)路線一條龍【內(nèi)含入門到進階到高級精選資源】無套路獲?。。?!

        哈嘍,大家好 我是xy???????。從我最初接觸vue3版本到現(xiàn)在已經(jīng)有一年的時間。由于 vue3.2 版本的發(fā)布,<script setup> 的實驗性標志已經(jīng)去掉,已經(jīng)陸陸續(xù)續(xù)有不少公司開始使用 vue3.2開發(fā)項目了。這篇文章就來幫助大家如何快速使用 vue3.xtypeScript, vite 搭建一套企業(yè)級的開發(fā)腳手架 ??。廢話不多說,直接上手開搞 ??

        搭建前準備

        1. Vscode: 前端人必備寫碼神器
        2. Chrome:對開發(fā)者非常友好的瀏覽器(反正我是很依賴它的)
        3. Nodejs&npm:配置本地開發(fā)環(huán)境,安裝 Node 后你會發(fā)現(xiàn) npm 也會一起安裝下來
        4. Vue.js devtools:瀏覽器調(diào)試插件
        5. Vue Language Features (Volar):Vscode 開發(fā) vue3 必備插件,提供語法高亮提示,非常好用
        6. Vue 3 Snippets:vue3 快捷輸入

        由于Vue.js devtools 需要到谷歌擴展商店才能下載,貼心 ?? 的xy已經(jīng)為大家準備好了crx文件了,公眾號回復(fù):【VueDevTools】可自動獲取哦 ??

        Vue2 與 Vue3 的區(qū)別

        Vue3由于完全由TS進行重寫,在應(yīng)用中對類型判斷的定義和使用有很強的表現(xiàn)。同一對象的多個鍵返回值必須通過定義對應(yīng)的接口(interface)來進行類型定義。要不然在 ESLint 時都會報錯。

        vue2 的雙向數(shù)據(jù)綁定是利用 ES5 的一個 API Object.definePropert()對數(shù)據(jù)進行劫持 結(jié)合 發(fā)布訂閱模式的方式來實現(xiàn)的。Vue3 中使用了 es6ProxyAPI 對數(shù)據(jù)代理。

        Vue3支持碎片(Fragments)

        Vue2 與 Vue3 最大的區(qū)別: Vue2 使用Options API而 Vue3 使用的Composition API

        生命周期鉤子變化:

        Vue2 ~~~~~~~~~~~ vue3
        beforeCreate  -> setup()
        created       -> setup()
        beforeMount   -> onBeforeMount
        mounted       -> onMounted
        beforeUpdate  -> onBeforeUpdate
        updated       -> onUpdated
        beforeDestroy -> onBeforeUnmount
        destroyed     -> onUnmounted
        activated     -> onActivated
        deactivated   -> onDeactivated

        介紹 vite

        Vite:下一代前端開發(fā)與構(gòu)建工具

        • ?? 極速的開發(fā)服務(wù)器啟動
        • ?? 輕量快速的熱模塊重載(HMR)
        • ??? 豐富的功能
        • ?? 自帶優(yōu)化的構(gòu)建
        • ?? 通用的插件接口
        • ?? 完全類型化的 API

        Vite (法語意為 “迅速”,發(fā)音 /vit/)是一種全新的前端構(gòu)建工具,它極大地改善了前端開發(fā)體驗。

        它主要由兩部分組成:

        • 一個開發(fā)服務(wù)器,它基于 原生 ES 模塊 提供了 豐富的內(nèi)建功能,如速度快到驚人的 模塊熱更新(HMR)。

        • 一套構(gòu)建指令,它使用 Rollup 打包你的代碼,并且它是預(yù)配置的,可以輸出用于生產(chǎn)環(huán)境的優(yōu)化過的靜態(tài)資源。

        • Vite 意在提供開箱即用的配置,同時它的 插件 API 和 JavaScript API 帶來了高度的可擴展性,并有完整的類型支持。

        使用 vite 快速創(chuàng)建腳手架

        兼容性注意:Vite 需要 Node.js 版本 >= 12.0.0

        1. 第一步: 在需要創(chuàng)建項目文件目錄下打開 cmd 運行以下命令
        # npm 6.x
        npm init @vitejs/app vite_vue3_ts --template

        # npm 7+, 需要額外的雙橫線:
        npm init @vitejs/app vite_vue3_ts -- --template

        # yarn
        yarn create @vitejs/app vite_vue3_ts --template

        這里我采用 yarn 來安裝

        1. 第二步: 選擇 vue回車 => vue-ts回車

        1. 第三步: cd 到項目文件夾,安裝依賴,啟動項目
        # 進入項目文件夾
        cd vite_vue3_ts
        # 安裝依賴
        yarn
        # 啟動
        yarn dev

        約束代碼風(fēng)格

        Eslint 支持

        # eslint 安裝
        yarn add eslint --dev
        # eslint 插件安裝
        yarn add eslint-plugin-vue --dev

        yarn add @typescript-eslint/eslint-plugin --dev

        yarn add eslint-plugin-prettier --dev

        # typescript parser
        yarn add @typescript-eslint/parser --dev

        注意: 如果 eslint 安裝報錯:

        可以嘗試運行以下命令:

        yarn config set ignore-engines true

        運行成功后再次執(zhí)行 eslint 安裝命令

        項目下新建 .eslintrc.js

        配置 eslint 校驗規(guī)則:

        module.exports = {
          roottrue,
          env: {
            browsertrue,
            nodetrue,
            es2021true,
          },
          parser'vue-eslint-parser',
          extends: [
            'eslint:recommended',
            'plugin:vue/vue3-recommended',
            'plugin:@typescript-eslint/recommended',
            'plugin:prettier/recommended',
            // eslint-config-prettier 的縮寫
            'prettier',
          ],
          parserOptions: {
            ecmaVersion12,
            parser'@typescript-eslint/parser',
            sourceType'module',
            ecmaFeatures: {
              jsxtrue,
            },
          },
          // eslint-plugin-vue @typescript-eslint/eslint-plugin eslint-plugin-prettier的縮寫
          plugins: ['vue''@typescript-eslint''prettier'],
          rules: {
            '@typescript-eslint/ban-ts-ignore''off',
            '@typescript-eslint/no-unused-vars''off',
            '@typescript-eslint/explicit-function-return-type''off',
            '@typescript-eslint/no-explicit-any''off',
            '@typescript-eslint/no-var-requires''off',
            '@typescript-eslint/no-empty-function''off',
            '@typescript-eslint/no-use-before-define''off',
            '@typescript-eslint/ban-ts-comment''off',
            '@typescript-eslint/ban-types''off',
            '@typescript-eslint/no-non-null-assertion''off',
            '@typescript-eslint/explicit-module-boundary-types''off',
            'no-var''error',
            'prettier/prettier''error',
            // 禁止出現(xiàn)console
            'no-console''warn',
            // 禁用debugger
            'no-debugger''warn',
            // 禁止出現(xiàn)重復(fù)的 case 標簽
            'no-duplicate-case''warn',
            // 禁止出現(xiàn)空語句塊
            'no-empty''warn',
            // 禁止不必要的括號
            'no-extra-parens''off',
            // 禁止對 function 聲明重新賦值
            'no-func-assign''warn',
            // 禁止在 return、throw、continue 和 break 語句之后出現(xiàn)不可達代碼
            'no-unreachable''warn',
            // 強制所有控制語句使用一致的括號風(fēng)格
            curly'warn',
            // 要求 switch 語句中有 default 分支
            'default-case''warn',
            // 強制盡可能地使用點號
            'dot-notation''warn',
            // 要求使用 === 和 !==
            eqeqeq'warn',
            // 禁止 if 語句中 return 語句之后有 else 塊
            'no-else-return''warn',
            // 禁止出現(xiàn)空函數(shù)
            'no-empty-function''warn',
            // 禁用不必要的嵌套塊
            'no-lone-blocks''warn',
            // 禁止使用多個空格
            'no-multi-spaces''warn',
            // 禁止多次聲明同一變量
            'no-redeclare''warn',
            // 禁止在 return 語句中使用賦值語句
            'no-return-assign''warn',
            // 禁用不必要的 return await
            'no-return-await''warn',
            // 禁止自我賦值
            'no-self-assign''warn',
            // 禁止自身比較
            'no-self-compare''warn',
            // 禁止不必要的 catch 子句
            'no-useless-catch''warn',
            // 禁止多余的 return 語句
            'no-useless-return''warn',
            // 禁止變量聲明與外層作用域的變量同名
            'no-shadow''off',
            // 允許delete變量
            'no-delete-var''off',
            // 強制數(shù)組方括號中使用一致的空格
            'array-bracket-spacing''warn',
            // 強制在代碼塊中使用一致的大括號風(fēng)格
            'brace-style''warn',
            // 強制使用駱駝拼寫法命名約定
            camelcase'warn',
            // 強制使用一致的縮進
            indent'off',
            // 強制在 JSX 屬性中一致地使用雙引號或單引號
            // 'jsx-quotes': 'warn',
            // 強制可嵌套的塊的最大深度4
            'max-depth''warn',
            // 強制最大行數(shù) 300
            // "max-lines": ["warn", { "max": 1200 }],
            // 強制函數(shù)最大代碼行數(shù) 50
            // 'max-lines-per-function': ['warn', { max: 70 }],
            // 強制函數(shù)塊最多允許的的語句數(shù)量20
            'max-statements': ['warn'100],
            // 強制回調(diào)函數(shù)最大嵌套深度
            'max-nested-callbacks': ['warn'3],
            // 強制函數(shù)定義中最多允許的參數(shù)數(shù)量
            'max-params': ['warn'3],
            // 強制每一行中所允許的最大語句數(shù)量
            'max-statements-per-line': ['warn', { max1 }],
            // 要求方法鏈中每個調(diào)用都有一個換行符
            'newline-per-chained-call': ['warn', { ignoreChainWithDepth3 }],
            // 禁止 if 作為唯一的語句出現(xiàn)在 else 語句中
            'no-lonely-if''warn',
            // 禁止空格和 tab 的混合縮進
            'no-mixed-spaces-and-tabs''warn',
            // 禁止出現(xiàn)多行空行
            'no-multiple-empty-lines''warn',
            // 禁止出現(xiàn);
            semi: ['warn''never'],
            // 強制在塊之前使用一致的空格
            'space-before-blocks''warn',
            // 強制在 function的左括號之前使用一致的空格
            // 'space-before-function-paren': ['warn', 'never'],
            // 強制在圓括號內(nèi)使用一致的空格
            'space-in-parens''warn',
            // 要求操作符周圍有空格
            'space-infix-ops''warn',
            // 強制在一元操作符前后使用一致的空格
            'space-unary-ops''warn',
            // 強制在注釋中 // 或 /* 使用一致的空格
            // "spaced-comment": "warn",
            // 強制在 switch 的冒號左右有空格
            'switch-colon-spacing''warn',
            // 強制箭頭函數(shù)的箭頭前后使用一致的空格
            'arrow-spacing''warn',
            'no-var''warn',
            'prefer-const''warn',
            'prefer-rest-params''warn',
            'no-useless-escape''warn',
            'no-irregular-whitespace''warn',
            'no-prototype-builtins''warn',
            'no-fallthrough''warn',
            'no-extra-boolean-cast''warn',
            'no-case-declarations''warn',
            'no-async-promise-executor''warn',
          },
          globals: {
            defineProps'readonly',
            defineEmits'readonly',
            defineExpose'readonly',
            withDefaults'readonly',
          },
        }

        項目下新建 .eslintignore

        # eslint 忽略檢查 (根據(jù)項目需要自行添加)
        node_modules
        dist

        prettier 支持

        # 安裝 prettier
        yarn add prettier --dev

        解決 eslint 和 prettier 沖突

        解決 ESLint 中的樣式規(guī)范和 prettier 中樣式規(guī)范的沖突,以 prettier 的樣式規(guī)范為準,使 ESLint 中的樣式規(guī)范自動失效

        # 安裝插件 eslint-config-prettier
        yarn add eslint-config-prettier --dev

        項目下新建 .prettier.js

        配置 prettier 格式化規(guī)則:

        module.exports = {
          tabWidth2,
          jsxSingleQuotetrue,
          jsxBracketSameLinetrue,
          printWidth100,
          singleQuotetrue,
          semifalse,
          overrides: [
            {
              files'*.json',
              options: {
                printWidth200,
              },
            },
          ],
          arrowParens'always',
        }

        項目下新建 .prettierignore

        # 忽略格式化文件 (根據(jù)項目需要自行添加)
        node_modules
        dist

        package.json 配置:

        {
          "script": {
            "lint""eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx",
            "prettier""prettier --write ."
          }
        }

        上面配置完成后,可以運行以下命令測試下代碼檢查個格式化效果:

        # eslint 檢查
        yarn lint
        # prettier 自動格式化
        yarn prettier

        配置 husky + lint-staged

        使用husky + lint-staged助力團隊編碼規(guī)范, husky&lint-staged 安裝推薦使用 mrm, 它將根據(jù) package.json 依賴項中的代碼質(zhì)量工具來安裝和配置 husky 和 lint-staged,因此請確保在此之前安裝并配置所有代碼質(zhì)量工具,如 Prettier 和 ESlint

        首先安裝 mrm

        npm i mrm -D --registry=https://registry.npm.taobao.org

        husky 是一個為 git 客戶端增加 hook 的工具。安裝后,它會自動在倉庫中的 .git/ 目錄下增加相應(yīng)的鉤子;比如 pre-commit 鉤子就會在你執(zhí)行 git commit 的觸發(fā)。

        那么我們可以在 pre-commit 中實現(xiàn)一些比如 lint 檢查單元測試、代碼美化等操作。當然,pre-commit 階段執(zhí)行的命令當然要保證其速度不要太慢,每次 commit 都等很久也不是什么好的體驗。

        lint-staged,一個僅僅過濾出 Git 代碼暫存區(qū)文件(被 git add 的文件)的工具;這個很實用,因為我們?nèi)绻麑φ麄€項目的代碼做一個檢查,可能耗時很長,如果是老項目,要對之前的代碼做一個代碼規(guī)范檢查并修改的話,這可能就麻煩了呀,可能導(dǎo)致項目改動很大。

        所以這個 lint-staged,對團隊項目和開源項目來說,是一個很好的工具,它是對個人要提交的代碼的一個規(guī)范和約束

        安裝 lint-staged

        mrm 安裝 lint-staged自動husky 一起安裝下來

        npx mrm lint-staged

        安裝成功后會發(fā)現(xiàn) package.json 中多了一下幾個配置:

        因為我們要結(jié)合 prettier 代碼格式化,所有修改一下配置:

        "husky": {
            "hooks": {
              "pre-commit""lint-staged"
            }
          },
          "lint-staged": {
            "*.{js,jsx,vue,ts,tsx}": [
              "yarn lint",
              "prettier --write",
              "git add"
            ]
          }

        好了,到這里代碼格式化配置基本大功告成了!!!

        可以修改部分代碼嘗試 git commit ,你會發(fā)現(xiàn)代碼將自動格式化:

        提交前的代碼(發(fā)現(xiàn)編輯器爆紅了):

        執(zhí)行 commit 操作,控制臺可以看到走了哪些流程:

        commit 后的代碼,是不是已經(jīng)被格式化了

        配置文件引用別名 alias

        直接修改 vite.config.ts 文件配置:

        import { defineConfig } from 'vite'
        import vue from '@vitejs/plugin-vue'
        import path from 'path'

        // https://vitejs.dev/config/
        export default defineConfig({
          plugins: [vue()],
          resolve: {
            alias: {
              '@': path.resolve(__dirname, 'src'),
            },
          },
        })

        修改 tsconfig.json

        {
          "compilerOptions": {
            "target""esnext",
            "module""esnext",
            "moduleResolution""node",
            "strict"true,
            "jsx""preserve",
            "sourceMap"true,
            "resolveJsonModule"true,
            "esModuleInterop"true,
            "lib": ["esnext""dom"],
            "baseUrl"".",
            "paths": {
              "@/*":["src/*"]
            }
          },
          "include": ["src/**/*.ts""src/**/*.d.ts""src/**/*.tsx""src/**/*.vue"]
        }

        配置 css 預(yù)處理器 scss

        雖然 vite 原生支持 less/sass/scss/stylus,但是你必須手動安裝他們的預(yù)處理器依賴

        安裝

        yarn ass sass-loader --dev
        yarn add dart-sass --dev
        yarn add sass --dev

        配置全局 scss 樣式文件

        src/assets 下新增 style 文件夾,用于存放全局樣式文件

        新建 main.scss, 設(shè)置一個用于測試的顏色變量 :

        $test-color: red;

        如何將這個全局樣式文件全局注入到項目中呢?配置 Vite 即可:

        css:{
            preprocessorOptions:{
              scss:{
                additionalData:'@import "@/assets/style/mian.scss";'
              }
            }
          },

        組件中使用

        不需要任何引入可以直接使用全局scss定義的變量

        .test{
        color: $test-color;
        }

        路由

        # 安裝路由
        yarn add vue-router@4

        src 文件下新增 router 文件夾 => router.ts 文件,內(nèi)容如下:

        import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

        const routes: RouteRecordRaw[] = [
          {
            path'/',
            name'Login',
            component() => import('@/pages/login/Login.vue'), // 注意這里要帶上 文件后綴.vue
          },
        ]

        const router = createRouter({
          history: createWebHistory(),
          routes,
        })

        export default router

        修改入口文件 mian.ts :

        import { createApp } from 'vue'
        import App from './App.vue'
        import router from './router/index'

        const app = createApp(App)

        app.use(router)

        app.mount('#app')

        到這里路由的基礎(chǔ)配置已經(jīng)完成了,更多配置信息可以查看 vue-router 官方文檔:

        vue-router: https://next.router.vuejs.org/zh/guide/

        vue-router4.x 支持 typescript,配置路由的類型是 RouteRecordRaw,這里 meta 可以讓我們有更多的發(fā)揮空間,這里提供一些參考:

        • title:string; 頁面標題,通常必選。
        • icon?:string; 圖標,一般配合菜單使用。
        • auth?:boolean; 是否需要登錄權(quán)限。
        • ignoreAuth?:boolean; 是否忽略權(quán)限。
        • roles?:RoleEnum[]; 可以訪問的角色
        • keepAlive?:boolean; 是否開啟頁面緩存
        • hideMenu?:boolean; 有些路由我們并不想在菜單中顯示,比如某些編輯頁面。
        • order?:number; 菜單排序。
        • frameUrl?:string; 嵌套外鏈。

        這里只提供一些思路,每個項目涉及到的業(yè)務(wù)都會存在些差異,這里就不作詳細講解了,根據(jù)自己業(yè)務(wù)需求做配置即可。

        統(tǒng)一請求封裝

        使用過 vue2.x 的同學(xué)應(yīng)該對 axios 很熟悉了,這里我們直接使用 axios 做封裝:

        # 安裝 axios
        yarn add axios
        # 安裝 nprogress 用于請求 loading
        # 也可以根據(jù)項目需求自定義其它 loading
        yarn add nprogress
        # 類型聲明,或者添加一個包含 `declare module 'nprogress'
        yarn add @types/nprogress --dev

        實際使用中可以根據(jù)項目修改,比如RESTful api中可以自行添加putdelete請求,ResType也可以根據(jù)后端的通用返回值動態(tài)的去修改

        新增 service 文件夾,service 下新增 http.ts 文件以及 api 文件夾:

        http.ts : 用于axios封裝

        //http.ts
        import axios, { AxiosRequestConfig } from 'axios'
        import NProgress from 'nprogress'

        // 設(shè)置請求頭和請求路徑
        axios.defaults.baseURL = '/api'
        axios.defaults.timeout = 10000
        axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
        axios.interceptors.request.use(
          (config): AxiosRequestConfig<any> => {
            const token = window.sessionStorage.getItem('token')
            if (token) {
              //@ts-ignore
              config.headers.token = token
            }
            return config
          },
          (error) => {
            return error
          }
        )
        // 響應(yīng)攔截
        axios.interceptors.response.use((res) => {
          if (res.data.code === 111) {
            sessionStorage.setItem('token''')
            // token過期操作
          }
          return res
        })

        interface ResType<T> {
          code: number
          data?: T
          msg: string
          err?: string
        }
        interface Http {
          get<T>(url: string, params?: unknown): Promise<ResType<T>>
          post<T>(url: string, params?: unknown): Promise<ResType<T>>
          upload<T>(url: string, params: unknown): Promise<ResType<T>>
          download(url: string): void
        }

        const http: Http = {
          get(url, params) {
            return new Promise((resolve, reject) => {
              NProgress.start()
              axios
                .get(url, { params })
                .then((res) => {
                  NProgress.done()
                  resolve(res.data)
                })
                .catch((err) => {
                  NProgress.done()
                  reject(err.data)
                })
            })
          },
          post(url, params) {
            return new Promise((resolve, reject) => {
              NProgress.start()
              axios
                .post(url, JSON.stringify(params))
                .then((res) => {
                  NProgress.done()
                  resolve(res.data)
                })
                .catch((err) => {
                  NProgress.done()
                  reject(err.data)
                })
            })
          },
          upload(url, file) {
            return new Promise((resolve, reject) => {
              NProgress.start()
              axios
                .post(url, file, {
                  headers: { 'Content-Type''multipart/form-data' },
                })
                .then((res) => {
                  NProgress.done()
                  resolve(res.data)
                })
                .catch((err) => {
                  NProgress.done()
                  reject(err.data)
                })
            })
          },
          download(url) {
            const iframe = document.createElement('iframe')
            iframe.style.display = 'none'
            iframe.src = url
            iframe.onload = function ({
              document.body.removeChild(iframe)
            }
            document.body.appendChild(iframe)
          },
        }
        export default http

        api : 項目中接口做統(tǒng)一管理,按照模塊來劃分

        api 文件下新增 login 文件夾,用于存放登錄模塊的請求接口,login 文件夾下分別新增 login.ts types.ts :

        login.ts:

        import http from '@/service/http'
        import * as T from './types'

        const loginApi: T.ILoginApi = {
            login(params){
                return http.post('/login', params)
            }

        }
        export default loginApi

        types.ts:

        export interface ILoginParams {
            userName: string
            passWord: string | number
        }
        export interface ILoginApi {
            login: (params: ILoginParams)=> Promise<any>
        }

        至此,一個簡單地請求封裝完成了!!!!

        除了自己手動封裝 axios ,這里還推薦一個 vue3 的請求庫: VueRequest,非常好用,下面來看看 VueRequest有哪些比較好用的功能吧!!!

        • ?? 所有數(shù)據(jù)都具有響應(yīng)式
        • ?? 輪詢請求
        • ?? 自動處理錯誤重試
        • ?? 內(nèi)置請求緩存
        • ?? 節(jié)流請求與防抖請求
        • ?? 聚焦頁面時自動重新請求
        • ?? 強大的分頁擴展以及加載更多擴展
        • ?? 完全使用 Typescript 編寫,具有強大的類型提示
        • ?? 兼容 Vite
        • ?? 輕量化
        • ?? 開箱即用

        是不是很強大 ??

        官網(wǎng)鏈接: https://www.attojs.com/

        狀態(tài)管理 pinia

        由于 vuex 4 對 typescript 的支持讓人感到難過,所以狀態(tài)管理棄用了 vuex 而采取了 pinia. pinia 的作者是 Vue 核心團隊成員

        尤大好像說 pinia 可能會代替 vuex,所以請放心使用。

        安裝 pinia

        Pinia 與 Vuex 的區(qū)別:

        • id 是必要的,它將所使用 store 連接到 devtools。
        • 創(chuàng)建方式:new Vuex.Store(...)(vuex3),createStore(...)(vuex4)。
        • 對比于 vuex3 ,state 現(xiàn)在是一個函數(shù)返回對象
        • 沒有 mutations,不用擔(dān)心,state 的變化依然記錄在 devtools 中。
        # 安裝
        yarn add pinia@next

        main.ts 中增加

        # 引入
        import { createPinia } from "pinia"
        # 創(chuàng)建根存儲庫并將其傳遞給應(yīng)用程序
        app.use(createPinia())

        src 文件夾下新增 store 文件夾,接在在 store 中新增 main.ts

        創(chuàng)建 store, mian.ts :

        import { defineStore } from 'pinia'

        export const useMainStore = defineStore({
          id'mian',
          state() =>({
            name'超級管理員'
          })
        })

        組建中獲取 store :

        <template>
          <div>{{mainStore.name}}</div>
        </template>

        <script setup lang="ts">
        import { useMainStore } from "@/
        store/mian"

        const mainStore = useMainStore()

        </script>

        getters 用法介紹

        Pinia 中的 getter 與 Vuex 中的 getter 、組件中的計算屬性具有相同的功能

        store => mian.ts

        import { defineStore } from 'pinia'

        export const useMainStore = defineStore({
          id'mian',
          state() => ({
            name'超級管理員',
          }),
          // getters
          getters: {
            nameLength(state) => state.name.length,
          }
        })

        組件中使用:

        <template>
          <div>用戶名:{{ mainStore.name }}<br />長度:{{ mainStore.nameLength }}</div>
          <hr/>
          <button @click="updateName">修改store中的name</button>
        </template>

        <script setup lang="ts">
        import { useMainStore } from '@/
        store/mian'

        const mainStore = useMainStore()

        const updateName = ()=>{
          // $patch 修改 store 中的數(shù)據(jù)
          mainStore.$patch({
            name: '
        名稱被修改了,nameLength也隨之改變了'
          })
        }
        </script>

        actions

        這里與 Vuex 有極大的不同,Pinia 僅提供了一種方法來定義如何更改狀態(tài)的規(guī)則,放棄 mutations 只依靠 Actions,這是一項重大的改變。

        PiniaActions 更加的靈活:

        • 可以通過組件或其他 action 調(diào)用
        • 可以從其他 storeaction 中調(diào)用
        • 直接在 store 實例上調(diào)用
        • 支持同步異步
        • 有任意數(shù)量的參數(shù)
        • 可以包含有關(guān)如何更改狀態(tài)的邏輯(也就是 vuex 的 mutations 的作用)
        • 可以 $patch 方法直接更改狀態(tài)屬性
        import { defineStore } from 'pinia'

        export const useMainStore = defineStore({
          id: 'mian',
          state: () => ({
            name: '超級管理員',
          }),
          getters: {
            nameLength: (state) => state.name.length,
          },
          actions: {
            async insertPost(data:string){
              // 可以做異步
              // await doAjaxRequest(data);
              this.name = data;
            }
          },
        })

        環(huán)境變量配置

        vite 提供了兩種模式:具有開發(fā)服務(wù)器的開發(fā)模式(development)和生產(chǎn)模式(production)

        項目根目錄新建:.env.development :

        NODE_ENV=development

        VITE_APP_WEB_URL= 'YOUR WEB URL'

        項目根目錄新建:.env.production :

        NODE_ENV=production

        VITE_APP_WEB_URL= 'YOUR WEB URL'

        組件中使用:

        console.log(import.meta.env.VITE_APP_WEB_URL)

        配置 package.json:

        打包區(qū)分開發(fā)環(huán)境和生產(chǎn)環(huán)境

        "build:dev""vue-tsc --noEmit && vite build --mode development",
        "build:pro""vue-tsc --noEmit && vite build --mode production",

        使用組件庫 Naive UI

        組件庫選擇,這里我們選擇 Naive UI 至于為什么選擇它?我可以直接說尤大大推薦的嗎?

        • 官方介紹:
          • 一個 Vue 3 組件庫
          • 比較完整,主題可調(diào),使用 TypeScript,不算太慢
          • 有點意思

        介紹還是比較謙虛的,既然尤大推薦,肯定有它的優(yōu)勢了!!!

        安裝 Naive UI

        # 安裝 組件庫
        yarn add naive-ui
        # 安裝 字體
        yarn add vfonts

        如何使用

        import { NButton } from "naive-ui"
        <n-button>naive-ui</n-button>

        全局配置 Config Provider

        全局化配置設(shè)置內(nèi)部組件的主題、語言和組件卸載于其他位置的 DOM 的類名。

        <n-config-provider :locale="zhCN" :theme="theme">
            <!-- 容器 -->
        </n-config-provider>

        尤其是主題配置這個功能,我真的很喜歡 ??

        組件庫選擇上不做任何強制,根據(jù)自己的項目需要選擇合適的組件庫即可

        Vite 常用基礎(chǔ)配置

        基礎(chǔ)配置

        運行 代理打包 配置

        server: {
            host'0.0.0.0',
            port3000,
            opentrue,
            httpsfalse,
            proxy: {}
        },

        生產(chǎn)環(huán)境去除 console debugger

        build:{
          ...
          terserOptions: {
              compress: {
                drop_consoletrue,
                drop_debuggertrue
              }
          }
        }

        生產(chǎn)環(huán)境生成 .gz 文件

        開啟 gzip 可以極大的壓縮靜態(tài)資源,對頁面加載的速度起到了顯著的作用。

        使用 vite-plugin-compression 可以 gzipbrotli 的方式來壓縮資源,這一步需要服務(wù)器端的配合,vite 只能幫你打包出 .gz 文件。此插件使用簡單,你甚至無需配置參數(shù),引入即可。

        # 安裝
        yarn add --dev vite-plugin-compression

        plugins 中添加:

        import viteCompression from 'vite-plugin-compression'

        // gzip壓縮 生產(chǎn)環(huán)境生成 .gz 文件
        viteCompression({
              verbosetrue,
              disablefalse,
              threshold10240,
              algorithm'gzip',
              ext'.gz',
            }),

        最終 vite.config.ts

        import { defineConfig } from 'vite'
        import vue from '@vitejs/plugin-vue'
        import path from 'path'
        //@ts-ignore
        import viteCompression from 'vite-plugin-compression'

        // https://vitejs.dev/config/
        export default defineConfig({
          base'./'//打包路徑
          plugins: [
            vue(),
            // gzip壓縮 生產(chǎn)環(huán)境生成 .gz 文件
            viteCompression({
              verbosetrue,
              disablefalse,
              threshold10240,
              algorithm'gzip',
              ext'.gz',
            }),
          ],
          // 配置別名
          resolve: {
            alias: {
              '@': path.resolve(__dirname, 'src'),
            },
          },
          css:{
            preprocessorOptions:{
              scss:{
                additionalData:'@import "@/assets/style/mian.scss";'
              }
            }
          },
          //啟動服務(wù)配置
          server: {
            host'0.0.0.0',
            port8000,
            opentrue,
            httpsfalse,
            proxy: {}
          },
          // 生產(chǎn)環(huán)境打包配置
          //去除 console debugger
          build: {
            terserOptions: {
              compress: {
                drop_consoletrue,
                drop_debuggertrue,
              },
            },
          },
        })

        常用插件

        可以查看官方文檔:https://vitejs.cn/plugins/

        • @vitejs/plugin-vue 提供 Vue 3 單文件組件支持
        • @vitejs/plugin-vue-jsx 提供 Vue 3 JSX 支持(通過 專用的 Babel 轉(zhuǎn)換插件)
        • @vitejs/plugin-legacy 為打包后的文件提供傳統(tǒng)瀏覽器兼容性支持
        • unplugin-vue-components 組件的按需自動導(dǎo)入
        • vite-plugin-compression 使用 gzip 或者 brotli 來壓縮資源
        • .....

        非常推薦使用的 hooks 庫

        因為vue3.xreact hooks真的很像,所以就稱為 hooks

        VueUse:https://vueuse.org/

        看到這個庫的第一眼,讓我立馬想到了 react 的 ahooks

        VueUse 是一個基于 Composition API 的實用函數(shù)集合。通俗的來說,這就是一個工具函數(shù)包,它可以幫助你快速實現(xiàn)一些常見的功能,免得你自己去寫,解決重復(fù)的工作內(nèi)容。以及進行了基于 Composition API 的封裝。讓你在 vue3 中更加得心應(yīng)手。

        ??想要入手 vue3 的小伙伴,趕快學(xué)習(xí)起來吧?。?!

        ??最后給大家奉上倉庫地址吧:https://github.com/xushanpei/vite_vue3_ts

        寫在最后

        公眾號前端開發(fā)愛好者 專注分享 web 前端相關(guān)技術(shù)文章、視頻教程資源、熱點資訊等,如果喜歡我的分享,給 ???? 點一個 ?? 或者 ?關(guān)注 都是對我最大的支持。


        請你喝杯?? 記得三連哦~

        1.閱讀完記得給?? 醬點個贊哦,有?? 有動力

        2.關(guān)注公眾號前端那些趣事,陪你聊聊前端的趣事

        3.文章收錄在Github frontendThings 感謝Star?

        瀏覽 43
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            99re6热在线精品视频播放 | 人妻巨大乳HD免费看 | 成人性生交大片免费看黄103 | 午夜精品极品粉嫩国产尤物 | 日本天堂免费a | 夜色福利在线 | 18 女人腿打开免费网站 | 别揉我的奶头一区二区三区 | 少妇口述性高潮 | 欧美日韩人妻精品一区 |