从零开始搭建vue移动端项目到上线的步骤

2018-10-15 22 Mr、Gao

初始化项目

1、在安装了node.js的前提下,使用以下命令

npm install --g vue-cli

2、在将要构建项目的目录下

vue init webpack myproject(项目目录名称)

一路回车如下

从零开始搭建vue移动端项目到上线的步骤

中间会让选择ESLint进行项目代码风格检查,为了美观和效率,可以开起来,vue-router用起来,红框框中的两个测试,不要也罢,后面是问要使用哪个进行install依赖包,默认npm好了;然后回车,等待下载依赖;慢的话可以用镜像。

下载完成之后会看到如下提示:

从零开始搭建vue移动端项目到上线的步骤

按照步骤往下走就好了

接下来在浏览器里输入localhost:8080,就可以进入到vue的世界了

从零开始搭建vue移动端项目到上线的步骤

只有这些还不够,这距离一个响应式的app框架还差好多,接下来就正式搭建一个移动端的项目吧。

首先我们来看一下刚构建好的vue的项目结构

从零开始搭建vue移动端项目到上线的步骤

可以发现项目中有assets和static两个文件夹可存放静态文件,那岂不是冲突了?其实不然,assets中存放的静态文件是会经过webpack处理的,一般放一些图片之类的静态资源,而static则不会收到webpack的影响,调用的时候也是通过绝对路径调用的,通常用来存放一些第三方的静态资源库。

此项目将基于vue-cli的项目目录进行改造,使其集成vue-router、vuex、axios,而且可以自动适配移动端大小。

在开始写代码之前,先说一下ESlint警告和报错,可以选择性修改校验规则,点击参考修改,也可以使用 /* eslint-disable */ 选择性忽略校验

路由(vue-router)

一个项目的路由是一个项目的基础,我们先从路由开始,在刚一开始初始化项目的时候,vue-router就被引进项目里来了,上面的图片里在src\router里面放的就是路由配置文件,按照个人习惯我将对上面的目录结构进行调整,如下

从零开始搭建vue移动端项目到上线的步骤

新建page目录存放主逻辑页面,components存放公共组件,router统一管理路由

从零开始搭建vue移动端项目到上线的步骤

如图引入新的页面,路由跳转可通过this.$router.push('/Home')

路由vue-cli都给封装的差不多了,倒也没什么要大改的地方,接下来来看下vuex

vuex(状态管理模块)

关于vuex的介绍官网也给了比较详细的介绍,对其作用不太了解的话可以参考什么是vuex,这里只说怎么集成在项目里面,并且简单介绍其用法

(1)安装vuex

npm install vuex --save

(2)配置vuex

根据个人开发习惯,项目中vuex的配置也不相同,不过大体都差不多,也有差别大的地方,比方说官网推荐在actions里写异步操作改变state状态,但是我还是比较喜欢将请求数据等异步操作放在store外面操作,在通过commit去改变状态,具体将会在下面的数据请求模块的封装里提到

废话不多说了,看下面图片

从零开始搭建vue移动端项目到上线的步骤

首先创建了一个状态的文件夹,用于管理整个状态;在modules里面分开来写各个模块的状态,如下

/**
 * home.js
 * 用于home模块的状态管理
 */
import * as types from '../mutation-type' // 引入定义的方法
const home = {
 state: {
 number: 1
 },
 mutations: {
 [types.SET_NUM](state, num) { // 修改state 可通过mapMutations调用
 state.number = num
 }
 },
 actions: {},
 getters: {  // 定义getters,可以通过mapGetters拓展函数调用
 number: state => {
 return state.number
 }
 }
}
export default home // 输出home模块

mutation-type定义了一些修改state的方法,如下

从零开始搭建vue移动端项目到上线的步骤

在index.js统一输出,如下

import Vue from 'vue'
import Vuex from 'vuex'
import home from './modules/home'
import createLogger from 'vuex/dist/logger'

Vue.use(Vuex)
const debug = true

export default new Vuex.Store({
 modules: {
 home
 },
 plugins: debug ? [createLogger()] : [] // 是否开启vuex的debug模式
})

这里用到了一个vuex的内置插件,如上图,开启之后状态的每次改变都可以在console里面查看修改信息如下图

从零开始搭建vue移动端项目到上线的步骤

