一個極簡的JS模板庫WildWood | 語法相容vue
阿新 • • 發佈:2018-12-04
一個極簡的JS模板庫WildWood | 語法相容vue
既生vue,何生WildWood?
Vue是一個非常先進的工具。 我非常喜歡它極簡的語法,可以滿足幾乎所有需求。然而在實際專案中配合framework7 ui庫的過程中還是踩了坑。
Vue在生成頁面的時候實際上是繫結的div整個替換。這會導致問題:
- 一些dom元素上繫結的事件處理函式會被丟掉
- 一些dom元素上的一些通過js附加的自定義屬性會被丟掉
所以,在使用一些依賴js的ui庫時會出問題。在使用framework7 ui庫的過程中就發生了一些衝突。
最終通過修改vue.js,把丟失的事件和自定義屬性附加上去了,問題解決了。但是我覺得可以更簡單一些,就花了2個小時寫了一個更簡單的庫,取名叫WildWood.js.後來又花了2天時間做了一些完善. 現在已基本相容vue的語法
Vue.min.js大小80k,比angular已經小了一些。可是.對於很多隻使用一些簡單模板功能的人來說,體積還是大了一些。WildWood.min.js只有3k. 總共400多行程式碼
WildWood在原有的dom上操作元素,與現有的js元件庫可以完美共存.
so the answer is:
it is smaller, compatible, faster. So it is here.
WildWood在哪裡?
去github:
https://github.com/HiYuChen/WildWood
那裡有個完整的demo
先睹為快
WildWood支援的模板指令包括
{{變數}} v-model="變數" v-bind:value="變數" v-bind:style="變數" v-bind:class="變數" v-if="變數" v-for="for student in students" v-on="方法()"
JS結構語法如下
var WildWood = new WildWood({
el: '#app',
data: {
/*定義變數*/
},
methods:{
/*定義方法*/
},
watch:{
/*定義監聽變數的函式*/
},
computed:{
/*定義根據一些變數自動計算數值的函式*/
}
};
使用上的幾個限制:
- 巢狀for in block中變數的使用
假設
data:{
total:300,
arrStudents:[
{name:'tom',
subjects:[{name:'chinese'},[name:'english'}]
},
{value:13},
subjects:[{name:'chinese'},[name:'english'}],
],
}
在巢狀的for row in arrRows 這樣塊裡可以使用當前塊的變數或者全域性變數,但是不能引用外層for 塊裡的變數, 如下所示
<li v-for="student in arrStudents" >
<ul>
<li v-for="subject in student.subjects" >
<div>{{subject.name}} </div><!--OK-->
<div>{{total}} </div><!--OK-->
<div>{{student .name}} </div> <!-- 不允許 -->
</li>
</ul>
</li>
- 陣列中物件屬性的監聽原則
array中的物件中的屬性要在放進陣列之前就定義好.不能後來再修改。array中的物件中的屬性要在放進陣列之前就有.不能後來再修改。否則就無法監聽到該屬性的變化了。
比如:
arrStudents中student一開始沒有score屬性,在新增到arrStudents後,執行
arrStudents[0].name=‘jack’; 這就是錯誤的用法。
正確的方式應該是:
var student={name:‘jack’,score:‘90’};
arrStudent.push(student);
這是因為在push的時候,wildWood就開始監聽student的屬性變化了。後加的屬性就監聽不到了。
來一個實際的例子
HTML:
<div>
<div style="display:flex;">
<div>Total:</div>
<div >
<input type="text" v-model="totalAmount" placeholder="Please input" >
</div>
</div>
<div style="display:flex;">
<div>Coupon:</div>
<div >
<label>{{couponAmount}} </label>
</div>
</div>
<div style="display:flex;">
<div>Coupon:</div>
<div >
<label>{{cashAmount}} </label>
</div>
</div>
</div>
<div style="margin-top:10px;margin-left:10px;">Please select a coupon</div>
<div>Selected coupon id is: {{m_couponToUse}}</div>
<div>
<ul>
<li v-for="row in m_coupons" >
<div style="display:flex">
<input type="radio" name="radio_coupon" style="" v-on:change ="couponClicked();" v-bind:value="row.coupon_id" v-model="m_couponToUse" />
<img v-bind:style="{visibility:row.isChecked?'visible':'hidden'}" style="width:32px;height:32px;" src="check.svg"/>
<div>
{{row.value}}元
</div>
<div></div>
<div class="item-title">{{row.goods_name}}</div>
</div>
</li>
</ul>
</div>
JS程式碼:
var WildWood = new WildWood({
el: '#app',
data: {
couponToUse: '',
couponAmount: 0,
totalAmount: '',
cashAmount: 0,
m_coupons:[ { isChecked: false, coupon_id: '3', goods_name: 'cup', value: '30' },
{ isChecked: false, coupon_id: '4', goods_name: 'book', value: '40' }
],
oper:'jack'
},
methods: {
couponClicked: function () {
var i;
for (i in this.m_rows) {
var r = me.m_rows[i];
if (r.coupon_id === me.m_couponToUse) {
me.m_couponAmount = r.value;
r.isChecked = true;
}
else r.isChecked = false;
}
},
},
watch: {
couponAmount: function () {
if (parseFloat(this.couponAmount) > 0 && (this.totalAmount === '' || this.m_totalAmount < this.m_couponAmount)) {
this.m_totalAmount = this.m_couponAmount;
}
},
},
computed: {
cashAmount: function () {
return this.totalAmount - this.couponAmount;
}
}
});
完整demo請到github下載:https://github.com/HiYuChen/WildWood