├── .browserslistrc
├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ ├── css
│ │ ├── base.css
│ │ └── normalize.css
│ └── img
│ │ ├── cart
│ │ └── tick.svg
│ │ ├── common
│ │ ├── arrow-left.svg
│ │ ├── back.svg
│ │ ├── collect.svg
│ │ ├── placeholder.png
│ │ └── top.png
│ │ ├── detail
│ │ ├── cart.png
│ │ └── detail_bottom.png
│ │ ├── home
│ │ └── recommend_bg.jpg
│ │ ├── profile
│ │ ├── avatar.svg
│ │ ├── cart.svg
│ │ ├── message.svg
│ │ ├── phone.svg
│ │ ├── pointer.svg
│ │ ├── shopping.svg
│ │ └── vip.svg
│ │ └── tabbar
│ │ ├── category.svg
│ │ ├── category_active.svg
│ │ ├── home.svg
│ │ ├── home_active.svg
│ │ ├── profile.svg
│ │ ├── profile_active.svg
│ │ ├── shopcart.svg
│ │ └── shopcart_active.svg
├── common
│ ├── const.js
│ ├── mixin.js
│ └── utils.js
├── components
│ ├── common
│ │ ├── backTop
│ │ │ └── BackTop.vue
│ │ ├── gridView
│ │ │ └── GridView.vue
│ │ ├── navbar
│ │ │ └── NavBar.vue
│ │ ├── scroll
│ │ │ └── Scroll.vue
│ │ ├── swiper
│ │ │ ├── Swiper.vue
│ │ │ ├── SwiperItem.vue
│ │ │ └── index.js
│ │ ├── tabbar
│ │ │ ├── TabBar.vue
│ │ │ └── TabBarItem.vue
│ │ └── totast
│ │ │ ├── Toast.vue
│ │ │ └── index.js
│ └── content
│ │ ├── goods
│ │ ├── GoodsList.vue
│ │ └── GoodsListItem.vue
│ │ ├── mainTabBar
│ │ └── MainTabBar.vue
│ │ └── tabControl
│ │ └── TabControl.vue
├── main.js
├── network
│ ├── category.js
│ ├── detail.js
│ ├── home.js
│ └── request.js
├── router
│ └── index.js
├── store
│ ├── actions.js
│ ├── getters.js
│ ├── index.js
│ ├── mutation-type.js
│ ├── mutations.js
│ └── state.js
├── views
│ ├── cart
│ │ ├── cart.vue
│ │ └── childComps
│ │ │ ├── CartBottonBar.vue
│ │ │ ├── CartList.vue
│ │ │ ├── CartListItem.vue
│ │ │ └── CheckButton.vue
│ ├── category
│ │ ├── category.vue
│ │ └── childComps
│ │ │ ├── TabContentCategory.vue
│ │ │ └── TabMenu.vue
│ ├── detail
│ │ ├── Detail.vue
│ │ └── childComps
│ │ │ ├── CartButton.vue
│ │ │ ├── DetailBaseInfo.vue
│ │ │ ├── DetailBottomBar.vue
│ │ │ ├── DetailCommentInfo.vue
│ │ │ ├── DetailGoodsInfo.vue
│ │ │ ├── DetailNavBar.vue
│ │ │ ├── DetailParamInfo.vue
│ │ │ ├── DetailShopInfo.vue
│ │ │ └── DetailSwiper.vue
│ ├── home
│ │ ├── childComps
│ │ │ ├── FeatureView.vue
│ │ │ ├── HomeSwiper.vue
│ │ │ └── RecommendView.vue
│ │ └── home.vue
│ └── profile
│ │ ├── childComps
│ │ ├── AccountInfo.vue
│ │ ├── NormalListView.vue
│ │ └── UserInfo.vue
│ │ └── profile.vue
└── vue.config.js
└── vue.config.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # supermall
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Customize configuration
19 | See [Configuration Reference](https://cli.vuejs.org/config/).
20 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "supermall",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "axios": "^0.18.0",
11 | "better-scroll": "^1.13.2",
12 | "core-js": "^3.6.5",
13 | "vue": "^2.6.11",
14 | "vue-router": "^3.0.1",
15 | "vuex": "^3.0.1"
16 | },
17 | "devDependencies": {
18 | "@vue/cli-plugin-babel": "~4.5.0",
19 | "@vue/cli-service": "~4.5.0",
20 | "vue-template-compiler": "^2.6.11"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiangfeidog/vue2_mall/1f6b512d0615584be7ddf5d9aa2ea4e00b2d5e73/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 购物小程序
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/src/assets/css/base.css:
--------------------------------------------------------------------------------
1 | @import "./normalize.css";
2 | :root {
3 | /* 定义变量 */
4 | --color-text: #666;
5 | --color-high-text: #ff5777;
6 | --color-tint: #ff8198;
7 | --color-background: #fff;
8 | --font-size: 14px;
9 | --line-height: 1.5;
10 | }
11 |
12 | *,
13 | *::before,
14 | *::after {
15 | margin: 0;
16 | padding: 0;
17 | box-sizing: border-box;
18 | }
19 |
20 | body {
21 | font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
22 | user-select: none;
23 | /* 禁止用户鼠标在页面上选中文字/图片等 */
24 | -webkit-tap-highlight-color: transparent;
25 | /* webkit是苹果浏览器引擎,tap点击,highlight背景高亮,color颜色,颜色用数值调节 */
26 | background: var(--color-background);
27 | color: var(--color-text);
28 | /* rem vw/vh */
29 | width: 100vw;
30 | }
31 |
32 | a {
33 | color: var(--color-text);
34 | text-decoration: none;
35 | }
36 |
37 | .clear-fix::after {
38 | clear: both;
39 | content: '';
40 | display: block;
41 | width: 0;
42 | height: 0;
43 | visibility: hidden;
44 | }
45 |
46 | .clear-fix {
47 | zoom: 1;
48 | }
49 |
50 | .left {
51 | float: left;
52 | }
53 |
54 | .right {
55 | float: right;
56 | }
--------------------------------------------------------------------------------
/src/assets/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 |
4 | /* Document
5 | ========================================================================== */
6 |
7 |
8 | /**
9 | * 1. Correct the line height in all browsers.
10 | * 2. Prevent adjustments of font size after orientation changes in iOS.
11 | */
12 |
13 | html {
14 | line-height: 1.15;
15 | /* 1 */
16 | -webkit-text-size-adjust: 100%;
17 | /* 2 */
18 | }
19 |
20 |
21 | /* Sections
22 | ========================================================================== */
23 |
24 |
25 | /**
26 | * Remove the margin in all browsers.
27 | */
28 |
29 | body {
30 | margin: 0;
31 | }
32 |
33 |
34 | /**
35 | * Render the `main` element consistently in IE.
36 | */
37 |
38 | main {
39 | display: block;
40 | }
41 |
42 |
43 | /**
44 | * Correct the font size and margin on `h1` elements within `section` and
45 | * `article` contexts in Chrome, Firefox, and Safari.
46 | */
47 |
48 | h1 {
49 | font-size: 2em;
50 | margin: 0.67em 0;
51 | }
52 |
53 |
54 | /* Grouping content
55 | ========================================================================== */
56 |
57 |
58 | /**
59 | * 1. Add the correct box sizing in Firefox.
60 | * 2. Show the overflow in Edge and IE.
61 | */
62 |
63 | hr {
64 | box-sizing: content-box;
65 | /* 1 */
66 | height: 0;
67 | /* 1 */
68 | overflow: visible;
69 | /* 2 */
70 | }
71 |
72 |
73 | /**
74 | * 1. Correct the inheritance and scaling of font size in all browsers.
75 | * 2. Correct the odd `em` font sizing in all browsers.
76 | */
77 |
78 | pre {
79 | font-family: monospace, monospace;
80 | /* 1 */
81 | font-size: 1em;
82 | /* 2 */
83 | }
84 |
85 |
86 | /* Text-level semantics
87 | ========================================================================== */
88 |
89 |
90 | /**
91 | * Remove the gray background on active links in IE 10.
92 | */
93 |
94 | a {
95 | background-color: transparent;
96 | }
97 |
98 |
99 | /**
100 | * 1. Remove the bottom border in Chrome 57-
101 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
102 | */
103 |
104 | abbr[title] {
105 | border-bottom: none;
106 | /* 1 */
107 | text-decoration: underline;
108 | /* 2 */
109 | text-decoration: underline dotted;
110 | /* 2 */
111 | }
112 |
113 |
114 | /**
115 | * Add the correct font weight in Chrome, Edge, and Safari.
116 | */
117 |
118 | b,
119 | strong {
120 | font-weight: bolder;
121 | }
122 |
123 |
124 | /**
125 | * 1. Correct the inheritance and scaling of font size in all browsers.
126 | * 2. Correct the odd `em` font sizing in all browsers.
127 | */
128 |
129 | code,
130 | kbd,
131 | samp {
132 | font-family: monospace, monospace;
133 | /* 1 */
134 | font-size: 1em;
135 | /* 2 */
136 | }
137 |
138 |
139 | /**
140 | * Add the correct font size in all browsers.
141 | */
142 |
143 | small {
144 | font-size: 80%;
145 | }
146 |
147 |
148 | /**
149 | * Prevent `sub` and `sup` elements from affecting the line height in
150 | * all browsers.
151 | */
152 |
153 | sub,
154 | sup {
155 | font-size: 75%;
156 | line-height: 0;
157 | position: relative;
158 | vertical-align: baseline;
159 | }
160 |
161 | sub {
162 | bottom: -0.25em;
163 | }
164 |
165 | sup {
166 | top: -0.5em;
167 | }
168 |
169 |
170 | /* Embedded content
171 | ========================================================================== */
172 |
173 |
174 | /**
175 | * Remove the border on images inside links in IE 10.
176 | */
177 |
178 | img {
179 | border-style: none;
180 | }
181 |
182 |
183 | /* Forms
184 | ========================================================================== */
185 |
186 |
187 | /**
188 | * 1. Change the font styles in all browsers.
189 | * 2. Remove the margin in Firefox and Safari.
190 | */
191 |
192 | button,
193 | input,
194 | optgroup,
195 | select,
196 | textarea {
197 | font-family: inherit;
198 | /* 1 */
199 | font-size: 100%;
200 | /* 1 */
201 | line-height: 1.15;
202 | /* 1 */
203 | margin: 0;
204 | /* 2 */
205 | }
206 |
207 |
208 | /**
209 | * Show the overflow in IE.
210 | * 1. Show the overflow in Edge.
211 | */
212 |
213 | button,
214 | input {
215 | /* 1 */
216 | overflow: visible;
217 | }
218 |
219 |
220 | /**
221 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
222 | * 1. Remove the inheritance of text transform in Firefox.
223 | */
224 |
225 | button,
226 | select {
227 | /* 1 */
228 | text-transform: none;
229 | }
230 |
231 |
232 | /**
233 | * Correct the inability to style clickable types in iOS and Safari.
234 | */
235 |
236 | button,
237 | [type="button"],
238 | [type="reset"],
239 | [type="submit"] {
240 | -webkit-appearance: button;
241 | }
242 |
243 |
244 | /**
245 | * Remove the inner border and padding in Firefox.
246 | */
247 |
248 | button::-moz-focus-inner,
249 | [type="button"]::-moz-focus-inner,
250 | [type="reset"]::-moz-focus-inner,
251 | [type="submit"]::-moz-focus-inner {
252 | border-style: none;
253 | padding: 0;
254 | }
255 |
256 |
257 | /**
258 | * Restore the focus styles unset by the previous rule.
259 | */
260 |
261 | button:-moz-focusring,
262 | [type="button"]:-moz-focusring,
263 | [type="reset"]:-moz-focusring,
264 | [type="submit"]:-moz-focusring {
265 | outline: 1px dotted ButtonText;
266 | }
267 |
268 |
269 | /**
270 | * Correct the padding in Firefox.
271 | */
272 |
273 | fieldset {
274 | padding: 0.35em 0.75em 0.625em;
275 | }
276 |
277 |
278 | /**
279 | * 1. Correct the text wrapping in Edge and IE.
280 | * 2. Correct the color inheritance from `fieldset` elements in IE.
281 | * 3. Remove the padding so developers are not caught out when they zero out
282 | * `fieldset` elements in all browsers.
283 | */
284 |
285 | legend {
286 | box-sizing: border-box;
287 | /* 1 */
288 | color: inherit;
289 | /* 2 */
290 | display: table;
291 | /* 1 */
292 | max-width: 100%;
293 | /* 1 */
294 | padding: 0;
295 | /* 3 */
296 | white-space: normal;
297 | /* 1 */
298 | }
299 |
300 |
301 | /**
302 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
303 | */
304 |
305 | progress {
306 | vertical-align: baseline;
307 | }
308 |
309 |
310 | /**
311 | * Remove the default vertical scrollbar in IE 10+.
312 | */
313 |
314 | textarea {
315 | overflow: auto;
316 | }
317 |
318 |
319 | /**
320 | * 1. Add the correct box sizing in IE 10.
321 | * 2. Remove the padding in IE 10.
322 | */
323 |
324 | [type="checkbox"],
325 | [type="radio"] {
326 | box-sizing: border-box;
327 | /* 1 */
328 | padding: 0;
329 | /* 2 */
330 | }
331 |
332 |
333 | /**
334 | * Correct the cursor style of increment and decrement buttons in Chrome.
335 | */
336 |
337 | [type="number"]::-webkit-inner-spin-button,
338 | [type="number"]::-webkit-outer-spin-button {
339 | height: auto;
340 | }
341 |
342 |
343 | /**
344 | * 1. Correct the odd appearance in Chrome and Safari.
345 | * 2. Correct the outline style in Safari.
346 | */
347 |
348 | [type="search"] {
349 | -webkit-appearance: textfield;
350 | /* 1 */
351 | outline-offset: -2px;
352 | /* 2 */
353 | }
354 |
355 |
356 | /**
357 | * Remove the inner padding in Chrome and Safari on macOS.
358 | */
359 |
360 | [type="search"]::-webkit-search-decoration {
361 | -webkit-appearance: none;
362 | }
363 |
364 |
365 | /**
366 | * 1. Correct the inability to style clickable types in iOS and Safari.
367 | * 2. Change font properties to `inherit` in Safari.
368 | */
369 |
370 | ::-webkit-file-upload-button {
371 | -webkit-appearance: button;
372 | /* 1 */
373 | font: inherit;
374 | /* 2 */
375 | }
376 |
377 |
378 | /* Interactive
379 | ========================================================================== */
380 |
381 |
382 | /*
383 | * Add the correct display in Edge, IE 10+, and Firefox.
384 | */
385 |
386 | details {
387 | display: block;
388 | }
389 |
390 |
391 | /*
392 | * Add the correct display in all browsers.
393 | */
394 |
395 | summary {
396 | display: list-item;
397 | }
398 |
399 |
400 | /* Misc
401 | ========================================================================== */
402 |
403 |
404 | /**
405 | * Add the correct display in IE 10+.
406 | */
407 |
408 | template {
409 | display: none;
410 | }
411 |
412 |
413 | /**
414 | * Add the correct display in IE 10.
415 | */
416 |
417 | [hidden] {
418 | display: none;
419 | }
--------------------------------------------------------------------------------
/src/assets/img/cart/tick.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/common/arrow-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/common/back.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/img/common/collect.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/common/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiangfeidog/vue2_mall/1f6b512d0615584be7ddf5d9aa2ea4e00b2d5e73/src/assets/img/common/placeholder.png
--------------------------------------------------------------------------------
/src/assets/img/common/top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiangfeidog/vue2_mall/1f6b512d0615584be7ddf5d9aa2ea4e00b2d5e73/src/assets/img/common/top.png
--------------------------------------------------------------------------------
/src/assets/img/detail/cart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiangfeidog/vue2_mall/1f6b512d0615584be7ddf5d9aa2ea4e00b2d5e73/src/assets/img/detail/cart.png
--------------------------------------------------------------------------------
/src/assets/img/detail/detail_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiangfeidog/vue2_mall/1f6b512d0615584be7ddf5d9aa2ea4e00b2d5e73/src/assets/img/detail/detail_bottom.png
--------------------------------------------------------------------------------
/src/assets/img/home/recommend_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiangfeidog/vue2_mall/1f6b512d0615584be7ddf5d9aa2ea4e00b2d5e73/src/assets/img/home/recommend_bg.jpg
--------------------------------------------------------------------------------
/src/assets/img/profile/avatar.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/profile/cart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/profile/message.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/profile/phone.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/profile/pointer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/profile/shopping.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/profile/vip.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/category.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
22 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/category_active.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
22 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/home.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
20 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/home_active.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
20 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/profile.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
20 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/profile_active.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
20 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/shopcart.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
19 |
--------------------------------------------------------------------------------
/src/assets/img/tabbar/shopcart_active.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
19 |
--------------------------------------------------------------------------------
/src/common/const.js:
--------------------------------------------------------------------------------
1 | export const TOP_DISTANCE = 1000
2 | export const POP = 'pop'
3 | export const NEW = 'new'
4 | export const SELL = 'sell'
--------------------------------------------------------------------------------
/src/common/mixin.js:
--------------------------------------------------------------------------------
1 | import BackTop from "@/components/common/backTop/BackTop"
2 | import { POP, NEW, SELL } from './const'
3 | export const backTopMxin = {
4 | components: {
5 | BackTop
6 | },
7 | data() {
8 | return {
9 | isShowTop: false
10 | }
11 | },
12 | methods: {
13 | backTopClick() {
14 | this.$refs.scroll.scroll.scrollTo(0, 0, 300)
15 | }
16 | }
17 | }
18 |
19 | export const tabControlMixin = {
20 | data: function() {
21 | return {
22 | currentType: POP
23 | }
24 | },
25 | methods: {
26 | tabClick(index) {
27 | switch (index) {
28 | case 0:
29 | this.currentType = POP
30 | break
31 | case 1:
32 | this.currentType = NEW
33 | break
34 | case 2:
35 | this.currentType = SELL
36 | break
37 | }
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/common/utils.js:
--------------------------------------------------------------------------------
1 | //防抖函数
2 | export function debounce(fun, delay) {
3 | let timer = null;
4 | return function(...args) {
5 | if (timer) clearTimeout(timer)
6 | timer = setTimeout(() => {
7 | fun.apply(this, args)
8 | }, delay)
9 | }
10 | }
11 | export function formatDate(date, fmt) {
12 | if (/(y+)/.test(fmt)) {
13 | fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
14 | }
15 | let o = {
16 | 'M+': date.getMonth() + 1,
17 | 'd+': date.getDate(),
18 | 'h+': date.getHours(),
19 | 'm+': date.getMinutes(),
20 | 's+': date.getSeconds()
21 | };
22 | for (let k in o) {
23 | if (new RegExp(`(${k})`).test(fmt)) {
24 | let str = o[k] + '';
25 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
26 | }
27 | }
28 | return fmt;
29 | };
30 |
31 | function padLeftZero(str) {
32 | return ('00' + str).substr(str.length);
33 | };
--------------------------------------------------------------------------------
/src/components/common/backTop/BackTop.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/src/components/common/gridView/GridView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
65 |
66 |
72 |
--------------------------------------------------------------------------------
/src/components/common/navbar/NavBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/src/components/common/scroll/Scroll.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
54 |
55 |
--------------------------------------------------------------------------------
/src/components/common/swiper/Swiper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
211 |
212 |
246 |
--------------------------------------------------------------------------------
/src/components/common/swiper/SwiperItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
23 |
--------------------------------------------------------------------------------
/src/components/common/swiper/index.js:
--------------------------------------------------------------------------------
1 | import Swiper from './Swiper'
2 | import SwiperItem from './SwiperItem'
3 |
4 | export {
5 | Swiper, SwiperItem
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/common/tabbar/TabBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
16 |
17 |
--------------------------------------------------------------------------------
/src/components/common/tabbar/TabBarItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
33 |
34 |
--------------------------------------------------------------------------------
/src/components/common/totast/Toast.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{message}}
4 |
5 |
6 |
7 |
18 |
19 |
--------------------------------------------------------------------------------
/src/components/common/totast/index.js:
--------------------------------------------------------------------------------
1 | import Toast from './Toast'
2 |
3 | const plugin = {}
4 |
5 | function removeDom(event) {
6 | if (event.target.parentNode) {
7 | event.target.parentNode.removeChild(event.target)
8 | }
9 | }
10 |
11 | plugin.install = (Vue) => {
12 | const ToastConstructor = Vue.extend(Toast)
13 |
14 | // 注意:这里不能用箭头函数
15 | ToastConstructor.prototype.close = function() {
16 | this.isShow = false
17 | this.$el.addEventListener('transitionend', removeDom)
18 | }
19 |
20 | Vue.prototype.$toast = (options = {}) => {
21 | // 1.将创建出来的组件,挂载到某个div中
22 | const toast = new ToastConstructor()
23 | toast.$mount(document.createElement('div'))
24 |
25 | // 2.将toast的$el添加到body中
26 | document.body.appendChild(toast.$el)
27 |
28 | // 3.获取用户自定义数据
29 | const duration = options.duration || 2500
30 | toast.message = options.message
31 | toast.isShow = true
32 |
33 | // 4.定时器让toast消失
34 | setTimeout(() => {
35 | toast.close()
36 | }, duration)
37 | }
38 | }
39 |
40 | export default plugin
--------------------------------------------------------------------------------
/src/components/content/goods/GoodsList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
24 |
25 |
--------------------------------------------------------------------------------
/src/components/content/goods/GoodsListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
{{goodsItem.title}}
6 |
{{goodsItem.price}}
7 |
{{goodsItem.cfav}}
8 |
9 |
10 |
11 |
12 |
39 |
40 |
--------------------------------------------------------------------------------
/src/components/content/mainTabBar/MainTabBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 首页
7 |
8 |
9 |
10 |
11 | 分类
12 |
13 |
14 |
15 |
16 | 购物车
17 |
18 |
19 |
20 |
21 | 我的
22 |
23 |
24 |
25 |
26 |
37 |
38 |
--------------------------------------------------------------------------------
/src/components/content/tabControl/TabControl.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
32 |
33 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import Totast from '@/components/common/totast/index.js'
6 | Vue.use(Totast)
7 | Vue.config.productionTip = false
8 | Vue.prototype.$bus = new Vue()
9 | new Vue({
10 | render: h => h(App),
11 | router,
12 | store
13 | }).$mount('#app')
--------------------------------------------------------------------------------
/src/network/category.js:
--------------------------------------------------------------------------------
1 | import { request } from './request'
2 |
3 |
4 | export function getCategory() {
5 | return request({
6 | url: '/category'
7 | })
8 | }
9 |
10 | export function getSubcategory(maitKey) {
11 | return request({
12 | url: '/subcategory',
13 | params: {
14 | maitKey
15 | }
16 | })
17 | }
18 |
19 | export function getCategoryDetail(miniWallkey, type) {
20 | return request({
21 | url: '/subcategory/detail',
22 | params: {
23 | miniWallkey,
24 | type
25 | }
26 | })
27 | }
--------------------------------------------------------------------------------
/src/network/detail.js:
--------------------------------------------------------------------------------
1 | import { request } from "./request";
2 |
3 | export function getDetail(iid) {
4 | return request({
5 | url: '/detail',
6 | params: {
7 | iid
8 | }
9 | })
10 | }
11 | export function getRecommend() {
12 | return request({
13 | url: '/recommend'
14 | })
15 | }
16 | export class Goods {
17 | constructor(itemInfo, columns, services) {
18 | this.title = itemInfo.title
19 | this.desc = itemInfo.desc
20 | this.newPrice = itemInfo.price
21 | this.oldPrice = itemInfo.oldPrice
22 | this.discount = itemInfo.discountDesc
23 | this.columns = columns
24 | this.services = services
25 | this.realPrice = itemInfo.lowNowPrice
26 | }
27 | }
28 | export class Shop {
29 | constructor(shopInfo) {
30 | this.logo = shopInfo.shopLogo;
31 | this.name = shopInfo.name;
32 | this.fans = shopInfo.cFans;
33 | this.sells = shopInfo.cSells;
34 | this.score = shopInfo.score;
35 | this.goodsCount = shopInfo.cGoods
36 | }
37 | }
38 | export class GoodsParam {
39 | constructor(info, rule) {
40 | // 注: images可能没有值(某些商品有值, 某些没有值)
41 | this.image = info.images ? info.images[0] : '';
42 | this.infos = info.set;
43 | this.sizes = rule.tables;
44 | }
45 | }
--------------------------------------------------------------------------------
/src/network/home.js:
--------------------------------------------------------------------------------
1 | import { request } from "./request";
2 | export function getHomeMultidata() {
3 | return request({
4 | url: '/home/multidata'
5 | })
6 | }
7 | export function getHomeGoods(type, page) {
8 | return request({
9 | url: '/home/data',
10 | params: {
11 | type,
12 | page
13 | }
14 | })
15 | }
--------------------------------------------------------------------------------
/src/network/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 |
3 | export function request(config) {
4 | // 1.创建axios的实例
5 | const instance = axios.create({
6 | baseURL: 'http://152.136.185.210:7878/api/m5',
7 | timeout: 5000
8 | })
9 |
10 | // 2.axios的拦截器
11 | // 2.1.请求拦截的作用
12 | instance.interceptors.request.use(config => {
13 | return config
14 | }, err => {
15 | // console.log(err);
16 | })
17 |
18 | // 2.2.响应拦截
19 | instance.interceptors.response.use(res => {
20 | return res.data
21 | }, err => {
22 | console.log(err);
23 | })
24 |
25 | // 3.发送真正的网络请求
26 | return instance(config)
27 | }
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 |
4 | Vue.use(Router)
5 | import Home from '../views/home/home.vue'
6 | import Category from '../views/category/category.vue'
7 | import Cart from '../views/cart/cart.vue'
8 | import Profile from '../views/profile/profile.vue'
9 | import Detail from '../views/detail/Detail'
10 | // 解决ElementUI导航栏中的vue-router在3.0版本以上重复点菜单报错问题
11 | // const originalPush = Router.prototype.push
12 | // Router.prototype.push = function push(location) {
13 | // return originalPush.call(this, location).catch(err => err)
14 | // }
15 |
16 | export default new Router({
17 | mode: 'hash',
18 | routes: [
19 | {
20 | path: '/',
21 | redirect: '/home',
22 | },
23 | {
24 | path: '/home',
25 | component: Home,
26 | },
27 | {
28 | path: '/category',
29 | component: Category,
30 | },
31 | {
32 | path: '/cart',
33 | component: Cart,
34 | },
35 | {
36 | path: '/profile',
37 | component: Profile,
38 | },
39 | {
40 | path: '/detail/:id',
41 | component: Detail,
42 | },
43 | ],
44 | })
45 |
--------------------------------------------------------------------------------
/src/store/actions.js:
--------------------------------------------------------------------------------
1 | import {
2 | ADD_COUNTER,
3 | ADD_TO_CART
4 | } from './mutation-type'
5 | export default {
6 | addCart(context, payload) {
7 | return new Promise((resolve, reject) => {
8 | // debugger;
9 | // 查看之前的cartlist中是否已经存在该商品
10 | let oldProduct = context.state.cartList.find(item =>
11 | item.iid === payload.iid
12 | )
13 | if (oldProduct) {
14 | // oldProduct.count++;
15 | context.commit(ADD_COUNTER, oldProduct)
16 | resolve('当前商品+1')
17 | } else {
18 | payload.count = 1
19 | // context.state.cartList.push(payload)
20 | context.commit(ADD_TO_CART, payload)
21 | resolve('添加了新商品')
22 | }
23 | })
24 | }
25 | }
--------------------------------------------------------------------------------
/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export default {
2 | getCartListLength(state) {
3 | return state.cartList.length
4 | },
5 | getCartList(state) {
6 | return state.cartList
7 | }
8 | }
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import actions from "./actions"
4 | import mutations from "./mutations"
5 | import state from "./state"
6 | import getters from "./getters"
7 | //安装插件
8 | Vue.use(Vuex)
9 | //创建store实例
10 | const store = new Vuex.Store({
11 | state,
12 | mutations,
13 | actions,
14 | getters
15 | })
16 | //挂载到Vue实例上
17 | export default store
--------------------------------------------------------------------------------
/src/store/mutation-type.js:
--------------------------------------------------------------------------------
1 | export const ADD_COUNTER = 'add_counter'
2 | export const ADD_TO_CART = 'add_to_cart'
--------------------------------------------------------------------------------
/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | import {
2 | ADD_COUNTER,
3 | ADD_TO_CART
4 | } from './mutation-type'
5 | export default {
6 | [ADD_COUNTER](state, payload) {
7 | payload.count++
8 | },
9 | [ADD_TO_CART](state, payload) {
10 | payload.checked = true
11 | state.cartList.push(payload)
12 | }
13 | }
--------------------------------------------------------------------------------
/src/store/state.js:
--------------------------------------------------------------------------------
1 | export default {
2 | cartList: [],
3 | isShow:false
4 | }
--------------------------------------------------------------------------------
/src/views/cart/cart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 购物车({{length}})
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
36 |
37 |
--------------------------------------------------------------------------------
/src/views/cart/childComps/CartBottonBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
71 |
72 |
111 |
--------------------------------------------------------------------------------
/src/views/cart/childComps/CartList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
21 |
22 |
--------------------------------------------------------------------------------
/src/views/cart/childComps/CartListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
![商品图片]()
8 |
9 |
10 |
{{itemInfo.title}}
11 |
{{itemInfo.desc}}
12 |
13 |
¥{{itemInfo.price}}
14 |
x{{itemInfo.count}}
15 |
16 |
17 |
18 |
19 |
20 |
50 |
51 |
--------------------------------------------------------------------------------
/src/views/cart/childComps/CheckButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
17 |
18 |
--------------------------------------------------------------------------------
/src/views/category/category.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 商品分类
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
124 |
125 |
--------------------------------------------------------------------------------
/src/views/category/childComps/TabContentCategory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
{{item.title}}
7 |
8 |
9 |
10 |
11 |
12 |
30 |
31 |
49 |
--------------------------------------------------------------------------------
/src/views/category/childComps/TabMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 |
16 |
17 |
44 |
45 |
--------------------------------------------------------------------------------
/src/views/detail/Detail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
131 |
132 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/CartButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailBaseInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{goods.title}}
4 |
5 | {{goods.newPrice}}
6 | {{goods.oldPrice}}
7 | {{goods.discount}}
8 |
9 |
10 | {{goods.columns[0]}}
11 | {{goods.columns[1]}}
12 | {{goods.services[goods.services.length-1].name}}
13 |
14 |
15 |
16 |
17 | {{goods.services[index-1].name}}
18 |
19 |
20 |
21 |
22 |
23 |
35 |
36 |
103 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailBottomBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 客服
7 |
8 |
9 |
10 | 店铺
11 |
12 |
13 |
14 | 收藏
15 |
16 |
17 |
21 |
22 |
23 |
24 |
33 |
34 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailCommentInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
25 |
26 |
27 |
46 |
47 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailGoodsInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{detailInfo.desc}}
7 |
8 |
9 |
{{detailInfo.detailImage[0].key}}
10 |
11 |
![图片故障]()
12 |
13 |
14 |
15 |
16 |
47 |
48 |
101 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailNavBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |

6 |
7 |
10 |
11 |
12 |
13 |
14 |
37 |
38 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailParamInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 | {{info.key}} |
12 | {{info.value}} |
13 |
14 |
15 |
16 |
![]()
17 |
18 |
19 |
20 |
21 |
31 |
32 |
69 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailShopInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
{{shop.name}}
6 |
7 |
8 |
9 |
10 |
11 | {{shop.sells | sellCountFilter}}
12 |
13 |
总销量
14 |
15 |
16 |
17 | {{shop.goodsCount}}
18 |
19 |
全部宝贝
20 |
21 |
22 |
23 |
24 |
25 | {{item.name}} |
26 | {{item.score}} |
27 | {{item.isBetter ? '高':'低'}} |
28 |
29 |
30 |
31 |
32 |
35 |
36 |
37 |
38 |
58 |
59 |
159 |
--------------------------------------------------------------------------------
/src/views/detail/childComps/DetailSwiper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
28 |
29 |
--------------------------------------------------------------------------------
/src/views/home/childComps/FeatureView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/src/views/home/childComps/HomeSwiper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
39 |
40 |
--------------------------------------------------------------------------------
/src/views/home/childComps/RecommendView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
{{item.title}}
6 |
7 |
8 |
9 |
10 |
25 |
26 |
--------------------------------------------------------------------------------
/src/views/home/home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
购物街
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
141 |
142 |
--------------------------------------------------------------------------------
/src/views/profile/childComps/AccountInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 0.00元
6 |
7 |
我的余额
8 |
9 |
10 |
11 | 0个
12 |
13 |
我的优惠
14 |
15 |
16 |
17 | 0分
18 |
19 |
我的积分
20 |
21 |
22 |
23 |
24 |
29 |
30 |
--------------------------------------------------------------------------------
/src/views/profile/childComps/NormalListView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
{{item.info}}
8 |
9 |
10 |
11 |
12 |
30 |
31 |
--------------------------------------------------------------------------------
/src/views/profile/childComps/UserInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
登录/注册
6 |
7 |

8 |
暂无绑定手机号
9 |
10 |
11 |
12 |

13 |
14 |
15 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/src/views/profile/profile.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 我的档案
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
42 |
43 |
--------------------------------------------------------------------------------
/src/vue.config.js:
--------------------------------------------------------------------------------
1 | // module.exports = {
2 | // configureWebpack: {
3 | // resolve: {
4 | // alias: {
5 | // assets: "@/assets",
6 | // common: "@/common",
7 | // components:"@/components",
8 | // network: "@/network",
9 | // views: "@/views"
10 | // }
11 | // }
12 | // }
13 | // };
14 | // 用来配置文件的别名,方便路径的寻找
15 | // const path = require('path'); //引入path模块
16 | // function resolve(dir) {
17 | // return path.join(__dirname, dir) //path.join(__dirname)设置绝对路径
18 | // }
19 |
20 | // module.exports = {
21 | // chainWebpack: (config) => {
22 | // config.resolve.alias
23 | // //set第一个参数:设置的别名,第二个参数:设置的路径
24 | // .set('@', resolve('./src')) //根据目录的层级来决定,也可以自行设
25 | // .set('components', resolve('./src/components'))
26 | // .set('views', resolve('./src/views'))
27 | // .set('assets', resolve('./src/assets'))
28 | // }
29 | // }
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | publicPath: './',
3 | }
4 |
--------------------------------------------------------------------------------
{{commentInfo.content}}
16 |