这里的index配置好之后就是要在main.js里注册一下

从零开始搭建vue移动端项目到上线的步骤

通过以上几步设置,就可以在项目里面使用状态了,这里以home.vue为例,看下面代码

import {mapMutations, mapGetters, mapState} from 'vuex' // 引入map方法
export default {
 data () {
 return {
 num: 0
 }
 },
 methods: {
 ...mapMutations({  // 调用setNum方法
 setNum: 'SET_NUM'
 }),
 increase() {
 this.num++
 this.setNum(this.num) // 将this.num转入setNum
 }
 },
 computed: {
 // ...mapGetters([  // 通过getters获取state数据
 // 'number'
 // ]),
 ...mapState({  // 通过state获取state数据
 number: state => state.home.number
 })
 }

到这里vuex的引入就结束了,下面来继续看数据请求模块(axios)

axios(数据请求模块)

之前vue数据请求模块用的是vue-resource,官方不推荐,弃之;说下axios的集成步骤,以及需要注意的一些地方

(1)安装axios和js-cookie

npm install axios --save

(2)配置axios

在src目录下面新建apiconfig文件夹,用来封装请求和定义一些关于请求的全局变量;同时创建api文件夹,用来分别声明各个模块的请求方法,如下图

从零开始搭建vue移动端项目到上线的步骤

先来看apiconfig里的公共封装部分;这里会对请求做以下处理

  • 定义一些像请求返回成功的状态、请求超时时间等常量,
  • 对请求做一次公共的封装,
  • 对token的存储和拦截当操作,

下面看代码

/* eslint-disable */
import axios from 'axios'

/**
* 定义请求常量
* TIME_OUT、ERR_OK
*/
export const TIME_OUT = 1000; // 请求超时时间
export const ERR_OK = true; // 请求成功返回状态,字段和后台统一
export const baseUrl = process.env.BASE_URL // 引入全局url,定义在全局变量process.env中,开发环境为了方便转发,值为空字符串

// 请求超时时间
axios.defaults.timeout = TIME_OUT

// 封装请求拦截
axios.interceptors.request.use(
 config => {
 let token = localStorage.getItem('token') // 获取token
 config.headers['Content-Type'] = 'application/json;charset=UTF-8'
 config.headers['Authorization'] = ''
 if(token != null){    // 如果token不为null,否则传token给后台
  config.headers['Authorization'] = token
 }
 return config
 },
 error => {
 return Promise.reject(error)
 }
)
// 封装响应拦截,判断token是否过期
axios.interceptors.response.use(
 response => {
 let {data} = response
 if (data.message === 'token failure!') { // 如果后台返回的错误标识为token过期,则重新登录
 localStorage.removeItem('token')  // token过期,移除token
 // 进行重新登录操作
 } else {
 return Promise.resolve(response)
 }
 },
 error => {
 return Promise.reject(error)
 }
)
// 封装post请求
export function fetch(requestUrl, params = '') {
 return axios({
 url: requestUrl,
 method: 'post',
 data: {
 'body': params
 }
 })
}

以上代码以post请求为例,对请求进行公共封装,并且定义了一些常量以供请求使用,另外分别对请求和响应进行了拦截,方便在请求或者数据返回时,对数据进行统一处理,具体在代码的注释里都可以看到,下面就以登录为例,对封装的请求方法进行调用。

下面来看api模块部分,以home-api为例,看代码

/**
 * 引入fetch、baseUrl
 * @param params
 * @returns {*}
 */
import {fetch, baseUrl} from 'config/index'
// 登录接口
export function loginUserNo(params) {
 return fetch(`${baseUrl}/root/login/checkMemberLogin`, params)
}

在文件里引入fetch方法和baseUrl,这里为什么可以简写成'config/index'呢,需要在'build/webpack.base.conf.js'里添加以下代码,后面引入api同理

从零开始搭建vue移动端项目到上线的步骤

这里export登录方法loginUserNo之后,就可以在组件里面使用这个登录方法了,如下代码

import * as homeApi from 'api/home-api' // 引入api
import { ERR_OK } from 'config/index' // 引入请求成功状态
// 请求方法
login() {
 let params = {
 password: '*******',
 storeNo: '',
 userName: '*********'
 }
 homeApi.loginUserNo(params).then((res) => {
 let {data} = res
 if (data.success === ERR_OK) {
  // 请求成功操作,存储token
  localStorage.setItem('token', data.value.token)
 } else {
 }
 }).catch(() => {
 })
 }
}

