vite+vue3專案最佳起始點(保姆級)

哈哈哈hh發表於2022-06-15

一 、透過雲開發平臺快速建立初始化應用

1.建立相關應用模版請參考連結: 去中心化的前端構建工具 — Vite

2.完成建立後就可以在github中檢視到新增的Vite倉庫

file

二 、 本地編寫 Vite後臺專案最佳起始點

1.將應用模版克隆到本地

  • 首先假定你已經安裝了Git、node,沒有安裝請移步node官網進行安裝。克隆專案:
git clone + 專案地址
  • 進入專案檔案
cd Vite
  • 切換到feature/1.0.0 分支上
git checkout feature/1.0.0
  • 安裝依賴包
npm install
  • 啟動服務
 npm run dev

這裡開啟瀏覽器3000埠,並出現預設頁面。

2.路由

  • 安裝 vue-router 4.x
npm i vue-router@next -S

file

  • 路由配置 router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'; const router = createRouter({   history: createWebHashHistory(),   routes: [     { path: '/', component: () => import('views/home.vue') }   ] }); export default router
  • 引入 main.js
import router from "@/router"; createApp(App).use(router).mount("#app");

3.狀態管理

  • 安裝 vuex 4.x
npm i vuex@next -S

file

  • Store配置 store/index.js
import {createStore} from 'vuex'; export default createStore({   state: {     couter: 0   } });
  • 引入 main.js
import store from "@/store"; createApp(App).use(store).mount("#app");

4.樣式組織

  • 安裝 sass
npm i sass -D

styles 目錄儲存各種樣式

file

index.scss 作為出口組織這些樣式,同時編寫一些全域性樣式

file

最後在main.js匯入

5.UI庫

  • 安裝
npm i element3 -S
  • 完整引入 main.js
import element3 from "element3"; import "element3/lib/theme-chalk/index.css"; createApp(App).use(element3)
  • 按需引入 main.js
import "element3/lib/theme-chalk/button.css"; import { ElButton } from "element3" createApp(App).use(ElButton)

抽取成外掛會更好 plugins/element3.js

// 完整引入 import element3 from "element3"; import "element3/lib/theme-chalk/index.css"; // 按需引入 // import { ElButton } from "element3"; // import "element3/lib/theme-chalk/button.css"; export default function (app) {   // 完整引入   app.use(element3)   // 按需引入   // app.use(ElButton); }
  • 測試
<el-button>my button</el-button>

6.基礎佈局

我們應用需要一個基本佈局頁,類似下圖,將來每個頁面以佈局頁為父頁面即可:

file

  • 佈局頁面 layout/index.vue
<template>   <div>     <!-- 側邊欄 -->     <div></div>     <!-- 內容容器 -->     <div>       <!-- 頂部導航欄 -->       <navbar />       <!-- 內容區 -->       <app-main />     </div>   </div> </template> <script setup> import AppMain from "./components/AppMain.vue"; import Navbar from "./components/Navbar.vue"; </script> <style scoped> @import "../styles/mixin.scss"; .app-wrapper {   @include clearfix;   position: relative;   height: 100%;   width: 100%; } </style>
  • 路由配置 router/index.js
{   path: "/", component: Layout,   children: [     {       path: "",       component: () => import('views/home.vue'),       name: "Home",       meta: { title: "首頁", icon: "el-icon-s-home" },     },   ], },

7.動態導航

  • 側邊導航

根據路由表動態生成側邊導航選單。

file

首先建立側邊欄元件,遞迴輸出routes中的配置為多級選單,layout/Sidebar/index.vue

<template>   <el-scrollbar wrap-class="scrollbar-wrapper">     <el-menu       :default-active="activeMenu"       :background-color="variables.menuBg"       :text-color="variables.menuText"       :unique-opened="false"       :active-text-color="variables.menuActiveText"       mode="vertical"     >       <sidebar-item         v-for="route in routes"         :key="route.path"         :item="route"         :base-path="route.path"       />     </el-menu>   </el-scrollbar> </template> <script setup> import SidebarItem from "./SidebarItem.vue"; import { computed } from "vue"; import { useRoute } from "vue-router"; import { routes } from "@/router"; import variables from "styles/variables.module.scss"; const activeMenu = computed(() => {   const route = useRoute();   const { meta, path } = route;   if (meta.activeMenu) {     return meta.activeMenu;   }   return path; }); </script>
  • 新增相關樣式:

