banner
xingli

xingli

猫娘爱好者

uniapp整合viewPlus vue3

uniapp+vue3+vite+ts+uview-plus 最完整最詳細搭建項目步驟#

搭建項目的準備工作:

透過vue-cli腳手架 創建 uni-app 項目,便於更好的兼容 TS 寫法

node 版本:v18.16.0

pnpm 版本:8.3.0

vscode 安裝 uni-app 開發插件:

  • uni-create-view :快速創建 uni-app 頁面;
  • uni-helper :uni-app 代碼提示,其中包括 5 個小程序擴展包;

一。創建 uni-app 項目#

主要是透過vue-cli腳手架 創建 uni-app 項目,便於更好的兼容 TS 寫法,使用 Vue3/Vite 版:

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

注意:

  • Vue3/Vite 版要求 node 版本^14.18.0 || >=16.0.0
  • 如命令行創建失敗,請直接訪問 gitee 下載模板

更多的注意安裝流程和注意事項可以參考官方網站:uni-app 官方網站

二。編譯和運行 uni-app 項目#

安裝依賴 pnpm install

2. 運行項目 pnpm dev:mp-weixin

在運行項目時,可以打開 package.json 文件,在 scripts 配置中可以查看到運行項目的命令,如果是運行微信小程序,則透過 pnpm dev,打包則是 pnpm build,當然也可以自行配置快捷啟動命名哦,如 "serve": "pnpm dev";

運行完項目後,目錄會生成 dist 文件夾,裡面的 dev 中 mp-weixin 文件則是用於運行編譯的文件;

3. 導入微信開發者工具

在運行項目完成後,按照提示運行方式:打開微信開發者工具,導入 dist\dev\mp-weixin 運行,此時就可以在微信開發者工具成功運行並編譯該項目;

三. TS 類型校驗#

打開項目結構,會發現 tsconfig.json 有報錯提示:

Option 'importsNotUsedAsValues' is deprecated and will stop functioning in TypeScript 5.5. Specify compilerOption '"ignoreDeprecations": "5.0"' to silence this error.
  Use 'verbatimModuleSyntax' instead.ts

描述:警告消息與 TypeScript 編譯器選項的棄用有關 importsNotUsedAsValues,並建議改用該 verbatimModuleSyntax 選項。要在 TypeScript 5.5 之前使錯誤消息靜音,您可以添加 ignoreDeprecations":"5.0" 到編譯器選項;

解決:可以在 tsconfig.json 文件中 "compilerOptions" 配置項內添加 "ignoreDeprecations": "5.0"

  "compilerOptions": {
    "ignoreDeprecations": "5.0"
  },

此時我們打開 vue 文件中,任意寫一些組件,如:

<image mode="xxx"></image>

在 image 內置組件的 mode 屬性中很顯然是沒有 “xxx” 的屬性值,但是代碼中並沒有錯誤提示,所以為了符合 Ts 校驗,我們需要額外配置 Ts 類型校驗:

1. 安裝類型聲明文件

npm i -D @types/wechat-miniprogram @uni-helper/uni-app-types

2. 配置 tsconfig.json

// tsconfig.json
{
  "extends": "@vue/tsconfig/tsconfig.json",
  "compilerOptions": {
    "ignoreDeprecations": "5.0",
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "lib": ["esnext","dom"],
    "types": [
      "@dcloudio/types", // uni-app API 類型
      "miniprogram-api-typings", // 原生微信小程序類型
      "@uni-helper/uni-app-types" // uni-app 組件類型
    ]
  },
  // vue 編譯器類型,校驗標籤類型
  "vueCompilerOptions": {
    "nativeTags": ["block","component","template","slot"],
  },
  "include": ["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]
}

在配置完成後,剛才的 vue 組件就會提示報錯信息,~~ 並且在 image 組件下方會有紅色波浪線顯示;~~ 也可能不會

四. JSON 注釋問題#

在 manifest.json 和 pages.json 文件中,往往我們會添加一些注釋信息,但是 JSON 規範不支持在文件中添加注釋,會被視為無效的標記,並且會導致解析錯誤。

此時我們可以 vscode 工作區中進行配置:

在 vscode 面板中,點擊右小角設置按鈕→點擊設置→在搜索設置中搜索 “文件關聯”→找到 Files: Associations 的配置項→點擊添加項→把 manifest.jsonpages.json 設置為 jsonc即可;

五。安裝 uview-plus#

我們使用的 UI 框架是 uview-plus, uview-plus 是基於 uView2.0 初步修改,支持 vue3 寫法,組件也是很豐富的,這裡會簡單介紹一下安裝以及配置的步驟,具體的詳細步驟流程可以參考官方網站:uview-plus 3.0 - 全面兼容 nvue 的 uni-app 生態框架 - uni-app UI 框架

1. 安裝

npm install uview-plus
npm install dayjs
npm install clipboard

注意: 此安裝方式必須要按照npm 方式安裝的配置中的說明配置了才可用,且項目名稱不能有中文字符。

因為 uview-plus 依賴 SCSS,所以必須要安裝此插件,否則無法正常運行。

// 安裝sass
npm install sass -D 
// 安裝sass-loader,注意需要版本10,否則可能會導致vue與sass的兼容問題而報錯
npm install sass-loader@10 -D

2. 配置步驟

引入 uview-plus 主 JS 庫:在項目src目錄中的main.ts中,引入並使用 uview-plus 的 JS 庫,注意這兩行要放在const app = createSSRApp(App)之後。

// main.ts
import uviewPlus from 'uview-plus'
import App from './App.vue'
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
  const app = createSSRApp(App)
  app.use(uviewPlus)
  return {
    app
  }
}
// #endif

