uniapp-vue3-vite模板搭建

1,552 阅读2分钟

初始化项目

npx degit dcloudio/uni-preset-vue#vite my-vue3-project

限制包管理工具

{
  "scripts": {
    "preinstall": "npx only-allow npm"
  }
}

github.com/pnpm/only-a…

vite.config.js

配置环境变量与公共基础路径

在根路径创建新文件.env.development

NODE_ENV=development
​
VITE_APP_BASE=/

在根路径创建新文件.env.production

NODE_ENV=production
​
VITE_APP_BASE=/

配置vite.config.js

import { defineConfig, loadEnv } from 'vite'
import path from 'path'
export default ({mode}) => {
  const env = loadEnv(mode, process.cwd())
  return defineConfig({
    base: env.VITE_APP_BASE
 })
}

配置开发服务器选项

{
  server: {
    host: '0.0.0.0',
      port: 6400,
      proxy: {
      '/mock': {
        target: 'https://mock.apifox.cn/m1/1156743-0-default',
          changeOrigin: true,
          rewrite: path => path.replace(/^/mock/, '')
      }
    }
  }
}

生产环境去除打印与debugger

{
    esbuild: {
      drop: ['console', 'debugger']
    }
}

配置别名

resolve: {
  alias: {
    '@': path.resolve(__dirname, 'src')
  }
}

添加项目规范

设置工作空间及其配置

在根目录下创建.vscode文件夹, 并创建settings.json, 如下:

{
  "npm.packageManager": "npm",
  "editor.tabSize": 2,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "files.eol": "\n",
  "editor.minimap.enabled": false,
  "search.exclude": {
    "**/node_modules": true,
    "**/*.log": true,
    "**/*.log*": true,
    "**/bower_components": true,
    "**/dist": true,
    "**/elehukouben": true,
    "**/.git": true,
    "**/.gitignore": true,
    "**/.svn": true,
    "**/.DS_Store": true,
    "**/.idea": true,
    "**/.vscode": false,
    "**/yarn.lock": true,
    "**/tmp": true,
    "out": true,
    "dist": true,
    "node_modules": true,
    "CHANGELOG.md": true,
    "examples": true,
    "res": true,
    "screenshots": true,
    "yarn-error.log": true,
    "**/.yarn": true
  },
  "files.exclude": {
    "**/.cache": true,
    "**/.editorconfig": true,
    "**/.eslintcache": true,
    "**/bower_components": true,
    "**/.idea": true,
    "**/tmp": true,
    "**/.git": true,
    "**/.svn": true,
    "**/.hg": true,
    "**/CVS": true,
    "**/.DS_Store": true
  },
  "files.watcherExclude": {
    "**/.git/objects/**": true,
    "**/.git/subtree-cache/**": true,
    "**/.vscode/**": true,
    "**/node_modules/**": true,
    "**/tmp/**": true,
    "**/bower_components/**": true,
    "**/dist/**": true,
    "**/yarn.lock": true
  },
  "eslint.validate": ["javascript", "javascriptreact", "vue"],
  "path-intellisense.mappings": {
    "@": "${workspaceRoot}/src"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[less]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "prettier.configPath": ".prettierrc",
  "editor.formatOnSave": true,
  "files.associations": {
    "*.cjson": "jsonc",
    "*.wxss": "css",
    "*.wxs": "javascript",
    "manifest.json": "jsonc",
    "pages.json": "jsonc"
  }
}
​

prettier

根目录下创建.prettierrc,内容如下:

{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none",
  "arrowParens": "avoid",
  "jsxBracketSameLine": false,
  "printWidth": 80,
  "tabWidth": 2,
  "tabSize": 2
}

安装依赖:

npm i prettier -D

eslint相关

  1. 安装相关依赖

@vue/eslint-config-standard``babel-eslint``eslint-plugin-import``eslint-plugin-node``eslint-plugin-promise eslint-plugin-standard``eslint-plugin-vue``eslint @babel/eslint-parser

npm i @vue/eslint-config-standard babel-eslint eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard eslint-plugin-vue eslint @babel/eslint-parser -D
  1. 添加eslint规则配置文件

在根目录下添加.eslintrc.js

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: ['plugin:vue/vue3-essential'],
  parserOptions: {
    parser: '@babel/eslint-parser',
    requireConfigFile: false
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'space-before-function-paren': 'off',
    'no-unused-vars': 'warn',
    'handle-callback-err': 'warn',
    'vue/multi-word-component-names': 'off',
    'vue/no-deprecated-v-bind-sync': 'off'
  }
}
​
  1. 在根目录下添加忽略文件 .eslintignore
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.local
/bin
Dockerfile

