使用 HBuilderX
可視化界面快速建立項目,HBuilderX
內置處理了相關環境依賴。css
在HBuilderX
編輯器中點擊工具欄裏的文件 -> 新建 -> 項目
:vue
選擇uni-app,輸入項目名稱,這裏有不少模板,選擇你所須要的。爲了以後表述方便,這裏先建立了ColorUI模板
,爲了方便之後引用ColorUI。而後有建立了一個默認模板
,這個默認模板文件不多,方便之後自由開發。以下兩圖所示。git
文件 | 做用 |
---|---|
pages.json | 配置頁面路由、導航條、選項卡等頁面類信息 |
manifest.json | 配置應用名稱、appid、logo、版本等打包信息 |
App.vue | 應用配置,用來配置App全局樣式以及監聽應用的生命週期 |
main.js | Vue初始化入口文件 |
static目錄 | 存放應用引用靜態資源(如圖片、視頻等)的地方,注意:靜態資源只能存放於此 |
pages目錄 | 業務頁面文件存放目錄 |
components目錄 | 組件文件存放目錄 |
注意:在開發過程當中,當你寫登陸功能後,某個頁面你須要常常進入而且屢次修改,你每次修改都須要登陸後的信息,因此就很麻煩了。你須要一直從登陸開始操做,直到你到達這個界面。這時候你就能夠用這個了condition
。github
如今來介紹一下condition
:web
condition 啓動模式配置,僅開發期間生效,用於模擬直達頁面的場景,如:小程序轉發後,用戶點擊所打開的頁面。json
屬性說明:小程序
屬性 | 類型 | 是否必填 | 描述 |
---|---|---|---|
current | Number | 是 | 當前激活的模式,list節點的索引值 |
list | Array | 是 | 啓動模式列表 |
list說明:後端
屬性 | 類型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 是 | 啓動模式名稱 |
path | String | 是 | 啓動頁面路徑 |
query | String | 否 | 啓動參數,可在頁面的 onLoad 函數裏得到 |
在 5+App 裏真機運行可直接打開配置的頁面,微信開發者工具裏須要手動改變編譯模式,過程:微信開發工具 -> 工具 -> 編譯配置 -> 找到在condition
裏配置的name
。
在pages.josn
裏配置condition
,代碼以下:
"condition": { //模式配置,僅開發期間生效
"current": 0, //當前激活的模式(list 的索引項)
"list": [{
"name": "jingdian_detail", //模式名稱
"path": "pages/jingdian_detail/jingdian_detail", //啓動頁面,必選
"query": "id=5d1483336d724301607b2c23" //啓動參數,在頁面的onLoad函數裏面獲得。
}
]
}
複製代碼
有了第二步建立好的模板,咱們就能夠引用了。
首先複製一下ColorUI
項目目錄下的colorui
目錄,而後粘貼到demo
項目的根目錄下,與pages
目錄同級。
若是喜歡ColorUI裏自定義的navigationBar
,即cu-custom
組件,那就須要在demo
項目中的main.js
裏導入。建議仍是使用cu-custom
組件。
/* demo/main.js */
import cuCustom from './colorui/components/cu-custom.vue'
Vue.component('cu-custom',cuCustom)
複製代碼
下圖就是ColorUI的狀態欄:
你能夠直接複製ColorUI
項目裏的App.vue
文件,由於這裏面設置好了cu-custom
組件的高度以及定義了全局的顏色。而且還須要將pages.json
配置取消系統導航欄。(開啓 custom 後,全部窗口均無導航欄)
"globalStyle": {
"navigationStyle": "custom"
},
複製代碼
若是不想用cu-custom
組件,那就直接在demo
項目裏的App.vue
文件的<style></style>
裏引入這兩句話就OK了。固然上面也須要加。
@import "colorui/main.css";
@import "colorui/icon.css";
複製代碼
關於引用ColorUI的介紹,也能夠查看引用ColorUI
/* ColorUI/pages/index/index.vue */
<template>
<view>
//使用v-if條件判斷,來顯示相應的界面
//若是點擊了底部中的「操做條元素->basics」、「組件->component」 或者 「擴展->plugin」,界面會出現相應的主界面。如上圖所示。
<basics v-if="PageCur=='basics'"></basics>
<components v-if="PageCur=='component'"></components>
<plugin v-if="PageCur=='plugin'"></plugin>
//這裏的「元素」,「組件」,「擴展」三個操做都是綁定一個點擊事件NavChange,經過設置PageCur的值再結合:class屬性來改變圖片的路徑,進而改變了按鈕的顏色
<view class="cu-bar tabbar bg-white shadow foot">
<view class="action" @click="NavChange" data-cur="basics">
<view class='cuIcon-cu-image'>
<image :src="'/static/tabbar/basics' + [PageCur=='basics'?'_cur':''] + '.png'"></image>
</view>
<view :class="PageCur=='basics'?'text-green':'text-gray'">元素</view>
</view>
<view class="action" @click="NavChange" data-cur="component">
<view class='cuIcon-cu-image'>
<image :src="'/static/tabbar/component' + [PageCur == 'component'?'_cur':''] + '.png'"></image>
</view>
<view :class="PageCur=='component'?'text-green':'text-gray'">組件</view>
</view>
<view class="action" @click="NavChange" data-cur="plugin">
<view class='cuIcon-cu-image'>
<image :src="'/static/tabbar/plugin' + [PageCur == 'plugin'?'_cur':''] + '.png'"></image>
</view>
<view :class="PageCur=='plugin'?'text-green':'text-gray'">擴展</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
PageCur: 'basics'
}
},
methods: {
NavChange: function(e) {
this.PageCur = e.currentTarget.dataset.cur
}
}
}
</script>
<style>
</style>
複製代碼
當點擊「元素」,「組件」,「擴展」三個按鈕的其中之一時,都會出現相應的頁面,緣由就是在ColorUI的項目裏mian.js
裏要引入下面的代碼:
import basics from './pages/basics/home.vue'
Vue.component('basics',basics)
import components from './pages/component/home.vue'
Vue.component('components',components)
import plugin from './pages/plugin/home.vue'
Vue.component('plugin',plugin)
複製代碼
這個底部操做條還有其它方式,能夠查看這個底部操做條
上前端代碼
<view class="list">
<view class="list-call">
<text class="cuIcon-mobile text-style "></text>
<input class="biaoti" v-model="phoneNum" type="number" maxlength="11" placeholder="輸入手機號" />
</view>
<view class="list-call">
<text class="cuIcon-lock text-style "></text>
<input class="biaoti" v-model="password" type="text"
maxlength="32" placeholder="輸入密碼" :password='tfpsw' />
<image class="img"
:src="showPassword?'../../static/login-reg-forget/op.png':'../../static/login-reg-forget/cl.png'"
@tap="display"></image>
</view>
<view class="list-call">
<text class="cuIcon-people text-style "></text>
<input class="biaoti" v-model="username" type="text" placeholder="輸入用戶名" />
</view>
</view>
<view class="dlbutton bg-color" hover-class="dlbutton-hover" @tap="bindReg">
<text>註冊</text>
</view>
<script>
export default {
data() {
return {
phoneNum:'',
password:'',
username:'',
tfpsw:true,
xieyi:true,
showPassword:false,
};
},
methods: {
//密碼顯示或打馬
display() {
this.showPassword = !this.showPassword
this.tfpsw =!this.tfpsw
},
//協議
xieyitong(){
this.xieyi = !this.xieyi;
},
//註冊
bindReg() {
//簡單驗證
if (this.xieyi == false) {
uni.showToast({
icon: 'none',
title: '請先閱讀《軟件用戶協議》'
});
return;
}
if (this.phoneNum.length !=11) {
uni.showToast({
icon: 'none',
title: '手機號不正確'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: '密碼位數至少6位'
});
return;
}
//將信息傳到後臺
uni.request({
//this.websiteUrl是全局api,在mian.js裏設置
url: this.websiteUrl+'/user/signup',
data: {
mobile:this.phoneNum,
password:this.password,
username:this.username,
},
method: 'POST',
dataType:'json',
success: (res) => {
if(res.statusCode==200){
uni.reLaunch({
url: "../login/login" //跳轉到首頁
});
uni.showToast({title:"註冊成功!",icon:'none'});
}else{
uni.showToast({title:"註冊失敗",icon:'wrong'});
}
}
});
}
}
}
</script>
//樣式表就不加啦
複製代碼
uni.request 是發起網絡請求 查看更多,在這裏我就提一下url: this.websiteUrl+'/user/signup',
這個url
裏的this.websiteUrl
,這個是在main.js
裏定義的全局api。
//設置全局的api地址
Vue.prototype.websiteUrl = 'http://10.4.14.132:7000';
複製代碼
其中10.4.14.132
是本地的IPV4
,:7000
是後端的端口號。
結合運行界面,更加直觀(圖有點大......)
此次換了一個手機類型,如今小了不少,先看看界面吧!
撂主要的代碼,以下:<view class="list">
<view class="list-call">
<text class="cuIcon-mobile text-style "></text>
<input class="biaoti" v-model="phoneNum" type="number" maxlength="11" placeholder="輸入手機號" />
</view>
<view class="list-call">
<text class="cuIcon-lock text-style "></text>
<input class="biaoti" v-model="password" type="text" maxlength="32" placeholder="輸入密碼" password="true" />
</view>
</view>
<view class="dlbutton bg-color" hover-class="dlbutton-hover" @tap="bindLogin()">
<text>登陸</text>
</view>
<script>
export default {
data() {
return {
phoneNum: '',
password: ''
};
},
methods: {
bindLogin() {
if (this.phoneNum.length != 11) {
uni.showToast({
icon: 'none',
title: '手機號不正確'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: '密碼不正確'
});
return;
}
uni.request({
url: this.websiteUrl+'/user/login',
data: {
mobile: this.phoneNum,
password: this.password
},
method: 'POST',
dataType: 'json',
success: (res) => {
console.log("登陸返回數據",res);
if (res.data.data.code == 1) {
uni.showToast({
title: "登陸成功!",
icon: 'none'
});
uni.setStorageSync('token', res.data.data.token);
uni.setStorageSync('loginUser',res.data.data.userinfo);
uni.reLaunch({
url: "../index/index" //跳轉到首頁
});
} else {
uni.showToast({
title: "登陸失敗!",
icon: 'wrong'
});
}
}
});
}
}
}
</script>
複製代碼
在登錄的時候用到了uni.setStorageSync
,uni.setStorageSync
將 data 存儲在本地緩存中指定的 key 中,會覆蓋掉原來該 key 對應的內容,這是一個同步接口。當使用uni.setStorageSync
接口將數據存到本地緩存中時,就須要uni.getStorageSync
來獲取信息。查看更多
在開發中會使用到class
與 style
的綁定,來介紹一下:
class 支持的語法:
<view :class="{ active: isActive }">111</view>
<view class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">222</view>
<view class="static" :class="[activeClass, errorClass]">333</view>
<view class="static" v-bind:class="[isActive ? activeClass : '', errorClass]">444</view>
<view class="static" v-bind:class="[{ active: isActive }, errorClass]">555</view>
複製代碼
style 支持的語法:
<view v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">666</view>
<view v-bind:style="[{ color: activeColor, fontSize: fontSize + 'px' }]">777</view>
複製代碼
接下來咱們來寫個例子:
當咱們提交「申請」以前,按鈕的顏色是綠色的,符合用戶的習慣。當點擊按鈕以後,會進行一系列的操做,好比與後端進行交互,這個例子比較簡單,就是普通的改變樣式。
html:
<button class="static"
:class="[isSubmit ? Submited: '', NoSubmit]"
@click="submitFile">{{text}}</button>
複製代碼
js: 必定要在data裏註冊後,再在class裏使用,這樣纔會被渲染出來。
export default {
data() {
return {
Submited: 'Submited',
NoSubmit: 'NoSubmit',
isSubmit:false,
text:'申請'
}
},
methods: {
submitFile(){
this.text ='已申請';
this.isSubmit = true;
}
}
}
複製代碼
這裏就簡單說一下路由跳轉問題,詳情能夠看官網。
保留當前頁面,跳轉到應用內的某個頁面,使用uni.navigateBack
能夠返回到原頁面。
示例:
//在起始頁面跳轉到test.vue頁面並傳遞參數
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
複製代碼
// 在test.vue頁面接受參數
export default {
onLoad: function (option) { //option爲object類型,會序列化上個頁面傳遞的參數
console.log(option.id); //打印出上個頁面傳遞的參數。
console.log(option.name); //打印出上個頁面傳遞的參數。
}
}
複製代碼
關閉當前頁面,跳轉到應用內的某個頁面。 示例:
uni.redirectTo({
url: 'test?id=1'
});
複製代碼
關閉全部頁面,打開到應用內的某個頁面。
須要跳轉的應用內頁面路徑 , 路徑後能夠帶參數。參數與路徑之間使用?
分隔,參數鍵與參數值用=
相連,不一樣參數用&
分隔;如 path?key=value&key2=value2
,若是跳轉的頁面路徑是 tabBar 頁面則不能帶參。
跳轉到 tabBar 頁面,並關閉其餘全部非 tabBar 頁面。 示例:
pages.json
{
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首頁"
},{
"pagePath": "pages/other/other",
"text": "其餘"
}]
}
}
複製代碼
other.vue
uni.switchTab({
url: '/pages/index/index'
});
複製代碼
就好比點擊這個景點的卡片,會進入這個景點的詳情頁面,這個過程當中就用到了頁面的傳參。
主要代碼以下:
//index.vue
<template>
<view class="cu-card case " v-for="(item, index) in jingdian" :key="index" @click="jd_Detial(item)">
<view class="cu-item shadow">
<view class="image">
<image :src="item.img" mode="widthFix"></image>
<view class="cu-tag bg-red">Hot</view>
</view>
<view class="cu-list menu-avatar">
<view class="cu-item">
<view class="content flex-sub" style="left: 20px;">
<view class="text-grey">{{item.name}}</view>
<view class="text-gray text-sm flex justify-between">
<view class="text-gray text-sm">
<text class="icon-icon_like-copy margin-lr-xs"></text>收藏
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
jingdian:[]
}
},
created:function () {
try {
//獲取全部景點的數據
uni.request({
url: this.websiteUrl+'/api/showCityTickets/'+ this.cityId,
method: 'GET',
dataType: 'json',
success: (res) => {
this.jingdian = res.data.data;
}
})
} catch (e) {
// error
console.log('error',e)
}
},
methods: {
jd_Detial(item){
console.log('id',item._id);
//頁面跳轉以及傳到下一頁面所須要的參數_id,
uni.navigateTo({
url:"../jingdian_detail/jingdian_detail?id=" + item._id
})
}
}
}
</script>
複製代碼
下面是jingdian_detail.vue
的詳情頁面
jingdian_detail.vue
頁面經過
onLoad()
生命週期函數來獲取上一頁面傳過來的參數
_id
。主要代碼以下:
onLoad(options) {
var _this = this;
this.ticketId = options.id;
//根據這個ID來獲取相應的景點的詳情數據,根據詳情數據再來渲染出詳情頁面
uni.request({
url: this.websiteUrl + '/api/ticketsShowDetial/' + options.id,
method: 'GET',
dataType: 'json',
success: function success(res) {
if (res.statusCode == 200) {
_this.detail = res.data.data;
}
}
});
console.log('&&&&&&&&this.detail&&&&&&', this.detail);
}
複製代碼
本身寫了一個簡單的定位,只是爲了方便你們瞭解這一功能是如何實現的。
這個獲取位置只能在手機端進行測試,H5端沒有GPS。
上代碼:
<template>
<view style="margin: 10px auto;">
<button @click="getLocal()">定位</button>
<p>經度:{{longitude}} </p>
<p>緯度:{{latitude}}</p>
<p>詳細地址{{address.country+address.province+address.city + address.district+ address.street}}</p>
</view>
</template>
<script>
export default {
data() {
return {
latitude:'',//緯度
longitude:'',//經度
address:{},//地址信息
}
},
methods: {
getLocal(){
// 獲取當前的地理位置、速度。
let that = this;
try{
uni.getLocation({
type: 'wgs84',
geocode:true,//解析地址信息
success: function (res) {
that.latitude = res.latitude
that.longitude = res.longitude
that.address = res.address
//查看地圖
uni.openLocation({
latitude: that.latitude,
longitude: that.longitude,
success: function () {
console.log('打開地圖success');
}
});
},
fail:function(res){
console.log("fail====",res)
}
});
}catch(e){
console.log("error",e)
}
}
}
}
複製代碼
點擊定位按鈕,獲取本地的經緯度和詳細地址,而後會自動跳到地圖頁面。
具體想要知道 獲取位置和 查看地圖的API,能夠查看官網哦!對於運行和發佈,官網上的「快速上手」中有介紹,請點擊查看