2020年uniapp學習手記-基礎篇,和我一起學uniapp
uniapp基礎部分
有文件還看什麼教程?
官網文件非常的詳細,但是如果沒有接觸過的新人看文件其實是沒法學的,因為他不知道要完成一個開發,需要學習那些知識點,而且如何正確的使用文件也不清楚
本次內容主要是為後面的實戰課打基礎,如果你會的話完全可以不看,也大可不必說什麼風言風語,你會不代表別人都會,說這種話真的讓人挺難受的
其實我昨天晚上凌晨已經錄了一套視訊是完全現場看文件錄的,效果不好,還是得寫個簡單的文件來錄(肝?)
本次的內容主要就是帶你看文件,沒錯就是看文件,讓你學會看文件,並且有個整體的認知
開發工具
首先uniapp可以使用命令列的方式開發,然後選擇你喜歡的開發工具,但是大可不必,HBuilder X完全能滿足需求,記得下載app開發版本的
官方稱可以同時編譯十個平臺,但是如果你想讓每個平臺都是同樣的體驗的話,估計是要花很多的功夫的;即使你只需要開發微信小程式一個平臺,uniapp也是一個很好的選擇
我希望你是使用chrome瀏覽器的,新edge瀏覽器也可以,如果你對瀏覽器除錯感興趣的話還可以看我總結的瀏覽器除錯技巧
你還可以在電腦上安裝一個 Android的虛擬機器用來做安卓端的除錯,安裝小程式開發工具(一般安裝微信的就可以了)
前置知識
你最好能有vuejs的基礎知識,如果沒有也別怕,可以跟著我的vue基礎教程學習,花不了多少時間
認識一下官方文件
- 介紹 ;這個部分的內容更像一個說明書,可以看一下
- 框架;這個部分更多的是關於整個專案的配置方面的東西
- 元件;專案中的頁面實現主要看這個部分
- API;專案中的邏輯功能主要看這個部分
- unicloud;小公司利器,後面會專門講
意圖
首先你一定要明確自己的意圖,使用uniapp的目的,不能為了會什麼技術去做什麼東西,要為了實現什麼功能去學習技術
-
如果你是想開發精美的移動app 你完全可以使用原生就行開發 flutter也是更好的選擇
-
如果你只是想開發小程式,uniapp也是一個非常好的選擇
-
如果你想快速上線一個 小程式+app的應用,你需要提前做好填坑的心理準備
- uniapp繼承了weex那一套,再app端你可以使用nvue渲染,純原生渲染
我們認識一下專案
開啟manifest.json
可以對我們的專案進行配置,不過目前你也不能配置個啥,可以設定一下h5網頁的名稱或者是app端的圖示等等,後面需要配置的地方再說
page
pages.json
是專案的頁面配置,可能是我們前面最多配置的地方,pages
陣列裡面放置的就是一個個頁面,第一項配置就是預設開啟程式的頁面,後面如果我們除錯哪個頁面,為了方便可以把他放到第一個位置
tabBar
很多應用基本的標配
配置它也很簡單,我們先建立三個頁面來試一試,在pages
資料夾滑鼠右鍵可以選擇新建頁面
根據這個方式我們新建content、list
這兩個頁面,每個頁面的檔案中我們就隨便寫個文字區別就行了,uniapp的頁面結構和vuejs是幾乎一樣的
然後我們在static
目錄下放置一個圖示icon.png
在page.json
中配置我們的tabBar,可以通過color
和selectedColor
來設定預設和選中的字型顏色,list
裡面就是放置的具體每個選項,每個選項裡面需要配置pagePath
頁面連結,iconPath
預設圖selectedIconPath
選中以後的圖示,text
文字
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#f55f25",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/logo.png",
"selectedIconPath": "static/icon.png",
"text": "主頁"
},
{
"pagePath": "pages/list/list",
"iconPath": "static/logo.png",
"selectedIconPath": "static/icon.png",
"text": "列表"
}, {
"pagePath": "pages/content/content",
"iconPath": "static/logo.png",
"selectedIconPath": "static/icon.png",
"text": "內容"
}
]
}
看下效果
導航欄
當頁面的預設導航欄不滿足我們的需求的時候,我們可以自定義導航欄,只需要在這個頁面的page.json
欄目設定一下就可以了
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app",
"navigationStyle":"custom"
}
},
此時我們的導航欄就不見了,可以使用官方的元件,也可以自己實現,詳情看下方的使用元件
使用元件
uniapp的生態還是不錯的,除了官方的 uni-ui
外掛市場還有很多現成的東西
我們下載一個這個外掛
新版本的uniapp是不需要做任何配置可以直接使用第三方元件的
直接在頁面中使用這個外掛,然後看看效果
<uni-nav-bar left-icon="back" left-text="返回" right-text="選單" title="導航欄元件"></uni-nav-bar>
使用微信小程式的元件
有時候你需要的元件,uniapp外掛市場沒有,但是微信小程式元件裡面有怎麼辦呢,uniapp也是可以使用小程式元件的
在根目錄新建一個wxcomponents
資料夾,裡面繼續建立一個wxcomdemo
資料夾
建立以下幾個檔案
index.js
Component({
properties: {
// 這裡定義了innerText屬性,屬性值可以在元件使用時指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 這裡是一些元件內部資料
someData: {}
},
methods: {
// 這裡是一個自定義方法
customMethod: function(){}
}
})
index.json
{
"component": true
}
index.wxml
<view class="inner">
{{innerText}}
</view>
<slot></slot>
index.wxss
/* 這裡的樣式只應用於這個自定義元件 */
.inner {
color: red;
}
以上這幾個檔案便組成了一個標準的小程式元件了,這個元件的意思就是傳入一個字串,然後展示它字型為紅色,下面來使用這個元件吧!
在需要使用這個元件的頁面的page.json
項配置
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app",
"navigationStyle": "custom",
"usingComponents": {
"wxcomdemo": "/wxcomponents/wxcomdemo/index"
}
}
然後在這個頁面中使用
<wxcomdemo inner-text="Some text"></wxcomdemo>
此時我們看看效果
構建一個todolist
使用color ui
因為懶得寫樣式,我們引入colorui,匯入專案以後複製根目錄的 /colorui
資料夾到你的根目錄
App.vue引入關鍵Css
<style>
@import "colorui/main.css";
@import "colorui/icon.css";
</style>
平時開發的時候需要什麼效果,我們直接將這個示例專案執行起來,然後去複製它頁面中的程式碼就行
列表渲染
比如這個列表左滑就適合我們的頁面
直接複製過來做下修改,首先定義幾個需要使用的屬性
staticTodoList: [{
_id: 1,
_name: "第一件事",
_status: false
},
{
_id: 2,
_name: "第二件事",
_status: true
},
{
_id: 3,
_name: "第三件事",
_status: false
}
],
todoList: [],
modalName: null,
listTouchStart: 0,
listTouchDirection: null,
在onload
的時候我們要初始化資料,這個staticTodoList
就是我們模擬的靜態資料
onLoad() {
this.todoList = this.staticTodoList;
},
然後使用剛剛複製的頁面程式碼渲染它
<view class="cu-item"
:class="modalName=='move-box-'+ index?'move-cur':''"
v-for="(todo,index) in todoList"
:key="index"
@touchstart="ListTouchStart"
@touchmove="ListTouchMove"
@touchend="ListTouchEnd"
:data-target="'move-box-' + index">
<view class="content" >
<view class="text-grey">{{todo._name}}</view>
</view>
<view class="action">
<switch :checked="todo._status" :data-_id="todo._id" />
</view>
<view class="move">
<view class="bg-red" >刪除</view>
</view>
</view>
它的頁面中還定義了幾個事件,我們也拷貝過來
ListTouchStart(e) {
this.listTouchStart = e.touches[0].pageX
},
ListTouchMove(e) {
this.listTouchDirection = e.touches[0].pageX - this.listTouchStart > 0 ? 'right' : 'left'
},
ListTouchEnd(e) {
if (this.listTouchDirection == 'left') {
this.modalName = e.currentTarget.dataset.target
} else {
this.modalName = null
}
this.listTouchDirection = null
},
看下效果
刪除和切換(小技巧?)
<view class="action" >
<switch :checked="todo._status" @change="switchTodo" :data-_id="todo._id" />
</view>
<view class="move">
<view class="bg-red" @click="del(todo._id)">刪除</view>
</view>
這兩個事件也非常簡單,主要是狀態切換這裡有個小問題,@change
只能傳遞當前的是否選中的值,不能傳遞當前項的id值,這就沒法處理資料,所以可以給這個節點繫結一個:data-_id="todo._id"
,然後通過e.target.dataset._id
就能取出這個id值了!
switchTodo(e) {
const status = e.target.value;
const _id = e.target.dataset._id;
this.todoList = this.todoList.map(todo => {
if (todo._id == _id) {
todo._status = status;
}
return todo;
})
uni.showToast({
title: status ? "已完成" : "已取消",
icon: status ? "success" : "none"
})
},
del(_delId) {
this.todoList = this.todoList.filter(todo => {
return todo._id != _delId
});
},
mixin
vue中的mixin同樣的也可以在這裡面使用,不知道這個東西的朋友,可以理解為公用邏輯抽離,需要使用的地方直接引入就可以了
比如Toast
這個訊息通知經常用,我們可以封裝一下,新建一個mixin/message.js
module.exports = {
methods: {
toast(message, duration, success) {
uni.showToast({
title: message,
icon: success ? "success" : "none",
duration: duration
})
},
},
};
使用它
import message from "@/mixin/message.js"
export default {
... ...
mixins: [message],
... ...
}
然後可以直接通過this.toast("不能為空", 2000, false);
來使用
表單
新增todo的功能,還是去coloruI的專案裡面拷貝 form的模板程式碼
<form @submit="add" @reset="clear">
<view class="cu-form-group margin-top">
<view class="title">新增</view>
<input placeholder="todo" name="_name"></input>
</view>
<view class="padding flex flex-direction">
<button form-type="submit" class="cu-btn bg-blue lg">儲存</button>
<button form-type="reset" class="cu-btn bg-red margin-tb-sm lg">清空</button>
</view>
</form>
這個新增和清空事件也非常簡單
add(e) {
let _name = e.detail.value._name;
if (_name === null || _name === "") {
this.toast("不能為空", 2000, false);
return;
}
const _id = this.todoList.length > 0 ? this.todoList[this.todoList.length - 1]._id + 1 : 1;
this.todoList.push({
_id: _id,
_name: _name,
_status: false
});
this.toast("新增成功,_id:" + _id,1000,true)
e.detail.value = null;
},
clear() {
}
資料快取
刪除以後我們重新整理頁面資料又回來了,可以試一下資料快取(真實開發,這些都是後端返回)
我們在switchTodo、del、add
這三個事件裡面我們都新增一個快取,將最新資料快取到本地
uni.setStorageSync("todolist", this.todoList);
然後在頁面啟動的時候載入這個快取
onLoad() {
const todolist = uni.getStorageSync("todolist")
if (todolist != "") {
this.todoList = uni.getStorageSync("todolist");
} else {
this.todoList = this.staticTodoList;
}
},
頁面跳轉
我們新增一個todocontent
頁面,方便我們點進去檢視每一個todo的詳情
然後修改一下頁面的列表渲染,增加一個點選事件
<view class="cu-item"
:class="modalName=='move-box-'+ index?'move-cur':''"
v-for="(todo,index) in todoList"
:key="index"
@click="gotoContent(todo._id)"
... ...
寫一下這個事件gotoContent
,頁面傳參和網頁的形式差不多文件
gotoContent(_id) {
uni.navigateTo({
url: '../todocontent/todocontent?_id=' + _id
});
},
然後在 todocontent
這個頁面中接受這個引數
onLoad(e) {
console.log(e._id);
},
冒泡點選
上面的功能實現以後會有一個問題,此時我們再次點選刪除或者切換的按鈕,就會直接跳轉到另外一個頁面了,所以我們要阻止這個點選部位的跳轉事件,很簡單
<view class="action" @click.stop="">
<switch :checked="todo._status" @change="switchTodo" :data-_id="todo._id" />
</view>
<view class="move">
<view class="bg-red" @click.stop="del(todo._id)">刪除</view>
</view>
網路請求
為了有意思一點,我們這個具體的content
的資料將模擬後端返回
建立服務(小技巧?)
最方便的開啟一個服務可以使用vscode的 live server
外掛
我們新建個todolist.json
檔案
[
{
"_name": "第一件事",
"_id":1,
"_status":false,
"_time":1601956497000,
"_content":"花花世界迷人眼,沒有實力別賽臉。"
},
{
"_name": "第二件事",
"_id":2,
"_status":false,
"_time":1601956497000,
"_content":"天熱脾氣躁,我不微笑你別鬧。"
},
{
"_name": "第三件事",
"_id":3,
"_status":false,
"_time":1601956497000,
"_content":"江南江北一條街,打聽打聽誰是爹。"
}
]
這裡有個時間戳對吧,再介紹一個小技巧?,我們在瀏覽器中定義這樣的指令碼
然後按ctrl + p
使用快捷執行這個命令
想檢視更多的瀏覽器技巧嗎瀏覽器除錯
隨便建立一個html
檔案然後使用live server
開啟
接著我們在位址列找到我們的json檔案,服務啟動成功!
請求資料
我們開始在todocontent
這個頁面請求資料了
首先我們要onLoad
裡面進行請求
onLoad(e) {
this.loadData(parseInt(e._id));
},
寫一下這個loadData
loadData(_id) {
this.getTodoById(_id);
},
還用定義一個預設的空的todo物件
todo: {
_id: -1,
_name: "null",
_status: false,
_time: null,
_content: "null"
},
寫一下這個getTodoById
使用uni.request
請求資料,這裡使用 promise
的方式稍微寫複雜且沒有意義,單純就是為了給大家模擬一個實際開發的常規請求
async getTodoById(_id) {
uni.showLoading();
const value = await uni.request({
url: 'http://127.0.0.1:5500/todolist.json'
}).then(data => {
uni.hideLoading();
var [error, res] = data;
if (error != null | res == null) {
this.toast("網路異常", 1000, false)
return Promise.resolve(this.todo);
}
if (res.data.length > 0) {
const todo = res.data.find(todo => {
return todo._id === _id;
})
return Promise.resolve(todo);
}
});
this.todo = value;
}
渲染資料
還是像上面一下去拷貝一個頁面過來
<view class="flex justify-start align-center">
<view class="text-sl">
{{todo._name}}
</view>
<view class="margin-left-sm">
{{todo._time}}
</view>
<view class="margin-left-sm">
<switch :checked="todo._status" disabled="" />
</view>
</view>
<view class="text-xl text-gray margin-top-sm">
{{todo._content}}
</view>
<view class="padding flex flex-direction">
<button @click="del" class="cu-btn bg-red margin-tb-sm lg">刪除</button>
</view>
過濾器
上面的時間還是時間戳肯定是不行的,我們可以使用過濾器來轉換一下
來到main.js
中,這裡的時間戳稍微寫的繁雜一點,但是很實用,可以自定義返回
//補位
function formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n;
}
// 時間戳轉換日期
function formatTime(number, format) {
if (!number || number == null) {
return null;
}
let time = new Date(number);
let newArr = []
let formatArr = ['Y', 'M', 'D', 'h', 'm']
newArr.push(time.getFullYear())
newArr.push(formatNumber(time.getMonth() + 1))
newArr.push(formatNumber(time.getDate()))
newArr.push(formatNumber(time.getHours()))
newArr.push(formatNumber(time.getMinutes()))
for (let i in newArr) {
format = format.replace(formatArr[i], newArr[i])
}
return format;
}
Vue.filter('strtotime', function(msg, arg) {
return formatTime(msg, 'Y-M-D');
})
使用它
<view class="margin-left-sm">
{{todo._time|strtotime}}
</view>
頁面通訊
這裡有個刪除事件,可以通過 頁面通訊來通知上一個頁面刪除這個資料
定義一下這個del
del() {
uni.$emit('del_todo', {
_id: this.todo._id
});
//刪除完成後返回上一頁
uni.navigateBack();
},
然後在上一個頁面中監聽事件
onLoad() {
const todolist = uni.getStorageSync("todolist")
if (todolist != "") {
this.todoList = uni.getStorageSync("todolist");
} else {
this.todoList = this.staticTodoList;
}
uni.$on('del_todo', (data) => {
this.del(data._id);
})
},
下拉重新整理
如果我們想恢復最原本的資料,可以定義一個下拉重新整理事件
首先需要開啟page.json
中的配置enablePullDownRefresh
"style": {
"navigationBarTitleText": "uni-app",
"navigationStyle": "custom",
"usingComponents": {
"wxcomdemo":"/wxcomponents/wxcomdemo/index"
},
"enablePullDownRefresh":true
}
然後在頁面中重新這個事件
onPullDownRefresh() {
uni.setStorageSync("todolist", "")
this.todoList=this.staticTodoList
uni.stopPullDownRefresh();
},
完成!
條件編譯
條件編譯就是某些內容只在某個或者某些平臺編譯展示
模板中的條件編譯
比如我只想在微信小程式中展示這個內容可以使用 ifdef
<!-- #ifdef MP-WEIXIN -->
mp-weixin
<!-- #endif -->
如果是想除了微信小程式這個平臺不顯示,其他的都使用呢?使用ifndef
就可以了
樣式中的條件編譯
<style lang="less">
/* #ifdef MP-WEIXIN */
.content {
color: #DD524D;
}
/* #endif */
</style>
未完待續!!!!
相關文章
- 一起學 TypeScript 基礎篇TypeScript
- MySQL學習筆記【基礎篇】MySql筆記
- vue學習筆記【基礎篇一】Vue筆記
- 02 uniapp專案基礎配置APP
- 和菜鳥一起學linux之DBUS基礎學習記錄Linux
- PHP學習筆記(1)–基礎知識篇PHP筆記
- Python基礎學習篇Python
- React學習手記1--基礎知識React
- 安卓初學基礎學習筆記安卓筆記
- JAVA基礎學習篇之反射Java反射
- javaScript學習基礎篇(3)(字串)JavaScript字串
- MySQL學習基礎之起航篇MySql
- bootstrap基礎學習一篇boot
- Linux基礎學習-Docker學習筆記LinuxDocker筆記
- CSS 基礎學習筆記CSS筆記
- node基礎學習筆記筆記
- Web基礎學習筆記Web筆記
- Redis基礎學習筆記Redis筆記
- Shell 學習筆記 基礎筆記
- Oracle基礎學習筆記Oracle筆記
- Java基礎學習筆記Java筆記
- uniapp小程式筆記APP筆記
- 12c in memory option學習筆記一_基礎篇筆記
- 深度學習word2vec筆記之基礎篇深度學習筆記
- 強化學習-學習筆記1 | 基礎概念強化學習筆記
- TypeScript學習文件-基礎篇(完結)TypeScript
- [效能測試] locust學習-基礎篇
- javaScript學習基礎篇(1)(陣列)JavaScript陣列
- 安心學習,重學前端之(js基礎篇(1))前端JS
- 菜鳥學習筆記:Java基礎篇1(基礎語法、物件導向)筆記Java物件
- DI、IOC基礎學習筆記筆記
- JavaScript學習筆記——基礎部分JavaScript筆記
- 彙編基礎學習筆記筆記
- 基礎知識學習筆記筆記
- Python基礎學習筆記Python筆記
- 影象拼接基礎學習筆記筆記
- 類的基礎學習筆記筆記
- JavaWeb基礎-學習筆記02JavaWeb筆記