uniapp基礎教程

1. 介紹

uni-app 是一個使用 Vue.js 開發所有前端應用的框架,開發者編寫一套代碼,可發布到iOS、Android、Web(響應式)、以及各種小程序(微信/支付寶/百度/頭條/飛書/QQ/快手/釘釘/淘寶)、快應用等多個平臺。

uni-app在手,做啥都不愁。即使不跨端,uni-app也是更好的小程序開發框架(詳見)、更好的App跨平臺框架、更方便的H5開發框架。不管領導安排什么樣的項目,你都可以快速交付,不需要轉換開發思維、不需要更改開發習慣。

2. 環境搭建

2.1 安裝編輯器HBuilder X (APP開發版)

下載地址 通用前端開發工具,為uniapp做了特別強化

插件安裝(工具 -> 插件安裝 -> 選擇插件下載

  • sass

  • git

  • npm

    image.png

2.2 安裝微信開發者工具

下載地址

image.png

3. 使用HBuilderX初始化項目

文件 -> 新建 -> uniapp項目

image.png

微信開發者工具端口開放 設置 -> 安全設置 -> 端口開啟

image.png

4. 項目目錄及作用

image.png

┌─components 符合vue組件規范的uni-app組件目錄

│ └─comp-a.vue 可復用的組件

├─pages 業務頁面文件存放的目錄

│ ├─index

│ │ └─index.vue index頁面

│ └─list

│ └─list.vue list頁面

├─static 存放應用引用的本地靜態資源(如圖片、視頻等)的目錄,注意: 靜態資源只能存放于此

├─uni_modules 存放uni_module規范的插件

├─wxcomponents 存放小程序組件的目錄

├─main.js Vue初始化入口文件

├─App.vue 應用配置,用來配置App全局樣式以及監聽 應用生命周期

├─manifest.json 配置應用名稱、appid、logo、版本等打包信息

└─pages.json 配置頁面路由、導航條、選項卡等頁面類信息

  • pages: 頁面存放目錄

  • static: 靜態資源目錄

  • unpackage: 打包輸出目錄

  • components: 組件存放目錄

  • App.vue: 根組件,所有頁面都在App.vue下進行切換,是頁面入口文件,可以調用應用的生命周期函數。

  • main.js: 項目入口文件,初始化vue實例并使用需要的插件。

  • manifest.json: 應用的配置文件,用于指定應用的名稱、圖標、權限等。

  • pages.json: 對uni-app進行全局配置,決定頁面文件的路徑、窗口樣式、原生的導航欄以及底部tabbar等。

  • uni.scss: 預置了scss變量預置,方便整體控制應用的風格,比如按鈕顏色、邊框風格

開發規范:

  • 頁面文件遵循Vue單文件組件(SFC)規范

  • 組件標簽靠近小程序規范

  • 接口能力靠近小程序規范

  • 數據綁定及事件處理同Vue.js規范,同時補充了APP及頁面規范生命周期

  • 為兼容多端運行,建議使用flex布局進行開發

3.4 代碼運行

  • 運行到瀏覽器

    運行 -> 運行到瀏覽器 -> chrome

image.png
  • 運行到小程序

    運行 -> 運行到小程序模擬器 -> 微信開發者工具

    image.png

第一次使用,需要先配置小程序ide的相關路徑,才能運行成功。

`工具 -> 設置 -> 運行配置`

![image.png](https://upload-images.jianshu.io/upload_images/25475908-ccdb549ee6202cd7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


若HBuilderX不能正常啟動微信開發者工具,需要開發者手動啟動,然后將uniapp生成小程序工程的路徑拷貝到微信開發者工具里面,在HBuilderX里面開發,在微信開發者工具里面就可看到實時的效果。

5. 全局配置和頁面配置

pages.json 配置手冊

globelStyle: 全局配置

image.png

pages: 頁面配置 通過 pages 節點配置應用由哪些頁面組成,pages 節點接收一個數組,數組每個項都是一個對象,其屬性值如下:

image.png
image.png

tabbar: 導航欄配置 在App和小程序端提升性能。在這兩個平臺,底層原生引擎在啟動時無需等待js引擎初始化,即可直接讀取 pages.json 中配置的 tabBar 信息,渲染原生tab。

image.png

image.png

6. condition

啟動模式配置,僅開發期間生效,用于模擬直達頁面的場景,如:用戶點擊所打開的頁面
image.png

7. uni-app組件

搭建頁面基礎結構

  • 視圖組件 view

    image.png

  • 基礎組件 text

    image.png

  • 表單組件 button

    image.png

  • 媒體組件 image

    image.png

8. 樣式設置

image.png

9. 數據綁定和事件綁定

同vue: v-bind\v-on

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n99" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
<input v-model="inputValue" @input="onChangeInput" />
</view>
<button @click="onClick"></button>
</view>
</template>

<script>
export default {
data() {
return {
title: 'Hi',
inputValue: '。。'
}
},
onLoad() {

},
methods: {
onClick(){
console.log('click')
},
onChangeInput(){
console.log(this.inputValue)
}
}
}
</script></pre>

10. 生命周期

  • 應用生命周期 僅可在App.vue中監聽,在頁面監聽無效。

    image.png

  • 頁面生命周期
    image.png

11. 下拉刷新

11.1 開啟下拉刷新

pages.json中加入下拉刷新屬性,globalStyle為全局添加,page中為單頁面添加

image.png

11.2 在頁面中進行uni.startPullDownRefresh(OBJECT)調用

官方文檔查看 開始下拉刷新,調用后觸發下拉刷新動畫,效果與用戶手動下拉刷新一致。

image.png

11.3 監聽下拉刷新

在頁面生命周期中加入監聽事件。當處理完數據刷新后,uni.stopPullDownRefresh可以停止當前頁面的下拉刷新。

image.png

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n114" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">onPullDownRefresh() {
console.log('刷新了');
uni.stopPullDownRefresh();
}</pre>

12. 網絡請求

uni.request(Object)

image.png

13. 數據存儲

  • 異步存儲 uni.setStorage(OBJECT) 將數據存儲在本地緩存中指定的 key 中,會覆蓋掉原來該 key 對應的內容

    image.png

    uni.getStorage(OBJECT) uni.removeStorage(OBJECT)

  • 同步存儲 uni.setStorageSync(KEY, DATA) 將 data 存儲在本地緩存中指定的 key 中,會覆蓋掉原來該 key 對應的內容

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n124" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">try {
uni.removeStorageSync('storage_key');
} catch (e) {
// error
}</pre>

uni.getStorageSync(KEY) uni.removeStorageSync(KEY)

14. 圖片上傳預覽

uni.chooseImage(OBJECT) 從本地相冊選擇圖片或使用相機拍照。

image.png

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n128" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">uni.chooseImage({
count: 6, //默認9
sizeType: ['original', 'compressed'], //可以指定是原圖還是壓縮圖,默認二者都有
sourceType: ['album'], //從相冊選擇
success: function (res) {
console.log(JSON.stringify(res.tempFilePaths));
}
});</pre>

uni.previewImage(OBJECT) 預覽圖片。

image.png

15. 條件編譯跨端兼容

注釋: #ifdef <端名>... #endif
image.png

16. 導航跳轉和傳參

在起始頁面跳轉到test.vue頁面并傳遞參數

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n135" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">uni.navigateTo({
url: 'test?id=1&name=uniapp'
});</pre>

在頁面接受參數

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n137" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">export default {
onLoad: function (option) { //option為object類型,會序列化上個頁面傳遞的參數
console.log(option.id); //打印出上個頁面傳遞的參數。
console.log(option.name); //打印出上個頁面傳遞的參數。
}
}</pre>

17. 組件創建、生命周期與父子組件傳值

(同vue)


1647498320670.png

18. request封裝(引用參考文章2)

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n142" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">var http = {
post(path, params, contentType = 'form', otherUrl, ) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
rej('請求失敗')
}
uni.request({
method: 'POST',
url,
header: {
"Content-Type": contentType === 'json' ? "application/json" :
"application/x-www-form-urlencoded"
},
data: params,
success: (res) => {
console.log('request:POST請求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('請求失敗', 'err')
console.error('request:請求' + config.baseUrl + path + ' 失敗', err)
reject('請求失敗')
}
})
})
},
put(path, params, contentType = 'form', otherUrl, ) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
rej('請求失敗')
}
uni.request({
method: 'PUT',
url,
header: {
"Content-Type": contentType === 'json' ? "application/json" :
"application/x-www-form-urlencoded"
},
data: params,
success: (res) => {
console.log('request:PUT請求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('請求失敗', 'err')
console.error('request:PUT請求' + config.baseUrl + path + ' 失敗', err)
reject('請求失敗')
}
})
})
},

