zoukankan      html  css  js  c++  java
  • MPVUE

    MPVUE - 使用vue.js开发微信小程序

    什么是mpvue?

    mpvue 是美团点评前端团队开源的一款使用 Vue.js 开发微信小程序的前端框架。框架提供了完整的 Vue.js 开发体验,开发者编写 Vue.js 代码,mpvue 将其解析转换为小程序并确保其正确运行。

    简单上手mpvue

    官方提供了一套quickstart模板。

     vue init mpvue/mpvue-quickstart my-project
    

    安装好依赖之后,执行npm run dev,将会将小程序文件打包进dist文件夹,之后使用微信开发者工具将目录指向dist文件夹即可。

    差异化情况

    • 生命周期

    支持vue.js的生命周期部分,并且兼容了小程序的生命周期。

    new Vue({
      data: {
        a: 1
      },
      created () {
        // `this` 指向 vm 实例
        console.log('a is: ' + this.a)
      },
      onShow () {
        // `this` 指向 vm 实例
        console.log('a is: ' + this.a, '小程序触发的 onshow')
      }
    })
    // => "a is: 1"
    
    • 模板语法

    不支持 v-html,因为小程序里没有dom和bom的概念。

    • 不支持部分复杂的 JavaScript 渲染表达式

    mpvue会把 template 中的 {{}} 双花括号的部分,直接编码到 wxml 文件中,由于微信小程序的能力限制(数据绑定),所以无法支持复杂的 JavaScript 表达式

    目前可以使用的有 + - * % ?: ! == === > < [] .

    以下这几种情况都不支持:

    // 基本类型的方法调用
    <p>{{ message.split('').reverse().join('') }}</p>
    // 实例方法调用
    <p>{{ strDecode(message) }}</p>
    // 类型判断
    <p>{{ typeof message }}</p>
    // 过滤器
    <p>{{ message | strDecode }}</p>
    

    第一种可以使用计算属性来解决,第二种和第四种都是经常使用的,可以数据初始化的时候用js处理,只不过遍历的时候会稍微有点繁琐。也可以让后端支持,直接返回处理过的数据。

    支持短路和断路:

    <p>{{ false || '默认值' }}</p>
    <p>{{ true && '默认值' }}</p>
    
    • Class 与 Style 绑定

    基本全支持,不支持classObj和styleObj形式,例如:

    <p :class="classObj"></p>
    
    data () {
        return {
            classObj: {
                active: true
            }
        }
    }
    

    mpvue会解析成:

    <p class="object Object"></p>
    

    styleObj 类似,另外,暂不支持在组件上使用 Class 与 Style 绑定。

    • 条件渲染、列表渲染、计算属性全支持

    • 组件

    不支持列表:

    1. 暂不支持在组件引用时,在组件上定义 click 等原生事件、v-show(可用 v-if 代替)和 class style 等样式属性(例:<card class="class-name"> </card> 样式是不会生效的)
    2. Slot(scoped 暂时还没做支持)
    3. 动态组件
    4. 异步组件
    5. inline-template
    6. X-Templates
    7. keep-alive
    8. transition

    不支持复杂的slot,组件化会受限,不支持transition,过渡动画可能要用css3手写。

    支持小程序原生组件,原生组件上的事件绑定,需要以 vue 的事件绑定语法来绑定,如 bindchange="eventName" 事件,需要写成 @change="eventName",例如:

    <picker mode="date" :value="date" start="2015-09-01" end="2017-09-01" @change="bindDateChange">
        <view class="picker">
          当前选择: {{date}}
        </view>
    </picker>
    

    注意事项及踩坑

    • 模板中的img标签url指向相对路径时不能正确解析例如:

    <img src="~assets/images/home/header.png" />
    <img src="./assets/images/home/header.png" />
    

    在当前mpvue版本(1.0.8)中,图片相对url不能正确解析,官方已列入待修复bug(27 days ago),https://github.com/Meituan-Dianping/mpvue/issues/152,暂时的解决方法是可以将静态资源放入static文件夹中,然后img标签用绝对路径引入:

    <img src="/static/images/home/header.png" />
    

    带来的副作用是不能享受url-loader的处理(小图片转base64)。

    另外,css中却是可以通过相对路径引入图片的,例如:

    .icon {
        background-image: url('./assets/images/home/header.png');
    }
    
    .icon1 {
        background-image: url('~assets/images/home/header.png');
    }
    

    url-loader 会将小于limit数值的图片转成base64,但是小程序中好像规定了css中不能引入本地静态资源,可以通过配置url-laoder、nginx别名、host解决:

    host配置:

    127.0.0.1 sns-mp.guahao-inc.com
    

    nginx配置:

    server {
        listen 80;
        server_name sns-mp.guahao-inc.com;
        location /static/src/assets/ {
            alias /Users/lavyun/Code/FE/vue/vue-mp-demo/src/assets/;
        }
    }
    

    url-loader配置:

    const imageRule = {
        test: /.(png|jpe?g|gif|svg)(?.*)?$/,
        loader: 'url-loader',
        options: {
            limit: 10 * 1024,
            publicPath: 'http://sns-mp.guahao-inc.com/',
            name: utils.assetsPath('[path][name].[ext]')
        }
    }
    
    // 生产环境下指向静态资源服务器
    if (isProd) {
        imageRule.options.publicPath = 'http://static.gauhao-inc.com'
    }
    
    module.export = {
        ...,
        module: {
            rules: [
                imageRule,
                ...
            ]
        }
    }
    

    组件和小程序系统组件重名时的BUG

    比如:

    <loading></loading>
    

    小程序文档里没有提到有loading这个组件,之前直接使用loading做组件名,产生了很多莫名其妙的bug,框架层面也没做错误提示。所以大家开发时最好避免下命名冲突。

    slot的各种问题

    之前mpvue版本1.0.6时,使用slot生成的小程序代码少了import命令。
    https://github.com/Meituan-Dianping/mpvue/issues/217

    组件的代码:

    <template>
    	<div class="scroll-wrapper">
    		<slot></slot>
    		<loading v-if="loading"></loading>
    	</div>
    </template>
    

    使用组件时的代码:

    <scroll-wrapper :loading="loading">
    	<top-entries></top-entries>
    </scroll-wrapper>
    

    生成的wxml:

    <template name="data-v-7d8efa60-default-1">
        <template data="{{...$root[$kk+'0'], $root}}" is="home$69cf8ee0"></template>
    </template>
    

    少了一行:<import src="home$69cf8ee0" />

    现版本 1.0.8 使用slot时:

    <scroll-wrapper :loading="loading">
    	<circle-list v-if="circleList.length" :list="circleList"></circle-list>
    </scroll-wrapper>
    

    circleList状态被更新时不能正确的触发视图更新,官方的仓库中也有大部分issue也是关于slot的。

    使用vuex管理状态

    虽然小程序是多页的,但小程序的多页主要是指 视图层 是多个 webview,相互独立,但是 js 都是在同一个执行环境中的,所以在mpvue中可以直接使用vuex来管理状态。

    初始化一个vuex实例,然后在需要使用的组件里引入。

    import Vue from 'vue'
    import Vuex from 'vuex'
    import actions from './actions'
    import mutations from './mutations'
    import getters from './getters'
    import state from './state'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
        state,
        actions,
        mutations,
        getters
    })
    
    export default store
    

    在组件里使用:

    import store from '../../store'
    import * as types from '../../store/types'
    
    export default {
        data () {
            return {
                animate: false
            }
        },
        computed: {
            popup () {
                return store.getters.postEntryPopup
            }
        },
        methods: {
            close () {
                this.animate = false
                setTimeout(() => {
                    store.commit(types.POST_ENTRY_POPUP)
                }, this.popup.animateTime)
            }
        }
    }
    

    app.json 和 page.json

    框架规定在 src/main.js 中导出app.json配置,

    import Vue from 'vue'
    import App from './App'
    
    Vue.config.productionTip = false
    App.mpType = 'app'
    
    const app = new Vue(App)
    app.$mount()
    
    export default {
        // 这个字段走 app.json
        config: {
            // 页面前带有 ^ 符号的,会被编译成首页,其他页面可以选填,我们会自动把 webpack entry 里面的入口页面加进去
            pages: ['^pages/home/main'],
            window: {
                onReachBottomDistance: 10
            }
        }
    }
    

    在 src/pages/**/main.js 中导出page.json配置:

    import Vue from 'vue'
    import App from './index'
    
    const app = new Vue(App)
    app.$mount()
    
    export default {
        config: {
            navigationBarBackgroundColor: '#3f86ff',
            navigationBarTitleText: '首页',
            backgroundTextStyle: 'light',
            navigationBarTextStyle: 'light',
            enablePullDownRefresh: true,
            backgroundColor: '#3f86ff'
        }
    }
    

    使用总结

    使用mpvue可以很好降低开发人员的学习小程序语法的成本,可以很大程度上的实现h5和小程序代码复用(使用vuejs框架),在迁移一些vue组件到小程序时,可能都不需要改动代码或者改动少量代码就可以直接使用。官方对待框架的态度是很不错的,开源一个多月(3月9日 - 4月16日),一共有300个issue,处理了250个,获得7800star,社区比较活跃。

    文章推荐

    Mpvue一个基于Vue的微信小程序前端框架

  • 相关阅读:
    从Object对象中读取属性的值
    CentOS7安装Mysql
    CentOS初使用命令总结
    linux安装git、node、pm2
    将 ELASTICSEARCH 写入速度优化到极限
    Elasticsearch
    elasticsearch5.0.1集群索引分片丢失的处理
    ELASTICSEARCH健康red的解决
    使用linux远程登录另一台linux
    fiddler构造表单上传文件的请求
  • 原文地址:https://www.cnblogs.com/smartXiang/p/8868145.html
Copyright © 2011-2022 走看看