Vite 中文文档 Vite 中文文档
指南
GitHub (opens new window)
指南
GitHub (opens new window)
  • vite

    • 指引
    • 为什么选 Vite
    • 开始
    • 功能
    • 命令行界面
    • 使用插件
    • 依赖预构建
    • 静态资源处理
    • 构建生产版本
    • 部署静态站点
    • 环境变量和模式
    • 服务端渲染
    • 后端集成
    • 与其他工具比较
    • 故障排除
    • 从 v3 迁移
  • API

  • 配置参考

  • vite

  • API

  • 配置参考

Table of Contentsgenerated with DocToc

Vue3-Vite-Vant-TS-H5


基于Vue3 + Vite + Vant + Sass+ rem适配方案 + Axios封装,构建手机端模板脚手架 

预览


查看 demo 建议手机端查看

关注我的掘金


掘金:Vue3 Vite Vant TS rem 移动端H5框架方案

贡献代码


使用过程中发现任何问题都可以提Issue 给我,也非常欢迎 PR 或 Pull Request

Node 版本要求


Vite 需要 Node.js 12.0.0 或更高版本 (推荐 14.0.0+)。你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。

本示例 Node.js 14.18.1

启动项目


  1. ``` sh
  2. git clone https://github.com/talktao/Vue3-Vite-Vant-TS-H5.git

  3. cd Vue3-Vite-Vant-TS-H5

  4. yarn

  5. npm run dev
  6. 复制代码

  7. ```

目录


rem适配方案
VantUI组件按需加载
安装插件

Sass 全局样式
目录结构
父组件改变子组件样式 深度选择器
全局变量

Vuex 状态管理
Pinia 状态管理
1.安装
2. 创建Pinia的Store
3.在main.ts文件中引用
3. 定义State
i. 传统的options API方式
ii.Vue3 setup的编程模式

4.获取/修改 state

Vue-router
自动化导入路由
普通设置

Axios 封装及接口管理
接口管理
如何调用

vite.config.ts 基础配置
检查文件中的env路径
配置 alias 别名
配置 proxy 跨域
Eslint+Pettier 统一开发规范
批量全局注册公共组件

rem适配方案


Vant 中的样式默认使用px 作为单位,如果需要使用rem 单位,推荐使用以下两个工具:

postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem
lib-flexible 用于设置 rem 基准值

更多详细信息: vant

VantUI组件按需加载


项目采 用Vant 自动按需引入组件 (推荐) 下 面安装插件介绍:

安装插件


  1. ``` sh
  2. yarn add vite-plugin-style-import -D
  3. 复制代码

  4. ```

在 vite.config.ts 设置

  1. ``` sh
  2. import vue from '@vitejs/plugin-vue';
  3. import styleImport, { VantResolve } from 'vite-plugin-style-import';

  4. export default {
  5.   plugins: [
  6.     vue(),
  7.     styleImport({
  8.       resolves: [VantResolve()],
  9.     }),
  10.   ],
  11. };

  12. ```

但是每次页面使用的时候还是要引入,很麻烦,项目在 src/plugins/vant.ts 下统一管理组件,无需在main.ts文件中多次use()

Sass 全局样式


首先 你可能会遇到 node-sass 安装不成功,别放弃多试几次!!!

每个页面自己对应的样式都写在自己的 .vue 文件之中 scoped 它顾名思义给 css 加了一个域的概念。

  1. ``` sh
  2. <style lang="scss">
  3.     /* global styles */
  4. </style>

  5. <style lang="scss" scoped>
  6.     /* local styles */
  7. </style>
  8. 复制代码

  9. ```

目录结构


vue-h5-template 所有全局样式都在 @/src/assets/css 目录下设置

  1. ``` sh
  2. ├── assets
  3. │   ├── scss
  4. │   │   ├── index.scss               # 全局通用样式
  5. │   │   ├── mixin.scss               # 全局mixin
  6. │   │   └── reset.scss               # 清除标签默认样式
  7. │   │   └── variables.scss           # 全局变量
  8. 复制代码

  9. ```

父组件改变子组件样式 深度选择器


当你子组件使用了 scoped 但在父组件又想修改子组件的样式可以 通过 >>> 来实现:

  1. ``` sh
  2. <style scoped>
  3. .a >>> .b { /* ... */ }
  4. </style>
  5. 复制代码

  6. ```

