点击goods组件中的li会进入此商品的详情页
新建food组件
在goods.vue中引入
当我们在设置方法的时候父组件是可以调用子组件方法的,子组件不能调用父组件方法
传入当前选中的食物作为参数,用ref属性可以获取子组件的事件
<food :food="selectedFood" ref="food"></food>
当点击当前食物的时候会进入详情页
<li @click="selectFood(food,$event)" v-for="food in item.foods" class="food-item border-1px">
data() {
return {
selectedFood: {}
}
},
methods: {
selectFood(food,event){
if(!event._constructed){
return;//只有当自己定义的点击事件才能触发
}
this.selectedFood = food;
this.$refs.food.show();获取子组件的show方法
},
}
子组件food.vue
<template>
<div v-show="showFlag" class="food">
</div>
</template>
<script>
export default {
props: {
foods: {
type: Object
}
},
data() {
return {
showFlag: false
}
},
methods: {
//可以被外部组件调用不带下划线命名,带下划线只能内部调用,私有方法
show() {
this.showFlag = true;
}
}
}
</script>
<style lang="stylus">
.food
position: fixed
left: 0
top: 0
bottom: 48px
z-index: 30
width: 100%
background: #fff
</style>
给详情页进入增加动画
<transition name="move"></transition>
.food
position: fixed
left: 0
top: 0
bottom: 48px
z-index: 30
width: 100%
background: #fff
&.move-enter-active,&.move-leave-active
transition: all 0.2s linear
&.move-enter,&.move-leave-active
transform: translate3d(100%, 0,0 )
图片高度自适应
padding以及margin的上下,参考的是容器的宽度。注意不是容器的高度。
容器使用width:100% ,这样容器的高度由padding-top撑开
<transition name="move">
<div v-show="showFlag" class="food">
<div class="food-content">
<div class="image-header">
<!-- 图片加载是个异步过程 -->
<!-- 高度不能写死,高度和屏幕宽度是一致的,
屏幕宽未知,如果不设置高度,整个页面加载就会有一个抖动的过程
,优化的的方法就是先把宽高设置好了-->
<img :src="food.image">
</div>
</div>
</div>
</transition>
-------------------------------------------------------------------------------
.image-header
position: relative
width: 100% 和屏幕宽度保持一致
height: 0
padding-top:100% 值的计算相对于盒子的宽度计算的,保证宽高相等
img
position: absolute
top: 0
left: 0
width: 100%
height: 100%
给详情页设置返回按钮
<div class="back" @click="hide">
<i class="icon-arrow_lift"></i>
</div>
.back
position: absolute
top: 10px
left: 0
.icon-arrow_lift
display: block
padding: 10px
font-size: 20px
color: #fff
methods: {
//可以被外部组件调用不带下划线命名,带下划线只能内部调用,私有方法
show() {
this.showFlag = true;
},
hide() {
this.showFlag = false
}
}
用better-scroll滚动页面,不显示滚动条
<div v-show="showFlag" class="food" ref="food"></div>
methods:{
show() {
this.showFlag = true;
this.$nextTick(() => {
//dom渲染完成后执行
//因为这个组件会多次show
if(!this.scroll){
this.scroll = new BScroll(this.$refs.food,{
click: true
})
}else{
this.scroll.refresh();
}
})
}
}
子组件通知父组件
- 子组件:
select(type,event) {
if(!event._constructed){
return
}
//当点击按钮的时候,把selectType设置成我们传入的type
// 当子组件selectType发生变化的时候要通知父组件
this.$emit('selecttype',type)
},
toggleContent(event) {
if(!event._constructed){
return
}
this.$emit('content');
}
- 父组件:
@selecttype="setType" @content="setOnlycontent"
-----------------------------------------------------------------------------------
<ratingselect :select-type="selectType" :only-content="onlyContent" :desc="desc" :ratings="food.ratings" @selecttype="setType" @content="setOnlycontent"></ratingselect>
-------------------------------------------------------------------------------------
methods: {
setType(type) {
this.selectType = type;
//手动刷新better-scroll重新计算页面高度
this.$nextTick(() => {
this.scroll.refresh();
});
},
//手动刷新better-scroll重新计算页面高度
setOnlycontent() {
this.onlyContent = !this.onlyContent;
this.$nextTick(() => {
this.scroll.refresh();
});
},
}