MPVUE - 使用vue.js開發微信小程序


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的微信小程序前端框架


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM