uni-app最近超級火,各大招聘要求都把uni-app添加到任職需求,因此本身做死把公司的一個微信公衆號項目用uni-app開發。css
本文適合有Vue開發經驗者閱讀。html
下載HBuilderX編輯器,HBuilderX是uni-app官方推薦,其中包含可視化搭建uni-app項目、運行項目、打包編譯項目。前端
下載地址點這裏,由於我只開發微信公衆號項目,也是就H5項目,全部只下載標準版的就能夠。vue
我是使用less做爲css的預編譯語言,若是你選擇的是sass做用css的預編譯語言,能夠跳過這步。html5
修改這兩個文件的配置,就能夠解決這個問題。 webpack
把紅框的內容添加進去便可。nginx
在HBuilderX編輯器中建立項目很是簡單,只須要兩步。web
推薦選擇內置uni-ui項目模板,該模板已內置大量經常使用組件,並且不要刪除太多無用文件和代碼。chrome
建立好後項目的目錄結構如圖所示json
啓動uni-app項目,在HBuilderX編輯器中也很是簡單,一步搞定。
開始編譯
編譯成功
在瀏覽器打開http://loaclhost:8080/,若是頁面以下圖所示,說明項目啓動成功。
我這個項目原型中是沒有原生導航欄的,因此要把它先去掉。
方法在文檔這個地方這個地方。
當navigationStyle
設爲custom
或titleNView
設爲false
時,原生導航欄不顯示。因此去除H5端的原生導航欄有兩種方法。
都是在pages.json文件中
統一去除原生導航欄
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-ui基礎項目"
}
}
],
複製代碼
或者,只針對H5端去除原生導航欄。
"pages": [
{
"path": "pages/index/index",
"style": {
"h5":{
"titleNView":false
}
}
}
],
複製代碼
下圖就是去原生導航欄後的效果
目前前端項目大多都是用路由來控制頁面跳轉,因此入坑一個新框架,先要屬性一下這個框架的路由怎麼配置。
uni-app的路由配置方式和小程序很像,若是你會小程序,配置起來更容易了。
uni-app項目的路由仍是pages.json中pages屬性中配置,其實上面已經應用到了。
pages屬性的值是個數組,數組每項是個json對象,每一個路由就配置在json對象中,其中path屬性是頁面路徑,style是配置頁面的樣式,咱們先不看。
在uni-app項目中,咱們通常把頁面寫在pages文件夾下,例如在pagse文件夾下添加一個叫home.vue
的文件,文件內容以下
<template>
<view>我是home頁面</view>
</template>
<script>
</script>
<style>
</style>
複製代碼
那麼咱們要在pages.json中這麼配置。
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/home",
"style": {
"navigationStyle": "custom"
}
}
],
複製代碼
刷新頁面,你會發現瀏覽器上沒有 我是home頁面
。
固然這裏不是配置錯了。只是在uni-app有個規定pages節點的第一項爲應用入口頁(即首頁)。因此咱們要改一下。
"pages": [
{
"path": "pages/home",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom"
}
},
],
複製代碼
這時你會發現,編譯失敗了。 緣由就是在uni-app中配置文件,每一項結束尾巴都不能加
,
(逗號)。,把逗號去掉,在編譯,成功後刷新頁面,就會看到home.vue
這個頁面裏面的內容。
如今咱們把home.vue
這個文件刪掉,在編譯,會報錯,編譯不成功。
提示咱們找不到home.vue
這個文件,因此在新增/減小頁面,都須要對 pages 數組進行修改!
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom"
}
},
],
複製代碼
從新編譯,編譯成功。
阿里圖標這東西,幾乎在每一個項目中都會使用到。
在Vue項目,咱們引入阿里圖標是在public文件夾下的index.html文件,經過link引入的。
可是在uni-app項目中沒有index.html文件,那麼要在哪裏引入呢。
在前面有提到過App.vue是項目頁面主入口,那咱們能夠嘗試在這裏引入。
在Vue項目中.vue文件中咱們是這麼引入樣式
<style lang="less" scoped>
@import "./css/index.less";
</style>
複製代碼
去MDN查詢@import的用法(入口),發現 @import能夠這麼用。
@import url("chrome://communicator/skin/");
複製代碼
那麼嘗試在App.vue這麼引入阿里圖標
<style>
@import url("https://at.alicdn.com/t/font_1811528_5xzkmbymkb7.css");
</style>
複製代碼
而後在pages/index/index.vue文件中這麼使用
<template>
<view class="container">
<text class="iconfont iconSIMCard"></text>
</view>
</template>
複製代碼
刷新頁面,發現引入成功。
若是你會小程序開發,這一點能夠忽略不看。
咱們以前開發微信公衆號,是用H5開發的,天然可使用html5的標籤。如經常使用的div
、span
、img
。
那麼在uni-app項目中只能用它自帶的組件標籤,如<view></view>
就至關<div></div>
,<text></text>
至關<span></span>
,,<image></image>
至關<img/>
,具體可點這裏這裏看。
說到這個路徑,咱們首先要搞懂幾個常識。
~
表示Web應用程序根目錄,/
也是表示根目錄,../
表示當前目錄的上一級目錄,./
表示當前目錄。
在uni-app項目引入圖片,要用內置組件標籤<image></image>
,其src屬性就是配置圖片路徑,僅支持相對路徑、絕對路徑,支持 base64碼,但自定義組件裏面使用<image>
時,若 src 使用相對路徑可能出現路徑查找失敗的狀況,故建議使用絕對路徑。
在項目中我是把圖片資源放在根目錄的assets/images文件夾中。若是你的頁面在pages文件夾中的路徑很深,例如
那你是否是要在頁面上這麼寫
<template>
<view>
<image src="../../../../assets/images/indeximg1.png"></image>
</view>
</template>
複製代碼
其實咱們能夠利用~
來改造一下。
<template>
<view>
<image src="~assets/images/indeximg1.png"></image>
</view>
</template>
複製代碼
在less中使用background也能夠利用~
.home{
background:url(~images/card/home.png) no-repeat;
}
複製代碼
這樣寫能夠避免由於少些或者多些../
致使的路徑錯誤,配置起來也輕鬆。
另外咱們能夠像Vue項目中在根目錄下添加一個vue.config.js文件,來配置webpack,固然在uni-app項目中配置和在Vue項目中配置是有差別,能夠點這裏看。
咱們在vue.config.js文件配置一個路徑別名,配置方法和在Vue項目中同樣。
const path = require('path');
function resolve(dir) {
return path.resolve(__dirname, dir)
}
module.exports = {
configureWebpack: config => {
return baseConfig = {
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'assets': resolve('assets'),
'css': resolve('assets/css'),
'images': resolve('assets/images'),
}
},
}
},
}
複製代碼
在uni-app中使用第三方組件都會下載到components文件夾中。因此引入第三方組件的作法和Vue項目開發同樣。
如要使用 Popup 彈出層 ,這麼引入
components: {
uniPopup: () => import('@/components/uni-popup/uni-popup.vue'),
uniPopupDialog: () => import('@/components/uni-popup/uni-popup-dialog.vue'),
},
複製代碼
在uni.navigateTo()
中url
參數爲路徑,其後能夠帶參數,用於頁面傳參,參數在新頁面中onLoad
鉤子函數接收,以下示例。
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); //打印出上個頁面傳遞的參數。
}
}
複製代碼
框架以棧的形式管理當前全部頁面,記住棧是先進後出的。
當用戶按左上角返回按鈕、安卓用戶點擊物理back按鍵時,觸發uni.navigateBack
,關閉當前頁面,也就是將當前頁面出棧,返回上一個頁面,也就是返回頁面棧中最上層的頁面。固然uni.navigateBack
中OBJECT.delta
能夠控制返回頁面棧中第幾層的頁面。能夠用getCurrentPages()
能夠獲得全部頁面棧的對象。
uni.navigateTo()
,保留當前頁面,將當前頁面入棧,再跳轉新的頁面。
uni.redirectTo()
,關閉當前頁面,不將當前頁面入棧,再跳轉新的頁面。
uni.navigateTo()
, uni.redirectTo()
只能打開非 tabBar 頁面。
不能在 App.vue 裏面進行頁面跳轉。若是用瀏覽器刷新整個頁面,會清空當前頁面棧。
跟服務端交互時確定要用消息彈窗,好比報錯時給出錯誤提示。uni-app框架封裝幾種消息彈窗的足跡。
uni.showToast()
顯示消息提示彈窗。 uni.hideToast()
隱藏消息提示框。 uni.showModal()
顯示模態彈窗,相似於標準 html 的消息框:alert、confirm。
uni.showLoading()
顯示 loading 提示框, 需主動調用 uni.hideLoading()
才能關閉提示框。
uni.hideLoading()
隱藏 loading 提示框。
showToast 和 showLoading 是底層同一個,因此 showToast 和 showLoading 會相互覆蓋,而 uni.hideLoading()
也會關閉 showToast,因此注意調用順序。
點開manifest.json文件,在h5中devServer選項中設置"disableHostCheck": true
。
uni-app中是用uni.request()
和服務端通訊的。其中data
參數是傳給服務端的數據。
最終發送給服務器的數據是 String 類型,若是傳入的 data 不是 String 類型,會被轉換成 String。轉換規則以下:
會發現uni.request()
不能發送formData類型的數據給後端。若是要發送formData類型的數據,要用uni.uploadFile()
,其做用是將本地資源上傳到開發者服務器,客戶端發起一個 POST 請求,其中 content-type 爲 multipart/form-data。
formData
參數是用uni.uploadFile()
上傳本地資源中其餘額外的 form data數據。
uni.uploadFile()
中幾個必填的參數,如url
、filePath
、name
能夠隨便填寫。因此可用uni.uploadFile()
發起數據格式爲formData的接口請求了。
由於uni-app跨平臺時不支持引入jQuery等操做 DOM 的插件,H5 平臺能夠經過條件編譯的方式引入使用。因此在uni-app中最好不要引入jQuery,可使用uni.createSelectorQuery()
建立一個SelectorQuery
對象實例來獲取DOM信息。
例如要獲取<view class="p-list"></view>
的高度。
const _this = this;
uni.createSelectorQuery().select(".p-list").boundingClientRect(data => {
_this.height = data.height;
}).exec();
複製代碼
用uni-app中scroll-view內置組件和第三方uni-load-more組件實現。
注意scroll-view中要設定固定高度才能夠生效。
<template>
<view class="p-list">
<scroll-view scroll-y="true" @scrolltolower="lower" :style="{height:height+'px'}">
<view v-for="item in list">{{item}}</view>
<uni-load-more :status="status" iconType="auto" v-show="isShow"></uni-load-more>
</scroll-view>
</view>
</template>
<script>
export default {
data(){
return {
current:1,//頁碼
list:[],
height: 0,//列表區域高度
isShow:false,
status: 'loading',//加載更多的狀態
}
},
components: {
uniLoadMore: () => import('@/components/uni-load-more/uni-load-more.vue'),
},
mounted() {
this.getViewHeight();
},
methods: {
getViewHeight() {
const _this = this;
uni.createSelectorQuery().select(".p-list").boundingClientRect(data => {
_this.height = data.height;
}).exec();
},
lower() {
if (this.isShow) return;
this.isShow = true;
this.current++;
this.getList();
},
getList(){
let data = new Object;
data.current = this.current;
data.size = 15;//每次加載條數
API.getRenewRecord(data)
.then(res => {
this.isShow = false;
if (res.code == 200) {
this.list = [...this.list, ...res.data]
if (res.data.length == 0) {
this.status = 'noMore';
this.isShow = true;
}
}
})
.catch(err => {
this.isShow = false;
})
}
}
}
</script>
複製代碼
若是頁面頭部有固定內容,下拉刷新只能用scroll-view內置組件實現。 注意scroll-view中要設定固定高度才能夠生效。
<template>
<view class="p-list">
<scroll-view scroll-y refresher-enabled
:refresher-triggered="triggered"
:refresher-threshold="100"
@refresherrefresh="onRefresh" :style="{height:height+'px'}">
<view v-for="item in list">{{item}}</view>
</scroll-view>
</view>
</template>
<script>
export default {
data(){
return {
current:1,//頁碼
list:[],
height: 0,//列表區域高度
triggered:false,//下拉刷新狀態,true開啓下拉刷新,false結束下拉刷新
}
},
mounted() {
this.getViewHeight();
},
methods: {
getViewHeight() {
const _this = this;
uni.createSelectorQuery().select(".p-list").boundingClientRect(data => {
_this.height = data.height;
}).exec();
},
onRefresh() {
if (this.triggered) return;
this.triggered = true;
this.current++;
this.getList();
},
getList(){
let data = new Object;
data.current = this.current;
data.size = 15;//每次加載條數
API.getRenewRecord(data)
.then(res => {
this.triggered = false;
if (res.code == 200) {
this.list = [...res.data,...this.list]
}
})
.catch(err => {
this.triggered = false;
})
}
}
}
</script>
複製代碼
由於在微信瀏覽器中,下拉時整個頁面會下滑,而後致使scroll-view的下拉刷新卡頓。用如下方法解決
先在pages.json中開啓該頁面的下拉刷新監聽
{
"pages":[
{
"path": "testList",
"style": {
"enablePullDownRefresh": true
}
},
]
}
複製代碼
而後在頁面中監聽下拉刷新,一旦下拉刷新立刻執行uni.stopPullDownRefresh
把下拉刷新立刻關閉。
onPullDownRefresh() {
uni.stopPullDownRefresh()
},
複製代碼
同時在App.vue中,把下拉刷新的頁面效果隱藏
<style>
uni-page[data-page=websms] uni-page-refresh {
display: none;
}
</style>
複製代碼
<template>
<view>
<input v-model.trim="value" @blur="handleblur"/>
</view>
</template>
<script>
export default{
methods: {
handleblur() {
uni.pageScrollTo({
scrollTop: 0,
duration: 0
});
},
}
}
</script>
複製代碼
在父級元素加上min-height
屬性。或者避免嵌套
uni-app項目中默認是沒有index.html,不像Vue項目默認帶有index.html。那麼要用CND引入第三方庫,該怎麼操做。
首先在根目錄下,新建index.html文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
})
</script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
複製代碼
而後在manifest.json中添加以下配置,便可。
"h5":{
"template": "index.html",
}
複製代碼
開啓搖樹優化和預加載 而後在manifest.json中添加以下配置,便可。
"h5":{
"optimization": {
"prefetch": true,
"preload": true,
"treeShaking": {
"enable": true
}
}
}
複製代碼
先配置
而後打包編譯
最後打包生成的文件部署到服務器上。