全局变量


  1. ``` sh
  2. // 引入全局样式
  3. import '@/assets/css/index.scss'

  4. ```

Vuex 状态管理


目录结构

  1. ``` sh
  2. ├── store
  3. │   ├── index.ts
  4. 复制代码

  5. ```

main.ts 引入

使用

Pinia 状态管理


1.安装


node版本需>=14.0.0

  1. ``` js
  2. yarn add pinia
  3. # or with npm
  4. npm install pinia
  5. ```

2. 创建Pinia的Store


在src/store/index.ts 文件中,导出 piniaStore

  1. ``` js
  2. // src/store/index.ts

  3. import { createPinia } from 'pinia'

  4. export const piniaStore = createPinia()
  5. ```

3.在main.ts文件中引用


3. 定义State


在src/store 目录下新建有个testPinia.ts 文件

i. 传统的options API方式


  1. ``` js
  2. import { defineStore } from "pinia"
  3. export const usePiniaState = defineStore({
  4.     id: 'textPinia',
  5.     state: () => {
  6.         return {
  7.             userName: ''
  8.         }
  9.     },
  10.     getters: {

  11.     },
  12.     actions: {
  13.         getUserNmae(data) {
  14.             this.userName = data
  15.         }
  16.     }
  17. })
  18. ```

ii.Vue3 setup的编程模式


  1. ``` js
  2. import { ref } from 'vue'
  3. import { defineStore } from "pinia"
  4. export const usePiniaState = defineStore('pinia', ()=>{
  5.     const userName = ref('')
  6.     // 修改userName的方法
  7.     const getUserNmae = (data) => {
  8.         userName.value = data
  9.     }
  10.     return { userName, getUserNmae}
  11. })
  12. ```

4.获取/修改 state


  1. ``` js
  2. <script setup lang="ts">
  3. import { storeToRefs  } from 'pinia'
  4. import { usePiniaState } from '@/store/testPinia'

  5. // pinia
  6. const piniaStore = usePiniaState()

  7. // 通过storeToRefs方法将存储在pinia里的数据解构出来,保持state响应性
  8. const { userName } = storeToRefs(piniaStore)
  9. const { getUserNmae } = piniaStore

  10.         const handleBtn = () =>{
  11.             // pinia
  12.             getUserNmae('真乖,如果对您有帮助请在github上点个星星哦~')
  13.         }

  14. </script>
  15. ```

Vue-router


本案例采用 hash 模式,开发者根据需求修改 mode base

自动化导入路由


  1. ``` js
  2. import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";

  3. // 通过Vite的import.meta.glob()方法实现自动化导入路由
  4. const mainRouterModules = import.meta.glob('../layout/*.vue')
  5. const viewRouterModules = import.meta.glob('../views/**/*.vue')

  6. // 子路由
  7. const childRoutes = Object.keys(viewRouterModules).map((path)=>{
  8. const childName = path.match(/\.\.\/views\/(.*)\.vue$/)[1].split('/')[1];
  9. return {
  10.   path: `/${childName.toLowerCase()}`,
  11.   name: childName,
  12.   component: viewRouterModules[path]
  13. }
  14. })

  15. console.log(childRoutes,'childRouter');

  16. // 根路由
  17. const rootRoutes = Object.keys(mainRouterModules).map((path) => {
  18.     const name = path.match(/\.\.\/layout\/(.*)\.vue$/)[1].toLowerCase();
  19.     const routePath = `/${name}`;
  20.     if (routePath === '/index') {
  21.   return {
  22.    path: '/',
  23.    name,
  24.    redirect: '/home',
  25.    component: mainRouterModules[path],
  26.    children: childRoutes
  27.   };
  28.     }
  29. })

  30. const routes: Array<RouteRecordRaw> = rootRoutes

  31. const router = createRouter({
  32.     history: createWebHashHistory(),
  33.     routes,
  34. });

  35. export default router
  36. ```

