美文网首页Typescriptuni-appreact & vue & angular
Uniapp + Vue3 + TS 搭建基础项目

Uniapp + Vue3 + TS 搭建基础项目

作者: 硅谷干货 | 来源:发表于2022-05-15 09:45 被阅读0次

    基础介绍

    个人使用背景是因为公司业务覆盖多个小程序端,主要包括:支付宝小程序、微信小程序、百度小程序、快应用。项目基于npm包管理,vscode相关插件提供更好的开发体验。

    • 主要用到相关技术:uni-app相关 / vue3 / typescript / axios / sass / eslint / prettier

    下面直接开始从头开始搭建一个可用的初始项目~ 如果"需求紧急"可以参考底部的GitHub源码。如果遇到问题可参照对应步骤。

    使用npm安装uni-app

    npm install -g @vue/cli
    vue create -p dcloudio/uni-preset-vue#vue3 uni-app-vue3-demo
    // 等待片刻 ...
    > 请选择 uni-app 模板: 默认模板(TypeScript)
    
    cd uni-app-vue3-demo
    
    npm install
    // 安装较慢时可使用
    npm install --registry=https://registry.npm.taobao.org
    
    // 卸载不需要的包
    npm uninstall vue-class-component vue-property-decorator
    // 更新包
    npm install vue@3.2.20 vuex@4.0.2 typescript@4.4.4
    
    复制代码
    

    配置 eslint + prettier 自动格式化代码

    • 安装相关npm包
    npm install eslint prettier --save-dev
    npm install eslint-config-prettier eslint-plugin-prettier eslint-plugin-vue --save-dev
    npm install @typescript-eslint/eslint-plugin @typescript-eslint/parser --save-dev
    
    复制代码
    
    module.exports = {
      parser: 'vue-eslint-parser',
      extends: ['plugin:vue/recommended', 'plugin:prettier/recommended'],
      parserOptions: {
        parser: '@typescript-eslint/parser',
        ecmaVersion: 2018,
        sourceType: 'module',
      },
      plugins: ['vue', '@typescript-eslint'],
    }
    
    复制代码
    
    • prettier配置 .prettierrc.js
    module.exports = {
      printWidth: 120,
      tabWidth: 2,
      tabs: false,
      semi: false,
      singleQuote: true,
      quoteProps: 'as-needed',
      bracketSpacing: true,
      jsxBracketSameLine: false,
      arrowParens: 'always',
      endOfLine: 'auto',
    }
    复制代码
    
    • vscode 配置 .vscode/settings.json
    {
      "vetur.validation.template": false,
      "editor.formatOnSave": true,
      "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
      },
      "elint.validate": ["typescript", "vue", "html", "json"],
      "editor.defaultFormatter": "esbenp.prettier-vscode",
      "[javascript]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      },
      "[vue]": {
        "editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
      },
      "[html]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      },
      "[json]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      },
      "json.format.enable": false
    }
    复制代码
    
    • 测试代码自动格式化 (重启vscode 打开 src pages/index.vue 输入几个空格 然后在保存看是否会自动格式化)

    Typescript 配置允许默认 any 类型 tsconfig.json

    {
      compilerOptions: {
        "noImplicitAny": false,
      }
    }
    复制代码
    

    配置 SASS

    • 安装 npm 相关包
     npm install node-sass@4.0.0 sass-loader@7.3.1 --save-dev 
     // 如遇到安装问题可手动在package.json devDependencies 手动中添加
     // 删除 node_modules 然后 重新安装npm install
    复制代码
    
    • 在 vue 中使用
    <style lang="scss">
    </style>
    复制代码
    

    配置全局公共变量 并 自动导入

    • 新建全局样式变量 style/var.scss
    $test-size: 400rpx;
    复制代码
    
    • 在全局自动导入 vue.config.js
    process.env.UNI_USING_VUE3 = true
    process.env.UNI_USING_VUE3_OPTIONS_API = true
    module.exports = {
      css: {
        loaderOptions: {
          sass: {
            prependData: `@import "@/styles/var.scss";`, //引入全局变量
          },
        },
      },
      configureWebpack: {
        resolve: {
          extensions: ['.js', '.ts', '.vue', '.json'],
        },
      },
    }
    
    复制代码
    
    • vscode 相关插件
    image.png

    安装 axios api层 适配小程序

    import axios, { AxiosError } from 'axios'
    import qs from 'qs'
    let TOKEN_KEY = 'x-token' // TODO 根据自己后端配置
    let API_SOURCE = ''
    // #ifdef  MP-WEIXIN
    API_SOURCE = 'weixin' // 微信小程序
    // #endif
    // #ifdef  MP-BAIDU
    API_SOURCE = 'bdapplets' // 百度小程序
    // #endif
    
    // 设置表单类型
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
    
    let baseURL = process.env.VUE_APP_API_HOST
    
    const fetch = axios.create({
      withCredentials: true,
      baseURL,
      timeout: 5000,
    })
    let jumpLoginCount = 0
    
    // request拦截器,在请求之前做一些处理
    fetch.interceptors.request.use(
      (config) => {
        Object.assign(config.headers, {
          Authorization: uni.getStorageSync(TOKEN_KEY),
        })
        config.data = qs.stringify(config.data)
    
        return config
      },
      (error) => {
        return Promise.reject(error)
      }
    )
    
    // 配置成功后的拦截器
    fetch.interceptors.response.use(
      (res) => {
        const params = qs.parse(res.config.data)
    
        // 设置 token
        if (res.headers.Authorization) {
          uni.setStorageSync(TOKEN_KEY, res.headers.Authorization)
        }
        // TODO 根据后端成功状态配置
        if (['20001'].includes(`${res.data.code}`)) {
          // 是否返回根数据
          if (params.rootResult) return res
          else return res.data
        } else {
          return Promise.reject(res.data)
        }
      },
      (error: AxiosError) => {
        const params = qs.parse(error.config.data)
        // 未登录 跳转登录页
        if (error.response!.status == 401) {
          if (jumpLoginCount == 0) {
            uni.navigateTo({
              url: '/pages/login/index', // TODO 配置成自己的登录页路径
            })
            ++jumpLoginCount
            setTimeout(() => (jumpLoginCount = 0), 2000)
          }
          return Promise.reject(error)
        }
    
        return Promise.reject(error)
      }
    )
    
    // 适配 小程序
    fetch.defaults.adapter = function (config: any) {
      return new Promise((resolve, reject) => {
        var settle = require('axios/lib/core/settle')
        var buildURL = require('axios/lib/helpers/buildURL')
    
        uni.request({
          method: config.method.toUpperCase(),
          url: config.baseURL + buildURL(config.url, config.params, config.paramsSerializer),
          header: config.headers,
          data: config.data,
          dataType: config.dataType,
          responseType: config.responseType,
          sslVerify: config.sslVerify,
          complete: function complete(response: any) {
            response = {
              data: response.data,
              status: response.statusCode,
              errMsg: response.errMsg,
              headers: response.header, // 注意此处 单复数
              config: config,
            }
            settle(resolve, reject, response)
          },
        })
      })
    }
    
    export { fetch, API_SOURCE }
    
    复制代码
    

    总结

    通过上述步骤后,就能愉快的进行踩坑之旅了~ 如有需要可访问源码
    uni-app-vue3-demo

    相关文章

      网友评论

        本文标题:Uniapp + Vue3 + TS 搭建基础项目

        本文链接:https://www.haomeiwen.com/subject/qukcjrtx.html