如何使用 Taro3 Vue3 開發(fā)小程式?以下這篇文章為大家介紹一下使用 Taro3 Vue3 開發(fā)微信小程式的方法,希望對大家有幫助!
微信小程式是以微信為運(yùn)作環(huán)境的一種應(yīng)用,其實(shí)質(zhì)是Hybrid
技術(shù)的應(yīng)用,Hybrid App 即混合模式行動應(yīng)用,因此與H5
類似,但又比H5 擁有許多原生的能力,例如呼叫位置資訊和相機(jī)等。
小程式的開發(fā)方式與 H5 十分相似,用的也是 ?JavaScript
、HTML
、CSS
? 語言。
因此,小程式開發(fā)可以說是前端工程師必須要掌握的技能。
原生小程式開發(fā)有一定的學(xué)習(xí)成本,現(xiàn)今市面上有許多開發(fā)小程式的第三方多端框架,如果不是追求極致效能和穩(wěn)定,還是不要用原生小程式開發(fā)了,開發(fā)效率太低。
第三方多端框架中,taro
和uni-app
的使用度是最廣的,一般來說,做技術(shù)選型時,團(tuán)隊(duì)用react
,就用taro,團(tuán)隊(duì)用vue
,就用uni-app,兩者之間沒有什麼優(yōu)劣之分,都挺好用的。
但許多開發(fā)者可能不知道,taro3.0 以上版本是支援使用 vue 的,這篇文章就來介紹如何使用 Taro3 Vue3 開發(fā)微信小程式。
我根據(jù)網(wǎng)路上的資料完成了本項(xiàng)目的搭建之後,用本項(xiàng)目開發(fā)過一個小程序,那種開發(fā)體驗(yàn)真的是超越了我以往開發(fā)過的所有項(xiàng)目,非常絲滑(可能是我第一次寫vue3 的script setup 吧,用起來確實(shí)很舒服)。
可直接存取本項(xiàng)目 github 位址 clone 使用。
目標(biāo)功能
- 整合vue3,使用
script setup
語法開發(fā) - 整合
Typescript
- 程式碼檢查和格式最佳化
- 全域狀態(tài)管理
- 小程式分包配置
- 樣式封裝,相容於瀏海兒螢?zāi)坏葮邮絾栴}
- #http 方法封裝
主要技術(shù)堆疊
- Taro3
- Vue3
- TypeScript
- NutUi
- # Pinia
vue3 剛發(fā)佈時,由於沒有合適的ui 框架支持,我學(xué)習(xí)vue3 的熱情直接被勸退了。直到現(xiàn)在,類似於 quasar、element-plus、ant-design-vue 等優(yōu)秀框架陸續(xù)支援vue3,並且許多vue3 專案被用到了生產(chǎn)環(huán)境中,才發(fā)現(xiàn)大家是把vue3 真的用起來了。
例如我們公司隔壁專案小組,重構(gòu)專案就用了vue3,這時我才發(fā)現(xiàn)自己學(xué)習(xí)vue3 有點(diǎn)晚了(tips:前端真的太捲了)
NutUI 是京東風(fēng)格的行動端元件庫,它支援使用Vue 語言來編寫可以在H5,小程式平臺上的應(yīng)用,幫助研發(fā)人員提升開發(fā)效率,並改善開發(fā)體驗(yàn)。
我是從Taro 文件 知道NutUI 的,taro 官方推薦使用NutUI 開發(fā),他們似乎也都是來自京東同一個開發(fā)團(tuán)隊(duì),我抱著試一試的心態(tài)上手使用,使用體驗(yàn)還不錯。
Pinia 是一個用於 Vue 的狀態(tài)管理函式庫,類似 Vuex, 是 Vue 的另一種狀態(tài)管理方案,支援 Vue2 和 Vue3。
我第一次接觸前端狀態(tài)管理工具,是剛實(shí)習(xí)時公司的一個後臺管理系統(tǒng),用的 dva,那可叫一個折磨啊,差點(diǎn)直接把我勸退。後面慢慢熟悉了一些,但不管用 redux,還是 vuex,還是覺得寫著麻煩。
這次嘗試使用 Pinia,用起來確實(shí)很舒服,符合直覺,易于學(xué)習(xí) ,有點(diǎn)類似于 recoil,但沒有 recoil 那么多的概念和 API,主體非常精簡,極易上手。Pinia 快速入門
vscode 需安裝插件
- Eslint
- Prettier
- Volar
與vetur
相同,volar
是一個針對 vue 的 vscode 插件,不過與 vetur 不同的是,volar 提供了更為強(qiáng)大的功能。
搭建項(xiàng)目架構(gòu)
初始化項(xiàng)目
初始化項(xiàng)目之前,需安裝 taro,請參考 Taro 文檔,完成 taro 安裝
使用命令創(chuàng)建模板項(xiàng)目:
taro init myApp
安裝 cli 用來執(zhí)行構(gòu)建等操作,之后啟動項(xiàng)目,會生成一個 dist 目錄
yarn add @tarojs/cli yarn dev:weapp
打開微信開發(fā)工具 工程目錄需要指向構(gòu)建出來的 dist 文件
Hello world 出現(xiàn),項(xiàng)目成功跑起來了!
設(shè)置代碼規(guī)范
- 代碼規(guī)范 ESlint
- 代碼格式化 Prettier
- 提交前檢查 husky
個人認(rèn)為,eslint + prettier 足以應(yīng)付大部分前端代碼規(guī)范問題了,且配置起來很簡單,有特殊需求也可繼續(xù)配置。
安裝依賴
yarn add @vue/eslint-config-prettier @vue/eslint-config-typescript eslint-plugin-prettier vue-tsc husky -D
設(shè)置代碼規(guī)范和格式化規(guī)則
.eslintrc.js
module.exports = { root: true, env: { node: true, 'vue/setup-compiler-macros': true }, extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/prettier', '@vue/typescript'], parserOptions: { parser: '@typescript-eslint/parser' }, rules: { 'prettier/prettier': [ 'error', { singleQuote: true, semi: false, trailingComma: 'none', arrowParens: 'avoid', printWidth: 100 } ], 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' } }
.prettierrc
{ "tabWidth": 2, "singleQuote": true, "semi": false, "trailingComma": "none", "arrowParens": "avoid", "endOfLine": "auto", "printWidth": 100 }
在 package.json 中 script 添加 Ts 檢查命令和 Eslint 檢查命令
"scripts":{ "tsc": "vue-tsc --noEmit --skipLibCheck", "lint": "eslint --ext .vue --ext .js --ext .ts src/" }
添加 husky 觸發(fā) Git 鉤子,代碼提交前檢查
npx husky install
編輯 pre-commit 執(zhí)行 Eslint 檢查和 Ts 檢查
#!/bin/sh . "$(dirname "$0")/_/husky.sh" echo "---eslint start---" npm run lint echo "---eslint end---" echo "---ts lint start---" npm run tsc echo "---ts lint end---"
至此,項(xiàng)目的代碼規(guī)范和格式規(guī)范配置完畢,多人協(xié)作也不是問題了。
引入 NutUI
yarn add @nutui/nutui-taro
在 .babelrc
或 babel.config.js
中添加配置:
module.exports = { // ... plugins: [ [ 'import', { libraryName: '@nutui/nutui', libraryDirectory: 'dist/packages/_es', camel2DashComponentName: false }, 'nutui3-vue' ], [ 'import', { libraryName: '@nutui/nutui-taro', libraryDirectory: 'dist/packages/_es', camel2DashComponentName: false }, 'nutui3-taro' ] ] }
按需引入,安裝插件 babel-plugin-import
yarn add babel-plugin-import -D
樣式處理 因?yàn)?nutui 的設(shè)計稿是 375 的 所以將框架的設(shè)計尺寸調(diào)整為 375
項(xiàng)目配置文件 config/index.js 中配置:
designWidth: 375
app.ts
import { createApp } from 'vue' import { Button } from '@nutui/nutui-taro' const app = createApp() app.use(Button)
index.vue 中,nut-button 組件直接在 template 中寫,不用再引入
<template> <view class="index"> <text>{{ msg }}</text> <nut-button type="primary">主要按鈕</nut-button> </view> </template>
說實(shí)話,配置起來還是有點(diǎn)麻煩,不過按照官網(wǎng)文檔說明來配也沒有踩坑,還行。
小程序分包配置
小程序主包超過 2M,就無法真機(jī)預(yù)覽了,為了提前做好準(zhǔn)備在一開始就進(jìn)行分包處理。比如下面這個小程序的配置,分了四個包。
app.config.ts
pages: ['pages/create/index', 'pages/find/index', 'pages/my/index'], subpackages: [ { root: 'pages/featureA', pages: ['index/index'] }, { root: 'pagesSub/search', pages: ['index'] }, { root: 'pagesSub/my', pages: ['detail/index', 'about/index'] }, { root: 'pagesSub/book', pages: ['detail/index', 'person/list/index', 'person/detail/index'] } ],
可以在小程序開發(fā)工具編輯器里的代碼依賴分析,查看主包和分包的大小
使用 script setup 語法封裝小程序頁面生命周期方法
hooks/life.ts
import { getCurrentInstance } from '@tarojs/taro' import { onMounted } from 'vue' const Current = getCurrentInstance() export function useDidShow(callback) { onMounted(callback) Current?.page?.onShow && (Current.page.onShow = callback) } export function usePullDownRefresh(callback) { Current?.page?.onPullDownRefresh && (Current.page.onPullDownRefresh = callback) }
使用
import { useDidShow } from '@/hooks/life' useDidShow(() => { // console.log('onShow') })
安裝 Pinia 進(jìn)行狀態(tài)管理
yarn add pinia yarn add taro-plugin-pinia
項(xiàng)目配置文件 config/index.js 中配置:
plugins: ['taro-plugin-pinia']
以管理用戶信息和用戶登錄狀態(tài)為例,實(shí)現(xiàn)一個用戶登錄功能
需要處理的文件代碼如下:
stores/auth.ts
import { defineStore } from 'pinia' interface UserInfoProp { nickName: string avatarUrl: string } const useAuth = defineStore({ id: 'authInfo', state: () => ({ userInfo: { nickName: '', avatarUrl: '' }, isLogin: false }), actions: { login() { this.isLogin = true }, logout() { this.isLogin = false }, setUserInfo(userInfo: UserInfoProp) { this.userInfo = userInfo } } }) export { useAuth }
stores/index.ts
import { createPinia } from 'pinia' import { useAuth } from './auth' export const store = createPinia() const storeObj = { auth: useAuth } // 封裝成useStore的形式,這樣一看引用就知道是store的數(shù)據(jù) export function useStore(key: string) { return storeObj[key]() }
個人中心 index.vue
<template> <main v-if="isLogin"> <user-info /> </main> <main v-else> <nut-button type="primary" @click="handleLogin">微信一鍵登錄</nut-button> </main> </template> <script setup> import Taro from '@tarojs/taro' import { computed } from 'vue' import { useStore } from '@/stores' import UserInfo from './userInfo.vue' const auth = useStore('auth') const isLogin = computed(() => auth.isLogin) const handleLogin = () => { setTimeout(() => { // 模擬后端請求得到token和userInfo Taro.setStorageSync('token', 'xxxx') auth.setUserInfo({ nickName: '林', avatarUrl: 'https://img12.360buyimg.com/imagetools/jfs/t1/143702/31/16654/116794/5fc6f541Edebf8a57/4138097748889987.png' }) auth.login() }, 500) } </script> </script>
userInfo 組件
<template> <article> <nut-avatar size="large" :icon="userInfo.avatarUrl"></nut-avatar> <span class="ellipsis name">{{ userInfo.nickName }}</span> </article> </template> <script setup> import Taro from '@tarojs/taro' import { computed } from 'vue' import { useStore } from '@/stores' const auth = useStore('auth') const userInfo = computed(() => auth.userInfo) </script>
總的來說, pinia 寫起來是非常簡潔的,這種類 react hooks 的寫法,我是非常喜歡的
請求方法封裝
http.ts
// 封裝axios的請求,返回重新封裝的數(shù)據(jù)格式 // 對錯誤的統(tǒng)一處理 import { HttpResponse } from '@/common/interface' import Taro from '@tarojs/taro' import publicConfig from '@/config/index' import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, Canceler } from 'axios-miniprogram' import errorHandle from '../common/errorHandle' const CancelToken = axios.CancelToken class HttpRequest { private baseUrl: string private pending: Record<string, Canceler> constructor(baseUrl: string) { this.baseUrl = baseUrl this.pending = {} } // 獲取axios配置 getInsideConfig() { const config = { baseURL: this.baseUrl, headers: { 'Content-Type': 'application/json;charset=utf-8' }, timeout: 10000 } return config } removePending(key: string, isRequest = false) { if (this.pending[key] && isRequest) { this.pending[key]('取消重復(fù)請求') } delete this.pending[key] } // 設(shè)定攔截器 interceptors(instance: AxiosInstance) { instance.interceptors.request.use( config => { console.log('config :>> ', config) let isPublic = false publicConfig.publicPath.map(path => { isPublic = isPublic || path.test(config.url || '') }) const token = Taro.getStorageSync('token') if (!isPublic && token) { config.headers.Authorization = 'Bearer ' + token } const key = config.url + '&' + config.method this.removePending(key, true) config.cancelToken = new CancelToken(c => { this.pending[key] = c }) return config }, err => { errorHandle(err) return Promise.reject(err) } ) // 響應(yīng)請求的攔截器 instance.interceptors.response.use( res => { const key = res.config.url + '&' + res.config.method this.removePending(key) if (res.status === 200) { return Promise.resolve(res.data) } else { return Promise.reject(res) } }, err => { errorHandle(err) return Promise.reject(err) } ) } // 創(chuàng)建實(shí)例 request(options: AxiosRequestConfig) { const instance = axios.create() const newOptions = Object.assign(this.getInsideConfig(), options) this.interceptors(instance) return instance(newOptions) } get(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse> | Promise<HttpResponse> { const options = Object.assign( { method: 'get', url: url }, config ) return this.request(options) } post(url: string, data?: unknown): Promise<AxiosResponse> | Promise<HttpResponse> { return this.request({ method: 'post', url: url, data: data }) } } export default HttpRequest
request.ts
import HttpRequest from './http' import config from '@/config/index' const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro const request = new HttpRequest(baseUrl) export default request
以獲取圖書列表和圖書詳情為例
apis/book.ts
import request from '../request' export function getBookList() { return request.get('books/getBookList') } export function getBookDetail(id: number) { return request.post('books/getBookDetail', { id }) }
請求方法封裝還是用到了 axios
,只是用的是 axios-miniprogram
,寫法和 web 端基本一致,http.js 文件引用的一些模塊太多,本文沒有列出來,可以直接訪問本項(xiàng)目 github 地址查看。
樣式封裝
iPhoneX 底部橫線適配
assets/styles/common.scss
.safe-area-bottom { padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom); }
劉海兒屏適配
assets/styles/hairline.scss
@mixin hairline-common() { position: absolute; box-sizing: border-box; content: ' '; pointer-events: none; } @mixin hairline() { @include hairline-common(); top: -50%; right: -50%; bottom: -50%; left: -50%; border: 0 solid #eaeaea; transform: scale(0.5); } @mixin hairline-top($color, $left: 0, $right: 0) { @include hairline-common(); top: 0; right: $right; left: $left; border-top: 1px solid $color; transform: scaleY(0.5); } @mixin hairline-bottom($color, $left: 0, $right: 0) { @include hairline-common(); right: $right; bottom: 0; left: $left; border-bottom: 1px solid $color; transform: scaleY(0.5); } [class*='van-hairline'] { &::after { @include hairline(); } } .van-hairline { &, &--top, &--left, &--right, &--bottom, &--surround, &--top-bottom { position: relative; } &--top::after { border-top-width: 1px; } &--left::after { border-left-width: 1px; } &--right::after { border-right-width: 1px; } &--bottom::after { border-bottom-width: 1px; } &, &-unset { &--top-bottom::after { border-width: 1px 0; } } &--surround::after { border-width: 1px; } }
多行文字省略
assets/styles/ellipsis.scss
@mixin multi-ellipsis($lines) { display: -webkit-box; overflow: hidden; text-overflow: ellipsis; -webkit-line-clamp: $lines; -webkit-box-orient: vertical; } @mixin ellipsis() { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .ellipsis { @include ellipsis(); } .multi-ellipsis--l2 { @include multi-ellipsis(2); } .multi-ellipsis--l3 { @include multi-ellipsis(3); }
總結(jié)
至此,終于完成了 Taro + Vue3 的項(xiàng)目搭建,強(qiáng)烈建議直接訪問項(xiàng)目 github 地址 clone 使用,有一些配置細(xì)節(jié)本文無法一一列舉,就在項(xiàng)目中去發(fā)掘吧!
如果我的文章能幫助到你,那將是我的榮幸!
【相關(guān)學(xué)習(xí)推薦:小程序開發(fā)教程】
以上是利用Taro + Vue3如何開發(fā)小程式? (實(shí)踐)的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

閒魚官方微信小程式悄悄上線,在小程式中可以發(fā)布閒置與買家/賣家私訊交流、查看個人資料及訂單、搜尋物品等,有用好奇閒魚微信小程式叫什麼,現(xiàn)在快來看一下。閒魚微信小程式叫什麼答案:閒魚,閒置交易二手買賣估價回收。 1、在小程式中可以發(fā)布閒置、與買家/賣家私訊交流、查看個人資料及訂單、搜尋指定物品等功能;2、在小程式的頁面中有首頁、附近、發(fā)閒置、訊息、我的5項(xiàng)功能;3、想要使用的話必要要開通微信支付才可以購買;

實(shí)現(xiàn)微信小程式中的圖片濾鏡效果隨著社群媒體應(yīng)用程式的流行,人們越來越喜歡在照片中應(yīng)用濾鏡效果,以增強(qiáng)照片的藝術(shù)效果和吸引力。在微信小程式中也可以實(shí)現(xiàn)圖片濾鏡效果,為使用者提供更多有趣和創(chuàng)意的照片編輯功能。本文將介紹如何在微信小程式中實(shí)現(xiàn)圖片濾鏡效果,並提供具體的程式碼範(fàn)例。首先,我們需要在微信小程式中使用canvas元件來載入和編輯圖片。 canvas元件可以在頁面

實(shí)現(xiàn)微信小程式中的下拉式選單效果,需要具體程式碼範(fàn)例隨著行動互聯(lián)網(wǎng)的普及,微信小程式成為了網(wǎng)路開發(fā)的重要一環(huán),越來越多的人開始關(guān)注和使用微信小程式。微信小程式的開發(fā)相比傳統(tǒng)的APP開發(fā)更加簡單快捷,但也需要掌握一定的開發(fā)技巧。在微信小程式的開發(fā)中,下拉式選單是一個常見的UI元件,實(shí)現(xiàn)了更好的使用者操作體驗(yàn)。本文將詳細(xì)介紹如何在微信小程式中實(shí)現(xiàn)下拉式選單效果,並提供具

閒魚官方微信小程式已經(jīng)悄悄上線,它為用戶提供了一個便捷的平臺,讓你可以輕鬆地發(fā)布和交易閒置物品。在小程式中,你可以與買家或賣家進(jìn)行私訊交流,查看個人資料和訂單,以及搜尋你想要的物品。那麼閒魚在微信小程式中究竟叫什麼呢,這篇教學(xué)攻略將為您詳細(xì)介紹,想要了解的用戶們快來跟著本文繼續(xù)閱讀吧!閒魚微信小程式叫什麼答案:閒魚,閒置交易二手買賣估價回收。 1、在小程式中可以發(fā)布閒置、與買家/賣家私訊交流、查看個人資料及訂單、搜尋指定物品等功能;2、在小程式的頁面中有首頁、附近、發(fā)閒置、訊息、我的5項(xiàng)功能;3、

微信小程式實(shí)現(xiàn)圖片上傳功能隨著行動網(wǎng)路的發(fā)展,微信小程式已經(jīng)成為了人們生活中不可或缺的一部分。微信小程式不僅提供了豐富的應(yīng)用場景,還支援開發(fā)者自訂功能,其中包括圖片上傳功能。本文將介紹如何在微信小程式中實(shí)作圖片上傳功能,並提供具體的程式碼範(fàn)例。一、前期準(zhǔn)備工作在開始編寫程式碼之前,我們需要先下載並安裝微信開發(fā)者工具,並註冊成為微信開發(fā)者。同時,也需要了解微信

使用微信小程式實(shí)現(xiàn)輪播圖切換效果微信小程式是一種輕量級的應(yīng)用程序,具有簡單、高效的開發(fā)和使用特點(diǎn)。在微信小程式中,實(shí)作輪播圖切換效果是常見的需求。本文將介紹如何使用微信小程式實(shí)現(xiàn)輪播圖切換效果,並給出具體的程式碼範(fàn)例。首先,在微信小程式的頁面檔案中,新增一個輪播圖元件。例如,可以使用<swiper>標(biāo)籤來實(shí)現(xiàn)輪播圖的切換效果。在該組件中,可以透過b

實(shí)現(xiàn)微信小程式中的圖片旋轉(zhuǎn)效果,需要具體程式碼範(fàn)例微信小程式是一種輕量級的應(yīng)用程序,為用戶提供了豐富的功能和良好的用戶體驗(yàn)。在小程式中,開發(fā)者可以利用各種元件和API來實(shí)現(xiàn)各種效果。其中,圖片旋轉(zhuǎn)效果是一種常見的動畫效果,可以為小程式增添趣味性和視覺效果。在微信小程式中實(shí)作圖片旋轉(zhuǎn)效果,需要使用小程式提供的動畫API。以下是一個具體的程式碼範(fàn)例,展示如何在小程

實(shí)作微信小程式中的滑動刪除功能,需要具體程式碼範(fàn)例隨著微信小程式的流行,開發(fā)者在開發(fā)過程中經(jīng)常會遇到一些常見功能的實(shí)作問題。其中,滑動刪除功能是常見、常用的功能需求。本文將為大家詳細(xì)介紹如何在微信小程式中實(shí)現(xiàn)滑動刪除功能,並給出具體的程式碼範(fàn)例。一、需求分析在微信小程式中,滑動刪除功能的實(shí)作涉及以下要點(diǎn):列表展示:要顯示可滑動刪除的列表,每個列表項(xiàng)目需要包