○ styles/variables.module.scss

○ styles/sidebar.scss

○ styles/index.scss中引入

建立SidebarItem.vue元件,解析當前路由是導航連結還是父選單:

file

8.麵包屑

透過路由匹配陣列可以動態生成麵包屑。

麵包屑元件,layouts/components/Breadcrumb.vue

<template>   <el-breadcrumb separator="/">       <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">         <span           v-if="item.redirect === 'noRedirect' || index == levelList.length - 1"           >{{ item.meta.title }}</span>         <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>       </el-breadcrumb-item>   </el-breadcrumb> </template> <script setup> import { compile } from "path-to-regexp"; import { reactive, ref, watch } from "vue"; import { useRoute, useRouter } from "vue-router"; const levelList = ref(null); const router = useRouter(); const route = useRoute(); const getBreadcrumb = () => {   let matched = route.matched.filter((item) => item.meta && item.meta.title);   const first = matched[0];   if (first.path !== "/") {     matched = [{ path: "/home", meta: { title: "首頁" } }].concat(matched);   }   levelList.value = matched.filter(     (item) => item.meta && item.meta.title && item.meta.breadcrumb !== false   ); } const pathCompile = (path) => {     var toPath = compile(path);   return toPath(route.params); } const handleLink = (item) => {   const { redirect, path } = item;   if (redirect) {     router.push(redirect);     return;   }   router.push(pathCompile(path)); } getBreadcrumb(); watch(route, getBreadcrumb) </script> <style scoped> .app-breadcrumb.el-breadcrumb {   display: inline-block;   font-size: 14px;   line-height: 50px;   margin-left: 8px;   .no-redirect {     color: #97a8be;     cursor: text;   } } </style>

9.資料封裝

統一封裝資料請求服務,有利於解決一下問題:

  • 統一配置請求
  • 請求、響應統一處理

準備工作:

  • 安裝axios:
npm i axios -S

新增配置檔案:.env.development

VITE_BASE_API=/api

請求封裝 utils/request.js

import axios from "axios"; import { Message, Msgbox } from "element3"; // 建立axios例項 const service = axios.create({   // 在請求地址前面加上baseURL   baseURL: import.meta.env.VITE_BASE_API,   // 當傳送跨域請求時攜帶cookie   // withCredentials: true,   timeout: 5000, }); // 請求攔截 service.interceptors.request.use(   (config) => {     // 模擬指定請求令牌     config.headers["X-Token"] = "my token";     return config;   },   (error) => {     // 請求錯誤的統一處理     console.log(error); // for debug     return Promise.reject(error);   } ); // 響應攔截器 service.interceptors.response.use(   /**    * 透過判斷狀態碼統一處理響應,根據情況修改    * 同時也可以透過HTTP狀態碼判斷請求結果    */   (response) => {     const res = response.data;     // 如果狀態碼不是20000則認為有錯誤     if (res.code !== 20000) {       Message.error({         message: res.message || "Error",         duration: 5 * 1000,       });       // 50008: 非法令牌; 50012: 其他客戶端已登入; 50014: 令牌過期;       if (res.code === 50008 || res.code === 50012 || res.code === 50014) {         // 重新登入         Msgbox.confirm("您已登出, 請重新登入", "確認", {           confirmButtonText: "重新登入",           cancelButtonText: "取消",           type: "warning",         }).then(() => {           store.dispatch("user/resetToken").then(() => {             location.reload();           });         });       }       return Promise.reject(new Error(res.message || "Error"));     } else {       return res;     }   },   (error) => {     console.log("err" + error); // for debug     Message({       message: error.message,       type: "error",       duration: 5 * 1000,     });     return Promise.reject(error);   } ); export default service;

10.常見業務處理

  • 結構化資料展

使用el-table展示結構化資料,配合el-pagination做資料分頁。

file

檔案組織結構如下:list.vue展示列表,edit.vue和create.vue編輯或建立,內部複用detail.vue處理,model中負責資料業務處理。

file

list.vue中的資料展示

