




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】怎么用Taro+Vue3開(kāi)發(fā)小程序
這篇文章主要介紹了怎么用Taro+Vue3開(kāi)發(fā)小程序,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。微信小程序是以微信為運(yùn)行環(huán)境的一種應(yīng)用,其實(shí)質(zhì)是Hybrid技術(shù)的應(yīng)用,HybridApp即混合模式移動(dòng)應(yīng)用,因此與H5類似,但又比H5擁有很多原生的能力,例如調(diào)用位置信息和攝像頭等。小程序的開(kāi)發(fā)方式與H5十分相似,用的也是
JavaScript、HTML、CSS
語(yǔ)言。因此,小程序開(kāi)發(fā)可以說(shuō)是一名前端工程師必須要掌握的技能。原生小程序開(kāi)發(fā)有一定的學(xué)習(xí)成本,現(xiàn)如今市面上有很多開(kāi)發(fā)小程序的第三方多端框架,如果不是追求極致性能和穩(wěn)定,還是不要用原生小程序開(kāi)發(fā)了,開(kāi)發(fā)效率太低。第三方多端框架中,taro和uni-app的使用度是最廣的,一般來(lái)說(shuō),做技術(shù)選型時(shí),團(tuán)隊(duì)用react,就用taro,團(tuán)隊(duì)用vue,就用uni-app,兩者之間沒(méi)有什么優(yōu)劣之分,都挺好用的。但很多開(kāi)發(fā)者可能不知道,taro3.0以上版本是支持使用vue的,本篇文章就來(lái)介紹一下如何使用Taro3+Vue3開(kāi)發(fā)微信小程序。我根據(jù)網(wǎng)上的資料完成了本項(xiàng)目的搭建之后,用本項(xiàng)目開(kāi)發(fā)過(guò)一個(gè)小程序,那種開(kāi)發(fā)體驗(yàn)真的是超越了我以往開(kāi)發(fā)過(guò)的所有項(xiàng)目,非常絲滑(可能是我第一次寫vue3的scriptsetup吧,用起來(lái)確實(shí)很舒服)。目標(biāo)功能集成vue3,使用scriptsetup語(yǔ)法開(kāi)發(fā)集成Typescript代碼檢查和格式優(yōu)化全局狀態(tài)管理小程序分包配置樣式封裝,兼容劉海兒屏等樣式問(wèn)題http方法封裝主要技術(shù)棧Taro3Vue3TypeScriptNutUiPiniavue3剛發(fā)布時(shí),由于沒(méi)有合適的ui框架支持,我學(xué)習(xí)vue3的熱情直接被勸退了。直到現(xiàn)在,類似于quasar、element-plus、ant-design-vue等優(yōu)秀框架陸續(xù)支持vue3,并且許多vue3項(xiàng)目被用到了生產(chǎn)環(huán)境中,才發(fā)現(xiàn)大家是把vue3真的用起來(lái)了。比如我們公司隔壁項(xiàng)目組,重構(gòu)項(xiàng)目就用了vue3,這時(shí)我才發(fā)現(xiàn)自己學(xué)習(xí)vue3有點(diǎn)晚了(tips:前端真的太卷了)NutUI是京東風(fēng)格的移動(dòng)端組件庫(kù),它支持使用Vue語(yǔ)言來(lái)編寫可以在H5,小程序平臺(tái)上的應(yīng)用,幫助研發(fā)人員提升開(kāi)發(fā)效率,改善開(kāi)發(fā)體驗(yàn)。我是從Taro文檔知道NutUI的,taro官方推薦使用NutUI開(kāi)發(fā),他們似乎也都是來(lái)自京東同一個(gè)開(kāi)發(fā)團(tuán)隊(duì),我抱著試一試的心態(tài)上手使用,使用體驗(yàn)還不錯(cuò)。Pinia是一個(gè)用于Vue的狀態(tài)管理庫(kù),類似Vuex,是Vue的另一種狀態(tài)管理方案,支持Vue2和Vue3。我第一次接觸前端狀態(tài)管理工具,是剛實(shí)習(xí)時(shí)公司的一個(gè)后臺(tái)管理系統(tǒng),用的dva,那可叫一個(gè)折磨啊,差點(diǎn)直接把我勸退。后面慢慢熟悉了一些,但是不管用redux,還是vuex,還是覺(jué)得寫著麻煩。這次嘗試使用Pinia,用起來(lái)確實(shí)很舒服,符合直覺(jué),易于學(xué)習(xí),有點(diǎn)類似于recoil,但沒(méi)有recoil那么多的概念和API,主體非常精簡(jiǎn),極易上手。Pinia快速入門vscode需安裝插件EslintPrettierVolar與vetur相同,volar是一個(gè)針對(duì)vue的vscode插件,不過(guò)與vetur不同的是,volar提供了更為強(qiáng)大的功能。Volar介紹搭建項(xiàng)目架構(gòu)初始化項(xiàng)目初始化項(xiàng)目之前,需安裝taro,請(qǐng)參考Taro文檔,完成taro安裝使用命令創(chuàng)建模板項(xiàng)目:taro
init
myApp安裝cli用來(lái)執(zhí)行構(gòu)建等操作,之后啟動(dòng)項(xiàng)目,會(huì)生成一個(gè)dist目錄yarn
add
@tarojs/cli
yarn
dev:weapp打開(kāi)微信開(kāi)發(fā)工具工程目錄需要指向構(gòu)建出來(lái)的dist文件打開(kāi)微信開(kāi)發(fā)工具工程目錄需要指向構(gòu)建出來(lái)的dist文件Helloworld出現(xiàn),項(xiàng)目成功跑起來(lái)了!設(shè)置代碼規(guī)范代碼規(guī)范ESlint代碼格式化Prettier提交前檢查husky個(gè)人認(rèn)為,eslint+prettier足以應(yīng)付大部分前端代碼規(guī)范問(wèn)題了,且配置起來(lái)很簡(jiǎn)單,有特殊需求也可繼續(xù)配置。安裝依賴yarn
add
@vue/eslint-config-prettier
@vue/eslint-config-typescript
eslint-plugin-prettier
vue-tsc
husky
-D設(shè)置代碼規(guī)范和格式化規(guī)則.eslintrc.jsmodule.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é)作也不是問(wèn)題了。引入NutUIyarn
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-importyarn
add
babel-plugin-import
-D樣式處理因?yàn)閚utui的設(shè)計(jì)稿是375的所以將框架的設(shè)計(jì)尺寸調(diào)整為375項(xiàng)目配置文件config/index.js中配置:designWidth:
375app.tsimport
{
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>說(shuō)實(shí)話,配置起來(lái)還是有點(diǎn)麻煩,不過(guò)按照官網(wǎng)文檔說(shuō)明來(lái)配也沒(méi)有踩坑,還行。小程序分包配置小程序主包超過(guò)2M,就無(wú)法真機(jī)預(yù)覽了,為了提前做好準(zhǔn)備在一開(kāi)始就進(jìn)行分包處理。比如下面這個(gè)小程序的配置,分了四個(gè)包。app.config.tspages:
['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']
}
],可以在小程序開(kāi)發(fā)工具編輯器里的代碼依賴分析,查看主包和分包的大小使用scriptsetup語(yǔ)法封裝小程序頁(yè)面生命周期方法hooks/life.tsimport
{
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)一個(gè)用戶登錄功能需要處理的文件代碼如下:stores/auth.tsimport
{
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.tsimport
{
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]()
}個(gè)人中心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(()
=>
{
//
模擬后端請(qǐng)求得到token和userInfo
Taro.setStorageSync('token',
'xxxx')
auth.setUserInfo({
nickName:
'林',
avatarUrl:
'/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>總的來(lái)說(shuō),pinia寫起來(lái)是非常簡(jiǎn)潔的,這種類reacthooks的寫法,我是非常喜歡的請(qǐng)求方法封裝http.ts//
封裝axios的請(qǐng)求,返回重新封裝的數(shù)據(jù)格式
//
對(duì)錯(cuò)誤的統(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ù)請(qǐng)求')
}
delete
this.pending[key]
}
//
設(shè)定攔截器
interceptors(instance:
AxiosInstance)
{
erceptors.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)請(qǐng)求的攔截器
erceptors.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)
erceptors(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
HttpRequestrequest.tsimport
HttpRequest
from
'./http'
import
config
from
'@/config/index'
const
baseUrl
=
process.env.NODE_ENV
===
'development'
?
config.baseUrl.dev
:
config.baseU
const
request
=
new
HttpRequest(baseUrl)
export
default
request以獲取圖書列表和圖書詳情為例apis/book.tsimport
request
from
'../request'
export
function
getBookList()
{
return
request.get('books/getBookList')
}
export
function
getBookDetail(id:
number)
{
return
request.post('books/getBookDetail',
{
id
})
}請(qǐng)求方法封裝還是用到了axios,只是用的是axios-miniprogram,寫法和web端基本一致,http.js文件引用的一些模塊太多,本文沒(méi)有列出來(lái),可以直接訪問(wèn)本項(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;
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- Unit 5 第2課時(shí) Section A (3a-3d)2024-2025學(xué)年新教材七年級(jí)英語(yǔ)上冊(cè)同步教學(xué)設(shè)計(jì)(人教版2024)河北專版
- 2025年中國(guó)X射線機(jī)市場(chǎng)調(diào)查研究及行業(yè)投資潛力預(yù)測(cè)報(bào)告
- 2025年鋼結(jié)構(gòu)裝配式建筑構(gòu)件加工合作合同
- 2025年度電子商務(wù)物流配送合同風(fēng)險(xiǎn)評(píng)估與優(yōu)化方案
- 9《古詩(shī)三首》第二課時(shí) 教學(xué)設(shè)計(jì)-2024-2025學(xué)年語(yǔ)文四年級(jí)上冊(cè)統(tǒng)編版
- 2025年度環(huán)保型二次結(jié)構(gòu)模板施工及廢棄物處理合同
- 2025年度戶外探險(xiǎn)搭棚安全保障合同
- some和any (教學(xué)設(shè)計(jì))-2024-2025學(xué)年人教新目標(biāo)Go For It!英語(yǔ)八年級(jí)上冊(cè)
- 2025-2030年中國(guó)瓷地磚項(xiàng)目投資可行性研究分析報(bào)告
- 2023-2024學(xué)年江蘇省無(wú)錫市惠山區(qū)錫山高級(jí)中學(xué)錫西分校高一下學(xué)期期中考試化學(xué)試卷
- 倪師十二經(jīng)穴起止歌經(jīng)絡(luò)歌訣
- 電力電子技術(shù)全套課件
- 配電箱(剩余電流動(dòng)作斷路器)檢測(cè)報(bào)告
- DB32T 4004-2021 水質(zhì) 17種全氟化合物的測(cè)定 高效液相色譜串聯(lián)質(zhì)譜法
- JIS C9335-2-5-2021 家用和類似用途電器.安全性.第2-5部分:洗碗機(jī)的特殊要求
- 建設(shè)年飼養(yǎng)240萬(wàn)只蛋雛雞培育基地項(xiàng)目可行性研究報(bào)告
- 大連理工畫法幾何電子教案2003第八章
- 中國(guó)數(shù)學(xué)發(fā)展歷史(課堂PPT)
- 一至六年級(jí)下冊(cè)音樂(lè)期末試卷及答案
- 黃金太陽(yáng)漆黑的黎明金手指
- 節(jié)水灌溉理論與技術(shù)
評(píng)論
0/150
提交評(píng)論