在点击登录之后执行登录方法,就可以调用请求方法了,但是这里还有一个问题

关于数据请求,避不开的一个老生常谈的问题就是跨域,同样的上面点击登录也会涉及到跨域无法请求的问题,不过好在vue-cli里面已经配置了解决跨域问题的模块,我们可以在config/index.js里面配置以下要代理的地址,如下图

从零开始搭建vue移动端项目到上线的步骤

将以root开头的api转发出去,将地址指向接口地址,这样就解决了跨域的问题。

到此,vue全家桶的引入及应用就基本完成了,但是到目前为止这个项目还只能进行简单的路由跳转、状态存储以及数据请求,而我们的目标是一个移动端应用框架,接下来我们还要解决如下几个问题

  • 移动端适配问题
  • 移动端ui框架的引入
  • 项目组织架构的优化问题

下面我们就先从移动端适配问题入手

项目的适配

因为移动端设备屏幕大小,屏幕比例什么的差别比较大,所以移动端项目的适配问题就显得尤为重要,这里我们主要使用flexible.js进行适配,关于flexible.js,不懂得话可以点这里,这里我们以最常用的750*1334的尺寸为例

引入flexible.js,在main.js里引入flexible.js文件,可将flexible.js作为静态文件放在最外层static文件夹里引入,如下图

从零开始搭建vue移动端项目到上线的步骤

使用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文件夹,放入以下文件

从零开始搭建vue移动端项目到上线的步骤

在每个组件里的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 id="app">
 <transition :name="transitionName">
 <router-view class="Router"></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框架选择

作为移动端项目,上面步骤其实已经算完善了,但是往往会遇到项目工期紧,或者缺少人手的时候,这个时候引入一个移动端的UI就如虎添翼了,不用自己去封装一些ui组件了,这里使用mint-ui,优点可自行搜索,这里讲一下对mint-ui的引入。

(1)安装mint-ui

npm install mint-ui --save

(2)引入mint-ui

在main.js里引入mint-ui

import Mint from 'mint-ui'
import 'mint-ui/lib/style.css' // 引入css
Vue.use(Mint) // 全局使用

这样就可以在整个vue项目里面使用mint-ui的组件了。

打包

打包遇到的一些问题

(1)打包之后在ios上点击元素会闪出来一个半透明的灰色框,这里需要加一句css做下兼容-webkit-tap-highlight-color:rgba(0,0,0,0); 放入#app的css里

(2)点击事件右300ms的延迟,可采用fastclick.js解决,参考以下代码

npm install fastclick --save

// 在main.js引入
import FastClick from 'fastclick'
FastClick.attach(document.body)

打包注意事项

如果将项目打包用于移动端浏览器,则直接打包,不需要更改其它的东西,在包之后上传至服务器,使用nginx做下接口转发即可

如果想将打包的静态文件进一步打包成移动端应用,则需要修改以下config/index.js

从零开始搭建vue移动端项目到上线的步骤

在config/prod.env.js新增baseUrl

从零开始搭建vue移动端项目到上线的步骤

打包成app之后,移动端不会存在跨域问题。

写在最后

上面项目纯属个人搭建,适用于移动端项目,包括浏览器端,微信公众号以及打包之后的android,ios应用,目前还存在一些不足的地方,不过基本功能可以正常使用,具体的代码,如有需要可在我的github中下载使用,如果觉得对你有用,请给我点赞,如有修改建议,请提出。

项目地址:https://github.com/MrKaKaluote/vue-mobile.git

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

展开阅读全文

更多Javascript文章

前淘宝前端开发工程师阿当的PPT中有JS技术理念问题
Jan 15 14
javascript调试过程中找不到哪里出错的可能原因
Dec 16 21
jQuery实现仿百度首页滑动伸缩展开的添加服务效果代码
Sep 09 22
AngularJS数据源的多种获取方式汇总
Feb 02 16
Bootstrap轮播插件简单使用方法介绍
Jun 21 24
JS实现图片上传预览功能
Nov 21 20
基于JavaScript实现一个简单的Vue
Sep 26 22
手机访问当前页面