原文链接: vue 仿小米官网
上一篇: js for of
下一篇: vue 父组件向子组件传递对象
官网
仿照的样式
关于停留在目录上显示推荐物品做的不是很好,,,
物品展示的那个div无法将宽度设为子元素所占的宽度,需要手动计算使用js设置,经过试验,这个div的宽度与里面的item的宽度相同,没想明白问题在哪里,不过应该将这个推荐层作为一个组件,这样复用性好一点,而且可以解决这个问题
通过手动计算,动态设置隐藏div宽度即可,每列放置5个div,多余的需要向上取整,效果完成
// 列数 加上左右两边的 padding值
let width = parseInt(Math.ceil(this.category[index]['items'].length / 6)) * 100 + 40
<template>
<div ref="app" class="container">
<div class="left">
<div class="item" v-cloak v-for="(item,index) of category" @mouseenter="itemIn(index)"
@mouseleave="itemLeave(index)">
<span>
{{item['title']}}
</span>
<span>
>
</span>
</div>
</div>
<!--左右按钮和表示图片选中状态的的原点-->
<div class="right" @click="recommend">
<!--隐藏的物品div-->
<div class="hide-content" v-show="isShowContent" @mouseenter="isShowContent=true"
@mouseleave="isShowContent=false"
ref="hide_content"
>
<div v-for="item in category[show_item_index]['items']" class="hide-content-item">
{{item}}
</div>
</div>
<label class="btn" @click.stop="prev"><</label>
<div class="dots">
<div v-for="item,index in imgs" class="dot-base" :class="{'cur-dot':index==cur_img}"></div>
</div>
<label class="btn" @click.stop="next">></label>
</div>
</div>
</template>
<script>
export default {
name: "xiaomi",
data() {
return {
// 在相应的条目上悬浮,会显示一个物品列表
isShowContent: false,
show_item_index: 0,
// 背景图片以及,当前显示的第几个图片,推荐将图片等资源放置到统一的静态资源站点
cur_img: 0,
imgs: [
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=423921803,865481119&fm=27&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=519016328,2903928941&fm=27&gp=0.jpg',
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1321439853,1436775495&fm=27&gp=0.jpg',
'https://i1.mifile.cn/a4/xmad_15060801726665_Mjisa.jpg',
],
// 类别以及对应的分类下载物品信息
category: [
{
title: '手机 电话卡',
items: [
"小米note3",
'小米max',
"小米6",
'小米5X',
'小米MAX2',
"红米5 plus",
"红米5",
"小米note3",
'小米max',
"小米6",
'小米5X',
'小米MAX2',
"红米5 plus",
"红米5",
]
},
{
title: '电视 盒子',
items: [
"小米note3",
'小米max',
"小米6",
'小米5X',
'小米MAX2',
"红米5 plus",
"红米5",
"小米note3",
'小米max',
"小米6",
'小米5X',
'小米MAX2',
"红米5 plus",
"红米5",
]
},
{
title: '笔记本',
items: [
1, 2, 3, 4
]
},
{
title: '智能家电',
items: [
1, 2, 3, 4, 5, 6, 7, 8, 9
]
},
{
title: '健康家园',
items: [
1, 2, 3, 4, 5, 6, 7, 8
]
},
{
title: '出行 儿童',
items: [
1, 2, 3
]
},
{
title: '路由器 手机配件',
items: [
1, 2, 3, 4, 5, 6
]
},
{
title: '移动电源 插线板',
items: [
1, 2, 3, 4, 5,
]
},
{
title: '生活 米兔',
items: [
1, 2, 3, 4]
},
]
}
},
watch: {
cur_img(newVal, oldVal) {
console.log(newVal, oldVal, this.cur_img)
this.set_img()
}
},
computed: {
cur_url() {
return this.imgs[this.cur_img]
},
},
methods: {
recommend() {
console.log('recommend')
},
itemIn(index) {
this.show_item_index = index
this.isShowContent = true
// 列数 加上左右两边的 padding值
let width = parseInt(Math.ceil(this.category[index]['items'].length / 6)) * 100 + 40
console.log('width ', width)
this.$refs.hide_content.style.width = `${width }px`
},
itemLeave(index) {
this.isShowContent = false
},
set_img() {
let bg = `url('${this.imgs[this.cur_img]}') no-repeat`
console.log(bg)
this.$refs.app.style.background = bg
this.$refs.app.style.backgroundSize = "cover"
},
prev() {
this.cur_img = (this.cur_img + this.imgs.length - 1) % this.imgs.length
},
next() {
this.cur_img = (this.cur_img + 1) % this.imgs.length
}
},
mounted() {
console.log(this)
this.set_img()
// 每隔3秒 换一次 图片
setInterval(this.next, 3000)
}
}
</script>
<style scoped>
.container {
width: 1226px;
height: 460px;
display: flex;
}
.hide-content {
width: auto;
height: 100%;
padding: 20px;
display: inline-flex;
background: white;
overflow-x: visible;
position: absolute;
left: 0px;
flex-direction: column;
flex-grow: 1;
flex-shrink: 1;
flex-wrap: wrap;
box-sizing: border-box;
}
.hide-content-item {
display: flex;
width: 100px;
height: 70px;
box-sizing: border-box;
border: 1px solid black;
justify-content: center;
align-items: center;
}
.left {
display: flex;
flex-direction: column;
width: 250px;
height: 100%;
background: rgba(0, 0, 0, 0.3);
align-items: center;
justify-content: space-around;
}
.right {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
position: relative;
}
.btn {
font-size: 50px;
color: gray;
}
.dots {
width: fit-content;
height: fit-content;
display: flex;
padding: 10px;
flex-direction: row;
/*justify-content: flex-end;*/
/*align-items: flex-end;*/
align-self: flex-end;
}
.dot-base {
width: 15px;
height: 15px;
background: white;
margin: 10px;
border-radius: 50%;
}
.cur-dot {
background: orangered;
}
.item {
width: 100%;
color: white;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 15px;
}
.item:hover {
background: orangered;
}
</style>