关于数据请求,避不开的一个老生常谈的问题就是跨域,同样的上面点击登录也会涉及到跨域无法请求的问题,不过好在vue-cli里面已经配置了解决跨域问题的模块,我们可以在config/index.js里面配置以下要代理的地址,如下图
将以root开头的api转发出去,将地址指向接口地址,这样就解决了跨域的问题。
到此,vue全家桶的引入及应用就基本完成了,但是到目前为止这个项目还只能进行简单的路由跳转、状态存储以及数据请求,而我们的目标是一个移动端应用框架,接下来我们还要解决如下几个问题
移动端适配问题
移动端ui框架的引入
项目组织架构的优化问题
下面我们就先从移动端适配问题入手
项目的适配
因为移动端设备屏幕大小,屏幕比例什么的差别比较大,所以移动端项目的适配问题就显得尤为重要,这里我们主要使用flexible.js进行适配,关于flexible.js,不懂得话可以点这里,这里我们以最常用的750*1334的尺寸为例
引入flexible.js,在main.js里引入flexible.js文件,可将flexible.js作为静态文件放在最外层static文件夹里引入,如下图
使用less作为css预处理器,首先安装less
(1)安装less和less-loader
npm install lessless-loader --save-dev
(2)配置less
在build/webpack.base.conf.js 的module.exports.module.rules 里面添加
{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' },
然后在组件里面使用的时候,在style标签上加上 lang="less",就可以正常的使用less了,这里我们来引入几个初始化项目的less文件,在src下面创建styles文件夹,放入以下文件
在每个组件里的style标签里引入index.less和variable.less
<style scoped lang="less"> @import "~styles/index.less"; @import "~styles/variable.less"; .hello{ h1{ color: red; .fs(38); // mixin里数字大小函数 } } </style>
然后上面写关于像素的样式的时候,都在mixin.less定义下,就可以实现对所有移动端的适配问题。
移动端页面切换及切换动画
此处将切换动画单独拿出来说以下,作为移动端一般要实现的需求是,第一级菜单切换不需要转场动画,第一级菜单向第二级菜单转场时需要过渡动画;针对这一需求提供以下解决方案。
需要用到动画的话肯定会用到vue的transition,不熟悉的话可以看这里,这里实现动画的解决方案是判断要执行路由的方向,如下代码,在路由配置文件里定义路由的方法
// 需要左方向动画的路由用this.$router.to('****') Router.prototype.togo = function (path) { this.isleft = true this.isright = false this.push(path) } // 需要右方向动画的路由用this.$router.goRight('****') Router.prototype.goRight = function (path) { this.isright = true this.isleft = false this.push(path) } // 需要返回按钮动画的路由用this.$router.goBack(),返回上一个路由 Router.prototype.goBack = function () { this.isright = true this.isleft = false this.go(-1) } // 点击浏览器返回按钮执行,此时不需要路由回退 Router.prototype.togoback = function () { this.isright = true this.isleft = false }
上面在执行路由跳转的时候,在App.vue里面判断滑动的方向,来指定动画的方向,不需要动画的话,可以直接使用this.$router.push('****'),下面是App.vue里处理的动画代码
<template> <div> <transition :name="transitionName"> <router-view></router-view> </transition> </div> </template> <script> export default { name: 'App', data() { return { transitionName: 'slideleft' } }, watch: { $route() { // 监听路由变化重新赋值 if (this.$router.isleft) { this.transitionName = 'slideleft' } if (this.$router.isright) { this.transitionName = 'slideright' } } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } .Router { position: absolute; top: 0; left: 0; right: 0; width: 100%; height: 100%; transition: all .5s ease; -webkit-transition: all .5s ease; -moz-transition: all .5s ease; } .slideleft-enter, .slideright-leave-active { opacity: 0; -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } .slideleft-leave-active, .slideright-enter { opacity: 0; -webkit-transform: translate(-100%, 0); transform: translate(-100%, 0); } </style>
在组件中使用的话则使用
this.$router.goBack() // 返回 this.$router.to('****') // 进入到详情
还有一步,就是监听点击浏览器返回按钮,在main.js里写如下代码
window.addEventListener('popstate', function(e) { router.togoback() // router已经在上面import进来 }, false)
移动端UI框架选择