规范化提交

专题: 规范提交

安装Sass

npm i sass -D

配置使用:

  1. 新建 src/styles文件夹, 添加global.scss, mixin.scss, animations.scss
  2. 填充文件内容

src/styles/mixin.scss:

@mixin commonSizeColor {
  color: pink;
  font-size: 32px;
  font-weight: 600;
}

src/styles/global.scss:

@import './animations.scss';
@import './mixin.scss';
$header-bgColor: #007aff;
$color-success: #4cd964;
  1. 配置全局scss

vite.config.js

{
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: '@import "@/styles/global.scss";'
      }
    }
  }
}

配置unocss

安装

npm i -D unocss
// vite.config.ts
import Unocss from 'unocss/vite'export default {
  plugins: [
    Unocss({ /* options */ }),
  ],
}
// main.ts
import 'uno.css'

简单使用

      <div class="color-green color-pink">{{ title }}</div>
      <div class="color-green font-bold ml-3">{{ title }}</div>

使用Pinia进行状态管理

安装

npm i pinia

注册

// main.js
import { createSSRApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'const pinia = createPinia()
​
export function createApp() {
  const app = createSSRApp(App)
  app.use(pinia)
  return {
    app
  }
}

封装Store

src下新建store目录, 在store下新建user.js

// user.js
import { defineStore } from 'pinia'// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useUserStore = defineStore('user', {
  state: () => ({ count: 0, token: 'rtfyuyio' }),
  getters: {
    double: state => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    }
  }
})
​

使用Store

// App.vue
<script setup>
  import { useUserStore } from '@/store/user.js'
  const store = useUserStore()
  console.log('store.token', store.token)
</script>

请求封装

安装Axios

npm i axios

封装Axios

src下新建api文件夹, 在api下新建http.js

// http.js
import axios from 'axios'import { getFullURL } from '@/utils'import { useUserStore } from '@/store/user.js'const instance = axios.create({
  // Web 侧可以通过 vite.config.js 中的 proxy 配置,指定代理
  // 小程序APP里需写完整路径,如 https://service-rbji0bev-1256505457.cd.apigw.tencentcs.com/release
  // 可使用条件编译,详见 https://uniapp.dcloud.io/tutorial/platform.html#preprocessor
  // #ifdef H5
  baseURL: import.meta.env.VITE_APP_AXIOS_BASE_URL,
  // #endif
  // #ifndef H5
  baseURL: 'https://mock.apifox.cn/m1/1156743-0-default',
  // #endif
  adapter(config) {
    // console.log('request adapter ↓↓')
    // console.log(config)
    const { url, method, data, params, headers, baseURL, paramsSerializer } =
      config
    return new Promise((resolve, reject) => {
      uni.request({
        method: method.toUpperCase(),
        url: getFullURL(baseURL, url, params, paramsSerializer),
        header: headers,
        data,
        dataType: 'json',
        responseType: config.responseType,
        success: res => {
          // console.log('request success ↓↓')
          // console.log(res)
          resolve(res)
        },
        fail: err => {
          reject(err)
        }
      })
    })
  },
  timeout: 8000
})
​
// 请求拦截
instance.interceptors.request.use(config => {
  const store = useUserStore()
  const { method } = config
  const headers = {
    // token: uni.getStorageSync('token')
    token: store.token
  }
  // 不缓存get请求
  if (method === 'get') {
    headers['Cache-Control'] = 'no-cache'
  }
  // delete请求参数放入body中
  // if(method === 'delete') {
  //   headers['Content-type'] = 'application/json;'
  //   Object.assign(config, {
  //     data: params,
  //     params: {}
  //   })
  // }
​
  return {
    ...config,
    headers
  }
})
​
// 响应拦截
instance.interceptors.response.use(response => {
  // console.log('response ↓↓')
  // console.log(response)
  if ((response.status || response.statusCode) === 200) {
    return response.data
  }
  return Promise.reject(response)
})
​
export default instance
​

