在移動應(yīng)用中很多功能都是必不可少的,使用vue構(gòu)建移動應(yīng)用自然也就需要實(shí)現(xiàn)這些功能粤铭。之所以寫這篇文章,是希望大家能更多的將注意力放在項(xiàng)目的核心業(yè)務(wù)上杂靶,而不是過多的關(guān)注通用功能梆惯。
基礎(chǔ)設(shè)置
- 使用vue-cli搭建項(xiàng)目框架
- 在index.html文件中添加
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
,在移動端設(shè)置禁止縮放吗垮,以便顯示合適大小的頁面垛吗。 - 如果要將頁面封裝為app,那么需要將config/index.js中build的assetsPublicPath設(shè)置為'./'烁登,build獲得的頁面可以直接打開怯屉,而不需要使用服務(wù)器。
通用功能
一饵沧、頁面跳轉(zhuǎn)
一般應(yīng)用都會擁有多個頁面锨络,在vue中通過vue-router來管理頁面。移動應(yīng)用頁面跳轉(zhuǎn)時狼牺,都有轉(zhuǎn)場效果羡儿,在vue中我們也可以實(shí)現(xiàn)。
在路由文件中設(shè)置meta為數(shù)字是钥,meta表示其路由的深度掠归,然后在App.vue中設(shè)置:
<template>
<transition :name="transitionName">
<router-view></router-view>
</transition>
</template>
<script>
export default {
name: 'app',
data () {
return {
transitionName: 'fade'
}
},
watch: {
'$route' (to, from) {
let toDepth = to.meta
let fromDepth = from.meta
if (fromDepth > toDepth) {
this.transitionName = 'fade-left'
} else if (fromDepth < toDepth) {
this.transitionName = 'fade-right'
} else {
this.transitionName = 'fade'
}
}
}
}
</script>
<style>
</style>
監(jiān)聽$route,根據(jù)to悄泥、from meta值的大小設(shè)置不同的跳轉(zhuǎn)動畫虏冻。如果應(yīng)用到多種跳轉(zhuǎn)動畫,可以根據(jù)詳情弹囚,具體情況具體應(yīng)用厨相。
這樣實(shí)現(xiàn)跳轉(zhuǎn)效果需要在編寫router時添加設(shè)置,比較麻煩,更好的方法可以通過插件
vue-navigation
來實(shí)現(xiàn)领铐,更加方便悯森,無須對router進(jìn)行多余的設(shè)置。npm i -S vue-navigation
安裝绪撵,在main.js中導(dǎo)入:
import Navigation from 'vue-navigation'
Vue.use(Navigation, {router}) // router為路由文件
在App.vue中設(shè)置:
this.$navigation.on('forward', (to, from) => {
this.transitionName = 'fade-right'
})
this.$navigation.on('back', (to, from) => {
this.transitionName = 'fade-left'
})
this.$navigation.on('replace', (to, from) => {
this.transitionName = 'fade'
})
vue-navigation插件還有一個重要的功能就是保存頁面狀態(tài)瓢姻,與keep-alive相似,但是keep-alive保存狀態(tài)無法識別路由的前進(jìn)后退音诈,而實(shí)際應(yīng)用中幻碱,我們的需求是返回頁面時,希望頁面狀態(tài)保存细溅,當(dāng)進(jìn)入頁面時希望獲取新的數(shù)據(jù)褥傍,使用vue-navigation可以很好的實(shí)現(xiàn)這個效果。具體使用可以查看vue-navigation有詳細(xì)使用說明與案例喇聊。
PS:
這里的動畫效果引用自animate.scss;
二恍风、底部導(dǎo)航
直接引用Tabbar組件即可,如果需要添加跳轉(zhuǎn)動畫可以在<router-view></router-view>
外設(shè)置:
<template>
<div class="content">
<!--<transition name="fade" mode="out-in">-->
<router-view></router-view>
<!--</transition>-->
<Tabbar
:routers="[
{path: '/index/home', icon: 'icon-home', name: '首頁'},
{path: '/index/loading', icon: 'icon-course', name: '加載'},
{path: '/index/message', icon: 'icon-info', name: '信息'}
]"
>
</Tabbar>
</div>
</template>
<script>
export default {
name: 'Index',
components: {Tabbar: require('components/Tabbar')},
data () {
return {
}
}
}
</script>
<style lang="scss" scoped>
.content{
background-color: #eee;
}
</style>
三誓篱、數(shù)據(jù)加載
加載數(shù)據(jù)與加載頁面是存在先后順序的朋贬,比較通用方法是先加載頁面,顯示數(shù)據(jù)加載效果窜骄,在數(shù)據(jù)加載完成之后顯示完整的頁面锦募。數(shù)據(jù)加載效果作為組件添加到應(yīng)用中,比較繁瑣邻遏,所以使用自定義指令的方式實(shí)現(xiàn)數(shù)據(jù)加載效果的顯示糠亩。
四、接口文件
import fetch from 'isomorphic-fetch'
import store from 'store'
import router from './router'
var env = process.env.NODE_ENV
var rootUrl
if (env === 'development') {
rootUrl = ''
}
if (env === 'production') {
rootUrl = ''
}
const post = function (url, params = {}) {
return fetch(rootUrl + url, {
method: 'post',
headers: {
'Content-type': 'application/json; charset=utf-8',
'Authorization': store.get('token')
},
body: JSON.stringify(params)
}).then(function (res) {
if (res.status === 401) {
// 沒有權(quán)限
api.logout()
} else {
return res.json()
}
})
}
const urls = [
'classAtCurDate' // 普通接口列表
]
var api = {}
for (var url of urls) {
(function (url) {
api[url] = (params) => {
console.log(url)
return post('course/' + url, params)
}
})(url)
}
// 需要特殊處理的接口
api.logout = () => {
store.clearAll()
router.push('login')
}
api.login = (params) => {
store.set('id', 1)
store.set('token', 2)
return Promise.resolve({params})
}
export default api
可以在全局設(shè)置准验,也可以在需要時導(dǎo)入
// 在main.js中導(dǎo)入api接口
import api from '../src/api'
Vue.$api = Vue.prototype.$api = api
五赎线、登錄權(quán)限設(shè)置
路由加載前,檢查是否有登錄權(quán)限(判斷用戶id是否存在)糊饱,如果存在直接跳過登錄頁進(jìn)入首頁氛驮,如果不存在在跳轉(zhuǎn)登錄頁。
router.beforeEach((to, from, next) => {
if (cache.get('id') && to.path === '/login') {
next('/index')
} else if (!cache.get('id') && to.path !== '/login') {
next('/login')
} else {
next()
}
})
六济似、常用第三方組件
許多常用組件都已經(jīng)有了很好的實(shí)現(xiàn)矫废,在項(xiàng)目開發(fā)中重復(fù)造輪子是一件很不明智的事情。vue移動應(yīng)用有很多合適的庫可以選擇砰蠢,如mint-ui蓖扑、vux,這里不一一列舉台舱,想了解更多的可以自行谷歌律杠,或直接到GitHub上搜索潭流,這里已mint-ui為例,講一下比較常用的一些組件柜去。
提示組件
提示組件即顯示信息灰嫉、提示用戶的組件,toast嗓奢、alert讼撒、 prompt皆為此類。
加載數(shù)據(jù)
如上拉加載數(shù)據(jù)股耽、下拉加載(刷新)數(shù)據(jù)根盒、滾動加載數(shù)據(jù);這些在mint-ui中有較好的實(shí)現(xiàn)
日期選擇
比較通用的功能物蝙,但自己實(shí)現(xiàn)起來還是相對麻煩的炎滞,借助第三方組件就可以很快的實(shí)現(xiàn)了。
使用第三方組件雖然能夠快速完成項(xiàng)目诬乞,但是不建議過度使用册赛,一些常用的組件如按鈕、表單還是應(yīng)該自己實(shí)現(xiàn)震嫉,一是因?yàn)檫@些組件實(shí)現(xiàn)不是很復(fù)雜森瘪,二是因?yàn)橥鶎@些組件每個應(yīng)用都有自己的設(shè)計(jì)要求,使用第三方然后修改樣式责掏,不但比自編寫更復(fù)雜而且增加冗余文件。
使用第三方組件庫湃望,一般有兩種導(dǎo)入方式:一是全部導(dǎo)入换衬,這樣會引入很多不必要的文件;二是只導(dǎo)入使用的組件和樣式证芭。建議使用第二種方式瞳浦,避免導(dǎo)入多余組件,mint-ui可以使用Use babel-plugin-component簡化單獨(dú)導(dǎo)入組件的寫法废士。