為了降低學(xué)習(xí)成本,獨(dú)立支持了 vue 的指令子集,你可以在模板添加一個(gè) lang 屬性 <template lang="vue"> 即可使用。 注意必須在組件根元素上 template 上加 lang='vue'
模板中綁定的數(shù)據(jù)來(lái)均來(lái)自于 data、computed 屬性。
數(shù)據(jù)綁定使用 Mustache 語(yǔ)法(雙大括號(hào))將變量包起來(lái),可以作用于:
<view><text>{{ message }}</text></view>
<view :id="dynamicId"> </view> 或者 v-bind view v-bind:id="dynamicId"
<template lang='vue'>
<page title="chameleon">
<view><text>message:{{message}}</text></view>
<input v-model="message"></input>
</page>
</template>
<script>
class Comp {
data = {
message:'default-value'
}
watch = {
message(){
console.log('modelTest change');
}
}
}
export default new Comp();
</script>
<script cml-type="json">
{
"base": {}
}
</script>
v-model 元素上不支持再綁定 input 事件,如果對(duì)于輸入值變化之后想執(zhí)行一些操作,可以通過(guò) watch 對(duì)應(yīng)的值來(lái)進(jìn)行;
父組件
<template lang="vue">
<page title="chameleon">
<view><text>c-model的在組件上的使用</text></view>
<comp v-model="modelValueTest2" ></comp>
<view><text>組件使其改變{{modelValueTest2}}</text></view>
</page>
</template>
<script>
class Index {
data = {
currentComp: 'comp1',
modelValueTest2: 'sss',
};
methods = {
handleClick() {
this.currentComp = this.currentComp === 'comp1' ? 'comp1' : 'comp2';
},
};
}
export default new Index();
</script>
<style>
.scroller-wrap {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
<script cml-type="json">
{
"base": {
"usingComponents": {
"comp1":"/components/comp1",
"comp2":"/components/comp2"
}
}
}
</script>
子組件
<template lang="vue">
<view>
<input type="text" :value="value" v-on:input="handleInput"/>
</view>
</template>
<script>
class Comp {
props = {
value: {
type: String,
default: 'default-value',
},
};
methods = {
handleInput(e) {
console.log('input', e);
debugger;
this.$cmlEmit('input', {
value: e.detail.value,
});
},
};
}
export default new Comp();
</script>
<script cml-type="json">
{
"base": {}
}
</script>
{
{
number + 1;
}
}
{
{
ok ? 'YES' : 'NO';
}
}
{
{
message
.split('')
.reverse()
.join('');
}
}
<view><text>{{a + b}} + {{c}} + d</text></view>
class Index {
data = {
a: 1,
b: 2,
c: 3,
};
}
export default new Index();
view 中的內(nèi)容為 3 + 3 + d。
<view><text>{{"hello" + name}}</text></view>
特別注意:模板中的字符串都要使用雙引號(hào),不能使用單引號(hào)。
<view><text>{{object.key}}: {{array[0]}}</text></view>
class Index {
data = {
object: {
key: 'Hello ',
},
array: ['MINA'],
};
}
export default new Index();
在框架中,使用
v-if="condition"
來(lái)判斷是否需要渲染該代碼塊:
<view v-if="condition">True</view>
也可以用 v-else-if 和 v-else 來(lái)添加一個(gè) else 塊:
<view v-if="length > 5"><text>1</text></view>
<view v-else-if="length > 2"><text>2</text></view>
<view v-else><text>3</text></view>
因?yàn)?v-if 是一個(gè)控制屬性,需要將它添加到一個(gè)標(biāo)簽上。如果要一次性判斷多個(gè)組件標(biāo)簽,可以使用一個(gè) \<block\> 標(biāo)簽將多個(gè)組件包裝起來(lái),并在上邊使用 v-if 控制屬性。
<block v-if="true">
<view><text>view1</text></view>
<view><text>view2</text></view>
</block>
注意:: \<block\> 并不是一個(gè)組件,它僅僅是一個(gè)包裝元素,不會(huì)在頁(yè)面中做任何渲染,只接受控制屬性。
在組件上使用 v-for 控制屬性綁定一個(gè)數(shù)組,即可使用數(shù)組中各項(xiàng)的數(shù)據(jù)重復(fù)渲染該組件。
<view v-for="(item, index) in array">
<text>{{index}}: {{item.message}}</text>
</view>
<view v-for="(item, index) in array" :key="index">
<text> {{index}}: {{item.message}}</text>
</view>
<view v-for="(item, index) in array" :key="item.id">
<text> {{index}}: {{item.message}}</text>
</view>
類似 block v-if,也可以將 v-for 用在 \<block\> 標(biāo)簽上,以渲染一個(gè)包含多節(jié)點(diǎn)的結(jié)構(gòu)塊。例如:
<block v-for="(item, index) in [1, 2, 3]">
<view> <text>{{index}}: </text></view>
<view> <text>{{item}}</text> </view>
</block>
1.如果 :key="item.id",那么就是 vue 中正常的語(yǔ)法。
2.如果 :key="item",那么在微信端會(huì)被渲染成 wx:key="*this"; 保留關(guān)鍵字 *this 代表在 for 循環(huán)中的 item 本身,這種表示需要 item 本身是一個(gè)唯一的字符串或者數(shù)字,如: 當(dāng)數(shù)據(jù)改變觸發(fā)渲染層重新渲染的時(shí)候,會(huì)校正帶有 key 的組件,框架會(huì)確保他們被重新排序,而不是重新創(chuàng)建,以確保使組件保持自身的狀態(tài),并且提高列表渲染時(shí)的效率。
Chameleon 支持一些基礎(chǔ)的事件,保障各端效果一致運(yùn)行。如果你想要使用某個(gè)端特定的事件,請(qǐng)從業(yè)務(wù)出發(fā)使用多態(tài)組件或者多態(tài)接口差異化實(shí)現(xiàn)功能。
主要擴(kuò)展了事件的綁定:加強(qiáng)了符合 vue 語(yǔ)法的事件綁定;
主要增強(qiáng)了可以通過(guò) v-on @這種形式去綁定事件;
<view v-on:click="handleClick" @tap="handleTap"></view>
<template lang="vue">
<view id="tapTest" @tap="tapName" v-on:click="handleClick"> <text>Click me!</text> </view>
</template>
<script>
class Index {
data = {};
methods = {
tapName() {
console.log(e);
},
};
}
export default new Index();
</script>
事件類型列表:
類型 | 觸發(fā)條件 |
---|---|
touchstart | 手指觸摸動(dòng)作開(kāi)始 |
touchmove | 手指觸摸后移動(dòng) |
touchend | 手指觸摸動(dòng)作結(jié)束 |
tap | 手指觸摸后馬上離開(kāi) |
### 事件對(duì)象 當(dāng)組件觸發(fā)事件時(shí),邏輯層綁定該事件的處理函數(shù)會(huì)收到一個(gè)事件對(duì)象。chameleon將事件綁定做了一層代理,將各平臺(tái)的事件對(duì)象做統(tǒng)一,統(tǒng)一后的事件對(duì)象有如下屬性:
名稱 | 類型 | 說(shuō)明 |
---|---|---|
type | String | 事件類型 |
timeStamp | Number | 頁(yè)面打開(kāi)到觸發(fā)事件所經(jīng)過(guò)的毫秒數(shù) |
target | Object | 觸發(fā)事件的目標(biāo)元素 且 target = {id,dateset} |
currentTarget | Object | 綁定事件的目標(biāo)元素 且 currentTarget = {id,dataset} |
changedTouches | Array | 觸摸事件中的屬性,當(dāng)前變化的觸摸點(diǎn)信息的數(shù)組 且 changedTouches = [{ identifier, pageX, pageY, clientX, clientY }] |
detail | Object | 自定義事件所攜帶的數(shù)據(jù)。 通過(guò)$cmlEmit 方法觸發(fā)自定義事件,可以傳遞自定義數(shù)據(jù)即 detail。具體下面自定義事件 |
_originEvent | Object | CML 對(duì)各平臺(tái)的事件對(duì)象進(jìn)行統(tǒng)一,會(huì)把原始的事件對(duì)象放到_originEvent 屬性中,當(dāng)需要特殊處理的可以進(jìn)行訪問(wèn)。 |
屬性 | 類型 | 說(shuō)明 |
---|---|---|
id | String | 事件源組件的 id |
dataset | Object | 事件源組件上由data- 開(kāi)頭的自定義屬性的集合 |
dataset
在組件中可以定義數(shù)據(jù),這些數(shù)據(jù)將會(huì)通過(guò)事件傳遞給 SERVICE。 書(shū)寫方式: 以 data-開(kāi)頭,多個(gè)單詞由連字符-鏈接,不能有大寫(大寫會(huì)自動(dòng)轉(zhuǎn)成小寫)如 data-element-type,最終在 event.currentTarget.dataset 中會(huì)將連字符轉(zhuǎn)成駝峰 elementType。
<view data-alpha-beta="1" data-alphaBeta="2" c-bind:tap="bindViewTap"> DataSet Test </view>
<script>
class Index {
methods = {
bindViewTap: function(event) {
event.currentTarget.dataset.alphaBeta === 1; // - 會(huì)轉(zhuǎn)為駝峰寫法
event.currentTarget.dataset.alphabeta === 2; // 大寫會(huì)轉(zhuǎn)為小寫
},
};
}
export default new Index();
</script>
數(shù)組中的對(duì)象有如下屬性:
屬性 | 類型 | 說(shuō)明 |
---|---|---|
identifier | Number | 觸摸點(diǎn)的標(biāo)識(shí)符 |
pageX pageY | Number | 距離文檔左上角的距離,文檔的左上角為原點(diǎn),橫向?yàn)?X 軸,縱向?yàn)?Y 軸 |
clientX clientY | Number | 距離頁(yè)面可顯示區(qū)域(屏幕除去導(dǎo)航條)左上角距離,橫向?yàn)?X 軸,縱向?yàn)?Y 軸 |
注意:返回值的單位為 px;可以通過(guò)chameleon-api中的 px2cpx進(jìn)行單位的轉(zhuǎn)化;
自定義事件用于父子組件之間的通信,父組件給子組件綁定自定義事件,子組件內(nèi)部觸發(fā)該事件。規(guī)定事件名稱不能存在大寫字母觸發(fā)事件的方法是調(diào)用this.$cmlEmit(事件名稱,detail對(duì)象)。
注意:自定義事件名稱不支持click、scroll
例如: 子組件 yyl-com
<template>
<view @tap="triggerCustomEvent"><text>觸發(fā)自定義事件</text></view>
</template>
<script>
class Index {
data = {}
method = {
triggerCustomEvent(e) {
this.$cmlEmit('customevent', {
company: 'didi',
age: 18
})
}
}
}
export default new Index();
<script>
父組件
<template>
<yyl-com c-bind:customevent="customEventHandler">
</yyl-com>
</template>
<script>
class Index {
data = {}
method = {
customEventHandler(e) {
console.log(e)
}
}
}
export default new Index();
<script>
當(dāng)點(diǎn)擊yyl-com組件的按鈕時(shí),父組件中的 customEventHandler 方法中打印的 e 對(duì)象如下:
{
type: "customevent",
detail: {
company: "didi",
age: 18
}
}
事件綁定支持以下幾種形式(在內(nèi)聯(lián)語(yǔ)句中,$event代表事件對(duì)象)
<!-- 寫法(1) -->
<view c-bind:tap="handleElementTap"><text>觸發(fā)元素點(diǎn)擊事件</text></view>
<!-- 寫法(2) -->
<view
c-bind:tap="handleElementTap(1,2,3, 'message'+msg , $event)"><text>觸發(fā)元素點(diǎn)擊事件(1,2,3)</text></view>
<!-- 寫法(3) -->
<view c-bind:tap="handleElementTap()"><text>觸發(fā)元素點(diǎn)擊事件()</text></view>
**針對(duì)以上寫法返回的事件對(duì)象如下: **
寫法(1)調(diào)用事件函數(shù)輸出如下
'handleElementTap'[e];
寫法(2)調(diào)用事件函數(shù)輸出如下
'handleElementTap'[(1, 2, 3, 'messagetestEvent', e)];
寫法(3)調(diào)用事件函數(shù)輸出如下
'handleElementTap' []
chameleon-tool@0.2.0 + 的版本 支持了事件冒泡和阻止事件冒泡
vue語(yǔ)法下僅僅擴(kuò)展了 .stop;
注意:對(duì)于阻止事件冒泡,在內(nèi)聯(lián)事件傳參的情況下,需要傳遞 $event參數(shù);
<!-- 不會(huì)阻止冒泡 -->
<view v-on:click.stop="handleElementTap(1, 2)"><text>觸發(fā)元素點(diǎn)擊事件</text></view>
<!-- 會(huì)阻止冒泡 -->
<view v-on:click.stop="handleElementTap(1, 2, $event)"><text>觸發(fā)元素點(diǎn)擊事件</text></view>
<template lang="vue">
<view class="root">
<view class="pad">
vue語(yǔ)法事件冒泡測(cè)試
</view>
<view @click="rootClick">
<text style="font-size: 40px;">{{rootText}}</text>
<view class="outer" @click="parentClick">
<view>
<text style="font-size: 40px;">{{parentText}}</text>
</view>
<text class="inner" @click="click">{{innerText}}</text>
</view>
</view>
</view>
</template>
<script>
class Index {
methods = {
click: function(e) {
this.innerText = 'inner bubble';
console.log('this.innerText', this.innerText);
},
parentClick: function(e) {
this.parentText = 'parent bubble';
console.log('this.parentClick', this.parentClick);
},
rootClick: function(e) {
this.rootText = 'root bubble';
console.log('this.rootClick', this.rootClick);
},
};
}
export default new Index();
</script>
注意,事件綁定不支持直接傳入一個(gè)表達(dá)式,和綁定多個(gè)內(nèi)聯(lián)執(zhí)行函數(shù)比如
<div c-bind:tap="count++"></div>
<div c-bind:tap="handleTap1(); handleTap2()"></div>
根據(jù)表達(dá)式的真假值條件渲染元素
<div v-if="true">根據(jù)v-if的真假結(jié)果決定是否渲染</div>
用法
<div v-if="1 > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
<view v-for="(item, index) in array">
<text> {{idx}}: {{itemName.message}}</text>
</view>
父組件
<view><text>v-model的使用</text></view>
<input type="text" v-model="modelValueTest" />
<text>{{modelValueTest}}</text>
<comp v-model="modelValueTest2"></comp>
<view><text>組件使其改變{{modelValueTest2}}</text></view>
子組件
<template>
<view>
<input type="text" :value="value" @input="handleInput" />
</view>
</template>
<script>
methods = {
handleInput(e){
console.log('input',e);
this.$cmlEmit('input', {
value: Date.now()
})
}
}
}
</script>
<view v-text="message"></view>
不支持組件的 v-text
<view v-show="elementShow">
<text>測(cè)試元素c-show</text>
</view>
<view><text>組件v-show</text></view>
<comp v-show="elementShow"></comp>
component 接受兩個(gè)屬性
屬性名 | 說(shuō)明 |
---|---|
is | 接受一個(gè)計(jì)算屬性作為動(dòng)態(tài)渲染的標(biāo)簽名 |
shrinkcomponents | 接受 usingComponents 中的key值組成的字符串作為動(dòng)態(tài)組件選擇的范圍 |
<template>
<view class="page-container">
<view v-on:tap="handleElementClick"><text>組件改變</text></view>
<component :is="currentComp" shrinkcomponents="comp,comp1"></component>
</view>
</template>
<script>
class Index {
data = {
dataComp: 'comp',
};
computed = {
currentComp() {
return this.dataComp === 'comp' ? 'comp1' : 'comp';
},
};
methods = {
handleElementClick(a, b) {
console.log('handleElementClick', arguments, a, b);
this.dataComp = this.dataComp === 'comp' ? 'comp1' : 'comp';
},
};
}
export default new Index();
</script>
<script cml-type="json">
{
"base": {
"usingComponents": {
"comp":"./comp",
"comp1":"./comp1",
"comp2":"./comp2",
"comp3":"./comp3",
}
},
"wx": {
"navigationBarTitleText": "index",
"backgroundTextStyle": "dark",
"backgroundColor": "#E2E2E2"
},
"alipay": {
"defaultTitle": "index",
"pullRefresh": false,
"allowsBounceVertical": "YES",
"titleBarColor": "#ffffff"
},
"baidu": {
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "index",
"backgroundColor": "#ffffff",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50
}
}
</script>
component 動(dòng)態(tài)組件上同樣支持綁定事件,傳遞屬性;
比如
<component :is="currentComp"
type="upcaseEvent"
v-on:upcaseEvent="handleUpcaseEvent"
:id="id"
></component>
注意 : 小程序端是通過(guò)條件判斷來(lái)模擬 component is 的效果的,所以不要在 component 標(biāo)簽上在在寫 c-if c-else c-else-if 等條件判斷
如果使用 class 語(yǔ)法,支持如下寫法
<template lang="vue">
<view class="page-container">
<view><text :class="true? 'bg-green':''" class="font" >fafafa</text></view>
<view><text class="bg-green font" >fafafa</text></view>
</view>
</template>
<template>
<view>
<text :class="prefix + 'a'">class數(shù)據(jù)綁定</text>
</view>
</template>
<script>
class Index {
data() {
return {
prefix: 'cls',
};
}
}
export default new Index();
</script>
<view class="static" class="open ? 'cls1 cls2' : 'cls3 cls4'"> </view>
或者將其放入計(jì)算屬性
<template>
<view class="itemClass"> </view>
</template>
<script>
class Index {
computed = {
itemClass() {
return open ? 'cls1 cls2' : 'cls3 cls4';
},
};
}
export default new Index();
</script>
如果使用 style 語(yǔ)法支持如下寫法,style 不支持多個(gè) style,即 style :style 同時(shí)寫
<view> <text style="background-color:red">fafafa</text></view>
<view><text :style="computedString">fafafa</text> </view>
<script>
class Index {
data = {
inlineStyle: 'border: 1px solid red;',
};
computed = {
computedString() {
return inlineStyle;
},
};
}
export default new Index();
</script>
更多建議: