merge-requests/11/head
ch 2 years ago
commit 4beb13e940

@ -34,14 +34,4 @@ table {border-collapse: collapse; border-spacing: 0;
a { text-decoration:none;
color: #333;
&:hover { text-decoration:none;}
}
.c-white-main {
width: 1200px;
margin: 0 auto;
}
.c-grey-main{
width: 1200px;
margin: 0 auto;
background: #fff;
}

@ -85,4 +85,10 @@ $baseFontSize: 100 !default;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/*内容居中布局*/
@mixin layout-box {
width: 1200px;
margin: 0 auto;
}

@ -0,0 +1,20 @@
<template>
<div>
<div class="address"></div>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {},
};
</script>
<style lang="scss" scoped>
.address {
width: 1200px;
height: 189px;
border: 1px solid #dddddd;
}
</style>

@ -150,7 +150,7 @@ export default {
const { result } = await ApiPostLogin({
...this.form,
clientId: 1,
systemId: 1,
systemId: 3,
});
if (result) {
this.dialogTableVisible = false;

@ -15,7 +15,7 @@
<script>
import UiMoney from "@/components/UiMoney.vue";
export default {
name: "GoodsItem",
name: "UiGoodsItem",
componetns: { UiMoney },
props: {
item: {
@ -62,6 +62,7 @@ export default {
&__title {
width: 200px;
height: 45px;
line-height: 22px;
margin: 17px auto 10px;
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
@ -74,7 +75,7 @@ export default {
-webkit-line-clamp: 2;
&-label {
display: inline-block;
padding: 4px 8px;
padding: 2px 8px;
background: rgba(255, 135, 91, 0.1);
font-size: 12px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;

@ -8,7 +8,11 @@
<template>
<div class="layout">
<BsLogin :visible.sync="loginVisible" />
<Header />
<Header
:is-categroy-open="categroyOption.open"
:show-categroy-tab="categroyOption.show"
:is-sticky="isSticky"
/>
<Nuxt />
<Footer />
</div>
@ -17,10 +21,18 @@
import BsLogin from "@/components/BsLogin.vue";
import Header from "./module/header/index.vue";
import Footer from "./module/footer/index.vue";
const CATEGROY_OPEN_PAGES = ["/"]; // tab
const CATEGROY_HIDE_PAGES = ["/account"]; // tab
export default {
name: "Layout",
components: { Header, Footer, BsLogin },
data() {
return {
isSticky: false,
ticking: false,
};
},
computed: {
loginVisible: {
get() {
@ -30,6 +42,34 @@ export default {
this.$store.commit("setLoginVisible", val);
},
},
categroyOption() {
//
const currentPath = this.$route.path;
return {
open: CATEGROY_OPEN_PAGES.includes(currentPath),
show: !CATEGROY_HIDE_PAGES.includes(currentPath),
};
},
},
mounted() {
//
window.addEventListener("scroll", this.scrollEventMethod);
},
destroyed() {
window.removeEventListener("scroll", this.scrollEventMethod);
},
methods: {
scrollEventMethod(e) {
const that = this;
//
if (!that.ticking) {
window.requestAnimationFrame(function () {
that.ticking = false;
that.isSticky = window.scrollY > 300;
});
that.ticking = true;
}
},
},
};
</script>

@ -46,14 +46,20 @@
</div>
<template>
<div v-if="!menuVisible" class="header-wrap-content--line"></div>
<div class="header-wrap-content__common flex flex-middle">
<div
class="header-wrap-content__common flex flex-middle"
@click="onJumpPersonalPage('message')"
>
<img src="@/static/images/layout/icon-message.png" />
<span>消息</span>
<div class="wrap-content-message__tip">33</div>
</div>
</template>
<div class="header-wrap-content--line"></div>
<div class="header-wrap-content__common flex flex-middle">
<div
class="header-wrap-content__common flex flex-middle"
@click="onJumpPersonalPage('order')"
>
<img src="@/static/images/layout/icon-order.png" />
<span>我的订单</span>
</div>
@ -110,13 +116,20 @@ export default {
handleCommandClick(event) {
switch (event) {
case MENU_VALUE.PERSONAL:
this.$router.push('/account');
case MENU_VALUE.ADDRESS:
this.$router.push('/account');
this.$router.push("/account");
break;
case MENU_VALUE.ADDRESS:
this.$router.push("/account");
break;
case MENU_VALUE.LOGON_OUT:
this.$store.commit("setLoginOut");
}
},
//
onJumpPersonalPage(type) {
this.$router.push(`/account?type=${type}`);
},
},
};
</script>
@ -166,8 +179,7 @@ export default {
border-radius: 0px 0px 0px 0px;
.info-bar-header-wrap {
height: 100%;
width: 1200px;
margin: 0 auto;
@include layout-box;
.header-wrap__content {
.header-wrap-content__login {
.wrap-content-login__text {

@ -1,5 +1,5 @@
<template>
<div class="layout-header" :class="{ 'layout-sticky-bar-header': isSticky }">
<div class="layout-header">
<template v-if="isSticky">
<div class="sticky-bar-header">
<div class="sticky-bar-header__wrap flex flex-middle flex-between">
@ -9,7 +9,7 @@
src="@/static/images/layout/logo-sticky.png"
/>
<el-menu
:default-active="tabIndex"
:default-active="tabPath"
mode="horizontal"
@select="handleTabSelect"
>
@ -27,12 +27,21 @@
<img src="@/static/images/layout/icon-shop-sticky.png" />
<span class="">3</span>
</div>
<div class="header-wrap-icons__login">登录</div>
<div v-if="token" class="header-wrap-icons__login">
<img :src="userInfo.avatar" />
</div>
<div
v-else
class="header-wrap-icons__unlogin"
@click="onLoginClick"
>
登录
</div>
</div>
</div>
</div>
</template>
<template v-else>
<template>
<HeaderInfoBar />
<div class="default-bar-header">
<div class="bar-header-box">
@ -49,64 +58,80 @@
placeholder="请输入商品名称"
></el-input>
</div>
<div class="search-icon flex flex-center flex-middle">
<div
class="search-icon flex flex-center flex-middle"
@click="onSearch"
>
<img src="@/static/images/layout/icon-search.png" />
</div>
</div>
<div class="box-wrap-right__cart flex flex-middle">
<nuxt-link
class="box-wrap-right__cart flex flex-middle"
to="/cart"
>
<img src="@/static/images/layout/icon-shop.png" />
<span>购物车</span>
<div class="wrap-right-cart__tip">3</div>
</div>
</nuxt-link>
</div>
</div>
<div class="bar-header-box__tab flex flex-middle">
<div class="header-box-tab__category">
<div
v-show="showCategroyTab"
class="header-box-tab__category"
@mouseenter="handleCategoryChange(true)"
@mouseleave="handleCategoryChange(false)"
>
<div class="tab-category__label flex flex-center flex-middle">
<img src="@/static/images/layout/icon-category.png" />
<span>热门分类</span>
</div>
<div class="tab-category__menu flex flex-left">
<div
v-show="isCategroyOpen || categroyVisible"
class="tab-category__menu flex flex-left"
@mouseenter="handleCategoryTwoChange(true)"
@mouseleave="handleCategoryTwoChange(false)"
>
<!-- 左侧一级分类 -->
<div class="tab-category-menu__left">
<div
v-for="item in categrayData"
:key="item.id"
@mouseenter="handleMouEnter(item.id)"
@mouseleave="categrayHoverVisible = false"
@mouseenter="handleCategorySelect(item.id)"
class="menu-left__item flex flex-middle"
>
<img />
<span>{{ item.name }}</span>
</div>
</div>
<!-- 右侧二级分类 -->
<div
v-show="categrayHoverVisible"
v-show="categroyTwoVisible"
class="tab-category-menu__right"
@mouseenter="categrayHoverVisible = true"
@mouseleave="categrayHoverVisible = false"
>
<div
v-for="item in currentCategrayList"
:key="item.id"
class="menu-right__item"
@click="onCateogryTwoClick(item)"
>
{{ item.name }}
</div>
</div>
</div>
</div>
<nuxt-link
<div
v-for="item in tabList"
:key="item.value"
class="header-box-tab__common flex flex-center flex-middle"
:class="{
'header-box-tab__common--light':
item.path === $nuxt.$route.path,
item.value === $nuxt.$route.fullPath,
}"
:to="item.path"
@click="onTabSelect(item)"
>
{{ item.label }}
</nuxt-link>
</div>
</div>
</div>
</div>
@ -114,43 +139,53 @@
</div>
</template>
<script>
import { mapState } from "vuex";
import HeaderInfoBar from "./HeaderInfoBar.vue";
import {
ApiGetCategoryOneList,
ApiGetCategoryTwoAndGoods,
} from "@/plugins/api/goods";
const TAB_TYPE = {
HOME: 1,
RECOMMEND: 2,
BOOK: 3,
TIME_LIMIT: 4,
};
export default {
name: "DefaultHeader",
components: { HeaderInfoBar },
props: {
//
isSticky: {
type: Boolean,
default: false,
},
//
isCategroyOpen: {
type: Boolean,
default: false,
},
// tab
showCategroyTab: {
type: Boolean,
default: true,
},
},
data() {
return {
searchContent: "",
tabIndex: TAB_TYPE.HOME,
tabPath: "/",
tabList: [
{ label: "首页", value: TAB_TYPE.HOME, path: "/" },
{ label: "爆款推荐", value: TAB_TYPE.RECOMMEND, path: "/hot" },
{ label: "开发书籍", value: TAB_TYPE.BOOK, path: "/book" },
{ label: "限时秒杀", value: TAB_TYPE.TIME_LIMIT, path: "/skill" },
{ label: "首页", value: "/" },
{ label: "爆款推荐", value: "/goods/list?id=1" },
{ label: "开发书籍", value: "/goods/list?id=2" },
{ label: "限时秒杀", value: "/sckill" },
],
categrayHoverVisible: false,
currentCategrayId: 0,
categroyTwoVisible: false, //
categroyVisible: false, //
currentCategrayId: 0, // id
categrayData: [],
};
},
computed: {
...mapState(["userInfo", "token"]),
currentCategrayList() {
const data = this.categrayData.find(({ id }) => {
return this.currentCategrayId === id;
@ -162,10 +197,32 @@ export default {
this.getCategroyData();
},
methods: {
handleMouEnter(id) {
this.categrayHoverVisible = true;
onLoginClick() {
this.$isLoginValidate();
},
//
handleCategorySelect(id) {
this.currentCategrayId = id;
},
//
onCateogryTwoClick() {
this.$router.push("/goods/list");
},
//
handleCategoryChange(val) {
this.categroyVisible = val;
},
//
handleCategoryTwoChange(val) {
this.categroyTwoVisible = val;
},
handleTabSelect(path) {
this.$router.push({ path });
},
onTabSelect({ value }) {
this.tabPath = value;
this.$router.push({ path: value });
},
//
async getCategroyData() {
const { result } = await ApiGetCategoryOneList();
@ -185,23 +242,31 @@ export default {
);
}
},
onSearch() {
//
this.$router.push({
path: "/goods/list",
query: {
keyword: this.searchContent,
},
});
},
},
};
</script>
<style lang="scss" scoped>
.layout-sticky-bar-header {
height: 50px;
}
.sticky-bar-header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;
z-index: 10;
background: #ffffff;
box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.10000000149011612);
.sticky-bar-header__wrap {
width: 1200px;
@include layout-box;
height: 100%;
margin: 0 auto;
.bar-header-wrap__logo {
width: 164px;
height: 28px;
@ -210,15 +275,12 @@ export default {
.bar-header-wrap__icons {
cursor: pointer;
img {
width: 23px;
height: 23px;
width: 24px;
height: 24px;
}
.header-wrap-icons__shop {
position: relative;
margin: 0 30px 0 14px;
img {
width: 30px;
}
margin-left: 14px;
span {
position: absolute;
right: -6px;
@ -235,8 +297,17 @@ export default {
}
}
.header-wrap-icons__login {
margin-left: 47px;
img {
width: 34px;
height: 34px;
border-radius: 50%;
}
}
.header-wrap-icons__unlogin {
font-size: 16px;
color: #909399;
margin-left: 30px;
}
}
/deep/ .el-menu {
@ -263,8 +334,7 @@ export default {
position: relative;
z-index: 3;
.bar-header-box {
width: 1200px;
margin: 0 auto;
@include layout-box;
background: #ffffff;
.bar-header-box__wrap {
height: 42px;

@ -56,9 +56,14 @@ export default {
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
'@nuxtjs/axios',
'cookie-universal-nuxt'
'cookie-universal-nuxt',
'@nuxtjs/style-resources'
],
styleResources: {
scss: '@/assets/scss/global.scss'
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
transpile: [/^element-ui/],

216
package-lock.json generated

@ -39,6 +39,7 @@
"@babel/helpers": "^7.17.9",
"@babel/parser": "^7.17.10",
"@babel/template": "^7.16.7",
"@babel/traverse": "^7.17.10",
"@babel/types": "^7.17.10",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
@ -48,7 +49,7 @@
},
"dependencies": {
"@babel/traverse": {
"version": "7.17.9",
"version": "7.17.10",
"resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.17.9.tgz",
"integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==",
"requires": {
@ -2647,6 +2648,16 @@
"http-proxy-middleware": "^1.0.6"
}
},
"@nuxtjs/style-resources": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/@nuxtjs/style-resources/-/style-resources-1.2.1.tgz",
"integrity": "sha512-sOp71gCBNuGK2jchybTtVab83yB7jnSr+hw6DAKDgAGX/jrMYUyxRc9tiFxe+8YDSnqghTgQrkEkqPsfS4D4sg==",
"requires": {
"consola": "^2.15.3",
"glob-all": "^3.2.1",
"sass-resources-loader": "^2.2.4"
}
},
"@nuxtjs/youch": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/@nuxtjs/youch/-/youch-4.2.3.tgz",
@ -3493,6 +3504,11 @@
"resolved": "https://registry.npmmirror.com/assign-symbols/-/assign-symbols-1.0.0.tgz",
"integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw=="
},
"async": {
"version": "3.2.3",
"resolved": "https://registry.npmmirror.com/async/-/async-3.2.3.tgz",
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
},
"async-each": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
@ -7087,6 +7103,148 @@
"path-is-absolute": "^1.0.0"
}
},
"glob-all": {
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/glob-all/-/glob-all-3.3.0.tgz",
"integrity": "sha512-30gCh9beSb+YSAh0vsoIlBRm4bSlyMa+5nayax1EJhjwYrCohX0aDxcxvWVe3heOrJikbHgRs75Af6kPLcumew==",
"requires": {
"glob": "^7.1.2",
"yargs": "^15.3.1"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"requires": {
"p-locate": "^4.1.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"requires": {
"p-limit": "^2.2.0"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
},
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
"ansi-regex": "^5.0.1"
}
},
"wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"requires": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@ -13265,6 +13423,62 @@
}
}
},
"sass-resources-loader": {
"version": "2.2.5",
"resolved": "https://registry.npmmirror.com/sass-resources-loader/-/sass-resources-loader-2.2.5.tgz",
"integrity": "sha512-po8rfETH9cOQACWxubT/1CCu77KjxwRtCDm6QAXZH99aUHBydwSoxdIjC40SGp/dcS/FkSNJl0j1VEojGZqlvQ==",
"requires": {
"async": "^3.2.3",
"chalk": "^4.1.0",
"glob": "^7.1.6",
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",

@ -15,6 +15,7 @@
},
"dependencies": {
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/style-resources": "^1.2.1",
"cookie-universal-nuxt": "^2.1.5",
"core-js": "^3.19.3",
"element-ui": "^2.15.8",

@ -6,6 +6,7 @@
* @Description: file content
-->
<template>
<<<<<<< HEAD
<div class="c-white-main" style="padding-top:350px">
<div class="account">
<div class="account--nav">左侧栏</div>
@ -13,26 +14,66 @@
</div>
</div>
=======
<div class="account">
<div class="account--nav">左侧栏</div>
<nuxt-child class="account--main" />
</div>
>>>>>>> feature/task1.0.0
</template>
<script>
export default {
}
name: "Account",
data() {
return {
navTabs: [
{
label: "个人中心",
childrens: [
{ label: "我的主页", value: "/home" },
{ label: "消息通知", value: "/message" },
],
},
{
label: "订单中心",
childrens: [
{ label: "我的订单", value: "/order/lsit" },
{ label: "售后订单", value: "/order/saleAfter" },
],
},
{
label: "账户管理",
childrens: [
{ label: "个人资料", value: "/userInfo" },
{ label: "收货地址", value: "/address" },
],
},
],
};
},
};
</script>
<style lang="scss" scoped>
<<<<<<< HEAD
.account{
padding: 30px 0;
margin: 0 auto;
=======
.account {
@include layout-box;
padding-top: 370px;
margin: 0 auto;
>>>>>>> feature/task1.0.0
display: flex;
&--nav{
width: 170px;
height: 300px;
border: 1px solid #ddd;
border-radius: 4px;
margin-right: 30px;
&--nav {
width: 170px;
height: 300px;
border: 1px solid #ddd;
border-radius: 4px;
margin-right: 30px;
}
&--main{
flex: 1;
&--main {
flex: 1;
}
}
</style>
</style>

@ -13,18 +13,52 @@
</nav>
<main class="main flex">
<aside class="main__preview">
<img class="main__preview" src="~/static/images/goods/more.png" alt="商品大图" />
<img
class="main__preview-big"
:src="detailData.pictureList[activeImg]"
alt="商品大图"
/>
<div class="main__preview-control">
<img
class="main__preview-control--left"
src="~/static/images/goods/left.png"
alt="左侧切换"
@click="onImgLeft"
/>
<div
class="main__preview-control--imgs"
:style="
activeImg > 4
? 'transform: translateX(-' + (activeImg - 4) * 78 + 'px);'
: ''
"
>
<img
:class="index == activeImg ? 'img-active' : ''"
:src="item"
alt=""
v-for="(item, index) in detailData.pictureList"
:key="index"
@click="onActiveImg(index)"
/>
</div>
<img
class="main__preview-control--right"
src="~/static/images/goods/right.png"
alt="右侧切换"
@click="onImgRight"
/>
</div>
</aside>
<article class="main__details">
<p class="main__details-title">
<span class="main__details-title--label">新品</span>
Java从入门到项目实战全程视频版
编程入门it计算机书籍算法java编程思想java从入门到精通java核心技术javascript
{{ detailData.name }}
</p>
<div class="main__details-msg">
<div class="main__details-msg--price flex">
<span class="msg-txt">售价</span>
<UiMoney :money="123"></UiMoney>
<UiMoney :money="detailData.startingPrice"></UiMoney>
</div>
<div class="hr"></div>
<div class="main__details-msg--service flex flex-middle">
@ -40,41 +74,219 @@
</div>
</div>
<div class="main__details-option">
<div class="main__details-option--line flex flex-middle">
<span class="line-txt">规格</span>
<div
class="main__details-option--line flex flex-middle"
v-for="(item, index) in detailData.attributeGroupList"
:key="item.id"
>
<span class="line-txt">{{ item.name }}</span>
<div class="line-btns">
<UiButton
type="yellow_line"
v-for="(item, index) in 11"
:key="index"
>123</UiButton
v-for="val in item.attributes"
:key="val.symbol"
@click="handleAttrItem(val, index)"
:class="{
'attr-item__active': val.active,
'attr-item__disabled': val.disabled,
}"
>{{ val.name }}</UiButton
>
</div>
</div>
</div>
<div class="main__details-pay">
<UiButton type="yellow_line">加入购物车</UiButton>
<UiButton type="yellow_panel">立即购</UiButton>
<UiButton type="yellow_panel" @click="buyNow"></UiButton>
</div>
</article>
</main>
<section class="section flex">
<div class="section-recommend">
<p class="section-title">看了又看</p>
<UiGoodsItem
v-for="item in recommendedData"
:item="item"
:key="item.id"
></UiGoodsItem>
</div>
<div class="section-details">
<p class="section-title">商品详情</p>
<div class="rich" v-html="detailData.detail"></div>
</div>
</section>
</div>
</template>
<script>
import UiMoney from "@/components/UiMoney.vue";
import UiButton from "@/components/UiButton.vue";
import { ApiGetGoodsDetail, ApiGetGoodsSkus } from "@/plugins/api/goods";
import {
ApiGetGoodsDetail,
ApiGetGoodsSkus,
ApiGetRecommendedGoodsList,
} from "@/plugins/api/goods";
import UiGoodsItem from "@/components/UiGoodsItem.vue";
export default {
componetns: { UiMoney, UiButton },
componetns: { UiMoney, UiButton, UiGoodsItem },
data() {
return {};
return {
curBuyNum: 1,
activeImg: 0,
recommendedData: [],
skuData: {},
detailData: {
pictureList: [],
},
};
},
async created() {
let vm = this;
let id = this.$route.params.id;
let res1 = await ApiGetGoodsDetail({ id });
let res2 = await ApiGetGoodsSkus({ productId: id });
let res3 = await ApiGetRecommendedGoodsList();
vm.detailData = res1.result;
vm.skuData = res2.result;
vm.recommendedData = res3.result;
console.log(`res1`, res1.result);
console.log(`res2`, res2.result);
console.log(`res3`, res3.result);
},
computed: {
/**
* 当前选中SKU根据选中规格计算
*/
curSku() {
return (
this.skuData.find(
(i) => i.attributeSymbolList === this.selectedSymbol.join(",")
) || {}
);
},
// [1,.,3]
selectedSymbol() {
return this.detailData.attributeGroupList
.map((item) => {
const activeAttr = item.attributes.find((i) => i.active);
return activeAttr ? activeAttr.symbol : ".";
})
.filter((i) => i); //.sort();
},
/**
* 最大可购买数量
* 1有限购则对比限购跟库存取最小值
* 2没限购取库存
*/
maxBuyNum() {
const singleBuyLimit = this.detailData.singleBuyLimit;
const stock = this.curSku.stock;
return singleBuyLimit ? Math.min(singleBuyLimit, stock || 1) : stock;
},
},
methods: {
onActiveImg(i) {
this.activeImg = i;
},
onImgLeft() {
let vm = this;
if (vm.activeImg > 0) {
vm.activeImg--;
}
},
onImgRight() {
let vm = this;
if (vm.activeImg < vm.detailData.pictureList.length - 1) {
vm.activeImg++;
}
},
/**
* 设置默认选中规格
*/
setDefaultAttr() {
let vm = this;
const curSku = vm.skuData.find((i) => i.stock > 0);
if (!curSku) {
return false;
}
vm.detailData.attributeGroupList.forEach((item, index) => {
for (let i of item.attributes) {
if (curSku.attributeSymbolList.includes(i.symbol)) {
this.$set(i, "active", true);
this.setDisabledItem(i, index, true);
break;
}
}
});
this.$emit("input", this.curSku);
},
/**
* 点击属性项设置选中和禁用项
*/
handleAttrItem(item, groupIndex) {
let vm = this;
//
if (item.disabled) {
return false;
}
// 1
vm.curBuyNum = 1;
const active = item.active;
//
vm.detailData.attributeGroupList[groupIndex].attributes.forEach(
(item) => {
this.$set(item, "active", false);
}
);
//
this.$set(item, "active", !active);
this.setDisabledItem(item, groupIndex);
},
/**
* 每次点击选项属性时计算不可选属性
*/
setDisabledItem(item, groupIndex) {
let vm = this;
vm.detailData.attributeGroupList.forEach((group, idx) => {
//
let symbolCache = Object.assign([], this.selectedSymbol);
//
if (groupIndex === idx) return false;
//
group.attributes.forEach((item) => {
//
symbolCache[idx] = item.symbol;
const reg = new RegExp(symbolCache.join(","));
// SKU
const res = vm.skuData
.filter((i) => reg.test(i.attributeSymbolList))
.find((i) => i.stock > 0);
if (res) {
item.disabled = false;
} else {
item.disabled = true;
}
});
});
},
buyNow() {
if (!this.curSku.skuId) {
this.$message.error("请选择规格~");
return false;
}
let query = {
mode: "buyNow",
skuId: this.curSku.skuId,
num: this.curBuyNum,
activityType: 1,
};
console.log(query);
this.$router.push({
path: "/order/submit",
query,
});
},
},
};
</script>
@ -94,6 +306,64 @@ export default {
&__preview {
width: 456px;
margin-right: 30px;
&-big {
width: 456px;
height: 456px;
margin-bottom: 24px;
}
&-control {
width: 100%;
height: 58px;
position: relative;
overflow: hidden;
padding-left: 43px;
&::before {
content: "";
width: 43px;
height: 58px;
background: #fff;
position: absolute;
left: 0;
top: 0;
z-index: 1;
}
&::after {
content: "";
width: 43px;
height: 58px;
background: #fff;
position: absolute;
right: 0;
top: 0;
}
&--left,
&--right {
width: 20px;
height: 34px;
position: absolute;
top: 12px;
z-index: 1;
cursor: pointer;
}
&--left {
left: 0;
}
&--right {
right: 0;
}
&--imgs {
width: 1500px;
img {
width: 58px;
height: 58px;
margin-right: 20px;
cursor: pointer;
}
.img-active {
border: 1px solid #ff512b;
}
}
}
}
&__details {
width: 714px;
@ -195,4 +465,37 @@ export default {
}
}
}
.section {
width: 1200px;
margin: 64px auto 0;
&-recommend {
width: 210px;
margin-right: 30px;
/deep/.goods-item {
border: 1px solid #f2f2f2;
}
}
&-details {
width: 960px;
}
&-title {
width: 100%;
height: 40px;
line-height: 40px;
background: #f7f7f7;
border: 1px solid #f2f2f2;
padding-left: 16px;
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: #666666;
}
}
.attr-item__active {
background: red !important;
}
.attr-item__disabled {
background: cyan !important;
}
</style>

@ -36,17 +36,17 @@
</div>
</nav>
<div class="main__content">
<GoodsItem
<UiGoodsItem
:item="item"
v-for="item in listData"
:key="item.id"
></GoodsItem>
></UiGoodsItem>
</div>
<el-pagination
class="main__pagination flex flex-right"
@current-change="handleCurrentChange"
:current-page.sync="params.pageIndex"
:page-size="100"
:page-size="20"
layout="prev, pager, next, jumper"
:total="total"
>
@ -57,9 +57,9 @@
<script>
import { ApiGetGoodsList } from "@/plugins/api/goods";
import Sort from "./module/SortItem.vue";
import GoodsItem from "./module/Item.vue";
import UiGoodsItem from "@/components/UiGoodsItem.vue";
export default {
components: { Sort, GoodsItem },
components: { Sort, UiGoodsItem },
data() {
return {
navActive: 0,
@ -77,6 +77,7 @@ export default {
};
},
async created() {
this.params.name = this.$route.query.keyword;
this.getGoodsListData();
},
methods: {
@ -125,6 +126,14 @@ export default {
vm.getGoodsListData();
},
},
watch: {
//
//categoryId
"$route.query.keyword": function () {
this.params.name = this.$route.query.keyword;
this.getGoodsListData();
},
},
};
</script>
<style lang="scss" scoped>
@ -209,8 +218,3 @@ export default {
}
}
</style>
<style>
.tab-category__menu {
display: none;
}
</style>

Loading…
Cancel
Save