mpvue的特点
- 彻底的组件化开发能力:提高代码复用性
- 完整的 Vue.js 开发体验
- 方便的 Vuex 数据管理方案:方便构建复杂应用
- 快捷的 webpack 构建机制:自定义构建策略、开发阶段 hotReload
- 支持使用 npm 外部依赖
- 使用 Vue.js 命令行工具 vue-cli 快速初始化项目
- H5 代码转换编译成小程序目标代码的能力
项目搭建
- 采用mpvue 官方脚手架搭建项目底层结构
- 采用Fly.js 作为http 请求库
- 采用vuex作为状态库
安装
npm install -g vue-cli #全局安装vue-cli
vue init mpvue/mpvue-quickstart my-project #创建一个模板项目
cd my-project
npm install #安装依赖
npm run dev #监听修改并编译
目录结构
├── src // 我们的项目的源码编写文件
│ ├── components // 组件目录
│ │ └── head //导航组件
│ ├── config //公共配置
│ │ └── tips // 提示与加载工具类
│ ├── http //http请求配置文件
│ │ └── api // 接口调用文件
│ │ └── config //fly 配置文件
│ ├── pages //项目页面目录
│ ├── store //状态管理 vuex配置目录
│ │ └── actions.js //actions异步修改状态
│ │ └── getters.js //getters计算过滤操作
│ │ └── mutation-types.js //mutations 类型
│ │ └── mutations.js //修改状态
│ │ └── index.js //我们组装模块并导出 store 的地方
│ │ └── state.js //数据源定义
│ ├── stylus //stylus css处理器目录
│ │ └── common.styl // 全局css样式
│ │ └── index.styl // stylus 出口
│ │ └── mixin.styl //mixin 方法
│ │ └── reset.styl //reset css
│ ├── untils //工具函数目录
│ │ └── index.js
│ ├── App.vue // APP入口文件
│ ├── app.json // 项目主配置文件
│ ├── main.js // 主配置文件
使用fiyio进行数据交互
安装
npm install flyio --save
配置
//utils/httpConfig.js
var Fly = require("flyio/dist/npm/wx")
var fly = new Fly;
import config from '@/config'
//配置请求基地址
// //定义公共headers
// fly.config.headers={xx:5,bb:6,dd:7}
// //设置超时
fly.config.timeout = 20000;
// //设置请求基地址
fly.config.baseURL = config.serverApi;
//添加请求拦截器
fly.interceptors.request.use((request) => {
//给所有请求添加自定义header
let Authorization = wx.getStorageSync('Authorization');
if(Authorization){
request.headers["Authorization"] = Authorization;
}
//打印出请求体
// console.log(request.body)
//终止请求
//var err=new Error("xxx")
//err.request=request
//return Promise.reject(new Error(""))
//可以显式返回request, 也可以不返回,没有返回值时拦截器中默认返回request
return request;
})
//添加响应拦截器,响应拦截器会在then/catch处理之前执行
fly.interceptors.response.use(
(response) => {
//只将请求结果的data字段返回
return response.data
},
(err) => {
//发生网络错误后会走到这里
//return Promise.resolve("ssss")
}
)
// Vue.prototype.$http=fly //将fly实例挂在vue原型上
export default fly
封装
//utils/httpClient.js
import fly from './httpConfig'
import qs from 'qs'
// 通用的get请求
export const get = (url,params) => {
return fly.get(url, qs.stringify(params))
};
// 通用的post请求
export const post = (url,params) => {
return fly.post(url, qs.stringify(params))
};
使用
import * as httpClient from 'utils/httpClient'
httpClient.get(uri, payload).then(res=>{
console.log(res);
},error=>{});
路由
路由放在src/app.json文件中,第一个为首页
{
"pages":[
"pages/index/main",
"pages/logs/main",
.....
],
....
}
"pages/index/main"
对应的文件是 pages/index/main.js
,pages/index
目录下有2个文件,
- main.js,固定这么写
import Vue from 'vue'
import App from './index'
const app = new Vue(App)
app.$mount()
- index.vue 和vue组件一样写法
<template>
<div class="usermotto">
{{motto}}
</div>
</template>
<script>
export default {
data () {
return {
motto: 'Hello World',
userInfo: {}
}
},
}
</script>
<style scoped>
. usermotto{ font-size:16px }
</style>
- main.json 可选,页面配置
{
"navigationBarTitleText": "查看启动日志",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#cfd",
"navigationBarTextStyle": "black"
}
使用vuex管理状态
1、 首先需要一个定义动作名称的文件,我们把所有的动作都定义在store/mutation-types.js
里面,这么做的好处是所有的动作在一个文件里方便管理,不会重名,基本上一个动作就是一个api
//用户
export const USER_REGISTER = 'USER_REGISTER';//注册
export const USER_LOGIN = 'USER_LOGIN'; //登录
.....
2、具体的状态管理我全部放在store/modules
文件夹下,比如管理用户状态的操作我放在store/modules/user.js
文件中。例子如下
import {
USER_REGISTER, //注册
USER_LOGIN, //登录
} from '../mutation-types';
import Vue from 'vue';
export default {
state: {
session: {},
},
mutations: {
[USER_SESSION](state, payload) {
state.session = payload;
},
......
},
actions: {
//用户信息
[USER_SESSION](context, payload) {
let uri = Vue.cfg.serverApi + '/user/session';
return new Promise((resolve, reject) => {
Vue.utils.http.get(uri, payload).then(json => {
context.commit(USER_SESSION, json.data);
resolve(json.data);
}, error => {
reject(error)
});
});
},
//注册
[USER_REGISTER](context, payload) {
let uri = Vue.cfg.serverApi + '/user/register';
return Vue.utils.http.post(uri, payload);
},
......
}
}
3、然后我们把这些状态管理都导出 store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
import user from "./modules/user";
import user_follow from "./modules/user_follow";
import user_feedback from "./modules/user_feedback";
import user_collect from "./modules/user_collect";
export default new Vuex.Store({
modules:{
user,
user_follow,
user_feedback,
user_collect,
}
})
4、vue绑定vuex main.js
import store from "./store";
Vue.prototype.$store=store;
生命周期
vue生命周期钩子
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
小程序生命周期钩子
app 部分:
onLaunch,初始化
onShow,当小程序启动,或从后台进入前台显示
onHide,当小程序从前台进入后台
page 部分:
onLoad,监听页面加载
onShow,监听页面显示
onReady,监听页面初次渲染完成
onHide,监听页面隐藏
onUnload,监听页面卸载
onPullDownRefresh,监听用户下拉动作
onReachBottom,页面上拉触底事件的处理函数
onShareAppMessage,用户点击右上角分享
onPageScroll,页面滚动
onTabItemTap, 当前是 tab 页时,点击 tab 时触发 (mpvue 0.0.16 支持)
事件处理中的注意点
在mpvue中,一般可以使用Web的DOM事件名来绑定事件,mpvue会将Web事件名映射成对应的小程序事件名,对应列表如下:
// 左侧为WEB事件 : 右侧为对应的小程序事件
{
click: 'tap',
touchstart: 'touchstart',
touchmove: 'touchmove',
touchcancel: 'touchcancel',
touchend: 'touchend',
tap: 'tap',
longtap: 'longtap',
input: 'input',
change: 'change',
submit: 'submit',
blur: 'blur',
focus: 'focus',
reset: 'reset',
confirm: 'confirm',
columnchange: 'columnchange',
linechange: 'linechange',
error: 'error',
scrolltoupper: 'scrolltoupper',
scrolltolower: 'scrolltolower',
scroll: 'scroll'
}
除了上面的之外,Web表单组件<input>
和<textarea>
的change事件会被转为blur事件。
然后,像keydown、keypress之类的键盘事件也没有了,因为小程序没有键盘,所以不需要这些事件。
遇到的问题
- 动态设置页面标题,页面标题也可以在main.json中设置
onLoad(){
wx.setNavigationBarTitle({
title:'我的关注'
})
}
- 获取参数
this.$root.$mp.query.xxx
mpvue不支持列表
- mpvue不支持模板复杂的表达式
以下几种方式都不支持
// 基本类型的方法调用
<p>{{ message.split(‘‘).reverse().join(‘‘) }}</p>
// 实例方法调用
<p>{{ strDecode(message) }}</p>
// 类型判断
<p>{{ typeof message }}</p>
// 过滤器
<p>{{ message | strDecode }}</p>
- class与style
基本全支持,不支持classObj和styleObj形式,例如:
<p :class="classObj"></p>
data () {
return {
classObj: {
active: true
}
}
}
mpvue会解析成:
<p class="object Object"></p>
可以写成如下方式
<p :class="{active: true}"></p>
styleObj 类似,另外,暂不支持在组件上使用 Class 与 Style 绑定。
详细的不支持列表:
- 暂不支持在组件引用时,在组件上定义 click 等原生事件、v-show(可用 v-if 代替)和 class style 等样式属性(例:<card class="class-name"> </card> 样式是不会生效的),因为编译到 wxml,小程序不会生成节点,建议写在内部顶级元素上。
- Slot(scoped 暂时还没做支持)
- 动态组件
- 异步组件
- inline-template
- X-Templates
- keep-alive
- transition
- class
- style
参考资料
http://www.cnblogs.com/weichen913/p/9439203.html