1. mpvue-介紹
mpvue 是美團團隊開發的語法類似 Vue.js 的小程序的前端框架
1.1. 主要特性
主要有以下特性
- 徹底的組件化開發能力:提高代碼複用性
- 完整的
Vue.js
開發體驗 - 方便的
Vuex
數據管理方案:方便構建複雜應用 - 快捷的
webpack
構建機制:自定義構建策略、開發階段 hotReload - 支持使用 npm 外部依賴
- 使用
Vue.js
命令行工具 vue-cli 快速初始化項目 - H5 代碼轉換編譯成小程序目標代碼的能力
1.2. 優秀案例
1.3. 前置知識
1.3.1. 代碼示例
new Vue({
data: {
a: 1
},
created () {
// `this` 指向 vm 實例
console.log('a is: ' + this.a)
},
onShow () {
// `this` 指向 vm 實例
console.log('a is: ' + this.a, '小程序觸發的 onshow')
}
})
2. 啓動項目
2.1. 全局安裝vue腳手架工具
npm install --global vue-cli
2.2. 創建項目
mpvue 提供了開發企業級的模板 quickstart 和 頁面級的模板 simple。
vue init mpvue/mpvue-quickstart my-project
2.3. 安裝依賴
cd my-project
npm install
2.4. 修改微信入口地址
由於 mpvue中的 小程序入口路徑和打包編譯後的路勁 對應不上,因此需要我們手動的修改下 入口路徑。
修改 project.config.json
文件
// 源代碼
"miniprogramRoot": "./dist/",
// 修改爲
"miniprogramRoot": "./dist/wx/",
2.5. 啓動項目
npm run dev
2.6. 使用小程序開發者工具打開
編譯成功後,可以看到在 dist/wx
內有我們熟悉的小程序代碼文件,此時,使用小程序開發者工具直接打開 項目的根目錄(因爲直接在配置文件中配置過 /dist/wx/
入口路徑 )
3. 項目目錄結構
編譯成功後,可以看到如下的項目結構
├─build 打包構建相關配置文件
├─config 用於打包的一些變量文件
├─dist 小程序頁面文件
├─src mpvue源代碼
├─static 一些靜態資源
└─test 測試相關
│ .babelrc js的編譯配置
│ .editorconfig 編輯器風格
│ .gitignore git文件忽略清單
│ .postcssrc.js 轉換css到wxss的
│ index.html 入口模板
│ package-lock.json node包版本說明文件
│ package.json 項目描述文件
│ project.config.json 小程序開發者工具配置文件
│ README.md 項目說明文檔
4. 生命週期圖示
4.1. vue 生命週期
-
beforeCreate
在實例初始化之後,數據觀測 (data observer) 和 event/watcher 事件配置之前被調用
-
created
在實例創建完成後被立即調用,
$el
屬性目前不可見,data中的數據可以使用 -
beforeMount
在掛載開始之前被調用:相關的
render
函數首次被調用。 -
mounted
示例和對應的dom都被創建後開始調用,子組件不一定全部被掛載,如要確保,使用 [vm.KaTeX parse error: Expected 'EOF', got '#' at position 39: …ejs.org/v2/api/#̲vm-nextTick) 來代…el可用。
-
beforeUpdate
數據更新時調用,這裏適合在更新之前訪問現有的 DOM,data中的數據更新了,但是視圖還沒有更新
-
updated
由於數據更改導致的虛擬 DOM 重新渲染和打補丁時會被調用,data中的數據更新了,視圖也更新了
-
activated
keep-alive 組件激活時調用
-
deactivated
keep-alive 組件停用時調用
-
beforeDestroy
實例銷燬之前調用。在這一步,實例仍然完全可用
-
destroyed
Vue 實例銷燬後調用,Vue 實例指示的所有東西都會解綁定,所有的事件監聽器和所有的子實例都會被銷燬
4.2. 小程序生命週期
app 部分:
-
onLaunch
小程序初始化時被調用
-
onShow
當小程序啓動,或從後臺進入前臺顯示被調用
-
onHide
當小程序從前臺進入後臺
page 部分:
-
onLoad
頁面加載完畢被調用
-
onShow
頁面開始顯示時被調用
-
onReady,
頁面初次渲染完成被調用
-
onHide
頁面隱藏時被調用
-
onUnload
頁面卸載被調用
-
onPullDownRefresh
用戶下拉動作開始時被調用
-
onReachBottom
頁面上拉觸底時被調用
-
onShareAppMessage
用戶點擊右上角分享時被調用
-
onPageScroll
頁面滾動時被調用
-
onTabItemTap,
當前是 tab 頁時,點擊 tab 時觸發
4.3. mpvue-生命週期圖示
mpvue
會在小程序 onReady 後,再去觸發 vue mounted 生命週期- 不建議使用小程序的生命週期鉤子
5. mpvue 標籤映射
由於web中的標籤和小程序中的標籤存在差異,因此 mpvue內部提供了對應的標籤轉換,可以讓開發者專注於業務本身,省去了記憶新標籤的成本。
web標籤 | 小程序標籤 | 備註 |
---|---|---|
div | view[_div] | |
p | view[_p] | |
span | label | |
a | navigator | 屬性參照小程序的navigator |
img | image | 屬性參照小程序的image |
ul | view[_ul] | |
ol | view[_ol] |
6. mpvue 語法
6.1. 數據綁定
mpvue綁定數據的方式大部分和vue一樣。
6.1.1. 支持的語法
Mustache
(雙大括號) 文本插值v-text
屬性的方式綁定- 標籤內屬性方式綁定
:attr="value"
v-model
也是支持的
6.1.2. 不支持的語法
v-html
因爲小程序內部不支持動態標籤 (會被解釋爲rich-text
標籤)v-once
暫時不支持
6.1.3. 代碼示例
<!-- 1.0 支持的語法 -->
<!-- 雙括號 -->
{{msg}}
<!-- v-text -->
<view v-text="msg"></view>
<!-- :hidden -->
<view :hidden="false" >顯示與隱藏</view>
<!-- 2.0 不支持的錯誤 -->
<!-- v-html -->
<view v-html="htmlmsg"></view>
<!-- v-once -->
<view v-once="msg"></view>
6.2. JavaScript 渲染表達式
目前可以使用的有 + - * % ?: ! == === > < [] .
,剩下的還待完善。
但寫在 @event 裏面的表達式是都支持的,因爲這部分的計算放在了 vdom
裏面
<!-- 這種就不支持,建議寫 computed -->
<p>{{ message.split('').reverse().join('') }}</p>
<!-- 但寫在 @event 裏面的表達式是都支持的,因爲這部分的計算放在了 vdom 裏面 -->
<ul>
<li v-for="item in list">
<div @click="clickHandle(item, index, $event)">{{ item.value }}</p>
</li>
</ul>
6.3. computed 和 watch
6.3.1. computed
對於任何複雜邏輯,都應當使用計算屬性
使用方式和vue中一樣
computed:{
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
6.3.2. watch
watch
相比於computed
可以讓我們做更多的事情。
使用方式和vue中一樣
watch: {
msg(newValue, oldValue) {
console.log("watch被觸發了");
}
}
6.4. 條件渲染
6.4.1. v-if
支持 v-if v-else 和 v-else if
指令。
v-if
指令的顯示和隱藏是通過 增加和刪除節點實現。頻繁操作性能損耗大。
<div v-if="false">if</div>
<div v-else-if="true"> v-else-if</div>
<div v-else>v-else</div>
6.4.2. v-show
用法大致一樣
<div v-show="true">v-show</div>
6.5. 列表渲染
6.5.1. v-for
v-for
可以循環 數組和對象等可迭代的對象。mpvue
中,嵌套列表渲染,必須指定不同的索引!
數組
<ul v-for="(card, index) in list">
<li v-for="(item, itemIndex) in card">
{{item.value}}
</li>
</ul>
對象
<div v-for="(value, key) in object">
{{ key }}: {{ value }}
</div>
嵌套列表渲染
<ul v-for="(card, index) in list">
<li v-for="(item, itemIndex) in card">
{{item.value}}
</li>
</ul>
6.6. Class 與 Style 綁定
動態設置樣式
6.6.1. class 支持的語法:
<p :class="{ active: isActive }">111</p>
<p class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">222</p>
<p class="static" :class="[activeClass, errorClass]">333</p>
<p class="static" v-bind:class="[isActive ? activeClass : '', errorClass]">444</p>
<p class="static" v-bind:class="[{ active: isActive }, errorClass]">555</p>
6.6.2. style 支持的語法:
<p v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">666</p>
<p v-bind:style="[{ color: activeColor, fontSize: fontSize + 'px' }]">777</p>
6.6.3. 不支持的語法
- 不支持 官方文檔:Class 與 Style 綁定 中的
classObject
和styleObject
語法。 - 不支持在組件上使用 Class 與 Style 綁定
7. 事件
幾乎全支持 vue中的事件處理器
7.1. 綁定方式
使用v-bind
或者@
關鍵字來執行綁定
// v-bind
<view v-bind:click="clickHandle3">點我</view>
// @
<view @click="clickHandle3">點我</view>
7.2. 事件映射表
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 |
7.3. 踩坑注意
- 列表中沒有的原生事件也可以使用例如 bindregionchange 事件直接在 dom 上將bind改爲@
- 小程序能力所致,bind 和 catch 事件同時綁定時候,只會觸發 bind ,catch 不會被觸發,要避免踩坑。
- 事件修飾符
.stop
的使用會阻止冒泡,但是同時綁定了一個非冒泡事件,會導致該元素上的 catchEventName 失效!.prevent
可以直接幹掉,因爲小程序裏沒有什麼默認事件,比如submit並不會跳轉頁面.capture
支持1.0.9
.self
沒有可以判斷的標識.once
也不能做,因爲小程序沒有 removeEventListener, 雖然可以直接在 handleProxy 中處理,但非常的不優雅,違背了原意,暫不考慮
- 其他 鍵值修飾符 等在小程序中壓根沒鍵盤,所以。。。
@regionchange
,同時這個事件也非常特殊,它的 event type 有 begin 和 end 兩個,導致我們無法在handleProxy
中區分到底是什麼事件,所以你在監聽此類事件的時候同時監聽事件名和事件類型既<map @regionchange="functionName" @end="functionName" @begin="functionName"><map>
8. 表單控件綁定
建議開發過程中直接使用 微信小程序:表單組件
如:
9. 組件
有且只能使用單文件組件(.vue 組件)的形式進行支持。詳細的使用方式,參照vue中的組件文檔
9.1. 定義組件
新建組件文件 card.vue
組件也是分爲3個部分。 標籤 template
腳本 script
和 樣式 style
編輯內容
<template>
<div>
<p class="card">
{{text}}
</p>
</div>
</template>
<script>
export default {
data () {
return {
text: "卡片組件"
}
},
}
</script>
<style>
.card {
padding: 10px;
}
</style>
9.2. 使用組件
在某個頁面文件中使用組件 card.vue
<template>
<div>
<card></card>
</div>
</template>
<script>
import card from '@/components/card'
export default {
components: {
card
}
}
</script>
<style>
</style>
9.3. 組件傳值
父組件通過prop
來向子組件傳遞數據。
9.3.1. 父組件
在data
中定義數據同時在標籤上通過屬性的方式傳遞
<!-- template -->
<card :text="msg"></card>
<!-- script -->
data () {
return {
msg: "mpvue"
}
}
9.3.2. 子組件
通過props進行接收
export default {
props: ['text']
}
9.4. 組件通信
主要有三種方式
- 子向父 通過
$emit
- 所有的組件之間 通過事件總線
EventBus
- 企業級的組件通信,建議使用 vuex狀態管理方案 來實現,更好維護數據。
9.4.1. 子向父通信
通過 $emit
關鍵字觸發
父組件中
<template>
<card2 @parentEvent="parentHd"></card2>
</template>
<script>
import card2 from "@/components/card2.vue";
export default {
components: {
card2
},
methods: {
parentHd(...args) {
console.log(args);
console.log("父組件打印紙");
}
}
}
</script>
子組件中
<template>
<div>
</div>
</template>
<script>
export default {
props: ['text'],
mounted(){
setTimeout(() => {
this.$emit("parentEvent",1,2,3,4);
}, 5000);
}
}
</script>
9.4.2. 事件總線 EventBus
EventBus
又稱爲事件總線。它是組件共用的事件中心,可以向該中心註冊發送事件或接收事件,所以組件都可以上下平行地通知其他組件。使用起來很方便,但是容器導致代碼混亂,不好維護。
新建總線文件
在 utils/
中新建 js文件 event-bus.js
import Vue from 'vue'
export default new Vue()
組件中開始觸發事件
<!-- template -->
<div>
<p class="card" @click="clickHd"> 組件3 </p>
</div>
<script>
/* script */
import { EventBus } from "../utils/event-bus.js";
export default {
methods: {
clickHd() {
EventBus.$emit("incremented", {
num: 111,
deg: 222
});
}
}
}
</script>
其他頁面監聽
import { EventBus } from "@/utils/event-bus.js";
mounted() {
EventBus.$on("incremented", ({
num,
deg
}) => {
console.log(num, deg);
});
},
9.5. 不支持的功能
- 暫不支持在組件引用時,在組件上定義 click 等原生事件、v-show(可用 v-if 代替)和 class style 等樣式屬性(例:
<card class="class-name"> </card>
樣式是不會生效的),因爲編譯到 wxml,小程序不會生成節點,建議寫在內部頂級元素上。 - Slot(scoped 暫時還沒做支持)
- 動態組件
- 異步組件
- inline-template
- X-Templates
- keep-alive
- transition
- class
- style