构建vue3.x移动端项目

532 阅读5分钟

技术栈

  • 编程语言:TypeScript 4.x + JavaScript
  • 构建工具:vite2.x
  • 前端框架:vue3.x
  • 路由工具:vue-router 4.x
  • 状态管理:pinia 2.x
  • UI 框架:vantjs 3.x
  • CSS 预编译:Sass/Less
  • HTTP 工具:Axios

架构搭建

本项目使用 vite 构建工具,需要 Node.js版本>= 12.0.0。

查看 Node版本:

```js
node -v
```

建议将 Node.js升级到最新的稳定版本: js npm install stable

使用 vite 快速初始化项目雏形
  • 使用NPM:
    npm install @vitejs/app
    
  • 使用 Yarn
    yarn create @vitejs/app
    

然后按终端提示完成以下操作

  1. 输入项目名称
  2. 选择模板 vue-ts
  3. 安装依赖
  4. 启动项目
修改 Vite 配置文件

Vite 配置文件vite.config.ts 位于根目录下,项目启动时会自动读取。

简单配置,例如:设置@指向src目录、服务启动端口、打包路径、代理等。

关于 Vite 更多配置项及用法,请查看 Vite 官网 vitejs.dev/config

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 如果编辑器提示 path 模块找不到,则可以安装一下 @types/node -> npm i @types/node -D
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src') // 设置 `@` 指向 `src` 目录
    }
  },
  base: './', // 设置打包路径
  server: {
    port: 4000, // 设置服务启动端口号
    open: true, // 设置服务启动时是否自动打开浏览器
    cors: true // 允许跨域

    // 设置代理,根据我们项目实际情况配置
    // proxy: {
    //   '/api': {
    //     target: 'http://xxx.xxx.xxx.xxx:8000',
    //     changeOrigin: true,
    //     secure: false,
    //     rewrite: (path) => path.replace('/api/', '/')
    //   }
    // }
  }
})
规范目录结构
├── publish/
└── src/
    ├── assets/                    // 静态资源目录
    ├── common/                    // 通用类库目录
    ├── components/                // 公共组件目录
    ├── router/                    // 路由配置目录
    ├── store/                     // 状态管理目录
    ├── style/                     // 通用 CSS 目录
    ├── utils/                     // 工具函数目录
    ├── views/                     // 页面组件目录
    ├── App.vue
    ├── main.ts
    ├── shims-vue.d.ts
├── tests/                         // 单元测试目录
├── index.html
├── tsconfig.json                  // TypeScript 配置文件
├── vite.config.ts                 // Vite 配置文件
└── package.json
集成路由工具 Vue Router
  1. 安装支持 Vue3 的路由工具 vue-router@4
    npm i vue-router@4
    
  2. 创建 src/router/index.ts 文件
    import {
      createRouter,
      createWebHashHistory,
      RouteRecordRaw
    } from 'vue-router'
    import Home from '@/views/home.vue'
    
    const routes: Array<RouteRecordRaw> = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/axios',
        name: 'Axios',
        component: () => import('@/views/axios.vue') // 懒加载组件
      }
    ]
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    export default router
    
  3. main.ts 文件中挂载路由配置
    import { createApp } from 'vue'
    import App from './App.vue'
    
    import router from './router/index'
    
    createApp(App).use(router).mount('#app')
    
集成状态管理工具 Pinia
  1. 安装 Pinia
    npm i pinia
    
  2. 创建 src/store/index.ts文件
import { defineStore } from 'pinia'

export const mainStore = defineStore('main', {
    state: () => {
        return {
            msg: 'Hello W'
        }
    },
    getters: {},
    axtions: {}
})
  1. 挂载Pinia
    import { createPinia } from 'pinia'
    
    const pinia = createPinia()
    
    createApp(App).use(router).use(pinia).mount('#app')
    