get(path, params, otherUrl) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
return
}
uni.request({
url,
data: params,
success: (res) => {
console.log('request:GET請求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('請求失敗', 'err')
console.error('request:GET請求' + config.baseUrl + path + ' 失敗', err)
reject(err)
}
})

})

},
delete(path, params, otherUrl) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
return
}
uni.request({
url,
data: params,
method: "DELETE",
success: (res) => {
console.log('request:DELETE請求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('請求失敗', 'err')
console.error('request:DELETE請求' + config.baseUrl + path + ' 失敗', err)
reject(err)
}
})

})

},

async upload(path, fileArray, otherUrl) {

if (typeof fileArray !== 'object') {
console.error('request:參數錯誤,請傳入文件數組')
return
}
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
return
}
var arr = []
for (let i in fileArray) {
const res = await uni.uploadFile({
url: otherUrl || config.baseUrl + path,
filePath: fileArray[i],
name: 'file'
})
console.log(res)
if (res[0]) {
console.error('request:上傳失敗', res[0])
return
}
arr.push(JSON.parse(res[1].data).data)
}
return arr
},

}

function checkUrl(url) {
var urlReg = /((ht|f)tps?)://[\w-]+(.[\w-]+)+([\w-.,@?=%&:/+#]*[\w-@?^=%&/+#])?$/;
if (!urlReg.test(url)) {
console.error('request:請求路徑錯誤' + url)
return false
}
return true
}
module.exports = http</pre>

19. 小程序打包發布

19.1 登錄微信公眾平臺 -> 開發 -> 開發設置 -> 獲取AppId放在manifest.json微信小程序配置的AppID中

image.png

19.2 Hbuilder中發行 -> 小程序-微信

image.png

19.3 微信開發者工具中點擊上傳 -> 上傳

image.png

19.4 微信開發者平臺 -> 版本管理 -> 選擇提交的版本 -> 提交審核 -> 下一步填寫信息 -> 提交審核 (-> 撤回審核)-> 審核成功 -> 上線

image.png

20. H5發布

20.1 HBuilder中進入manifest.json H5頁面 -> 設置標題

image.png

20.2 HBuilder中點擊發行 -> 網站-H5手機版

image.png

參考文章:
uniapp實現小程序微信登錄
uniapp小程序開發的超長實踐總結

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容