作者:蜗牛老湿 原文链接
微信自推出小程序以来,热度一直居高不下,各大公司开始专门开发小程序,但是小程序自定义的wxml和wxss和自己定义的语法,让被三大框架统治的前端江湖头疼不易,因为需要专门为小程序开发一套代码来维护,也徒增了学习成本,中间虽有支持vuejs语法的wepy独领风骚,也是需要学习wepy的语法,直至今年3月,mpvue横空出世,也得到了vuejs作者的力推,以后有可能变为vuejs的标准
框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。(这段直接copy的)有了mpvue之后,开发小程序的体验直接上升一个档次
- 终于可以用npm了
- 使用html+css(scss)
- 完全的vue开发体验,全部.vue单文件组件
- 使用 Vue.js 命令行工具 vue-cli 快速初始化项目
- 支持 Vuex
- 废话不多说,我们先来体验一下
安装环境
- 需要大家执行
npm install vue-cli -g
安装vue-cli和小程序的开发者工具 - 执行
vue init mpvue/mpvue-quickstart mpvue-demo
然后一路回车下去,你就得到了一个mpvue项目脚手架 - 进入mpvue-demo目录,执行
npm install && npm run dev
启动项目,然后打开微信开发者工具,打开mpvue-demo目录,就进入了mpvue的世界,先看下mpvue的src目录,也就是源码目录结构
基本看不出这是一个小程序项目,然后我们打开/pages/counter/index.vue看下
<template>
<div class="counter-warp">
<p>Vuex counter:{{ count }}</p>
<p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</p>
<a href="/pages/index/main" class="home">去往首页</a>
</div>
</template>
<script>
// Use Vuex
import store from './store'
export default {
computed: {
count () {
return store.state.count
}
},
methods: {
increment () {
store.commit('increment')
},
decrement () {
store.commit('decrement')
}
}
}
</script>
<style>
.counter-warp {
text-align: center;
margin-top: 100px;
}
.home {
display: inline-block;
margin: 100px auto;
padding: 5px 10px;
color: blue;
border: 1px solid blue;
}
</style>
完全就是一个vuejs的组件,没有小程序的任何语法,我们现在把所有内容删掉,来尝试用vuejs做一个todolist
<template>
<div class="mpvue-demo">
<p class="title">{{title}}</p>
</div>
</template>
<script>
export default {
data () {
return {
title: 'Hello Mpvue'
}
}
}
</script>
<style>
.title{
color:#ed12a3;
text-align: center;
}
</style>
修改完毕后,打开src/main.js
修改一下pages的配置,改为pages:['^pages/counter/main']
, 这样counter页面就变成了首页,
这时候小程序的开发者工具应该就能显示出一行 hello mpvue的字样,如果没变化,可以看下命令行,可能是代码规范不符合
我们写的,都是单纯的html+css+vue的语法,但是已经能够在小程序里继续运行了,然后我们来继续,尝试渲染一个列表
<template>
<div class="mpvue-demo">
<p class="title">{{title}}</p>
<ul class="todos">
<li v-key='i' v-for='(todo,i) in todos'>{{todo}}</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
title: 'Hello Mpvue',
todos: ['吃饭', '睡觉', '慕课学习']
}
}
}
</script>
<style>
.title{
color:#ed12a3;
text-align: center;
}
ul.todos{
margin:20px;
}
</style>
我们新增了ul和li,并且使用v-for渲染列表,下面我们尝试加上用户输入,能够添加一条记录 ,需要用到input和button标签,以及vuejs的事件处理@click
<template>
<div class="mpvue-demo">
<p class="title">{{title}}</p>
<input type="text" v-model='mytodo'>
<button @click='addTodo'>添加一条</button>
<ul class="todos">
<li v-key='i' v-for='(todo,i) in todos'>{{todo}}</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
mytodo: '',
title: 'Hello Mpvue',
todos: ['吃饭', '睡觉', '慕课学习']
}
},
methods: {
addTodo () {
if (!this.mytodo) {
return
}
this.todos.push(this.mytodo)
this.mytodo = ''
}
}
}
</script>
<style>
.title{
color:#ed12a3;
text-align: center;
}
ul.todos{
margin:20px;
}
input{
border:2px solid #ed12a3;
}
</style>
然后我们再添加一个功能来尝试一下计算属性以及样式渲染,没个事件都添加一个点击时间,可以标记为完成,并且显示删除的样式,我们需要对todos的数据结构进行扩展,加入done字段
<template>
<div class="mpvue-demo">
<p class="title">{{title}}</p>
<input type="text" v-model='mytodo'>
<button @click='addTodo'>添加一条</button>
<ul class="todos">
<li
v-for='(todo,i) in todos'
v-key='i'
:class="{'done':todo.done}"
@click='toggle(i)'
>{{todo.text}}</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
mytodo: '',
title: 'Hello Mpvue',
todos: [
{text: '吃饭', done: false},
{text: '睡觉', done: false},
{text: '慕课学习', done: false}
]
}
},
methods: {
addTodo () {
if (!this.mytodo) {
return
}
this.todos.push(this.mytodo)
this.mytodo = ''
},
toggle (i) {
this.todos[i].done = !this.todos[i].done
}
}
}
</script>
<style>
.title{
color:#ed12a3;
text-align: center;
}
ul.todos{
margin:20px;
}
input{
border:2px solid #ed12a3;
}
.done{
text-decoration: line-through;
}
</style>
我们还需要显示已经完成的进度,以及清空按钮,这里就需要vuejs的计算属性
<template>
<div class="mpvue-demo">
<p class="title">{{title}}</p>
<input type="text" v-model='mytodo'>
<button @click='addTodo'>添加一条</button>
<button @click='clearTodo'>清空</button>
<ul class="todos">
<li
v-for='(todo,i) in todos'
v-key='i'
:class="{'done':todo.done}"
@click='toggle(i)'
>{{todo.text}}</li>
<li>
{{todoNum}}/{{todos.length}}
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
mytodo: '',
title: 'Hello Mpvue',
todos: [
{text: '吃饭', done: false},
{text: '睡觉', done: false},
{text: '慕课学习', done: false}
]
}
},
computed: {
todoNum () {
return this.todos.filter(v => !v.done).length
}
},
methods: {
clearTodo () {
this.todos = this.todos.filter(v => !v.done)
},
addTodo () {
if (!this.mytodo) {
return
}
this.todos.push({text: this.mytodo, done: false})
this.mytodo = ''
},
toggle (i) {
this.todos[i].done = !this.todos[i].done
}
}
}
</script>
<style>
.title{
color:#ed12a3;
text-align: center;
}
ul.todos{
margin:20px;
}
input{
border:2px solid #ed12a3;
}
.done{
text-decoration: line-through;
}
</style>
最后 我们在加入本地存储,每次变动的时候都存在localStorage里,并且再初始化的created生命周期函数里,从localStorage获取列表初始化todos即可
api文档
注意中间有一次刷新的操作,下次进来 依然能保存之前的状态,全部代码如下
<template>
<div class="mpvue-demo">
<p class="title">{{title}}</p>
<input type="text" v-model='mytodo'>
<button @click='addTodo'>添加一条</button>
<button @click='clearTodo'>清空</button>
<ul class="todos">
<li
v-for='(todo,i) in todos'
v-key='i'
:class="{'done':todo.done}"
@click='toggle(i)'
>{{todo.text}}</li>
<li>
{{todoNum}}/{{todos.length}}
</li>
</ul>
</div>
</template>
<script>
export default {
// 数据
data () {
return {
mytodo: '',
title: 'Hello Mpvue',
todos: [
]
}
},
// 计算属性
computed: {
todoNum () {
return this.todos.filter(v => !v.done).length
}
},
// created生命周期,组件创建后执行
created () {
// 从本地存储里获取数据
this.todos = wx.getStorageSync('todos') || []
},
methods: {
// 清空已完成的事情
clearTodo () {
this.todos = this.todos.filter(v => !v.done)
this.updateStorage()
},
// 更新本地存储
updateStorage () {
wx.setStorageSync('todos', this.todos)
},
// 添加事件
addTodo () {
if (!this.mytodo) {
return
}
this.todos.push({text: this.mytodo, done: false})
this.mytodo = ''
this.updateStorage()
},
// 设置事件状态
toggle (i) {
this.todos[i].done = !this.todos[i].done
this.updateStorage()
}
}
}
</script>
<style>
.title{
color:#ed12a3;
text-align: center;
}
ul.todos{
margin:20px;
}
input{
border:2px solid #ed12a3;
}
.done{
text-decoration: line-through;
}
</style>
当然,这只是一个非常简单的demo,但是也涉及到很多的能力,包括渲染列表,事件绑定,计算属性,生命周期等等,我们可以感受到mpvue的强大之处,完全使用vuejs的语法开发项目,这是mpvue系列文章教学的第一篇,后面我们介绍更复杂的mpvue如何开发
最后广告一下,欢迎大家关注我在慕课网的实战课程mpvue+koa2全栈开发小程序的课程,欢迎大家支持