集成 UI 框架 Vant
  1. 安装 vue3 的 UI 框架

    npm i vant
    
  2. 在 vite 项目中按需引入组件(推荐)

    在 vite 项目中使用 Vant 时,推荐安装 vite-plugin-style-import 插件,它可以自动按需引入组件的样式

    • 安装插件
    npm i vite-plugin-style-import@1.4.1 -D
    
    • 配置插件
    // vite.config.ts
    import vue from '@vitejs/plugin-vue';
    import styleImport, { VantResolve } from 'vite-plugin-style-import';
    
    export default {
      plugins: [
        vue(),
        styleImport({
          resolves: [VantResolve()],
        }),
      ],
    };
    
  3. 完成以上两步,即可直接使用组件

    import { Button } from 'vant';
    
集成 HTTP 工具 Axios
  1. 安装 Axios (Axios 跟Vue版本没有直接关系)
    npm i axios
    
  2. 配置 Axios
    // src/utils/axios.js
    import Axios from 'axios'
    import { ElMessage } from 'element-plus'
    
    const baseURL = 'https://api.github.com'
    
    const axios = Axios.create({
      baseURL,
      timeout: 20000 // 请求超时 20s
    })
    
    // 前置拦截器(发起请求之前的拦截)
    axios.interceptors.request.use(
      (response) => {
        /**
         * 根据你的项目实际情况来对 config 做处理
         * 这里对 config 不做任何处理,直接返回
         */
        return response
      },
      (error) => {
        return Promise.reject(error)
      }
    )
    
    // 后置拦截器(获取到响应时的拦截)
    axios.interceptors.response.use(
      (response) => {
        /**
         * 根据你的项目实际情况来对 response 和 error 做处理
         * 这里对 response 和 error 不做任何处理,直接返回
         */
        return response
      },
      (error) => {
        if (error.response && error.response.data) {
          const code = error.response.status
          const msg = error.response.data.message
          ElMessage.error(`Code: ${code}, Message: ${msg}`)
          console.error(`[Axios Error]`, error.response)
        } else {
          ElMessage.error(`${error}`)
        }
        return Promise.reject(error)
      }
    )
    
    export default axios
    
  3. 使用 Axios
集成 CSS 预编译器 Stylus/Sass/Less

直接安装为开发依赖即可。vite 内部已经集成了相关的 loader ,不需要额外配置。

  1. 安装

    npm i stylus -D
    # or
    npm i sass -D
    npm i less -D
    
  2. 或配置全局样式

    创建一个global.less文件,定义全局的主题色值等,这样在其它组件里面就可以随意引用了

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue';
    
    export default defineConfig ({
      plugins: [
        vue()
      ],
      css: {
        preprocessorOptions: {
          less: {
            charset: false,
            additionalData: '@import "./src/style/global.less";' // 加载全局样式,使用less特性
          }
        }
      }
    });
    
移动端适配
viewport
之前移动端适配一直使用 `lib-flexible`+`postcss-pxtorem` 方案,随着viewport单位得到越来越多浏览器的支持,lib-flexible 官方也基本已经废弃,建议大家都使用viewport方案。
  1. 安装 postcss-px-to-viewport

    将px自动转换成viewport单位vw,vw本质上还是一种百分比单位,100vw即等于100%,即window.innerWidth

     npm i postcss-px-to-viewport -D
    
  2. 在项目根目录下创建 postcss.config.js 文件

      module.exports = {
       plugins: {
         'postcss-px-to-viewport': {
           unitToConvert: 'px', // 需要转换的单位,默认为"px"
           viewportWidth: 375, // 设计稿的视口宽度
           exclude: [/node_modules/], // 解决vant375,设计稿750问题。忽略某些文件夹下的文件或特定文件
           unitPrecision: 5, // 单位转换后保留的精度
           propList: ['*'], // 能转化为vw的属性列表
           viewportUnit: 'vw', // 希望使用的视口单位
           fontViewportUnit: 'vw', // 字体使用的视口单位
           selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
           minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
           mediaQuery: false, // 媒体查询里的单位是否需要转换单位
           replace: true, //  是否直接更换属性值,而不添加备用属性
           landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
           landscapeUnit: 'vw', // 横屏时使用的单位
           landscapeWidth: 1125 // 横屏时使用的视口宽度
         }
       }
     }
    

    到此就配置好了,开发时根据设计稿的尺寸,配置viewportWidth,就可以一比一的进行px开发了,不用再计算了