v-show控制頁面的切換,隱藏顯示
在要加事件的地方,加@click.stop.prevent="card"
在要隱藏顯示組件的地方,加v-show="showCard"
如圖;
export default { name: 'center', data () { return { // 折疊 fold: false, showCard: false } }, methods: { card () { this.showCard = !this.showCard //這個很重要,如果寫成this.showCard = true,只能點擊一次
} } }
通過操作對象的變量或者模型(data里面的數據可以稱為模型),改變dom,而不是直接操作dom,間接達到vue和js的分離。
1.價格的增減功能,通過點擊,數量實現改變
用到v-model雙向綁定,
//part指的是循環遍歷里面的part,part in res
<span @click="changeMoney(part,-1)">-</span> <!--//根據-1和+1判斷用戶是點擊加還是法,記住此處的part和下面要綁定數據的input里面的part一樣的--> <input type="text" v-model="part.productNumber"> <span @click="changeMoney(part,+1)">+</span>
//加減數量,通過傳入的參數判斷數量的加減, changeMoney:function(product,way){ if(way>0){ product.productNumber++; }else{ product.productNumber--; if(product.productNumber<1){ //如果減到小於1的時候,讓商品至少為1,才能購買 product.productNumber=1 } } }
2.購物車的單選按鈕,選中商品功能,接口里面沒有字段,是監聽不到的,通過$set設置一個不存在的變量,放在data里面,
兩種方法,1.全局注冊 Vue.set(item,"checked",true);2.局部注冊 this.$set(part,"checked",true);
如果一個變量不在data里面聲明或者不在對象里面,用vue監控不到屬性(一個對象里面的變量不存在,解決辦法)
思路:先判斷商品是否選中,然后取反
注意:綁定class,一定是數組或者對象,{‘key’:},
<!--//記得class是個對象,判斷class是否存在checked指的是要判斷的class,后面是他的狀態,part.checked中的part指的是在遍歷中的索引的對象,與上面的遍歷應該一致-->
<--如果json里面有字段,應該寫成v-bind:class="{'checked':part.checked}",part指的是字段-->
<span class="checkbox fff" v-bind:class="{'checked':part.checked}" @click="selectProduct(part)"></span> //調用下面的方法,part.checked=true,即為checked:true
//選中商品的方法 selectProduct:function(part){//part是遍歷里的數組 if(typeof part.checked=='undefined'){//1.通過typeof判斷變量是否存在,json;里面沒有字段checked是否選中,所以需要判斷 // Vue.set(item,"checked",true)//第一種全局注冊,全局的set就是在data里面創建,用set創建checked屬性放到part變量里面,值為true,此時,part.checked=true this.$set(part,"checked",true);//局部注冊,帶有$符號的為局部變量,不帶$全局,例如過濾器,$.set可以在遍歷part里面創建 }else{ part.checked=!part.checked; //取反 } }
3.全選功能
思路:綁定class,通過判斷class
都不存在的屬性,如果是在item遍歷的時候需要加,用$set加,如果是頁面加屬性,加在data里面,調用data的全局變量
@click里面可以放表達式,可以放一元表達式和三元表達式,例如:checkAllFlag==true?true:false,調用函數,不能放業務邏輯,不能寫,例如var checkAllFlag=true
<!--就是將'checked':true通過一個checkAll的屬性變量來傳遞,最終目的是使checked=true-->
<div class="checkbox-wrap left"><span class="checkbox all" :class="{'checked':checkAllFlag}" @click="checkAllFlag=true"></span>
</div>
<!-- //在data里面定義一個變量,click里面可以放表達式,可以放一元表達式和三元表達式,例如:checkAllFlag==true?true:false,調用函數,不能放業務邏輯,不能寫,例如var checkAllFlag=true -->
<div class="check-text"><span class="checked-all" @click="checkAll(true)">全選</span>
<span class="unchecked-all" @click="checkAll(false)">取消全選</span></div>
data :function() { return { produceList:[], pro:'', tit:'this id ', checkAllFlag:false//一定要定義這個變量,否則不會監聽 } }
//全選 checkAll:function(flag){//flag判斷是全選還是取消取消 this.checkAllFlag=flag; var _this=this;//作用域發生變化, //控制當前全選按鈕是否選中取消選中把當前選中的取反 // if(this.checkAllFlag){//如果選中的話,遍歷商品列表 this.produceList.forEach(function(part,index){ if(typeof part.checked=='undefined'){//判斷變量是否存在,json;里面沒有字段checked是否選中,所以需要判斷 _this.$set(part,"checked",_this.checkAllFlag);//局部注冊,帶有$符號的為局部變量,不帶$全局,例如過濾器 }else{ part.checked=_this.checkAllFlag; //取反 } }) // } }
click事件,報錯[Vue warn]: Invalid handler for event "click": got undefined,傻逼百度了好久,后來發現是methods寫錯了,記住是methods不是method
設置一個不存在的字段,先引用vue,在使用vue.set方法
Vue.set(this.food, 'count', 1);
通過條件判斷加不同的class
<div class="content-right" :class="payClass"> <div class="pay">{{payDesc}}</div> </div>
payClass() { if (this.totalPrice < this.minPrice) { return 'not-enough'; } else { return 'enough'; } }
餓了么不能用vm.$dispatch,可以使用vue2.0的eventBus實現兄弟組件通信,解決這個問題,這個網址講解的還是挺仔細的http://blog.csdn.net/u013034014/article/details/54574989?locationNum=2&fps=1
1.新建一個EventBus.js,js內容為以下,在goods.vue和cartcontrol.vue中,分別引用
import Vue from 'vue'; export default new Vue();
2.cartcontrol.vue
methods: { addCart(event) { // 防止多次被點擊 if (!event._constructed) { return; } if (!this.food.count) { // 添加food不存在的字段時 需要調用vue.set方法添加,這樣才可以通過vue觀測到這個字段的變化 Vue.set(this.food, 'count', 1); } else { this.food.count++; } Bus.$emit('cart.add', event.target); },
}
3.goods.vue
created() { Bus.$on('cart.add', el => { this.$nextTick(() => { this.$refs.shopcart.drop(el); }); }); },
3.shopcart.vue
methods: { drop(el) { console.log(el); } }
會發現已打印出dom
報錯Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
原因:只能有一個根節點,所以在外層要包裹一個層
打開新頁面
父組件可以調用子組件的方法,子組件不能調用父組件的方法,
調用子組件的方法:
父組件:通過refs傳遞
<food :food="selectedFood" ref="food"> </food>
methods: { selectFood(food, event) { if (!event._constructed) { return; } this.selectFood = food; this.$refs.food.show(); //調用子組件的方法 } },
子組件food的方法:
export default {
props: {
food: {
type: Object
}
},
data() {
return {
showFlag: false
};
},
methods: {
show() {
this.showFlag = true;
}
}
};
created(),mounted()....這些生命周期鈎子函數
,所以要加()
,
methods,coputed...這些是對象,里面還可放屬性或方法,vue內部會遍歷這些對象加到對應的宿主上。
data(),created()
都是 簡寫。
圖片自適應,寬度和高度大小一樣,實現高速自適應
https://segmentfault.com/a/1190000004231995
.image-header { position: relative; width: 100%; height: 0; padding-top: 100%;
over-flow:hidden; img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } }
報錯Unexpected tab character,解決方法:在eslint.js里面加入
'no-tabs':'off',
vue對點擊的li添加class,傳值
在data里面定義一個i,在方法里面,讓i等於index,通過判斷i和index是否相等,添加class
html
<div class="news"> <ul> <li v-for='(item, index) in items' @click="toggle(item, index)" :class="{bgRed: i==index}"> <span>{{item.title}}</span> </li> </ul> </div>
js
toggle (item, index) {
this.isDetail = !this.isDetail
this.title = item
this.i = index
}
data定義i
data () { return { news: { }, isDetail: false, i: -1, title: '', items: [{ content: '標題1內容', title: '標題1' }, { content: '2 item', title: '標題2' }, { content: '3 item', title: '標題3' }] } },