引入 uview-plus 的全局 SCSS 主題文件: 在項目根目錄的uni.scss中引入此文件。

/* uni.scss */
@import 'uview-plus/theme.scss';

記得刪掉其他的 css

引入 uview-plus 基礎樣式: 在App.vue首行的位置引入,注意給 style 標籤加入 lang="scss" 屬性。

// App.vue
<style lang="scss">
	/* 注意要寫在第一行,同時給style標籤加入lang="scss"屬性 */
	@import "uview-plus/index.scss";
</style>

配置 easycom 組件模式:需要在項目src目錄的pages.json中進行。

// pages.json
{
	"easycom": {
		// 注意一定要放在custom裡,否則無效,https://ask.dcloud.net.cn/question/131175
		"custom": {
			"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
			"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
	        "^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
		}
	},
	
	// 此為本身已有的內容
	"pages": [
		// ......
	]
}

注意:

在配置完後,可以發現在 mian.ts 中引入 uview-plus 時會提示 ts 報錯:無法找到模塊 “uview-plus” 的聲明文件。

可以在 src 文件中創建一個 types 文件夾專門用來存放 ts 類型聲明文件,在文件中新建 uview.d.ts 文件寫入下方聲明代碼即可:

declare module "uview-plus"

3. 使用

下載和配置完成之後,在某個頁面可以直接使用組件,無需透過import引入組件

<u-button text="提交"></u-button>

六。配置 pinia 持久化#

在 vue3+vite 中使用的狀態管理庫是 pinia,官方網站:Pinia 中文文檔

**1. 安裝 pinia:** 使用 HBuilder X 不需要手動安裝,直接使用即可。使用 CLI 需要手動安裝:

  1. 用法:
//main.ts
 
import { createSSRApp } from 'vue';
import * as Pinia from 'pinia';
 
export function createApp() {
	const app = createSSRApp(App);
	app.use(Pinia.createPinia());
	return {
		app,
		Pinia, // 此處必須將 Pinia 返回
	};
}

創建創建一個 Store 文件夾 counter.ts

// stores/counter.js
import { defineStore } from 'pinia';
 
export const useCounterStore = defineStore('counter', {
	state: () => {
		return { count: 0 };
	},
	// 也可以這樣定義
	// state: () => ({ count: 0 })
	actions: {
		increment() {
			this.count++;
		},
	},
});

在組件中使用它:

<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
counter.count++
// 自動補全! ✨
counter.$patch({ count: counter.count + 1 })
// 或使用 action 代替
counter.increment()
</script>
<template>
  <!-- 直接從 store 中訪問 state -->
  <div>Current Count: {{ counter.count }}</div>
</template>

注意:pinia 和 vuex 同樣有個缺點刷新頁面後數據是會丟失的,所以一般登錄的 token 等信息既會保存到 store 中也會保存到本地存儲等,從而實現持久化存儲。

這裡我們實現持久化存儲用到了插件 快速開始 | pinia-plugin-persistedstate

1. 安裝插件

pnpm i pinia-plugin-persistedstate

2. 將插件添加到 pinia 實例上

import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
 
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

3. 用法

創建 Store 時,將 persist 選項設置為 true

import { defineStore } from 'pinia'
 
export const useStore = defineStore(
  'main',
  () => {
    const someState = ref('你好 pinia')
    return { someState }
  },
  {
    persist: true,
  },
)

4. 多端兼容

export const useMemberStore = defineStore(
  'main',
  () => {
    //…省略
  },
  {
    // 配置持久化
    persist: {
      // 調整為兼容多端的API
      storage: {
        setItem(key, value) {
          uni.setStorageSync(key, value) 
        },
        getItem(key) {
          return uni.getStorageSync(key) 
        },
      },
    },
  },
)