<el-table v-loading="loading" :data="list">   <el-table-column label="ID" prop="id"></el-table-column>   <el-table-column label="賬戶名" prop="name"></el-table-column>   <el-table-column label="年齡" prop="age"></el-table-column> </el-table>

list和loading資料的獲取邏輯,可以使用compsition-api提取到userModel.js

export function useList() {   // 列表資料   const state = reactive({     loading: true, // 載入狀態     list: [], // 列表資料   });   // 獲取列表   function getList() {     state.loading = true;     return request({       url: "/getUsers",       method: "get",     }).then(({ data, total }) => {       // 設定列表資料       state.list = data;     }).finally(() => {       state.loading = false;     });   }      // 首次獲取資料   getList();   return { state, getList }; }

list.vue中使用

import { useList } from "./model/userModel";
const { state, getList } = useList();

分頁處理 list.vue

<pagination       :total="total"       v-model:page="listQuery.page"       v-model:limit="listQuery.limit"       @pagination="getList"     ></pagination>

資料也在userModel中處理

const state = reactive({   total: 0,   // 總條數   listQuery: {// 分頁查詢引數     page: 1,  // 當前頁碼     limit: 5, // 每頁條數   }, });
request({   url: "/getUsers",   method: "get",   params: state.listQuery, // 在查詢中加入分頁引數 })

11.表單處理

使用者資料新增、編輯使用el-form處理

可用一個元件detail.vue來處理,區別僅在於初始化時是否獲取資訊回填到表單。

<el-form ref="form" :model="model" :rules="rules">   <el-form-item prop="name" label="使用者名稱">     <el-input v-model="model.name"></el-input>   </el-form-item>   <el-form-item prop="age" label="使用者年齡">     <el-input v-model.number="model.age"></el-input>   </el-form-item>   <el-form-item>     <el-button @click="submitForm" type="primary">提交</el-button>   </el-form-item> </el-form>

資料處理同樣可以提取到userModel中處理。

export function useItem(isEdit, id) {   const model = ref(Object.assign({}, defaultData));   // 初始化時,根據isEdit判定是否需要獲取詳情   onMounted(() => {     if (isEdit && id) {       // 獲取詳情       request({         url: "/getUser",         method: "get",         params: { id },       }).then(({ data }) => {         model.value = data;       });     }   });   return { model }; }

三 、 雲端一鍵部署上線應用

1.上傳程式碼

git add .  git commit -m '新增你的註釋' git push

2.在日常環境部署

一鍵進行應用部署。在應用詳情頁面點選日常環境的「部署」按鈕進行一鍵部署,部署狀態變成綠色已部署以後可以點選訪問部署網站檢視效果。

file

3.配置自定義域名線上上環境上線

  • 配置線上環境自定義域名。在功能開發驗證完成後要線上上環境進行部署,線上上環境的「部署配置」-「自定義域名」中填寫自己的域名。例如我們新增一個二級域名 company.workbench.fun 來繫結我們部署的前端應用。然後複製自定義域名下方的API閘道器地址對新增的二級域名進行CNAME配置。

file

  • 配置CNAME地址。複製好 API閘道器域名地址後,來到你自己的域名管理平臺(此示例中的域名管理是阿里雲的域名管理控制檯,請去自己的域名控制檯操作)。新增記錄的「記錄型別」選擇「CNAME」,在「主機記錄」中輸入你要建立的二級域名,這裡我們輸入「company」,在「記錄值」中貼上我們之前複製的 API閘道器域名地址,「TTL」保留預設值或者設定一個你認為合適的值即可。

file

  • 線上上環境部署上線。回到雲開發平臺的應用詳情頁面,按照部署的操作,點選線上環境的「部署按鈕」,部署完成以後就在你自定義的域名進行了上線。CNAME 生效之後,我們輸入 company.workbench.fun(示例網址) 可以開啟部署的頁面。至此,如何部署一個應用到線上環境,如何繫結自己的域名來訪問一個線上的應用就完成了,趕緊部署自己的應用到線上環境,用自己的域名玩起來吧 ;)

file

4.專案預覽效果

file

一鍵建立Vite應用模版連結 :

參考文獻:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70003733/viewspace-2900662/,如需轉載,請註明出處,否則將追究法律責任。

相關文章