Mpvue Note

使用mpvue的总结

Mpvue官网

1、搭建个基本的mpvue项目:

1)准备搭建环境:

1
2
node -v //检查node是否安装
npm -v //检查npm版本

2)全局安装 vue-cli:

1
sudo npm install --g vue-cli

这里一般要加sudo,不然会报错。

3)创建一个基于mpvue-quickstart模板的新项目:

1
vue init mpvue/mpvue-quickstart my-smallprogram

这里项目名称、作者、是否需要eslint等配置都可以默认,至于是否要用vuex则需要提前考虑好,否则需要单独install,或者添加到package.json。

4)下载依赖包:

1
2
npm install
npm run dev

查看项目中是否多了dist文件夹,有的话,证明我们的项目搭建成功:

图片

到了这一步,就可以在project.config.json中写好相应的appid,然后用微信开发者工具打开查看效果了。

2、开发中遇到的问题:

1)自己的项目中需要用vuex来管理数据,但是发现mapState、mapActions等辅助函数使用会报错。

解决方案:在每个page文件夹下的main.js中这样写:

1
2
3
4
5
6
7
8
import Vue from 'vue'
import App from './index'
//在这里引入store 并挂载到vue的原型链上
import store from './store';
Vue.prototype.$store = store;

const app = new Vue(App)
app.$mount()

在store.js中这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const store = new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        increment: (state, data) => state.count += data,
        decrement: (state) => state.count -= 1
    },
    actions: {
        getTotal({commit}) {
            commit('increment', 13);
        }
    }
});

在index.vue中:

1
2
3
4
5
6
7
8
9
    // ...
    ...mapActions([
        'getTotal'
    ]),
    increment () {
        this.getTotal();
    },
    // ...
    }

但要注意的是,即使这里可以用mapState,也不能在mapState里操作data里的数据,因为这种情况下mapState和正常vue组件下的mapState的作用域不同,修改无效。

2)新增页面需要npm run dev重启一下;

不重启会报错:

图片

3)小程序里所有的 BOM/DOM 都不能用,也就是说 v-html 指令不能用;

1
<p v-html="hehe"></p>

这种写法会被编译成:

1
<rich-text nodes="" class="_p data-v-5dddb4ac"></rich-text>

并且页面上不展示。

4)使用this.$root.$mp.query获取参数不能在created中获取,在created中会报Cannot read property ‘query’ of undefined :

可以引用的周期函数有:onShow、onLoad、onReady、mounted等,在onLaunch中也获取不到,但是不会报错。

5)项目中引用的echarts文件过大:

项目中需要引入echarts,直接引入后,打包完体积超过 2M了,没办法提交。echarts提供的有精简版本,我们可以导入精简的版本。

1
2
import echarts from "echarts/dist/echarts.simple.min";
import mpvueEcharts from "mpvue-echarts";

6)不支持复杂的js渲染表达式:

1
<p>{{ message.split('').reverse().join('') }}</p>

这种写法不支持,也不支持写成filter,可以放到computed中。

7)在template中不能写函数,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
    <div class="counter-warp">
        <p>{{ consoleLog() }}</p>
        <a href="/pages/index/main" class="home">去往首页</a>
    </div>
</template>

<script>
    // ...
    methods: {
        // ...
        consoleLog() {
            console.log('-----consoleLog-----');
        }
    }
</script>

效果如图:

图片

可以看到dom结构中原封不动的把consoleLog()渲染到页面上,并在console中打印了,但如果在consoleLog中返回一个值会怎么样?把上述代码的consoleLog变更一下:

1
2
3
4
5
6
7
    // ...
    methods: {
        // ...
        consoleLog() {
            return '-----consoleLog-----';
        }
    }

效果如图:

图片

这个时候,不但页面上没有体现出该字符串,控制台也没有输出。

7)嵌套列表渲染,必须使用不同的索引:

1
2
3
4
5
    <ul v-for="(card, index) in list" :key="index">
        <li v-for="(item, index) in card" :key="index">
            
        </li>
    </ul>

上述代码,会在编译器里报错:

图片

8)由于小程序不支持操作实体dom,所以ref不可用:

1
2
3
4
5
6
7
8
9
10
11
// ...
    <textarea class="text" ref="textareas"  placeholder="请输入" />

// ...
    methods: {
        // ...
        handleInsert(keyword) {
            let textareas = this.$refs.textareas;
            // ...
        }
    }

上述代码中变量textareas为一个空对象:

图片

9)替换图片或文件 需要重新run dev,不然会报错,新增加的页面找不到,同理,在发布体验版时也要run dev,不然最新的逻辑更新不了,会存在问题。

10)调取微信的扫码功能,成功后会刷新页面。

11)小程序内部设置了离线缓存机制,所以在离开页面时,最好初始化一下数据,不然在接口不正常调用或者获取数据为空时,小程序会自行填充数据,然而这种机制填充的数据多数是不对的。