目前(20230605)uni-app最新版本(3.8.4.20230531)
一、官網(wǎng)文檔
微信開放文檔
uni-app官網(wǎng)
二、創(chuàng)建項目
項目目標(biāo):vue3+ts+vite+vscode
創(chuàng)建以 typescript 開發(fā)的工程(如命令行創(chuàng)建失敗,請直接訪問?gitee?下載模板)
npx degit dcloudio/uni-preset-vue#vite-ts uniapp-base
?
本文創(chuàng)建成功
?
為了驗證gitee下載下來的項目是否完全一致,下載下來看一下
除了項目名不一樣,其他完全一致,兩種方法均可放心使用
?
?安裝依賴
pnpm i
?project.config.json增加
"miniprogramRoot": "dist/dev/mp-weixin/",
?啟動項目
pnpm run dev:mp-weixin
?
啟動成功?
三、熱更新
修改內(nèi)容后小程序開發(fā)工具重新編譯后沒有發(fā)現(xiàn)新的內(nèi)容展示處理,需要manifest.json修改版本號
修改后即刻更新
?
四、配置別名 @ ---- src
4.1、vite.config.ts
?
?import { resolve } from 'path'
resolve: {
// 配置別名
alias: {
'@': resolve(__dirname, 'src')
}
},
4.2、頁面使用
?
4.3、驗證成功
?
五、封裝請求
/**
* uni-request請求封裝
* 1. 統(tǒng)一配置接口地址
* 2. 統(tǒng)一設(shè)置超時時間/報文格式/報文加密
* 3. 統(tǒng)一身份認(rèn)證
* 4. 統(tǒng)一處理登錄超時/接口異常提示
* 5. 統(tǒng)一返回接口格式
*/
import Mock from 'mockjs'
type responseType = {
code: number
success: boolean
msg: string
result: any
}
console.log('18env', import.meta.env)
const request = (config: UniApp.RequestOptions) => {
let url: string
if (/^(http|https):\/\/.*/.test(config.url)) { // h5本地開發(fā)
console.log('22')
// 如果是以http/https開頭的則不添加VITE_REQUEST_BASE_URL
url = config.url
// eslint-disable-next-line no-underscore-dangle
} else if (Mock._mocked[import.meta.env.VITE_REQUEST_BASE_URL + config.url]) { // mock開發(fā)
console.log('27')
// 如果是mock數(shù)據(jù)也不添加VITE_REQUEST_BASE_URL,Mock._mocked上記錄有所有已設(shè)置的mock規(guī)則
url = import.meta.env.VITE_REQUEST_BASE_URL + config.url
} else { // 微信小程序
console.log('31', import.meta.env)
/**
* 開啟mock時需要去掉mock路徑,不能影響正常接口了。
* 如果碰巧你接口是 /api/mock/xxx這種,那VITE_REQUEST_BASE_URL就配置/api/mock/mock吧
*/
// url = import.meta.env.VITE_REQUEST_BASE_URL.replace(/\/mock$/, '') + config.url
// 小程序使用這樣的路徑,否則請求報錯,調(diào)試中
url = import.meta.env.VITE_SERVER_NAME + import.meta.env.VITE_REQUEST_BASE_URL.replace(/\/mock$/, '') + config.url
}
return new Promise<responseType>((resolve, reject) => {
uni.request({
...config,
url,
/** 統(tǒng)一設(shè)置超時時間 */
timeout: config.timeout || 60000,
header: {
...config.header,
/** 統(tǒng)一報文格式 */
'Content-Type': 'application/json;charset=UTF-8'
/** 統(tǒng)一身份認(rèn)證 */
// Authorization: Token
},
success(res) {
// 200狀態(tài)碼表示成功
if (res.statusCode === 200) {
resolve(res.data as any)
return
}
/**
* 這里可以做一些登錄超時/接口異常提示等處理
*/
reject(res.data)
},
fail(result) {
reject(result)
}
})
})
}
export default {
/**
* get請求
* @param url 請求地址
* @param data 請求的參數(shù)
* @param options 其他請求配置
*/
get: (url: string, data?: UniApp.RequestOptions['data'], options?: UniApp.RequestOptions) => {
return request({
...options,
url,
data,
method: 'GET'
})
},
/**
* post請求
* @param url 請求地址
* @param data 請求的參數(shù)
* @param options 其他請求配置
*/
post: (url: string, data?: UniApp.RequestOptions['data'], options?: UniApp.RequestOptions) => {
return request({
...options,
url,
data,
method: 'POST'
})
}
}
六、配置多環(huán)境開發(fā)及代理
6.1、定義環(huán)境變量文件
?
6.2、env/.env.dev
其他同理
?
?# 請求接口地址
VITE_REQUEST_BASE_URL = '/m-staff-center/api/v1'
VITE_SERVER_NAME = 'https://md.abc.com.cn'
# VITE開頭的變量才會被暴露出去
6.3、index.d.ts
/** 擴(kuò)展環(huán)境變量import.meta.env */
interface ImportMetaEnv {
? ? VITE_REQUEST_BASE_URL: string,
? ? VITE_SERVER_NAME: String
}
6.4、vite.config.ts 引入?loadEnv
import { defineConfig, loadEnv } from "vite";
使用環(huán)境變量文件?
envDir: resolve(__dirname, 'env'),?
?
6.5、配置代理
// 開發(fā)服務(wù)器配置
server: {
host: '0.0.0.0', // 允許本機(jī)
port: 3000, // 設(shè)置端口
open: false, // 設(shè)置服務(wù)啟動時自動打開瀏覽器
// cors: true, // 允許跨域
// 請求代理
proxy: {
'/m-staff-center': { // 匹配請求路徑,localhost:3000/m-staff-center,如果只是匹配/那么就訪問到網(wǎng)站首頁了
target: loadEnv(process.argv[process.argv.length-1], './env').VITE_SERVER_NAME, // 代理的目標(biāo)地址
changeOrigin: true, // 開發(fā)模式,默認(rèn)的origin是真實的 origin:localhost:3000 代理服務(wù)會把origin修改為目標(biāo)地址
// secure: true, // 是否https接口
// ws: true,
// rewrite target目標(biāo)地址 + '/m-staff-center',如果接口是這樣的,那么不用重寫
// rewrite: (path) => path.replace(/^\/m-staff-center/, '') // 路徑重寫,本項目不需要重寫
// https://www.bilibili.com/video/BV1p3411J7CE?p=21
}
}
},
6.6、測試接口
<template>
<view>my video</view>
<button @click="apiTest">調(diào)用代理接口new</button>
</template>
<script setup lang="ts">
import request from '@/utils/request'
const apiTest = () => {
request.post('/UcAuthCompany/getName').then((res: any) => {
console.log(res)
})
}
</script>
6.7、驗證成功
?
七、配置vuex
7.1、安裝vuex
pnpm add vuex
7.2、src/shime-uni.d.ts 擴(kuò)展useStore聲明
// 擴(kuò)展useStore聲明
import { StateType } from '@/store/index.d'
import { InjectionKey } from 'vue'
import { Store } from 'vuex'
declare module "vue" {
type Hooks = App.AppInstance & Page.PageInstance;
interface ComponentCustomOptions extends Hooks {
// 這里擴(kuò)展this.$store,還可以在這里對this添加其他的聲明
$store: Store<StateType>
}
}
declare module 'vuex' {
export function useStore<S = StateType>(injectKey?: InjectionKey<Store<S>> | string): Store<S>
}
7.3、定義store?
?
7.3.1、src/store/index.ts
import { createStore } from 'vuex'
import { StateType } from './index.d'
// 批量引入其他module,
const files = import.meta.globEager('./modules/*.ts') // vite的寫法
const keys = Object.keys(files)
const modules: any = {}
keys.forEach((key) => {
if (Object.prototype.hasOwnProperty.call(files, key)) {
// 提取文件的名字作為模塊名
modules[key.replace(/(\.\/modules\/|\.ts)/g, '')] = files[key].default
}
})
/** 全局的state,這個看自己的需求,如果有用到就在createStore中添加 */
export interface rootStateType {}
export default createStore<StateType>({
modules
})
7.3.2、src/store/index.d.ts
import { rootStateType } from './index'
import { systemStateType } from './modules/system'
export interface StateType extends rootStateType {
system: systemStateType
}
7.3.3、src/store/modules/system.ts
import { Module } from 'vuex'
import { rootStateType } from '@/store'
export interface systemStateType {
title: string
}
const systemModule: Module<systemStateType, rootStateType> = {
namespaced: true,
state: () => ({
title: '你好,我是snow'
}),
mutations: {
setTitle(state, val){
state.title= val
wx.setStorageSync('title', val || '0') // 持久化
}
}
}
export default systemModule
7.3.4、src/main.ts 掛載
?
import { createSSRApp } from "vue";
import App from "./App.vue";
import store from './store'
import '../mock'
export function createApp() {
const app = createSSRApp(App).use(store);
return {
app,
};
}
?7.3.5、業(yè)務(wù)文件使用
<view>{{ title }}</view>
import { useStore } from 'vuex'
import {reactive, ref, computed} from 'vue'
const store = useStore()
// const title = ref(store.state.system.title)
// 使用計算屬性
const title = computed(()=>{
return store.state.system.balance
})
// 提交mutations,如果使用了模塊化,store.commit('模塊名/mutations方法', '值')
store.commit('system/setBalance', res.data.balance)
7.3.6、 驗證成功
?
八、使用sass
8.1、安裝
pnpm add sass
8.2、src/styles/global.scss定義全局變量
$bg-color: #f5f5f5;
8.3、 vite.config.ts引入
css: {
// css預(yù)處理器
preprocessorOptions: {
scss: {
// 因為uni.scss可以全局使用,這里根據(jù)自己的需求調(diào)整
additionalData: '@import "./src/styles/global.scss";'
}
}
},
?
8.4、頁面使用
??
驗證成功
?
九、配置mockjs
十、配置頭部信息
10.1、src/pages.json文件定義
pages.json 頁面路由 | uni-app官網(wǎng)
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首頁", // title
"navigationBarTextStyle": "white", // 導(dǎo)航欄標(biāo)題顏色 black、white兩種顏色
"navigationBarBackgroundColor": "#FF0000", // 導(dǎo)航欄背景色
"enablePullDownRefresh": "false" ,// 是否開啟下拉刷新
"backgroundColor": "#F8F8F8", // 窗口的背景色
"navigationStyle":"default" , // 導(dǎo)航欄樣式,僅支持 default/customm,開啟 custom 后,所有窗口均無導(dǎo)航欄
"usingComponents": { // 引用小程序組件
"my-component": "/path/to/my-component"
}
}
},
?
1.02、在業(yè)務(wù)頁面onLoad聲明周期,函數(shù)式定義
onLoad() {
uni.setNavigationBarTitle({
title:'個人中心'
})
}
十一、配置tabbar
?
十二、uniapp組件
序號 | 組件 | 組件名 | 詳細(xì)?(uni-app官網(wǎng)) |
1 | 視圖容器 | view | 視圖容器。 類似于傳統(tǒng)html中的div,用于包裹各種元素內(nèi)容。 如果使用nvue,則需注意,包裹文字應(yīng)該使用 |
2 | scroll-view | 可滾動視圖區(qū)域。用于區(qū)域滾動。 需注意在webview渲染的頁面中,區(qū)域滾動的性能不及頁面滾動。 |
|
3 | swiper | 滑塊視圖容器。 一般用于左右滑動或上下滑動,比如banner輪播圖。 注意滑動切換和滾動的區(qū)別,滑動切換是一屏一屏的切換。swiper下的每個swiper-item是一個滑動切換區(qū)域,不能停留在2個滑動區(qū)域之間。 |
|
4 | match-media | media query 匹配檢測節(jié)點。 類似于網(wǎng)頁開發(fā)中使用媒體查詢來適配大屏小屏,match-media是一個可適配不同屏幕的基本視圖組件??梢灾付ㄒ唤M media query 媒體查詢規(guī)則,滿足查詢條件時,這個組件才會被展示。 例如在match-media組件中放置一個側(cè)邊欄,媒體查詢規(guī)則設(shè)置為寬屏才顯示,就可以實現(xiàn)在PC寬屏顯示該側(cè)邊欄,而在手機(jī)窄屏中不顯示側(cè)邊欄的效果。 |
|
5 | movable-area | 可拖動區(qū)域 由于app和小程序的架構(gòu)是邏輯層與視圖層分離,使用js監(jiān)聽拖動時會引發(fā)邏輯層和視圖層的頻繁通訊,影響性能。為了方便高性能的實現(xiàn)拖動,平臺特封裝了
即手指/鼠標(biāo)按住 當(dāng)然也可以不拖動,而使用代碼來觸發(fā)
|
|
6 | movable-view | 可移動的視圖容器,在頁面中可以拖拽滑動或雙指縮放。
|
|
7 | cover-view | 覆蓋在原生組件上的文本視圖。 app-vue和小程序框架,渲染引擎是webview的。但為了優(yōu)化體驗,部分組件如map、video、textarea、canvas通過原生控件實現(xiàn),原生組件層級高于前端組件(類似flash層級高于div)。為了能正常覆蓋原生組件,設(shè)計了cover-view。 |
|
8 | cover-image | 覆蓋在原生組件上的圖片視圖??筛采w的原生組件同cover-view ,支持嵌套在cover-view 里。 |
|
9 | 基礎(chǔ)內(nèi)容 | icon | 圖標(biāo)。 |
10 | text | 文本組件。 用于包裹文本內(nèi)容。 |
|
11 | rich-text | 富文本。 支持默認(rèn)事件,包括:click、touchstart、touchmove、touchcancel、touchend、longpress。 |
|
12 | progress | 進(jìn)度條。 | |
13 | 表單組件 | button | 按鈕。 |
14 | checkbox | 多項選擇器,內(nèi)部由多個 checkbox 組成。 | |
15 | editor | 富文本編輯器,可以對圖片、文字格式進(jìn)行編輯和混排。 在web開發(fā)時,可以使用 編輯器導(dǎo)出內(nèi)容支持帶標(biāo)簽的? 通過 富文本組件內(nèi)部引入了一些基本的樣式使得內(nèi)容可以正確的展示,開發(fā)時可以進(jìn)行覆蓋。需要注意的是,在其它組件或環(huán)境中使用富文本組件導(dǎo)出的html時,需要額外引入這段樣式,并維護(hù) 圖片控件僅初始化時設(shè)置有效。 |
|
16 | form | 表單,將組件內(nèi)的用戶輸入的 當(dāng)點擊? |
|
17 | input | 單行輸入框。 html規(guī)范中input不僅是輸入框,還有radio、checkbox、時間、日期、文件選擇功能。在uni-app規(guī)范中,input僅僅是輸入框。其他功能uni-app有單獨的組件或API:radio組件、checkbox組件、時間選擇、日期選擇、圖片選擇、視頻選擇、多媒體文件選擇(含圖片視頻)、通用文件選擇。 |
|
18 | label | 用來改進(jìn)表單組件的可用性,使用for屬性找到對應(yīng)的id,或者將控件放在該標(biāo)簽下,當(dāng)點擊時,就會觸發(fā)對應(yīng)的控件。 for優(yōu)先級高于內(nèi)部控件,內(nèi)部有多個控件的時候默認(rèn)觸發(fā)第一個控件。 目前可以綁定的控件有: |
|
19 | picker | 從底部彈起的滾動選擇器。支持五種選擇器,通過mode來區(qū)分,分別是普通選擇器,多列選擇器,時間選擇器,日期選擇器,省市區(qū)選擇器,默認(rèn)是普通選擇器。 | |
20 | picker-view | 嵌入頁面的滾動選擇器。 相對于 |
|
21 | radio | 單項選擇器,內(nèi)部由多個?<radio> ?組成。通過把多個radio 包裹在一個radio-group 下,實現(xiàn)這些radio 的單選。 |
|
22 | slider | 滑動選擇器。 | |
23 | switch | 開關(guān)選擇器。 | |
24 | textarea | 多行輸入框。 | |
25 | 路由與頁面跳轉(zhuǎn) | navigator | 頁面跳轉(zhuǎn)。 該組件類似HTML中的 該組件的功能有API方式,另見:uni.navigateTo(OBJECT) | uni-app官網(wǎng) |
26 | 媒體組件 | animation-view | Lottie動畫組件,動畫資源參考Lottie官方鏈接。 |
27 | audio | 音頻。 | |
28 | camera | 頁面內(nèi)嵌的區(qū)域相機(jī)組件。注意這不是點擊后全屏打開的相機(jī)。 | |
29 | image | 圖片。 | |
30 | video | 視頻播放組件。 | |
31 | live-player | 實時音視頻播放,也稱直播拉流。 使用live-player 組件需注意:如果發(fā)布到小程序,需要先通過各家小程序的審核。指定類目的小程序才能使用(微信小程序類目、百度小程序類目),審核通過后在各家小程序管理后臺自助開通該組件權(quán)限。 |
|
32 | live-pusher | 實時音視頻錄制,也稱直播推流。 | |
33 | 地圖 | map | 地圖組件。 地圖組件用于展示地圖,而定位API只是獲取坐標(biāo),請勿混淆兩者。 |
34 | 畫布 | canvas | 畫布。 |
35 | webview | web-view |
web-view ?是一個 web 瀏覽器組件,可以用來承載網(wǎng)頁的容器,會自動鋪滿整個頁面(nvue 使用需要手動指定寬高)。 |
36 | 拓展組件(uni-ui) | uni-app官網(wǎng) | uni-app官網(wǎng) |
十三、使用拓展組件
13.1、安裝uni-ui
pnpm add @dcloudio/uni-ui
13.2、src/pages.json配置
?
13.3、頁面直接使用
?
驗證成功?
??
十四、組件-easycom
?
14.1、定義組件video-player
src/components/video-player/video-player.vue
規(guī)則:目錄名/文件名.vue,目錄名與文件名需要相同,使用時候直接使用,無需引入
<template>
<view>my video</view>
</template>
<script setup lang="ts">
</script>
14.2、引入使用
src/pages/index/index.vue
<template>
<view class="content">
<image class="logo" src="/static/logo.png" />
<video-player></video-player>
</view>
</template>
<script setup lang="ts">
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
</style>
14.3、驗證成功
十五、全局文件
序號 | 文件 | 解釋 |
1 | pages.json |
pages.json 頁面路由 | uni-app官網(wǎng) |
2 | manifest.json |
manifest.json 應(yīng)用配置 | uni-app官網(wǎng) |
3 | package.json | uni-app 通過在 概述 | uni-app官網(wǎng) |
4 | vue.config.js | vue.config.js 是一個可選的配置文件,如果項目的根目錄中存在這個文件,那么它會被自動加載,一般用于配置 webpack 等編譯選項 uni-app官網(wǎng) |
5 | vite.config.js | vite.config.js 是一個可選的配置文件,如果項目的根目錄中存在這個文件,那么它會被自動加載,一般用于配置 vite 的編譯選項 uni-app官網(wǎng) |
6 | uni.scss |
uni-app官網(wǎng) |
7 | app.vue |
uni-app官網(wǎng) |
8 | main.js |
uni-app官網(wǎng) |
十六、仿 抖音/B站 視頻播放
16.1、上下切換使用小程序swiper組件
16.2、判斷是上滑、下滑,在下滑的事件方法內(nèi)處理
16.3、current屬性來定位播放哪一個,及在在swiper-item展示對應(yīng)的信息
video | uni-app官網(wǎng)
swiper | uni-app官網(wǎng)
利用uniapp中模仿抖音、滑動視頻組件、雙擊點贊、首個視頻自動播放_uniapp 抖音_是小橙鴨丶的博客-CSDN博客
uniapp實現(xiàn)視頻上下滑動功能(小程序)以及video組件的暫停和播放_uniapp video組件_^O^ ^O^的博客-CSDN博客
十七、tabbar設(shè)置數(shù)字角標(biāo)
?
?業(yè)務(wù)代碼:
uni.setTabBarBadge({ //顯示數(shù)字
index: 1, //tabbar下標(biāo)
text: '6' //數(shù)字
})
序號 | 方法 | 理解 |
1 | uni.showTabBarRedDot |
顯示 |
2 | uni.setTabBarBadge |
設(shè)置 |
3 | uni.removeTabBarBadge |
隱藏 |
十八、uniapp實現(xiàn)分享
<button open-type="share" style="border: none;" plain="true" class="operate-bar__item share">
<image :src="imagePlay.share" class="operate-bar__item__img share__img"></image>
<view>分享</view>
</button>
點擊分享后,選擇一個聊天即可?
十九、頁面和路由
小程序只能跳轉(zhuǎn)本地頁面。目標(biāo)頁面必須在pages.json中注冊。
uni.navigateTo(OBJECT) | uni-app官網(wǎng)
序號 | 方法 | 參數(shù) | 描述 |
1 | uni.navigateTo(object) | url、animationType、animationDuration、events、success、fail、complete | 保留當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面,使用uni.navigateBack 可以返回到原頁面。 |
2 | uni.redirectTo(object) | url、success、fail、complete | 關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面。 |
3 | uni.reLaunch(object) | url、success、fail、complete | 關(guān)閉所有頁面,打開到應(yīng)用內(nèi)的某個頁面。 |
4 | uni.switchTab(object) | url、success、fail、complete | 跳轉(zhuǎn)到 tabBar 頁面,并關(guān)閉其他所有非 tabBar 頁面。 |
5 | uni.navigateBack(object) | delta、animationType、animationDuration、success、fail、complete | 關(guān)閉當(dāng)前頁面,返回上一頁面或多級頁面??赏ㄟ^?getCurrentPages() ?獲取當(dāng)前的頁面棧,決定需要返回幾層。 如果 delta 大于現(xiàn)有頁面數(shù),則返回到首頁。 |
二十、uni.showToast
20.1、uni.showToast基礎(chǔ)使用
uni.showToast({
title: `網(wǎng)絡(luò)錯誤`,
icon: 'none'
})
20.2、?解決uni.showToast提示,一閃而過問題
在success回調(diào)里使用setTimeout
20.3、uni.showToast文字換行
\r\n? 開發(fā)工具無效,真機(jī)測試有效,可以使用
?
?
二十一、uni-nav-bar/自定義導(dǎo)航
21.1、pages.json
{
"path": "pages/my/index",
"style": { // 去掉原生導(dǎo)航
"navigationStyle": "custom",
"app-plus": {
"titleNView": false
}
}
},
21.2、業(yè)務(wù)頁面
<uni-nav-bar :border="false" height="176rpx"?background-color="#F1D4D8" color="#333" leftText="我的" />
21.3、使用插槽的方式/slot
vue2插槽寫法:
<block slot="left">
vue3插槽寫法:
<block #left>
<uni-nav-bar
:border="false"
height="176rpx"
background-color="#F1D4D8"
color="#333"
>
<block #left>
<!-- 設(shè)置文字高度與膠囊高度平齊 -->
<view
:style="{
height: menuButtonInfo.height + 'px',
lineHeight: menuButtonInfo.height + 'px',
paddingTop: (menuButtonInfo.top - (menuButtonInfo.top - statuBar)) + 'px',
fontSize: '36rpx',
fontWeight: 500,
textIndent: '20rpx'
}"
>
<text>我的</text>
</view>
</block>
</uni-nav-bar>
let menuButtonInfo = uni.getMenuButtonBoundingClientRect(); // 獲取的微信小程序膠囊布局位置信息在頁面上的具體展現(xiàn)
let statuBar:any = uni.getSystemInfoSync().statusBarHeight || 0; // 狀態(tài)欄高度
測試測試,成功?
21.4、使用uni-nav-bar左側(cè)只能放下兩個文字
經(jīng)過調(diào)試左側(cè)不容易增加寬度來放下更多內(nèi)容
21.5、自己開發(fā)一個組件 nav-bar
<template>
<view
class="nav-bar"
:style="{
backgroundColor: backgroundColor,
height: (menuButtonInfo.height + statuBar + 20) + 'px',
fontSize: fontSize,
fontWeight: 500,
}"
>
<view
class="nav-bar__left"
:style="{
height: menuButtonInfo.height + 'px',
lineHeight: menuButtonInfo.height + 'px',
paddingTop: menuButtonInfo.top + 'px',
textIndent: leftTextIndent,
width: leftWidth,
}"
>
<uni-icons
v-if="showIcon"
class="nav-bar__left__icon"
type="back"
size="18"
@click="toBack"
>
</uni-icons>
<text :style="{color: color, textIndent: showIcon? '10rpx' : ''}">{{ leftText }}</text>
</view>
<view
class="nav-bar__title"
:style="{
height: menuButtonInfo.height + 'px',
lineHeight: menuButtonInfo.height + 'px',
paddingTop: menuButtonInfo.top + 'px',
}"
>
<text :style="{color: color}">{{ titleText }}</text>
</view>
<view
class="nav-bar__right"
:style="{
height: menuButtonInfo.height + 'px',
lineHeight: menuButtonInfo.height + 'px',
paddingTop: menuButtonInfo.top + 'px',
}"
>
<text :style="{color: color}">{{ rightText }}</text>
</view>
</view>
<!-- 占位元素 -->
<view
:style="{
height: (menuButtonInfo.height + statuBar + 20) + 'px'
}">
</view>
</template>
<script setup lang="ts">
import { toRefs } from 'vue'
import { back } from '@/utils/tools'
interface Props {
icon?: string;
showIcon?: boolean;
leftText?: string;
titleText?: string;
rightText?: string;
backgroundColor?: string;
color?: string;
fontSize?: string;
leftTextIndent?: string;
leftWidth?: string;
}
const props = withDefaults(defineProps<Props>(), {
icon: 'http://211.145.63.170:18080/profile/upload/2023/07/15/doubleright@2x_20230715201840A002.png',
boolean: false,
leftText: '返回',
titleText: '',
rightText: '',
backgroundColor: '#FF7979;',
color: '#fff;',
fontSize: '36rpx;',
leftTextIndent: '30rpx;',
leftWidth: '200rpx;'
})
const toBack = () => {
back()
}
// 數(shù)據(jù)
const { icon, showIcon, leftText, titleText, rightText, backgroundColor, color, fontSize, leftTextIndent, leftWidth } = toRefs(props)
// 自定義導(dǎo)航的高度,文字與膠囊平齊
let menuButtonInfo = uni.getMenuButtonBoundingClientRect(); // 獲取的微信小程序膠囊布局位置信息在頁面上的具體展現(xiàn)
let statuBar:any = uni.getSystemInfoSync().statusBarHeight || 0; // 狀態(tài)欄高度
</script>
<style lang="scss">
.nav-bar {
display: flex;
position: fixed;
left: 0;
top: 0;
z-index: 100;
width: 100vw;
&__left{
width: 200rpx;
overflow: hidden; // 超出部分隱藏
text-overflow:ellipsis; // 省略號
white-space: nowrap; // 禁止換行
display: flex;
&__icon{
text{
color: #fff!important;
}
}
}
&__title{
flex: 1;
text-align: center;
}
&__right{
width: 200rpx;
}
}
</style>
真機(jī)測試,成功。
uni-app官網(wǎng)-uni-nav-bar
二十二、登錄/獲取用戶信息
22.1、button組件調(diào)用getPhoneNumber獲取手機(jī)號,獲取到phoneCode
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">去登錄</button>
22.2、調(diào)用wx.login獲取到code?
22.3、調(diào)用wx.getUserInfo獲取用戶信息,用戶名為“微信用戶”,頭像為默認(rèn)頭像,性別為0-未知(0-未知;1-男;2-女)
22.4、通過以上兩個步驟獲取到的信息,調(diào)用后端接口獲取token
22.5、通過點擊用戶名或頭像,調(diào)用wx.getUserProfile(開發(fā)工具可用,手機(jī)不可用),必須通過點擊事件調(diào)用,獲取真正的用戶昵稱,頭像。性別獲取不到,各種方法都嘗試了,獲取到的是0-未知。有能獲取的道友歡迎留言交流。
uniapp微信小程序最新登錄獲取頭像、昵稱_小吳在打碼的博客-CSDN博客
二十三、official-account公眾號關(guān)注組件
小程序:official-account公眾號關(guān)注組件_微信小程序official-account_snow@li的博客-CSDN博客
二十四、防止滑動穿透
24.1、使用css的touch-action屬性
在需要防止滑動穿透的元素(如彈框)的樣式中,添加touch-action: none;
屬性即可禁止滑動事件穿透到下面的元素。
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
padding: 20px;
touch-action: none; /* 禁止滑動事件穿透 */
}
24.2、使用vue的stop.propagation方法
在需要防止滑動穿透的元素上,添加@touchmove.stop.propagation
屬性,阻止滑動事件的繼續(xù)傳遞,從而實現(xiàn)防止滑動穿透的效果。
<view class="modal" @touchmove.stop.propagation>
<!-- 彈框內(nèi)容 -->
</view>
二十五、圖片預(yù)覽
// 圖片預(yù)覽
previewImg(img){
wx.previewImage({
urls: [img], //需要預(yù)覽的圖片http鏈接列表,多張的時候,url直接寫在后面就行了
current: '', // 當(dāng)前顯示圖片的http鏈接,默認(rèn)是第一個
success: function(res) {},
fail: function(res) {},
complete: function(res) {},
})
}
二十六、自定義進(jìn)度條
<view v-if="isPlayOperate" class="progress-area">
<view class="progress-area__bar" id="progressBar" @touchstart="onDragStart" @touchmove="onDragging" @touchend="onDragEnd">
<view class="progress-area__bar__progress" id="progress" :style="'width:' + progressBarWidth"></view>
<view class="progress-area__bar__thumb" id="thumb" :style="'left:' + progressBarWidth"></view>
</view>
</view>
// 播放進(jìn)度/進(jìn)度條區(qū)域
const progressPercent = ref(0);
const progressBarWidth = ref('0%');
const isDragging = ref(false);
// closeProgressArea() // 關(guān)閉進(jìn)度條區(qū)域
const closeProgressArea = () => {
isPlay.value = true // 播放暫停的icon
isPlayOperate.value = false // 關(guān)閉播放操作的彈窗
progressPercent.value = 0 // 播放進(jìn)度初始化
progressBarWidth.value = '0%' // 播放進(jìn)度初始化
isDragging.value = false // 播放進(jìn)度初始化
}
const onDragStart = ()=> {
isDragging.value = true;
}
const onDragging = async (e: TouchEvent) => {
let progressBarWidthValue = 0;
let progressBarLeftValue = 0;
let thumbWidthValue = 0;
uni.createSelectorQuery()
.select(`#progressBar`).boundingClientRect((rect: any) => {
progressBarWidthValue = rect.width
progressBarLeftValue = rect.left
})
.select(`#thumb`).boundingClientRect((rect: any) => {
thumbWidthValue = rect.width
})
.exec(()=>{
let offsetX = e.touches[0].clientX - progressBarLeftValue;
if (offsetX < 0) {
offsetX = 0;
} else if (offsetX > (progressBarWidthValue - thumbWidthValue)) {
offsetX = progressBarWidthValue - thumbWidthValue;
}
const percent = offsetX / (progressBarWidthValue - thumbWidthValue) * 100;
progressPercent.value = percent;
progressBarWidth.value = `${percent}%`;
});
}
const onDragEnd = () => {
isDragging.value = false;
const currentTime = (progressPercent.value / 100) * progressDurationNum.value
let seek = Number(currentTime.toString()?.split('.')[0])
videoContext.seek(seek) // 設(shè)置當(dāng)前播放的位置,該方法接受一個以秒為單位的數(shù)字參數(shù),表示要跳轉(zhuǎn)到的視頻位置。
setTimeout(()=>{
playVideo() // 播放
}, 100)
};
.progress-area{
position: absolute;
bottom: 190rpx;
display: flex;
align-items: center;
width: 80vw;
&__bar{
position: relative;
height: 20rpx;
width: 100%;
background: #f0f0f0;
border-radius: 10rpx;
&__progress{
position: absolute;
top: 0;
left: 0;
bottom: 0;
background: #F1D4D8;
border-radius: 10rpx;
}
&__thumb{
position: absolute;
top: 9rpx;
left: 0;
width: 40rpx;
height: 40rpx;
background: linear-gradient(137deg, #FF8E8E 0%, #FF5050 100%);
border-radius: 20rpx;
transform: translate(-50%, -50%);
}
}
}
二十七、點右上角三個點,分享給朋友、分享到朋友圈
頁面onLoad 或?onShow 執(zhí)行下面方法即可
wx.showShareMenu({
withShareTicket:true,
menus:['shareAppMessage','shareTimeline']
})
二十八、復(fù)制、粘貼
// 使用wx.setClipboardData方法將需要復(fù)制的文本放入系統(tǒng)剪貼板中
wx.setClipboardData({
data: '需要復(fù)制的文本內(nèi)容',
success: function (res) {
wx.showToast({
title: '復(fù)制成功',
});
}
})
// 使用wx.getClipboardData方法獲取系統(tǒng)剪貼板中的文本內(nèi)容。
wx.getClipboardData({
success: function(res) {
console.log(res.data) // 輸出剪貼板中的文本內(nèi)容
}
})
二十九、過程記錄
記錄一
?
?[plugin:vite:css] PostCSS plugin uni-app requires PostCSS 8.
https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users
解決
yarn add postcss
啟動項目,問題解決了。?
記錄二
?
解決
?project.config.json增加:
"miniprogramRoot": "dist/dev/mp-weixin/",
?
增加后,項目啟動成功。?
記錄三
微信開發(fā)工具,小程序請求接口報錯:
- errMsg:?"request:fail invalid url "/m-staff-center/api/v1/login/getCurrentAppList""
- errno:?600009
解決
?
?這樣就可以了。
記錄四
?
解決
根據(jù)提示進(jìn)行了更新,更新后正常
?
記錄五
Cannot find name 'wx'.ts(2304)
解決
這個錯誤通常是由于缺少小程序類型聲明文件(d.ts)導(dǎo)致的。你需要在項目中引入小程序類型聲明文件,解決這個報錯問題。
1、安裝小程序類型聲明文件
npm install -D @types/wechat-miniprogram
2、?在 tsconfig.json 中配置類型聲明文件路徑,配置如下
{
"compilerOptions": {
"types": ["wechat-miniprogram"]
}
}
3、測試成功,鼠標(biāo)放上去,出現(xiàn)了正確的提示。
記錄六、獲取url參數(shù)
// 獲取url參數(shù)
onLoad((option: any)=>{
console.log('54', option)
})
記錄七、[渲染層網(wǎng)絡(luò)層錯誤] Failed to load media
小程序加載視頻的時候提示 [渲染層網(wǎng)絡(luò)層錯誤] Failed to load media | 微信開放社區(qū)
記錄八、uniapp應(yīng)該使用view標(biāo)簽還是使用div標(biāo)簽
使用view?
uniapp編寫頁面時應(yīng)該使用div還是view元素
記錄九、小程序tabBar iconPath可以使用網(wǎng)絡(luò)圖片嗎
記錄十、<button>去掉邊框
uniapp 微信小程序 button 按鈕去除邊框_uniapp button 去掉邊框_周zerlinda的博客-CSDN博客
記錄十一、display-multiple-items
swiper? display-multiple-items? 當(dāng)播放數(shù)量需要大于等于設(shè)置的數(shù)量,當(dāng)只有一個item時,數(shù)量不能大于1,只能是1
記錄十二、實現(xiàn)錨點連接/錨點跳轉(zhuǎn)
小程序-uniapp:實現(xiàn)錨點連接/錨點跳轉(zhuǎn)_snow@li的博客-CSDN博客
記錄十三、為什么小程序預(yù)覽時必須打開‘調(diào)試工具vconsole’才能正常運行?
為什么小程序預(yù)覽時必須打開‘調(diào)試工具vconsole’才能正常運行?_小程序打開調(diào)試才正常運行_ghhuidan的博客-CSDN博客
記錄十四、uniapp中的@tap和@click的區(qū)別
在uniapp中,@tap和@click都是用來綁定點擊事件的。它們的區(qū)別在于:
1、@tap是在touchend事件結(jié)束后觸發(fā)的,而@click是在click事件結(jié)束后觸發(fā)的。
2、@tap在移動設(shè)備上可以避免click事件的300毫秒延遲,所以更適合移動端使用。
3、@tap可以在控件被長按時不觸發(fā),而@click無法避免這種情況。
因此,如果你主要是開發(fā)移動端應(yīng)用,建議使用@tap來綁定點擊事件。如果你同時支持PC端和移動端,則可以同時使用@click和@tap來綁定點擊事件,以確保能夠在不同平臺上都正常觸發(fā)。
當(dāng)uniapp編譯后,所有用@click綁定的點擊事件都會被轉(zhuǎn)換成@tap事件,以便在移動端能夠更快地響應(yīng)用戶操作。
這是因為在移動端,click事件有一個300毫秒的延遲,因為系統(tǒng)需要等待一段時間來判斷用戶是單擊還是雙擊等操作。這種延遲會影響用戶體驗,所以uniapp默認(rèn)將@click轉(zhuǎn)換成@tap綁定的事件。
然而,你仍然可以在代碼中使用@click來綁定點擊事件,編譯后會自動轉(zhuǎn)換成@tap事件。如果你需要在PC端使用@click綁定點擊事件,可以考慮使用條件編譯等方式來針對不同平臺設(shè)置不同的事件綁定。
記錄十五、微信小程序的APPID和原始ID的卻別
微信小程序的APPID和原始ID都是微信小程序的標(biāo)識符,但是它們的作用和用途不同。
15.1、APPID(Application ID)是微信小程序的唯一標(biāo)識符,每個小程序都有一個獨立的APPID,類似于一個應(yīng)用程序的ID,可以用來在微信公眾平臺上注冊和管理小程序。在小程序開發(fā)中,APPID用于獲取用戶信息、調(diào)用微信支付等操作,也是小程序上線發(fā)布的必要條件。
15.2、原始ID(Original ID)是微信公眾號和小程序的一個唯一標(biāo)識符,每個公眾號和小程序都有一個獨立的原始ID,類似于一個賬號的ID。原始ID是用于在后臺操作中識別公眾號和小程序的,比如獲取公眾號和小程序的統(tǒng)計數(shù)據(jù)、設(shè)置自動回復(fù)、獲取二維碼等。
記錄十六、textarea輸入字?jǐn)?shù)只能輸入149個,需要輸入不受限制
maxlength="-1"
小程序textarea組件字?jǐn)?shù)限制問題 | 微信開放社區(qū)
記錄十七、小程序input鍵盤上出現(xiàn)完成按鈕無法隱藏問題
qq小程序input鍵盤上出現(xiàn)完成按鈕無法隱藏問題_小程序的輸入法怎么有完成的按鈕-CSDN博客
記錄十八、scroll-view 區(qū)域滾動
小程序-uni-app:scroll-view/區(qū)域滾動、下拉刷新、上拉加載更多_uniapp scroll-view-CSDN博客
記錄十九、微信小程序有分包數(shù)量和體積的限制嗎
數(shù)量沒限制,大小有限制,整個小程序所有分包大小不超過 20M
請問小程序分包加載有數(shù)量上限嗎?最多可以多少個分包? | 微信開放社區(qū)
三十、歡迎交流指正,關(guān)注我,一起學(xué)習(xí)。
三十一、參考鏈接
Vue3.2在uniapp中如何接受uni.navigateTo跳轉(zhuǎn)時url上攜帶的參數(shù)_接收navigateto參數(shù)_天才較瘦的博客-CSDN博客
利用uniapp中模仿抖音、滑動視頻組件、雙擊點贊、首個視頻自動播放_uniapp 抖音_是小橙鴨丶的博客-CSDN博客
uniapp設(shè)置小程序更新無效怎么解決-uni-app-PHP中文網(wǎng)
[app.json文件內(nèi)容錯誤]app.json未找到】解決方法_app.json 文件內(nèi)容錯誤_快樂的叮小當(dāng)?shù)牟┛?CSDN博客
uniapp 使用 axios_小小雨傘的博客-CSDN博客_uniapp使用axios
uniapp調(diào)取接口的方法_Front 小思的博客-CSDN博客_uniapp接口調(diào)用
uniapp自定義環(huán)境配置開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境接口請求域名_吹了一夜風(fēng)~的博客-CSDN博客_uniapp環(huán)境配置
uniapp設(shè)置跨域代理_一生酷到底的博客-CSDN博客_uniapp配置代理
uniapp+typeScript+vue3.0+vite_Z Y X的博客-CSDN博客
uniapp(vuecli創(chuàng)建) 動態(tài)配置manifest.json文件_酋長殼的博客-CSDN博客_uniapp的manifest.json
uniapp 報錯 [ app.json 文件內(nèi)容錯誤] app.json: app.json 未找到(env: Windows,mp,1.05.2107090; lib: 2.20.1)_mb5ff4099f0a555的技術(shù)博客_51CTO博客文章來源:http://www.zghlxwxcb.cn/news/detail-612246.html
UNIAPP原生TABBAR設(shè)置并添加數(shù)字角標(biāo)或小紅點提示_uni.settabbarbadge_海鷗兩三的博客-CSDN博客文章來源地址http://www.zghlxwxcb.cn/news/detail-612246.html
到了這里,關(guān)于小程序-uni-app:uni-app-base項目基礎(chǔ)配置及使用/uni-app+vue3+ts+vite+vscode的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!