七。封裝 http 請求#

為了更方便的進行 axios 數據請求,可以將小程序的數據請求封裝為 Promise 請求函數

1. 請求和上傳文件攔截器

uniapp 攔截器: uni.addInterceptor

// src/utils/http.ts
 
// 請求基地址
const baseURL = 'xxxx'
 
// 攔截器配置
const httpInterceptor = {
  // 攔截前觸發
  invoke(options: UniApp.RequestOptions) {
    // 1. 非 http 開頭需拼接地址
    if (!options.url.startsWith('http')) {
      options.url = baseURL + options.url
    }
    // 2. 請求超時
    options.timeout = 10000
    // 3. 添加小程序端請求頭標識
    options.header = {
      'source-client': 'miniapp',
      ...options.header,
    }
    // 4. 添加 token 請求頭標識
    const memberStore = useMemberStore()
    const token = memberStore.profile?.token
    if (token) {
      options.header.Authorization = token
    }
  },
}
 
// 攔截 request 請求
uni.addInterceptor('request', httpInterceptor)
// 攔截 uploadFile 文件上傳
uni.addInterceptor('uploadFile', httpInterceptor)

注意事項:微信小程序端,需登錄微信公眾平台配置合法域名;

2. 封裝 Promise 請求函數

需求:返回 Promise 對象,用於處理返回值類型,成功通過 resolve 提取數據與添加泛型,失敗通過 reject 捕捉錯誤。

/**
 * 請求函數
 * @param  UniApp.RequestOptions
 * @returns Promise
 *  1. 返回 Promise 對象,用於處理返回值類型
 *  2. 獲取數據成功
 *    2.1 提取核心數據 res.data
 *    2.2 添加類型,支持泛型
 *  3. 獲取數據失敗
 *    3.1 401錯誤  -> 清理用戶信息,跳轉到登錄頁
 *    3.2 其他錯誤 -> 根據後端錯誤信息輕提示
 *    3.3 網絡錯誤 -> 提示用戶換網絡
 */
type Data<T> = {
  code: string
  msg: string
  result: T
}
// 2.2 添加類型,支持泛型
export const http = <T>(options: UniApp.RequestOptions) => {
  // 1. 返回 Promise 對象
  return new Promise<Data<T>>((resolve, reject) => {
    uni.request({
      ...options,
      // 響應成功
      success(res) {
        // 狀態碼 2xx,參考 axios 的設計
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 2.1 提取核心數據 res.data
          resolve(res.data as Data<T>)
        } else if (res.statusCode === 401) {
          // 401錯誤  -> 清理用戶信息,跳轉到登錄頁
          const memberStore = useMemberStore()
          memberStore.clearProfile()
          uni.navigateTo({ url: '/pages/login/login' })
          reject(res)
        } else {
          // 其他錯誤 -> 根據後端錯誤信息輕提示
          uni.showToast({
            icon: 'none',
            title: (res.data as Data<T>).msg || '請求錯誤',
          })
          reject(res)
        }
      },
      // 響應失敗
      fail(err) {
        uni.showToast({
          icon: 'none',
          title: '網絡錯誤,換個網絡試試',
        })
        reject(err)
      },
    })
  })
}

八。其他配置#

1. vue3 自動按需導入

在使用 vue3 的方法如‘ref’等需要手動進行導入很麻煩,這裡使用到插件 unplugin-auto-import 可以實現自動按需導入,官方網站:unplugin-auto-import - npm

安裝:

npm i unplugin-auto-import -save

vue.config.js 文件中添加配置:

//vite.config.ts
 
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import AutoImport from 'unplugin-auto-import/vite'
 
// https://vitejs.dev/config/
export default defineConfig({
  build: {
    sourcemap: process.env.NODE_ENV === 'development',
  },
  plugins: [
    uni(),
    AutoImport({ // 使用
      imports: ['vue'],
      dts: 'src/auto-import.d.ts',
      // 如有用到eslint記得加上寫段,沒有用到可以忽略
      eslintrc: {
        enabled: true,
      },
    })
  ],
})

eslintrc.js 文件配置(用到 eslint 才配置):

//.eslintrc.js
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/eslint-config-typescript',
    '@vue/eslint-config-prettier',
    'plugin:prettier/recommended', // 添加 prettier 插件,
  ],

配置完成後重新啟動一下項目就可以啦!


在項目配置過程中可以參考哔哩哔哩網站:Day1-01-uni-app 小兔鮮兒導學視頻_哔哩哔哩_bilibili

歡迎各位大佬討論、提供建議補充...

來源文章

其他依賴#

npm install miniprogram-api-typings --save-dev

如果 vscode 有報相關錯誤裝下這個包

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。