first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

View File

@@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,19 @@
# vuecli3study
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
{
"name": "vuecli3study",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"amfe-flexible": "^2.2.1",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"node-rsa": "^1.1.1",
"vant": "^2.12.25",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"postcss-pxtorem": "^5.1.1",
"style-resources-loader": "^1.4.1",
"vue-template-compiler": "^2.6.11"
}
}

View File

@@ -0,0 +1,12 @@
module.exports = {
plugins: {
'autoprefixer': {
browsers: ['Android >= 4.0', 'iOS >= 7']
},
'postcss-pxtorem': {
rootValue: 37.5,
//这是基准值在375px的屏幕变大rem的值会变大小于这个大小元素的rem值会变小
propList: ['*']
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_273pse87hq8.css">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -0,0 +1,12 @@
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
<style lang="less">
</style>

View File

@@ -0,0 +1,3 @@
@import "normalize";
@import "colors";
@import "mixins";

View File

@@ -0,0 +1,185 @@
.hairline(@position, @color) when (@position = top) {
&:before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: auto;
right: auto;
height: 1px;
width: 100%;
background-color: @color;
display: block;
z-index: 15;
// .transform-origin(50% 0%);
html.pixel-ratio-2 & {
.transform(scaleY(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleY(0.33));
}
}
}
.hairline(@position, @color) when (@position = left) {
&:before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: auto;
right: auto;
width: 1px;
height: 100%;
background-color: @color;
display: block;
z-index: 15;
// .transform-origin(0% 50%);
html.pixel-ratio-2 & {
.transform(scaleX(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleX(0.33));
}
}
}
.hairline(@position, @color) when (@position = bottom) {
&:after {
content: '';
position: absolute;
left: 0;
bottom: 0;
right: auto;
top: auto;
height: 1px;
width: 100%;
background-color: @color;
display: block;
z-index: 15;
html.pixel-ratio-2 & {
.transform(scaleY(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleY(0.33));
}
}
}
.hairline(@position, @color) when (@position = right) {
&:after {
content: '';
position: absolute;
right: 0;
top: 0;
left: auto;
bottom: auto;
width: 1px;
height: 100%;
background-color: @color;
display: block;
z-index: 15;
// .transform-origin(100% 50%);
html.pixel-ratio-2 & {
.transform(scaleX(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleX(0.33));
}
}
}
// Shadow
.depth(@level:1) {
& when (@level = 0) {
box-shadow: none;
}
& when (@level = 1) {
box-shadow: 0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);
}
& when (@level = 2) {
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);
}
& when (@level = 3) {
box-shadow: 0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12);
}
& when (@level = 4) {
box-shadow: 0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);
}
& when (@level = 5) {
box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12);
}
& when (@level = 6) {
box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);
}
& when (@level = 7) {
box-shadow: 0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12);
}
& when (@level = 8) {
box-shadow: 0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12);
}
& when (@level = 9) {
box-shadow: 0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12);
}
& when (@level = 10) {
box-shadow: 0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12);
}
& when (@level = 11) {
box-shadow: 0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12);
}
& when (@level = 12) {
box-shadow: 0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12);
}
& when (@level = 13) {
box-shadow: 0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12);
}
& when (@level = 14) {
box-shadow: 0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12);
}
& when (@level = 15) {
box-shadow: 0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12);
}
& when (@level = 16) {
box-shadow: 0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);
}
& when (@level = 17) {
box-shadow: 0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12);
}
& when (@level = 18) {
box-shadow: 0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12);
}
& when (@level = 19) {
box-shadow: 0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12);
}
& when (@level = 20) {
box-shadow: 0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12);
}
& when (@level = 21) {
box-shadow: 0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12);
}
& when (@level = 22) {
box-shadow: 0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12);
}
& when (@level = 23) {
box-shadow: 0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12);
}
& when (@level = 24) {
box-shadow: 0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);
}
}
.no-scrollbar() {
&::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
opacity: 0 !important;
}
}
.ellipsis() {
white-space:nowrap;
text-overflow:ellipsis;
overflow:hidden;
word-wrap: break-word;
}

View File