上面代码中有用到一个getFullURL方法, 如下:

import buildURL from 'axios/lib/helpers/buildURL'
export const getFullURL = (baseURL, url, params, paramsSerializer) => {
  if (url.startsWith('http')) {
    return buildURL(url, params, paramsSerializer)
  }
  baseURL = baseURL.endsWith('/') ? baseURL : `${baseURL}/`
  url = url.startsWith('/') ? url.slice(1) : url
  return buildURL(`${baseURL}${url}`, params, paramsSerializer)
}
​

开始使用

api下新建modules文件夹, 其下新建user.js

// user.js
import request from '../http'
export const apiLogin = data => {
  return request({
    url: '/login',
    method: 'POST',
    data
  })
}
​

路由使用

使用的路由插件为: uni-crazy-router

安装

npm i uni-crazy-router

注册与配置

src下新建文件夹router, 在其下新建index.js

import uniCrazyRouter from 'uni-crazy-router'
export function setupRouter(app) {
  // 接收vue3的实例,并注册uni-crazy-router
  app.use(uniCrazyRouter)
}
uniCrazyRouter.beforeEach(async (to, from, next) => {
  // 逻辑代码
  // console.log('to', to)
  next()
})
​
uniCrazyRouter.afterEach((to, from) => {
  // 逻辑代码
})
​
uniCrazyRouter.onError((to, from) => {
  // 逻辑代码
})

main.js中注册使用

// main.js
import { setupRouter } from './router'
// ...
setupRouter(app)

uniapp vue3版本H5 production环境下的特殊配置

因为uni vue3 vite在h5的production环境打包时会将uni.navigateTo等原生方法的字面量直接替换成底层函数,导致uni-crazy-router失效, 插件会恢复uni的5个全局跳转方法名

安装: npm i uni-vite-plugin-h5-prod-effectvite.config.js中进行配置加载

// vite.config.js
import { defineConfig } from 'vite'
import h5ProdEffectPlugin from 'uni-vite-plugin-h5-prod-effect'
export default defineConfig({
  plugins: [
    // 对h5 production环境打包时的特殊处理,否则uni-crazy-router在这个环境会异常
    h5ProdEffectPlugin()
  ],
})
​

使用

Demo: 进行页面跳转

uni.navigateTo({
    url: '/pages/test/test?a=1&b=1', // 不影响原生的参数传递
    // 提供了基于页面级别的路由参数对象
    routeParams: {
        c:1,
        d:1
    },
    // 提供了基于跳转过程的过程参数对象
    passedParams: {
        e:1,
        f:1
    }
})

Demo: 获取跳转参数

export default {
  data() {
    return {
      title: 'Hello'
    }
  },
  onLoad() {
    // 获取页面路由
    // uni-app官方推荐方式,适用所有端
    console.log(getCurrentPages()[getCurrentPages().length-1].route)
  },
  onShow() {
    // 获取路由页面参数
    console.log(this.$routeParams)
    console.log(getCurrentPages()[getCurrentPages().length-1].$routeParams)
    // 获取路由动作过程参数
    console.log(this.$passedParams)
    console.log(getCurrentPages()[getCurrentPages().length-1].$passedParams)
  },
  onUnload() {
​
  },
  methods: {
    //....
  }
}