携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
通过 Vue-CLI 脚手架工具,初始化项目,命名为 mi-detail,CSS 代码建议使用扩展语言 SASS 编码完成;
(1)、在 components 目录下创建 NavHeader.vue 组件、NavFooter.vue 组件、ProductParam.vue 组件;
(2)、在 src 目录下的 views 文件夹下新建 Detail.vue 组件;
(3)、将提供的 imgs 文件夹、json 文件夹放在 public 目录下;
3.编写 NavHeader.vue 组件,
<template>
<div class="header">
<div class="top">
<div class="left">
<p v-for="(item, index) in list" :key="index">
<span>{{ item }}</span>
</p>
</div>
<div class="right">
<p>
<span>登录</span>
</p>
<div>
<div>
<img src="../../public/imgs/icon-cart-checked.png" alt="" />
<span>购物车</span>
</div>
</div>
</div>
</div>
<div class="footer">
<ul>
<li>
<img src="imgs/mi-logo.png" alt="" />
</li>
<li>
<p
v-for="(item, index) in phone"
:key="index"
@mouseenter="hover(index, item.id)"
:class="{ hover: activeindex == index }"
@mouseleave="mouseleave"
>
<span> {{ item.name }}</span>
</p>
</li>
<li>
<p><input type="text" /></p>
<p><img src="../../public/imgs/icon-search.png" alt="" /></p>
</li>
</ul>
<transition-group name="animate__animated animate__bounce" appear enter-active-class="animate__bounceIn"
leave-active-class="animate__bounceOut" tag="ol">
<li v-for="(item, index) in a" :key="index" v-show="isShow">
<p>
<img :src="item.mainImage" alt="" />
</p>
<p>
{{ item.name }}
</p>
<p>
{{ item.price }}
</p>
</li>
</transition-group>
</div>
</div>
</template>
<script>
import axios from "axios";
import 'animate.css';
export default {
data() {
return {
list: [
"小米商城",
"MIUI",
"IoT",
" 云服务",
"金融",
"有品",
"小爱开放平台",
],
phone: [
{
id: 100013,
name: "电视",
},
{
id: 100012,
name: "小米手机",
},
{
id: 100014,
name: "RedMi红米",
},
{
id: 100015,
name: "笔记本",
},
{
id: 100016,
name: "路由器",
},
{
id: 100017,
name: "家电",
},
],
activeindex: -1,
milist: [],
a: [],
isShow: false,
};
},
methods: {
hover(index, id) {
console.log(index);
this.activeindex = index;
this.isShow = true;
this.a = this.milist.filter((r) => r.categoryId == id);
},
mouseleave() {
this.isShow = false;
this.activeindex = -1;
},
},
mounted() {
axios.get("json/nav.json").then(
({
data: {
data: { list },
},
}) => {
this.milist = list;
}
);
},
};
</script>
<style scoped lang="scss">
.header {
width: 100vw;
.top {
width: 1440px;
background: black;
height: 40px;
line-height: 40px;
display: flex;
justify-content: space-between;
padding: 0 100px;
span {
font-size: 14px;
color: #ccc;
}
.left {
display: flex;
color: #ccc;
p {
margin-right: 10px;
}
}
.right {
display: flex;
p {
color: #ccc;
margin-right: 10px;
}
div {
width: 100px;
background: #ff6401;
display: flex;
align-items: center;
justify-content: space-between;
div{
margin: 0 15px;
}
img {
width: 20px;
height: 20px;
}
span {
color: white;
font-size: 14px;
}
}
}
}
.footer {
ul {
height: 100px;
width: 1440px;
justify-content: space-between;
align-items: center;
display: flex;
padding: 0 100px;
li:nth-of-type(1) {
img {
width: 50px;
height: 50px;
background: #fe6401;
}
}
li:nth-of-type(2) {
display: flex;
height: 50px;
line-height: 50px;
p {
margin-right: 20px;
}
}
li:nth-of-type(3) {
display: flex;
border: 1px solid #ccc;
height: 30px;
input {
outline: none;
border: none;
}
p:nth-of-type(2) {
border-left: 1px solid #ccc;
height: 30px;
width: 30px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 14px;
height: 14px;
}
}
}
}
ol {
display: flex;
flex-wrap: wrap;
width: 1440px;
justify-content: center;
align-items: center;
padding: 0 100px;
z-index: 100;
position: absolute;
background: white;
li {
width: 206px;
p {
width: 206px;
text-align: center;
img {
width: 160px;
border-right: 1px solid #ccc;
margin-bottom: 20px;
}
}
p:nth-of-type(3) {
color: #fe6401;
}
}
li:nth-of-type(6) img {
border: none;
}
}
}
}
.hover {
color: #fe6401;
}
</style>
4.编写 NavFooter.vue
<template>
<div class="tfoot">
<ul>
<li>
<img src="../../public/imgs/logo-footer.png" alt="" />
</li>
<li>
<span>小米商城</span>
</li>
<li>
<span v-for="(item, index) in list" :key="index">
{{ item }}
</span>
</li>
<li>
<span>
© mi.com 京ICP证110507号 京ICP备10046444号 京公网安备11010802020134号
京网文[2020]0276-042号
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
list: [
"小米商城",
"|",
"小米商城",
"|",
"MIUI",
"|",
"米家",
"|",
"米聊",
"|",
"多看",
"|",
"游戏",
"|",
"政企服务",
"|",
"小米天猫店",
],
};
},
};
</script>
<style scoped lang="scss">
.tfoot {
width: 1440px;
background: #333333;
height: 170px;
margin-top: 30px;
border-top: 2px solid #fe6401;
display: flex;
justify-content: center;
align-items: center;
span {
color: #807e7f;
font-size: 14px;
}
ul {
width: 1440px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
li{
margin-bottom: 10px;
}
li:nth-of-type(1) {
width: 50px;
height: 30px;
img {
width: 50px;
height: 30px;
}
}
}
}
</style>
5.编写 ProductParam.vue 组件
<template>
<div class="produc">
<div class="top" ref="top">
<div class="left">红米Note7</div>
<div class="right">
<p>概述</p>
<p>|</p>
<p>参数</p>
<p>|</p>
<p>用户评价</p>
</div>
</div>
<div class="footer">
<div class="left">
<div class="swiper-container" ref="floor1Swiper">
<div class="swiper-wrapper">
<div
class="swiper-slide"
v-for="(item, index) in list"
:key="index"
>
<img :src="item.img" />
</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
</div>
</div>
<div class="right">
<div>
<p class="p1">
{{ product.name }}
</p>
<p class="p2">
相机全新升级 / 960帧超慢动作 / 手持超级夜景 / 全球首款双频GPS /
骁龙845处理器 / 红<br />外人脸解锁 / AI变焦双摄 / 三星 AMOLED 屏
</p>
<p class="p3">小米自营</p>
<p class="p4">
<span>{{ product.price }}元</span><span>{{ product.stock }}元</span>
</p>
</div>
<ul class="ul1">
<li>
<p>
<img src="imgs/detail/icon-loc.png" alt="" />
<span>北京 北京市 朝阳区 安定门街道</span>
</p>
<p>有现货</p>
</li>
</ul>
<ol class="ol1">
<li>选择版本</li>
<li>
<p
v-for="(item, index) in banben"
:key="item.no"
@mouseenter="mouseindex(item.no)"
@click="adds"
:class="activeindex == item.no ? 'tomoto' : 'tomoto1'"
:data-active="item.name"
>
{{ item.name }}
</p>
</li>
</ol>
<ol class="ol2">
<li>选择颜色</li>
<li>
<ol
@mouseenter="activeindex = 0"
:class="activeindex == 0 ? 'tomoto' : 'tomoto1'"
>
<li></li>
<li>深空灰</li>
</ol>
</li>
</ol>
<ul class="ul2">
<li>
<div>
<p v-for="(item, index) in shuju" :key="index">
{{ item }}
</p>
</div>
<div>总计:999元</div>
</li>
<li>999元</li>
</ul>
<div class="jg">加入购物车</div>
</div>
</div>
</div>
</template>
<script>
import Swiper from "swiper";
import axios from "axios";
export default {
data() {
return {
list: [
{ no: 1, img: "imgs/detail/phone-1.jpg" },
{ no: 2, img: "imgs/detail/phone-2.jpg" },
{ no: 3, img: "imgs/detail/phone-3.jpg" },
{ no: 4, img: "imgs/detail/phone-4.jpg" },
],
product: {},
banben: [
{
no: 1,
name: "6GB+64GB全网通 ",
},
{
no: 2,
name: "4GB+64GB移动4G ",
},
],
activeindex: 0,
shuju: ["红米Note7", "6GB+64GB全网通", "深空灰"],
};
},
mounted() {
window.addEventListener("scroll", this.scroll);
var mySwiper = new Swiper(this.$refs.floor1Swiper, {
// direction: 'vertical', // 垂直切换选项
loop: true, // 循环模式选项
autoplay: {
//自动播放
autoplay: true,
//设置间隔时间
delay: 3000,
// 用户操作swiper之后,是否禁止autoplay
disableOnInteraction: false,
},
// 如果需要分页器
pagination: {
el: ".swiper-pagination",
//点击分页器的指示点分页器会控制Swiper切换
clickable: true,
},
// 如果需要前进后退按钮
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
// 如果需要滚动条
scrollbar: {
el: ".swiper-scrollbar",
},
});
axios.get("json/product.json").then(({ data: { data } }) => {
this.product = data;
console.log(data);
});
},
destroyed() {
window.removeEventListener("score");
},
methods: {
scroll() {
if (document.documentElement.scrollTop >= 100) {
this.$refs.top.classList.add("active");
} else {
this.$refs.top.classList.remove("active");
}
},
mouseindex(index) {
this.activeindex = index;
},
adds(e) {
let { active } = e.target.dataset;
this.shuju.splice(1, 1, active);
},
// add1(e) {
// // this.shuju.length = 0;
// let { active } = e.target.dataset;
// this.shuju.unshift(active);
// },
},
};
</script>
<style scoped lang="scss">
.produc {
.top {
width: 1440px;
padding: 0 100px;
display: flex;
height: 40px;
line-height: 40px;
justify-content: space-between;
background: white;
// border: 1px solid #ccc;
.left {
font-size: 20px;
font-weight: bolder;
}
.right {
display: flex;
p {
margin-left: 10px;
color: #ccc;
}
}
}
.footer {
margin-top: 50px;
width: 1440px;
padding: 0 100px;
display: flex;
.left {
width: 620px;
height: 620px;
// border: 1px solid;
img {
width: 620px;
height: 620px;
}
}
.right {
// border: 1px solid #ccc;
width: 620px;
padding: 10px;
div:nth-of-type(1) {
border-bottom: 1px solid #ccc;
.p1 {
font-size: 20px;
font-weight: bolder;
}
.p2 {
margin-top: 10px;
font-size: 14px;
}
.p3 {
color: #fe6401;
font-size: 14px;
margin-top: 20px;
}
.p4 {
margin-bottom: 20px;
margin-top: 10px;
span:nth-of-type(1) {
color: #fe6401;
margin-right: 10px;
}
span:nth-of-type(2) {
color: #ccc;
font-size: 14px;
text-decoration: line-through;
}
}
}
.ul1 {
border: 1px solid #ccc;
background: #eee;
display: flex;
align-items: center;
height: 100px;
margin-top: 20px;
li {
margin-left: 30px;
p:nth-of-type(1) {
span {
margin-left: 10px;
}
}
p:nth-of-type(2) {
margin-left: 25px;
color: #fe6401;
}
}
// flex-direction: column;
img {
width: 15px;
width: 15px;
}
}
ol {
margin-top: 30px;
li {
ol {
display: flex;
justify-content: center;
align-items: center;
li:nth-of-type(1) {
width: 15px;
height: 15px;
background: #656565;
margin-right: 5px;
}
}
}
li:nth-of-type(1) {
font-weight: bolder;
font-size: 18px;
}
li:nth-of-type(2) {
display: flex;
justify-content: space-between;
.tomoto1 {
width: 290px;
// border: none;
border: 1px solid #ccc;
height: 40px;
line-height: 40px;
text-align: center;
margin-top: 30px;
}
}
}
.ul2 {
background: #fafafa;
display: flex;
margin-top: 30px;
li:nth-of-type(1) {
width: 420px;
// border: 1px solid red;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80px;
div {
display: flex;
border: none;
p {
margin-right: 5px;
}
}
div:nth-of-type(2) {
font-size: 18px;
color: #fe6401;
}
}
li:nth-of-type(2) {
color: rgb(145, 140, 140);
margin-left: 120px;
margin-top: 20px;
font-size: 14px;
}
}
.jg {
width: 400px;
background: #fe6401;
color: white;
text-align: center;
height: 50px;
line-height: 50px;
margin-top: 30px;
}
}
}
}
.active {
position: fixed;
top: 0;
z-index: 60;
border-bottom: 1px solid #eee;
box-shadow: 0 1px 5px #333;
}
.tomoto {
color: #fe6401;
border: 1px solid #fe6401;
width: 290px;
height: 40px;
line-height: 40px;
text-align: center;
margin-top: 30px;
}
</style>