普通设置


  1. ``` js
  2. import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";

  3. const routes: Array<RouteRecordRaw> = [
  4.    {
  5.         path: '/',
  6.         name: 'Index',
  7.         component: () => import ('@/layout/index.vue'),
  8.         redirect: '/home',
  9.         meta: {
  10.             title: '首页',
  11.             keepAlive:false
  12.         },
  13.         children: [
  14.             {
  15.                 path: '/home',
  16.                 name: 'Home',
  17.                 component: () => import('@/views/home/Home.vue')
  18.             },
  19.             {
  20.                 path: '/about',
  21.                 name: 'About',
  22.                 component: () => import('@/views/about/About.vue')
  23.             },
  24.         ]
  25.     },    
  26. ]

  27. const router = createRouter({
  28.     history: createWebHashHistory(),
  29.     routes,
  30. });

  31. export default router
  32. ```

更多:Vue Router

Axios 封装及接口管理


utils/request.js 封装 axios ,开发者需要根据后台接口做修改。

接口管理


在src/api 文件夹下统一管理接口

通过引入axios库的ts版本即可配置

  1. ``` js
  2. import axiosInstance, { AxiosResponseProps } from '@/uitls/request'

  3. export const getList = (params: any) => {
  4. return axiosInstance.get("/common/code/logisticsInfo/getOrderByPhone", { params: params || {} });
  5. }
  6. ```

如何调用


  1. ``` sh
  2. // 请求接口
  3. import { getUserInfo } from '@/api/home'

  4. const params = {user: 'talktao'}
  5. getUserInfo(params)
  6.   .then(() => {})
  7.   .catch(() => {})
  8. 复制代码

  9. ```

vite.config.ts 基础配置


检查文件中的env路径


配置 alias 别名


  1. ``` sh
  2. resolve: {
  3.     alias:{
  4.     // 配置src目录
  5.     "@": path.resolve(__dirname,"src"),
  6.     // 导入其他目录
  7.     "components": path.resolve(__dirname, "components")
  8.     }
  9. },

  10. ```

配置 proxy 跨域


如果你的项目需要跨域设置,你需要打开 vite.config.ts proxy 注释 并且配置相应参数

注意:你还需要将 src/env.development 里的 VITE_BASE_URL 设置成 '/'

  1. ``` sh
  2. module.exports = {
  3.   // 跨域代理
  4.     server:{
  5.         proxy:{
  6.               //这里是通过请求/api 来转发到 https://api.pingping6.com/
  7.              //假如你要请求https://api.*.com/a/a
  8.              //那么axios的url,可以配置为 /api/a/a
  9.             '/api': ''
  10.         }  
  11.     }
  12. }

  13. ```

Eslint+Pettier 统一开发规范


VScode安装 eslint prettier vetur 插件 .vue 文件使用 vetur 进行格式化,其他使用prettier

批量全局注册公共组件


文件地址在 src/plugins/components

  1. ``` js
  2. const modules = import.meta.globEager('../components/*.vue')

  3. export default {
  4.   install(app) {
  5.     Object.keys(modules).forEach(componentPath => {

  6.     let splitPart1 = componentPath.split("/")
  7.     let componentName = splitPart1[splitPart1.length - 1].split(".vue")[0]

  8.     // 获取所有组件的实例对象,它是个数组
  9.     let modulesData = Object.values(modules).map((v) => v.default)

  10.     // 过滤出当前组件的实例对象与注册组件匹配一致
  11.     let curComponent = modulesData.filter(
  12.         item=>item.__file.split("/")[item.__file.split("/").length-1].split(".vue")[0] === componentName
  13.     )[0]          

  14.     app.component(componentName, curComponent);
  15.     })
  16.   }
  17. }
  18. ```

上面的批量全局注册公共组件在本地启动中正常,但是上生产打包后,会有问题,具体是__file该组件路径找不到,可以修改成如下代码:

  1. ``` js

  2. const modules = import.meta.globEager('../components/*.vue')

  3. export default {
  4.   install(app) {
  5.       Object.keys(modules).forEach(componentPath => {

  6.           // 获取遍历的当前组件实例对象
  7.           let curComponent = modules[componentPath]?.default

  8.           app.component(curComponent.name, curComponent);
  9.       })
  10.   }

  11. }
  12. ```

注意:


由于sfc语法糖没有携带组件的name属性,上面的curComponent.name会报curComponent下没有name属性,此时需要在注册的公共组件中加上如下代码,比如在src/components/CustomHeader.vue中加上如下代码,这样组件的实例对象中就会有name属性

关于我


如果对你有帮助送我一颗小星星(づ ̄3 ̄)づ╭❤~

转载请联系作者!
Last Updated: 2023-05-23 11:11:51