@@ -0,0 +1,424 @@
/*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */
/**
* 1. Change the default font family in all browsers (opinionated).
* 2. Prevent adjustments of font size after orientation changes in IE and iOS.
*/
img {
width: 100%;
}
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/**
* Remove the margin in all browsers (opinionated).
*/
body {
margin: 0;
}
/* HTML5 display definitions
========================================================================== */
/**
* Add the correct display in IE 9-.
* 1. Add the correct display in Edge, IE, and Firefox.
* 2. Add the correct display in IE.
*/
article,
aside,
details, /* 1 */
figcaption,
figure,
footer,
header,
main, /* 2 */
menu,
nav,
section,
summary { /* 1 */
display: block;
}
/**
* Add the correct display in IE 9-.
*/
audio,
canvas,
progress,
video {
display: inline-block;
}
/**
* Add the correct display in iOS 4-7.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Add the correct display in IE 10-.
* 1. Add the correct display in IE.
*/
template, /* 1 */
[hidden] {
display: none;
}
/* Links
========================================================================== */
/**
* 1. Remove the gray background on active links in IE 10.
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
*/
a {
background-color: transparent; /* 1 */
-webkit-text-decoration-skip: objects; /* 2 */
}
/**
* Remove the outline on focused links when they are also active or hovered
* in all browsers (opinionated).
*/
a:active,
a:hover {
outline-width: 0;
}
/* Text-level semantics
========================================================================== */
/**
* 1. Remove the bottom border in Firefox 39-.
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
*/
b,
strong {
font-weight: inherit;
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* Add the correct font style in Android 4.3-.
*/
dfn {
font-style: italic;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/**
* Add the correct background and color in IE 9-.
*/
mark {
background-color: #ff0;
color: #000;
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10-.
*/
img {
border-style: none;
}
/**
* Hide the overflow in IE.
*/
svg:not(:root) {
overflow: hidden;
}
/* Grouping content
========================================================================== */
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct margin in IE 8.
*/
figure {
margin: 1em 40px;
}
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/* Forms
========================================================================== */
/**
* 1. Change font properties to `inherit` in all browsers (opinionated).
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
select,
textarea {
font: inherit; /* 1 */
margin: 0; /* 2 */
}
/**
* Restore the font weight unset by the previous rule.
*/
optgroup {
font-weight: bold;
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
* controls in Android 4.
* 2. Correct the inability to style clickable types in iOS and Safari.
*/
button,
html [type="button"], /* 1 */
[type="reset"],
[type="submit"] {
-webkit-appearance: button; /* 2 */
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Change the border, margin, and padding in all browsers (opinionated).
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Remove the default vertical scrollbar in IE.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10-.
* 2. Remove the padding in IE 10-.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
*/
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Correct the text style of placeholders in Chrome, Edge, and Safari.
*/
::-webkit-input-placeholder {
color: inherit;
opacity: 0.54;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}

View File

@@ -0,0 +1,80 @@
.home {
.header {
width: 100%;
position: fixed;
height: 45px;
left: 0;
top: 0;
right: 0;
display: flex;
justify-content: space-between;
padding: 0 15px;
box-sizing: border-box;
align-items: center;
background: #fff;
z-index: 999;
img {
width: 0.66667rem;
height: 0.42667rem;
margin-right: 10px;
}
.search {
display: flex;
align-items: center;
flex: 1;
background-color: #f7f8fa;
height: 38px;
padding: 15px;
box-sizing: border-box;
border-radius: 24px;
span {
font-size: 14px;
color: #8d8d8d;
margin-left: 8px;
}
}
.search_text {
font-size: 16px;
color: #8d8d8d;
margin-left: 10px;
}
}
.content {
margin-top: 45px;
margin-bottom: 50px;
.hot-item {
span {
color: #646566;
font-size: 0.32rem;
line-height: 1.5;
word-break: break-all;
margin-top: 8px;
}
}
.shop-list {
margin-top: 15px;
.van-col {
text-align: center;
margin-bottom: 15px;
.title{
font-size: 0.37333rem;
color: #000;
}
.desc {
color: rgba(0,0,0,0.54);
font-size: 0.32rem;
margin-top: 0.08333rem;
width: 80%;
margin: 0 auto;
.ellipsis();
}
.price {
color: #ea625b;
font-size: 0.37333rem;
margin-top: 0.13333rem;
}
}
}
}
}

View File

@@ -0,0 +1,134 @@
.Info {
.noAddCar {
background: linear-gradient(to right,#c9c9c8,#7d7b79) !important;
}
/deep/ .van-tabs__nav {
width: 40%;
margin: 0 auto;
z-index: 10;
background: none;
}
/deep/ .hidden .van-tabs__nav {
display: none;
}
/deep/ .van-button__text {
font-size: 14px;
}
.header {
box-sizing: border-box;
position: fixed;
width: 100%;
height: 45px;
left: 0;
right: 0;
top: 0;
z-index: 9;
}
.back {
background: #00000073;
border-radius: 100%;
padding: 7px;
color: #fff;
}
.noback {
color: #000;
padding: 7px;
}
.van-icon-arrow-left,
.van-icon-shopping-cart-o {
position: fixed;
top: calc(45px / 2 );
transform: translateY(-50%);
font-size: 18px;
z-index: 999;
}
.van-icon-arrow-left {
left: 15px;
}
.van-icon-shopping-cart-o {
right: 15px;
}
.info_content {
.top {
padding: 0 15px;
border-bottom: 0.13333rem solid #f7f7f7;
padding-bottom: 20px;
.title {
font-size: 0.56rem;
color: #3c3c3c;
margin-bottom: 0.26667rem;
}
.desc {
color: rgba(0,0,0,0.54);
font-size: 0.33333rem;
line-height: 0.5rem;
}
.price {
margin-top: 0.26667rem;
color: #ff6700;
font-size: 0.53333rem;
del {
color: #bdbaba;
font-size: 0.33333rem;
}
}
}
.norms {
padding: 0.13333rem 15px;
border-bottom: 0.13333rem solid #f7f7f7;
display: flex;
justify-content: space-between;
height: 1.06667rem;
align-items: center;
font-size: 0.34667rem;
.right {
display: flex;
align-items: center;
}
}
.quality {
display: flex;
padding: 0.13333rem 15px;
justify-content: space-between;
padding: 0 0.26667rem;
box-sizing: border-box;
height: 1.06667rem;
align-items: center;
border-bottom: 0.13333rem solid #f7f7f7;
.left {
line-height: 0.4rem;
.item_1 {
float: left;
margin-right: 0.26667rem;
img {
width: 0.26667rem;
height: 0.26667rem;
margin-right: 0.13333rem;
}
span {
font-size: 0.32rem;
color: rgba(0,0,0,0.54);
}
}
}
.van-icon {
font-size: 0.32rem;
color: rgba(0,0,0,0.54);
}
}
}
.shop_info {
padding-bottom: 50px;
img {
width: 100%;
}
}
}

View File

@@ -0,0 +1,76 @@
.hader{
width: 100%;
height: 5.33333rem;
background: url(/img/me_back.png) no-repeat;
background-position: center center;
background-size: cover;
position: relative;
}
.set{
position: absolute;
right: 0.4rem;
top: 0.53333rem;
width: 0.66667rem;
height: 0.66667rem;
z-index: 9;
}
.user{
display: flex;
align-items: center;
position: absolute;
bottom: 1.06667rem;
left: 0.53333rem;
img{
width: 1.46667rem;
height: 1.46667rem;
margin-right: 10px;
}
span{
font-size: 0.48rem
}
}
.type{
margin-top: 10px;
margin-bottom: 20px;
ul{
display: flex;
align-items: center;
justify-content: space-around;
li{
display: flex;
flex-direction:column;
align-items: center;
img{
width: 0.93333rem;
margin-bottom: 5px;
}
span{
color: #646566;
font-size: 0.32rem;
}
}
}
}
.setting{
ul{
padding: 0 18px;
li{
padding-top: 0.4rem;
padding-bottom: 0.4rem;
display: flex;
align-items: center;
justify-content: start;
border-bottom: 1px solid #ebedf0;
img{
width: 0.48rem;
height: 0.53333rem;
margin-right: 0.26667rem;
}
span{
color: #323233;
font-size: 0.37333rem;
}
}
}
}

View File

@@ -0,0 +1,78 @@
.top{
z-index: 999;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 5px;
span{
color: #323233;
font-size: 0.37333rem;
margin-right: 10px;
}
}
.van-search{
width: 300px;
}
.van-search__content{
border-radius: 26.64rem;
}
.content{
padding: 26px 10px 10px 10px;
ul{
display: flex;
li{
padding: 0rem 0.21333rem;
font-size: 0.37333rem;
border-radius: 0.10667rem;
margin-right: 10px;
line-height: 24px;
text-align: center;
background-color: #fff;
border: 0.02667rem solid #969799;
box-sizing: border-box;
color: #969799;
}
}
}
.title1{
margin-bottom: 0.26667rem;
font-size: 0.48rem;
}
.title{
display: flex;
padding-left: 10px;
padding-right: 10px;
justify-content: space-between;
flex-wrap: wrap;
li{
margin-bottom: 10px;
width: 45%;
.titlec{
font-size: 16px;
text-align: center;
width: 100%;
}
img{
width: 150px;
height: 150px;
}
.info{
.ellipsis();
width: 100%;
font-size: 13px;
color: #d2d1d1;
text-align: center;
}
.price{
text-align: center;
font-size: 16px;
}
}
}
.title12{
display: flex;
align-items:center;
flex-direction: column;
justify-content: center;
height: calc(100vh - 53px);
}

View File

@@ -0,0 +1,41 @@
.top{
width: 100%;
height: 46px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
box-sizing: border-box;
span{
padding-left: 16px;
color: #323233;
font-weight: 500;
font-size: 0.42667rem;
}
border-bottom: 1px solid #ebedf0;
}
.right_title{
display: flex;
flex-wrap: wrap;
li{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 150px;
padding-bottom: 10px;
padding-top: 10px;
img{
display: block;
width: 128px;
height: 141px;
}
span{
text-align: center;
width: 100%;
.ellipsis()
}
}
}

View File

@@ -0,0 +1,114 @@
.User {
.top_circular {
position: fixed;
left: -24px;
top: -171px;
width: 112%;
height: 10rem;
border-radius: 100%;
background: #534cef;
}
.right_circular {
position: fixed;
background: #fff;
height: 14rem;
width: 14.4rem;
right: -55%;
top: 12%;
box-shadow: -0.05333rem 0.18667rem 0.72rem #d2d1d1;
border-radius: 100%;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: flex-start;
padding-left: 1.46667rem;
box-sizing: border-box;
.item {
margin-bottom: 15px;
.icon {
display: flex;
align-items: center;
margin-bottom: 10px;
span {
color: #aebfca;
font-size: 16px;
}
.van-icon {
color: #aebfca;
font-size: 17px;
margin-left: 15px;
margin-right: 8px;
}
}
input {
width: 100%;
background: #f1f5f9;
border-radius: 10px;
height: 40px;
border: none;
outline: none;
padding-left: 15px;
box-sizing: border-box;
font-size: 16px;
color: #49657b;
}
}
.but {
width: 100%;
height: 40px;
border-radius: 10px;
background: #5950fe;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
letter-spacing: 5px;
}
.login,.reg{
width: 255px;
}
}
.bottom_circular {
position: fixed;
bottom: -23px;
left: -27px;
.blue {
background: linear-gradient(50deg,#5c52fb,#946fd9);
}
.one {
width: 5.9rem;
height: 5.9rem;
border-radius: 100%;
position: absolute;
left: -45px;
bottom: -42px;
}
.two {
position: absolute;
width: 2.6rem;
height: 2.6rem;
border-radius: 100%;
top: -3.9rem;
left: 1.1333rem;
color: #fff;
font-size: 19px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 1px 1px 32px #7f71e1;
background: linear-gradient( 50deg , #5046f3, #946fd9);
}
.three {
width: 1.9rem;
height: 1.9rem;
border-radius: 100%;
position: absolute;
right: -5.3rem;
top: -4.9rem;
z-index: -1;
box-shadow: 0px 0px 39px #a1a1a1;
}
}
}

View File

@@ -0,0 +1,33 @@
.opop{
height: 10px;
width: 100%;
background: #fdfdfd;
}
.van-cell{
align-items: center;
img{
width:50px
}
}
/deep/.van-cell__title{
display: flex;
align-items: center;
margin-right: 15px;
}
.vansad{
margin-top: 50px;
display: flex;
align-items: center;
flex-direction: column;
}
.price{
margin-top: 15px;
display: flex;
align-items: center;
}
/deep/.van-button--block{
position: fixed;
bottom: 11px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1,53 @@
<template>
<div class="Care">
<div v-if="list.length !=0 ">
<van-card
v-for="(item,index) in list"
:num="index"
:price="item.goods_num"
:desc="item.wares_info"
:title="item.wares_title"
:thumb="item.wares_masterimg[0]"
/>
</div>
<div class="zan" v-else>
<van-icon name="cart-circle-o" size="30"/>
暂无数据
</div>
</div>
</template>
<script>
export default {
name: "Care",
props:{
list:{
type: Array,
default:()=>[]
}
},
data() {
return {}
},
created() {
},
methods: {},
components: {},
}
</script>
<style scoped lang="less">
.zan{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: #8d8d8d;
height:calc(100vh - 100px);
.van-icon{
margin-bottom: 10px;
}
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<div class="swiper">
<van-swipe class="my-swipe" @change="onChange"
indicator-color="white">
<van-swipe-item v-for="(item,index) in data" :key="index">
<slot :item="item" :index="index"></slot>
</van-swipe-item>
<template #indicator v-if="showIndicator">
<div class="custom-indicator">{{ current + 1 }} / {{ data.length }}</div>
</template>
</van-swipe>
</div>
</template>
<script>
export default {
name: "swiper",
props: {
data: {
type: Array,
default: () => []
},
showIndicator: {
type: Boolean,
default: false
}
},
data() {
return {
current: 0
}
},
created() {
},
methods: {
onChange(index) {
this.current = index
}
}
}
</script>
<style scoped lang="less">
.custom-indicator {
position: absolute;
right: 5px;
bottom: 5px;
padding: 4px 10px;
font-size: 14px;
background-color: rgba(0,0,0,.5);
color: #fff;
border-radius: 12px;
}
</style>

View File

@@ -0,0 +1,28 @@
<template>
<div class="tabbar">
<van-tabbar v-model="active" route>
<van-tabbar-item icon="home-o" to="/">首页</van-tabbar-item>
<van-tabbar-item icon="search" to="/type">分类</van-tabbar-item>
<van-tabbar-item icon="friends-o" to="/car">购物车</van-tabbar-item>
<van-tabbar-item icon="setting-o" to="/me">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
export default {
name: "tabbar",
data() {
return {
active: 0
}
},
created() {
},
methods: {}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,46 @@
import Vant from 'vant';
import 'vant/lib/index.css';
export default {
devBaseUrl: 'http://127.0.0.1:9090',
testBaseUrl: 'http://127.0.0.1:9090',
prodBaseUrl: 'http://127.0.0.1:9090',
urlList: {
index: '/home/index',
add: '/user/add',
login: '/user/login',
banner: '/home/banner',
info: '/home/info',
addCar: '/car/addCar',
checkCar: '/car/checkCar',
activity:'/home/activity', /*推荐详情接口*/
list:'/type/list',/*分类接口*/
search:'/home/search',/*搜索接口*/
getCarList:'/car/getCarList',/*购物车接口*/
updateCarNum:'/car/updateCarNum',/*更新购物车购买数量接口*/
deleteCar:'/car/deleteCar',/*购物车删除接口*/
submitCar:'/car/submitCar',
allOrder:'/order/allOrder',
buyOrder:'/order/buyOrder'
},
publicKey: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9eo8WIbWS5Yql06imlhrW0ZXh
faivPavdULvYLIxIKyUaOwMPFrPuHqqBNGnYOpiPHAKL+zxk2j4u+6jhB6VK1SOD
ccSLxIRxd0HmSDS+hBzYRf4vKc8BLlhMrYhnLmcxCc+PJIIa4DfCZnu8FfQlu/5L
ljjpYN9kHOpHAT+xpQIDAQAB
-----END PUBLIC KEY-----`,
VuePlug: [ Vant ],
checkUrl: function () {
switch (process.env.NODE_ENV) {
case "development":
return this.devBaseUrl;
break;
case "test":
return this.testBaseUrl;
break;
case "production":
return this.prodBaseUrl;
break;
}
}
}

View File

@@ -0,0 +1,77 @@
import axios from "axios";
import config from "@/config"
import { Toast, Dialog } from 'vant';
import rsa from "../utils/rsa";
export default class http {
constructor() {
this.instance = axios.create({
baseURL: config.checkUrl(),
timeout: 3000
});
this.interceptors()
}
async get(params) {
return await this.instance.get(params.url, {
params: params.data,
headers: Object.assign({
token: localStorage.getItem("token"),
"Content-Type": "application/json;"
}, params.headers)
})
}
async post(params) {
return await this.instance.post(params.url, {}, {
headers: Object.assign({
token: localStorage.getItem("token"),
data: rsa.PublicKeyEncryption(params.data),
"Content-Type": "application/json;"
}, )
})
}
interceptors() {
// 添加请求拦截器
this.instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
this.instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
switch (response.data.status) {
case 200:
return rsa.PublicKeyDecryption(response.data.result)
break;
case 404:
Toast('用户名密码错误')
throw new Error(response.data.message);
break;
case 501:
Dialog.alert({
title: '温馨提示',
message: response.data.message,
}).then(() => {
location.href = "#/user"
});
throw new Error(response.data.message);
break;
case 500:
Toast(response.data.message);
throw new Error(response.data.message);
break;
}
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
}
}

View File

@@ -0,0 +1,21 @@
import 'amfe-flexible'
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import serve from "./serve/_";
import config from "./config";
import utils from "./utils/index";
config.VuePlug.forEach(v => Vue.use(v));
Vue.config.productionTip = false
Vue.prototype.$http = serve
Vue.prototype.$utils = new utils
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

View File

@@ -0,0 +1,171 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'layout',
component: () => import(/* webpackChunkName: "layout" */ '../views/layout.vue'),
children: [
{
path: '/',
name: 'home',
component: () => import(/* webpackChunkName: "type" */ '../views/Home.vue'),
meta: {
isLogin: false,
title: '首页',
keepAlive: true
}
},
{
path: '/type',
name: 'type',
component: () => import(/* webpackChunkName: "type" */ '../views/Type.vue'),
meta: {
isLogin: false,
title: '分类',
keepAlive: true
}
},
{
path: '/car',
name: 'car',
component: () => import(/* webpackChunkName: "car" */ '../views/Car.vue'),
meta: {
isLogin: true,
title: '购物车',
keepAlive: false
}
},
{
path: '/me',
name: 'me',
component: () => import(/* webpackChunkName: "me" */ '../views/Me.vue'),
meta: {
isLogin: true,
title: '我的',
keepAlive: false
}
}
]
},
{
path: '/user',
name: 'user',
component: () => import(/* webpackChunkName: "user" */ '../views/User.vue'),
meta: {
isLogin: false,
title: '登录/注册',
keepAlive: false
}
},
{
path: '/info',
name: 'info',
component: () => import(/* webpackChunkName: "info" */ '../views/Info.vue'),
meta: {
isLogin: false,
title: '详情',
keepAlive: false
}
},
{
path: '/activity',
name: 'activity',
component: () => import(/* webpackChunkName: "activity" */ '../views/Activity.vue'),
meta: {
isLogin: false,
title: '活动',
keepAlive: false
}
},
{
path: '/search',
name: 'search',
component: () => import(/* webpackChunkName: "search" */ '../views/Search.vue'),
meta: {
isLogin: false,
title: '搜索',
keepAlive: false
}
},
{
path: '/order',
name: 'order',
component: () => import(/* webpackChunkName: "search" */ '../views/order.vue'),
meta: {
isLogin: false,
title: '付款',
keepAlive: false
}
},
{
path: '/plaStetus',
name: 'plaStetus',
component: () => import(/* webpackChunkName: "search" */ '../views/plaStetus.vue'),
meta: {
isLogin: false,
title: '付款状态',
keepAlive: false
}
},
{
path: '/orderdata',
name: 'orderdata',
component: () => import(/* webpackChunkName: "search" */ '../views/orderdata.vue'),
meta: {
isLogin: false,
title: '付款状态',
keepAlive: false
}
}
]
const router = new VueRouter({
routes,
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
if (to.name == "info") {
return { x: 0, y: 0 }
}
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
});
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
return originalPush.call(this, location).catch(err => err)
}
router.beforeEach((to, from, next) => {
document.title = to.meta.title
// 你访问的那个页面需要登录
if (to.meta.isLogin) {
// 再次判断,你是否登录
// 登录了给你看页面
// 没登陆不给看,并且强制去登录
// 表示未登录,
if (localStorage.getItem("token") == null) {
next({
path: '/user',
query: {
from: to.path
}
})
} else {
next()
}
} else {
next()
}
})
export default router

View File

@@ -0,0 +1,7 @@
import http from "@/http";
import config from "@/config";
export default class BaseServe {
http = new http();
config = config;
}

View File

@@ -0,0 +1,85 @@
import BaseServe from "./BaseServe";
export default class CarServe extends BaseServe {
constructor() {
super();
}
async addCar (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.addCar,
data: data,
headers: headers
});
}
async checkCar (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.checkCar,
data: data,
headers: headers
});
}
async getCarList (data = {}, headers = {}) {
var res =await this.http.post({
url: this.config.urlList.getCarList,
data: data,
headers: headers
});
if(Array.isArray(res)){
res.forEach(v=>{
v.wares_masterimg = JSON.parse(v.wares_masterimg)
})
}else {
res=[]
}
return res
}
async updateCarNum (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.updateCarNum,
data: data,
headers: headers
});
}
async deleteCar (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.deleteCar,
data: data,
headers: headers
});
}
async submitCar (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.submitCar,
data: data,
headers: headers
});
}
async allOrder (data = {}, headers = {}) {
let res = await this.http.post({
url: this.config.urlList.allOrder,
data: data,
headers: headers
});
if(Array.isArray(res)){
res.forEach(v=>{
v.wares_masterimg=JSON.parse(v.wares_masterimg)
})
return res
}else {
return []
}
}
async buyOrder (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.buyOrder,
data: data,
headers: headers
});
}
}

View File

@@ -0,0 +1,56 @@
import BaseServe from "./BaseServe";
export default class IndexServe extends BaseServe {
constructor() {
super();
}
async banner (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.banner,
data: data,
headers: headers
});
}
async activity (data = {}, headers = {}) {
let res =await this.http.post({
url: this.config.urlList.activity,
data: data,
headers: headers
});
res.forEach(v=>{
v.wares_masterimg=JSON.parse(v.wares_masterimg)
})
return res
}
async list (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.list,
data: data,
headers: headers
});
}
async info (data = {}, headers = {}) {
let res = await this.http.post({
url: this.config.urlList.info,
data: data,
headers: headers
});
res.wares_infoimg = JSON.parse(res.wares_infoimg)
res.wares_masterimg = JSON.parse(res.wares_masterimg)
return res;
}
async home (data = {}, headers = {}) {
var res = await this.http.post({
url: this.config.urlList.index,
data: data,
headers: headers
});
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
});
return res
}
}

View File

@@ -0,0 +1,19 @@
import BaseServe from "./BaseServe";
export default class searchServe extends BaseServe {
constructor() {
super();
}
async search (data = {}, headers = {}) {
let res = await this.http.post({
url: this.config.urlList.search,
data: data,
headers: headers
});
res.forEach(v=>{
v.wares_masterimg=JSON.parse(v.wares_masterimg)
})
return res
}
}

View File

@@ -0,0 +1,23 @@
import BaseServe from "./BaseServe";
export default class UserServe extends BaseServe {
constructor() {
super();
}
async login (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.login,
data: data,
headers: headers
});
}
async add (data = {}, headers = {}) {
return await this.http.post({
url: this.config.urlList.add,
data: data,
headers: headers
});
}
}

View File

@@ -0,0 +1,11 @@
import IndexServe from "./IndexServe";
import CarServe from "./CarServe";
import UserServe from "./UserServe";
import SearchServe from "./SearchServe";
export default {
index: new IndexServe(),
car: new CarServe(),
user: new UserServe(),
Search: new SearchServe(),
}

View File

@@ -0,0 +1,8 @@
export default {
GET_CARLIST:(state)=>{
return state.car.carlist
},
GET_ORDERLIST:(state)=>{
return state.car.OrderedList
}
}

View File

@@ -0,0 +1,23 @@
import Vue from 'vue'
import Vuex from 'vuex'
import car from "./modules/car"
import home from "./modules/home"
import setting from "./modules/setting"
import getters from "./getters"
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
getters:getters,/*把getters作为一个文件拆分出去*/
mutations: {
},
actions: {
},
modules: {
car,home,setting,getters
}
}
)

View File

@@ -0,0 +1,25 @@
import carserve from "@/serve/CarServe"
export default {
state: {/*存放变量数据的*/ /*this.$store.state*/
carlist: [],
OrderedList: []
},
getters: {},
mutations: {
SET_CARLISTDATA: (state, data) => {
state.carlist = data
},
SET_ORDERLIST: (state, data) => {
state.OrderedList = data
}
},
actions: {
GET_CARLISTDATA: async ({commit}) => {
let res = await (new carserve()).getCarList()
console.log("购物车数据", res)
commit("SET_CARLISTDATA", res)
}
},
modules: {},
}

View File

@@ -0,0 +1,15 @@
export default {
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {},
}

View File

@@ -0,0 +1,15 @@
export default {
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {},
}

View File

@@ -0,0 +1,8 @@
import router from "@/router/index";
export default class utils{
back(){
//history.back()
router.back()
}
}

View File

@@ -0,0 +1,20 @@
import NodeRsa from "node-rsa";
import config from "../config";
class RSA {
constructor () {
this.public_key = config.publicKey
}
// 公钥加密
PublicKeyEncryption(text) {
return (new NodeRsa(this.public_key)).encrypt(JSON.stringify(text), 'base64')
}
// 公钥解密
PublicKeyDecryption(text) {
return JSON.parse((new NodeRsa(this.public_key)).decryptPublic(text, 'utf8'))
}
}
export default new RSA();

View File

@@ -0,0 +1,89 @@
<template>
<div class="activity">
<van-nav-bar
:title="$route.query.title"
left-text=""
left-arrow
@click-left="onClickLeft"
/>
<ul class="title">
<li v-for="(v,i) in activity" :key="i" @click="toinfo(v)">
<img :src="v.wares_masterimg[0]" alt="">
<div class="titlec">{{v.wares_title}}</div>
<div class="info">{{v.wares_info}}</div>
<div class="price">{{v.wares_oldprice}}</div>
</li>
</ul>
</div>
</template>
<script>
import router from "@/router";
export default {
name: "activity",
data() {
return {
activity:[]
}
},
created() {
this.getactivity()
},
methods: {
async getactivity() {
this.activity = await this.$http.index.activity({
id:this.$route.query.id,
});
console.log(this.activity)
},
onClickLeft(){
this.$utils.back()
},
toinfo(item){
console.log(item)
this.$router.push({
name: 'info',
query: {
id: item.wares_id
}
})
}
}
}
</script>
<style scoped lang="less">
.title{
display: flex;
padding-left: 10px;
padding-right: 10px;
justify-content: space-between;
flex-wrap: wrap;
li{
margin-bottom: 10px;
width: 45%;
.titlec{
font-size: 16px;
text-align: center;
width: 100%;
}
img{
width: 150px;
height: 150px;
}
.info{
.ellipsis();
width: 100%;
font-size: 13px;
color: #d2d1d1;
text-align: center;
}
.price{
text-align: center;
font-size: 16px;
}
}
}
</style>

View File

@@ -0,0 +1,203 @@
<template>
<div class="Car">
<van-nav-bar
title="购物车"
left-text="返回"
:right-text="status ? '管理' : '完成'"
left-arrow
fixed
@click-left="$utils.back()"
@click-right="status =! status"
/>
<div class="shiplist" v-if="carList.length != 0">
<van-checkbox-group v-model="selectCarItem" ref="checkboxGroup" @change="checkboxGroupchange">
<van-checkbox :name="v.wares_id" v-for="(v,i) in carList" :key="i">
<van-card
@click.stop="gotoinfo(v)"
:price="v.wares_oldprice"
:desc="v.wares_info"
:title="v.wares_title"
:thumb="v.wares_masterimg[0]"
>
<template #num>
<van-stepper
v-model="v.car_num"
@change="updateNums(v)"
theme="round"
button-size="22"
disable-input/>
</template>
</van-card>
</van-checkbox>
</van-checkbox-group>
</div>
<div class="shiplist nodata" v-else>
<p>暂时无数据</p>
</div>
<van-submit-bar :price="totalMoney">
<van-checkbox v-model="isSelectAll" @click="changeSelectAllStatus">全选</van-checkbox>
<template #button v-if="status">
<van-button round type="danger" @click="submitorder()">结算</van-button>
</template>
<template #button v-else>
<van-button round type="warning" @click="deleteCar()">删除</van-button>
</template>
</van-submit-bar>
</div>
</template>
<script>
import {mapGetters, mapActions, mapMutations} from 'vuex'
export default {
name: "Car",
data() {
return {
status: true,//T是管理F是删除
selectCarItem: [],/*储存选择对象的*/
isSelectAll: false,//是否点击全选按钮f没有
}
},
async created() {
if (this.carList.length == 0) {
await this.getcarl()
}
},
computed: {
...mapGetters({
carList: "GET_CARLIST",
getserOder:"GET_ORDERLIST"
}),
totalMoney() {
var total = 0;
this.selectCarItem.forEach(vid => {
this.carList.forEach(item => {
if (vid == item.wares_id) {
total += item.car_num * item.wares_oldprice
}
})
})
return total * 100
},
},
methods: {
...mapActions({
getcarl: "GET_CARLISTDATA"
}),
...mapMutations({
serOder: "SET_ORDERLIST"
}),
submitorder() {
var carIdArr = []
this.selectCarItem.forEach(vid => {
this.carList.forEach(item => {
if (vid == item.wares_id) {
carIdArr.push(item)
}
})
})
this.serOder(carIdArr)
console.log("this.ordered",this.getserOder)
this.$router.push({
name:"order"
})
},
gotoinfo(item) {
this.$router.push({
name: 'info',
query: {
id: item.wares_id
}
})
},
async updateNums(item) {
event.stopPropagation()
let res = await this.$http.car.updateCarNum({
carid: item.car_id,
quantity: item.car_num
})
console.log(item)
},
checkboxGroupchange() {
var Order = [];
this.selectCarItem.forEach(vid => {
this.carList.forEach(item => {
if (vid == item.wares_id) {
Order.push(item)
}
})
})
},
changeSelectAllStatus() {
if (this.isSelectAll) {
this.$refs.checkboxGroup.toggleAll(true);
} else {
this.$refs.checkboxGroup.toggleAll();
}
},
async deleteCar() {
var carIdArr = []
this.selectCarItem.forEach(vid => {
this.carList.forEach(item => {
if (vid == item.wares_id) {
carIdArr.push(item.car_id)
}
})
})
let res = await this.$http.car.deleteCar({carid: carIdArr})
await this.getcarl()
},/*购物车删除方法*/
},
}
</script>
<style scoped lang="less">
.nodata {
text-align: center;
align-items: center;
justify-content: center;
height: calc(100vh - 145px);
}
.Car {
.shiplist {
margin-top: 45px;
margin-bottom: 120px;
/deep/ .van-checkbox__icon {
margin-left: 16px;
}
/deep/ .van-checkbox__label {
width: 90%;
margin-left: 0;
}
/deep/ .van-card {
background-color: #ffffff;
}
}
/deep/ .van-submit-bar {
bottom: 50px;
}
/deep/ .van-button--danger,
/deep/ .van-button--warning {
width: 90px;
span {
font-size: 16px;
}
}
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<div class="home">
<div class="header">
<img src="/img/logo.png" alt="">
<div class="search" @click="gosearch">
<van-icon name="search" size="16"/>
<span>请输入搜索关键词</span>
</div>
<div class="search_text" @click="gosearch">搜索</div>
</div>
<div class="content">
<swiper :data="BannerList">
<template v-slot:default="slot">
<img :src="slot.item.banner" alt="" @click="toInfo(slot.item)">
</template>
</swiper>
<div class="hot">
<van-grid :border="false" :column-num="4">
<van-grid-item class="hot-item" @click="toActivity(item)" v-for="(item,index) in hotArr">
<van-image width="0.85333rem" :src="item.icon" />
<span>{{ item.title }}</span>
</van-grid-item>
</van-grid>
</div>
<van-row class="remm">
<van-col span="12">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/32b5d24417b673008f386592c4d17046.jpg?thumb=1&w=358&h=508" alt="">
</van-col>
<van-col span="12">
<van-row>
<van-col span="24">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/1480d862e1f5a41e5adae8c030eef511.jpg?thumb=1&w=358&h=252" alt="">
</van-col>
<van-col span="24">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/1480d862e1f5a41e5adae8c030eef511.jpg?thumb=1&w=358&h=252" alt="">
</van-col>
</van-row>
</van-col>
</van-row>
<div class="adb">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/3ca39ff880dfbcbc0e45314782c39fff.jpg?thumb=1&w=720&h=280" alt="">
</div>
<van-row class="shop-list">
<van-col span="12" @click="toInfo(item)" v-for="(item,index) in HomeList" :key="index">
<img :src="item.wares_masterimg[0]" alt="">
<div class="title">{{ item.wares_title }}</div>
<div class="desc">{{ item.wares_info }}</div>
<div class="price">{{ item.wares_oldprice }}</div>
</van-col>
</van-row>
</div>
</div>
</template>
<script>
import swiper from '@c/swiper.vue'
export default {
name: 'Home',
data() {
return {
HomeList: [],
BannerList: [],//保存banner数据
hotArr: [
{ id: 1, title: '限时白嫖', icon: '/img/type_1.png' },
{ id: 2, title: '新品推荐', icon: '/img/type_2.png' },
{ id: 3, title: '低价高配', icon: '/img/type_3.png' },
{ id: 4, title: '超值特卖', icon: '/img/type_4.png' },
]
}
},
created() {
this.getHome();
this.getBanner()
},
methods: {
gosearch(){
this.$router.push({
name: 'search',
})
},/*跳转搜索页面*/
toInfo(item) {
console.log(item)
this.$router.push({
name: 'info',
query: {
id: item.wares_id
}
})
},
toActivity(item) {
this.$router.push({
name: 'activity',
query: {
id: item.id,
title:item.title
}
})
},
async getBanner() {
this.BannerList = await this.$http.index.banner();
console.log(this.BannerList)
},
async getHome() {
this.HomeList = await this.$http.index.home();
console.log(this.HomeList)
}
},
components: {
swiper
}
}
</script>
<style lang="less" scoped>
@import "~@page/Home.less";
</style>

View File

@@ -0,0 +1,193 @@
<template>
<div class="Info">
<div class="header" :style="{ background: `rgba(255,255,255,${opacity})` }"></div>
<van-icon @click="$router.back()" :class="isShowTabs ? 'back' : 'noback' " name="arrow-left" />
<van-icon @click="$router.push('/car')" :class="isShowTabs ? 'back' : 'noback' " name="shopping-cart-o"/>
<div class="tabs">
<van-tabs ref="tabs" :class="{ hidden: isShowTabs }" v-model="active" scrollspy sticky>
<van-tab>
<template #title>
商品
</template>
<div class="shop_title">
<swiper ref="vswiper" :data="info.wares_masterimg" :show-indicator="true">
<template v-slot:default="slot">
<img @click="showImagePreview(slot.index)" :src="slot.item" alt="">
</template>
</swiper>
<div class="info_content">
<div class="top">
<div class="title">{{ info.wares_title }}</div>
<div class="desc">{{ info.wares_info }}</div>
<div class="price">
{{info.wares_oldprice}}
<del>{{info.wares_nowprice}}</del>
</div>
</div>
<div class="norms">
<p class="status">已选</p>
<p class="conf">全网公开版碳纤黑6+128...</p>
<p class="right">
<span>x1</span>
<van-icon name="arrow" />
</p>
</div>
<div class="quality" @click="isShow = true">
<div class="left">
<div class="item_1">
<img src="/img/icon_1.png" alt="" />
<span>品质保障</span>
</div>
<div class="item_1">
<img src="/img/icon_1.png" alt="" />
<span>顺丰发货</span>
</div>
<div class="item_1">
<img src="/img/icon_1.png" alt="" />
<span >7天无理由退货</span>
</div>
</div>
<van-icon name="arrow" />
</div>
</div>
</div>
</van-tab>
<van-tab>
<template #title>
详情
</template>
<div class="shop_info">
<div v-for="(v,i) in info.wares_infoimg"
@click="showImage(i)"
:key="i">
<img :src="v" alt="">
</div>
</div>
</van-tab>
</van-tabs>
</div>
<van-goods-action>
<van-goods-action-icon icon="chat-o" text="收藏"/>
<van-goods-action-icon icon="cart-o" text="购物车" :badge=carList.length @click="$router.push('/car')"/>
<van-goods-action-button
type="warning"
:class="isAddCar ? 'noAddCar' : '' "
@click="isAddCar ? '' : addCar()"
text="加入购物车" />
<van-goods-action-button type="danger" text="立即购买" />
</van-goods-action>
<van-popup v-model="isShow" round position="bottom" :style="{ height: '60%' }" />
</div>
</template>
<script>
import swiper from '@c/swiper.vue'
import { ImagePreview } from 'vant';
import { mapGetters, mapActions } from 'vuex'
export default {
name: "Info",
data() {
return {
active: 0,
isShowTabs: true, // true 隐藏 false 显示
opacity: 0,
isShow: false,// 品质保证的弹出层控制
isAddCar: false, // 判断商品是否被添加购物车
info: {}
}
},
async created() {
if(this.carList.length == 0){
await this.getcarl()
}
console.log("数据",this.carList)
this.checkCar()
this.getInfo()
},
computed:{
...mapGetters({
carList:"GET_CARLIST",
})
},
mounted(){
window.addEventListener('scroll',this.handleScroll)
},
beforeRouteLeave(to, from, next) {
this.handleScroll = null;
next()
},
methods: {
...mapActions({
getcarl:"GET_CARLISTDATA"
}),
async checkCar() {
let res = await this.$http.car.checkCar({
waresid: this.$route.query.id
});
this.isAddCar = res.isAddCar
console.log(res)
},
async addCar() {
let res = await this.$http.car.addCar({
waresid: this.$route.query.id
});
await this.getcarl()
console.log(res)
this.$toast("添加成功")
this.isAddCar = true
},
showImage(index) {
ImagePreview({
images: this.info.wares_infoimg,
startPosition: index,
});
},
showImagePreview(index) {
ImagePreview({
images: this.info.wares_masterimg,
startPosition: index,
onChange: (index) => {
this.$refs.vswiper.$children[0].swipeTo(index)
}
});
},
async getInfo() {
this.info = await this.$http.index.info({
id: this.$route.query.id
});
console.log(this.info)
},
handleScroll() {
try {
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
this.opacity = scrollTop.toFixed() / 45;
if (this.opacity >= 0.5) {
this.isShowTabs = false;
this.$refs.tabs.resize();
} else {
this.isShowTabs = true
}
} catch (e) {
}
}
},
components: {
swiper
}
}
</script>
<style scoped lang="less">
@import "~@page/Info.less";
</style>

View File

@@ -0,0 +1,73 @@
<template>
<div class="Me">
<div class="hader">
<img src="img/me_settin_2.png" alt="" class="set">
<div class="user">
<img src="img/user_head.png" alt="">
<span>sadsadsa</span>
</div>
</div>
<div class="type">
<ul>
<li v-for="(v,i) in inorderdata" :key="i" @click="infoorderdata(i)">
<img :src="v.img" alt="">
<span>{{v.span}}</span>
</li>
</ul>
</div>
<div class="setting">
<ul>
<li>
<img src="img/me_address.png" alt="">
<span>收获地址</span>
</li>
<li>
<img src="img/me_like.png" alt="">
<span>我的收藏</span>
</li>
<li>
<img src="img/me_settin_2.png" alt="">
<span>我的设置</span>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "Me",
data() {
return {
inorderdata:[
{span:"全部订单",img: "img/me_1.png"},
{span:"待付款",img: "img/me_2.png"},
{span:"代发货",img: "img/me_3.png"},
{span:"待收货",img: "img/me_4.png"},
{span:"退款/售后",img: "img/me_5.png"},
]
}
},
created() {
},
methods: {
infoorderdata(item){
this.$router.push({
name: 'orderdata',
query: {
active: item,
}
})
}
},
components: {
}
}
</script>
<style scoped lang="less">
@import "~@page/Me.less";
</style>

View File

@@ -0,0 +1,97 @@
<template>
<div class="Search">
<div class="top">
<van-icon name="arrow-left" size="20px" @click="toback"/>
<van-search v-model="data" placeholder="请输入搜索关键词" @click="oncontent"/>
<span @click="todata">搜索</span>
</div>
<div class="content" v-if="content">
<div class="title1">热门搜索</div>
<ul>
<li v-for="(v,i) in itemdata" :key="i" @click="dataup(v)">
{{v.title}}
</li>
</ul>
</div>
<div class="title12" v-else-if="datasearc.length==0">
<van-icon name="bag-o" />
<span>暂无数据</span>
</div>
<div v-else>
<ul class="title">
<li v-for="(v,i) in datasearc" :key="i" @click="toinfo(v)">
<img :src="v.wares_masterimg[0]" alt="">
<div class="titlec">{{v.wares_title}}</div>
<div class="info">{{v.wares_info}}</div>
<div class="price">{{v.wares_oldprice}}</div>
</li>
</ul>
</div>
</div>
</template>
<script>
import { Toast } from 'vant'
export default {
name: "Search",
data() {
return {
data: '',/*输入框返回值*/
itemdata:[{title:"小米"},{title:"华为"},{title:"16t"},{title:"11Pro"},{title:"锤子"},{title:"三星"}],
datasearc: [],/*ajax数据*/
content:true,/*显示标签 t 为显示*/
}
},
created() {
},
methods: {
async getsearch() {
this.datasearc = await this.$http.Search.search(
{
keyword:this.data
}
);
console.log(this.datasearc)
},
todata(){
if(this.data){
this.getsearch()
}else {
Toast('请输入搜索内容');
this.datasearc=[]
}
this.content=false
},
toback(){
this.$router.go(-1)
},/*回退上一页*/
oncontent(){
this.content=true
},/*标签控制显示隐藏*/
toinfo(item){
console.log(item)
this.$router.push({
name: 'info',
query: {
id: item.wares_id
}
})
},
dataup(v){
this.data=v.title
this.todata()
},
},
components: {},
}
</script>
<style scoped lang="less">
@import "~@page/Search.less";
</style>

View File

@@ -0,0 +1,86 @@
<template>
<div class="Type">
<div class="top">
<div></div>
<span>分类</span>
<van-icon name="search" size="15px" color="#a2a2a2" @click="gosearch"/>
</div>
<van-tree-select class="type_list" height="100%" :items="items" :main-active-index.sync="active" @click-nav="getlistxioam()">
<template #content>
<content v-for="(v,i) in items" :key="i"><!--v是指每个items,循环遍历出来items,右边的每一个接口数据-->
<ul class="right_title" v-if="active==i"><!--当active等于右边的i下标的时候显示-->
<li v-for="(cont,item ) in v.content" :key="item" @click="toInfo(cont.wares_id)"><!--这个cont才是没个items里面contennt的数据-->
<img :src="cont.wares_masterimg" alt="">
<span>{{cont.wares_title}}</span>
</li>
</ul>
</content>
</template>
</van-tree-select>
</div>
</template>
<script>
export default {
name: "Type",
data() {
return {
active: 0,
items: [
{ text: '小米' ,content: []},
{ text: '魅族' ,content: []},
{ text: '华为' ,content: []},
{ text: 'iphone' ,content: []},
{ text: '三星' ,content: []},
{ text: '锤子' ,content: []},
{ text: '诺基亚' ,content: []}
],
listdataxiaomi:[]
}
},
created() {
this.getlistxioam()
},
methods: {
async getlistxioam() {
if(this.items[this.active].content.length==0){
let res = await this.$http.index.list({
typename:this.items[this.active].text
});
this.items[this.active].content=res
console.log(this.items[this.active].content)
}
},
toInfo(item) {
console.log(item)
this.$router.push({
name: 'info',
query: {
id: item
}
})
},/*跳转详情页面*/
gosearch(){
this.$router.push({
name: 'search',
})
},/*跳转搜索页面*/
},
components: {
}
}
</script>
<style scoped lang="less">
@import "~@page/Type.less";
.Type {
height: calc(100vh - 50px);
.van-tree-select__content {
flex: 4;
}
.van-tree-select__content{
margin-bottom: 50px;
}
}
</style>

View File

@@ -0,0 +1,145 @@
<template>
<div class="User">
<!--上边的圆-->
<div class="top_circular"></div>
<div class="right_circular">
<!--登录-->
<div class="login" v-if="status">
<div class="item">
<div class="icon">
<van-icon name="manager-o"/>
<span>用户名</span>
</div>
<input type="text" v-model="loginParams.name"/>
</div>
<div class="item">
<div class="icon">
<van-icon name="manager-o" />
<span>密码</span>
</div>
<input type="password" v-model="loginParams.pwd"/>
</div>
<div class="but login_but" @click="login">立即登录</div>
</div>
<!--注册-->
<div class="reg" v-else>
<div class="item">
<div class="icon">
<van-icon name="manager-o"/>
<span>手机号</span>
</div>
<input type="number" v-model="regParams.phone"/>
</div>
<div class="item">
<div class="icon">
<van-icon name="manager-o" />
<span>用户名</span>
</div>
<input type="text" v-model="regParams.name"/>
</div>
<div class="item">
<div class="icon">
<van-icon name="manager-o" />
<span>密码</span>
</div>
<input type="password" v-model="regParams.pwd"/>
</div>
<div class="but login_but" @click="Reg">立即注册</div>
</div>
</div>
<div class="bottom_circular">
<div class="one blue"></div>
<div class="two blue" @click="status = !status">{{ status ? '注册':'登录' }}</div>
<div class="three blue"></div>
</div>
</div>
</template>
<script>
export default {
name: "User",
data() {
return {
status: true, // true 显示登录false 显示注册
loginParams: {
name: '',
pwd: '',
},
regParams: {
name: '',
pwd: '',
phone: ''
}
}
},
created() {
},
methods: {
async login() {
console.log(this.loginParams)
if (this.loginParams.name.length == 0) {
this.$toast('用户名不能为空');
return false;
}
if (this.loginParams.pwd.length == 0) {
this.$toast('密码不能为空');
return false;
}
let res = await this.$http.user.login(this.loginParams);
localStorage.setItem("token", res.token)
this.$toast.success({
message: '登录成功!',
onClose: () => {
if (this.$route.query.hasOwnProperty("from")) {
this.$router.push({
path: this.$route.query.from
})
} else {
this.$router.back()
}
}
});
},
async Reg() {
if(!(/^1[34578]\d{9}$/.test(this.regParams.phone))){
this.$toast('手机号格式不对');
return false;
}
if (this.regParams.name.length == 0) {
this.$toast('用户名不能为空');
return false;
}
if (this.regParams.pwd.length == 0) {
this.$toast('密码不能为空');
return false;
}
let res = await this.$http.user.add(this.regParams);
this.$toast.success({
message: '注册成功!',
onClose: () => {
this.status = true
}
});
}
}
}
</script>
<style scoped lang="less">
@import "~@page/User.less";
</style>

View File

@@ -0,0 +1,27 @@
<template>
<div class="layout">
<router-view></router-view>
<tabbar></tabbar>
</div>
</template>
<script>
import tabbar from '@c/tabbar.vue'
export default {
name: "layout",
data() {
return {}
},
created() {
},
methods: {},
components: {
tabbar
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,126 @@
<template>
<div class="order">
<van-nav-bar
title="用户结算"
left-text=""
left-arrow
@click-left="$utils.back()"
/>
<van-radio-group v-model="radio">
<van-cell-group>
<van-cell v-for="(v,i) in payment" :title="v.title" clickable @click="radio = i" :key="i">
<template #right-icon>
<van-radio :name=i />
</template>
</van-cell>
</van-cell-group>
</van-radio-group>
<div class="opop"></div>
<div class="order-list">
<van-cell :value="v.wares_oldprice" v-for="(v,i) in getserOder" :key="i">
<template #title>
<img :src="v.wares_masterimg[0]" alt="">
<span>{{v.wares_title}}</span>
</template>
</van-cell>
</div>
<van-submit-bar :price="totalMoney" button-text="付款" @submit="openis">
<span>共计:{{getserOder.length}}件商品</span>
</van-submit-bar>
<van-popup v-model="isShowpay"
closeable
close-icon-position="top-left"
position="bottom"
:style="{ height: '60%' }">
<div class="vansad">
<div class="title">付款人</div>
<div class="price">
<span class="price_icon"></span>
<span class="price_num">{{totalMoney/100}}.00</span>
</div>
</div>
<van-cell title="单元格" is-link value="内容" />
<van-button type="info" block @click="submitcart">立即付款</van-button>
</van-popup>
</div>
</template>
<script>
import {mapGetters, mapActions, mapMutations} from 'vuex'
export default {
name: "order",
data() {
return {
payment: [
{title: "支付宝", img: ""},
{title: "小米钱包", img: ""},
{title: "微信支付", img: ""},
{title: "银联支付", img: ""},
{title: "翼支付", img: ""},
{title: "信用卡支付", img: ""}
],
radio: null,
isShowpay:false
}
},
created() {
console.log(this.getserOder)
},
computed: {
...mapGetters({
getserOder: "GET_ORDERLIST"
}),
totalMoney() {
var total = 0;
this.getserOder.forEach(vid => {
total += vid.car_num * vid.wares_oldprice
})
return total * 100
},
},
methods: {
async submitcart(){
var list=[]
this.getserOder.forEach(v=>{
list.push({
waresid: v.wares_id,
goodsnum:v.car_num,
goodsprice:v.wares_oldprice,
})
})
var res =await this.$http.car.submitCar(JSON.stringify({
carList:list
}))
var allorder=await this.$http.car.allOrder(
{status:0}
)
var buyOrder=await this.$http.car.buyOrder(
{goodsid:JSON.stringify(allorder.map(v=>v.goods_id))}
)
console.log(res)
this.$router.push({
name:"plaStetus"
})
},
openis(){
this.isShowpay=true
}
},
components: {},
}
</script>
<style scoped lang="less">
@import "~@page/order.less";
</style>

View File

@@ -0,0 +1,60 @@
<template>
<div class="orderdata">
<van-nav-bar
title="订单状态"
left-arrow
@click-left="$router.back()"
/>
<van-tabs v-model="active" @change="getOrder()">
<van-tab v-for="(v,i) in tabs" :title="v.title" :key="i">
<Care :list="tabs[active].content"></Care>
</van-tab>
</van-tabs>
</div>
</template>
<script>
import Care from "@/components/Care";
export default {
name: "orderdata",
data() {
return {
active:0,
tabs:[
{title:'全部订单',status:-1,content:[]},
{title:'待付款',status:0,content:[]},
{title:'待发货',status:1,content:[]},
{title:'待收货',status:2,content:[]},
{title:'退款/售后',status:3,content:[]},
]
}
},
created() {
this.active=this.$route.query.active==undefined
? 0
:Number(this.$route.query.active)
this.getOrder()
},
methods: {
async getOrder() {
if(this.tabs[this.active].content==0){
let res = await this.$http.car.allOrder({
status:this.tabs[this.active].status
})
this.tabs[this.active].content=res
console.log(res)
}
}
},
components: {
Care
},
}
</script>
<style scoped lang="less">
</style>

View File

@@ -0,0 +1,43 @@
<template>
<div class="play">
<van-icon name="success"/>
<span>恭喜支付成功</span>
<div class="butt">
<van-button plain type="primary" class="buttom_11" @click="$router.push({name:'home'})">回到首页</van-button>
<van-button plain type="info" @click="$router.push({name:'orderdata'})">查看订单</van-button>
</div>
</div>
</template>
<script>
export default {
name: "play",
data() {
return {}
},
created() {
},
methods: {},
components: {},
}
</script>
<style scoped lang="less">
.play {
display: flex;
align-items: center;
flex-direction: column;
height: 100vh;
justify-content: center;
}
.butt{
margin-top: 30px;
display: flex;
align-items: center;
}
.buttom_11{
margin-right: 20px;
}
</style>

View File

@@ -0,0 +1,41 @@
const path = require('path');
module.exports = {
publicPath: './',
productionSourceMap: false,
chainWebpack:(config)=>{
// 配置路径别名
config.resolve.alias
.set('@',resolve('./src'))
.set('@less',resolve('./src/assets/less'))
.set('@page',resolve('./src/assets/less/page'))
.set('@c',resolve('./src/components'))
// 配置全局css
const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)))
// 移除 prefetch 插件
config.plugins.delete('prefetch')
config.plugins.delete('preload')
}
}
function resolve(dir){
return path.join(__dirname,dir)
}
function addStyleResource (rule) {
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [
path.resolve(__dirname, './src/assets/less/_.less'),
],
})
}

View File

@@ -0,0 +1,13 @@
1:
点击进入活动页面
实现点击进入详情,详情页调用 /home/activity
别写
2:
搜索
3
分类
4我的 静态页面 别写