@ -0,0 +1,9 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
Before Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 2.7 KiB |
@ -1,28 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<img alt="Vue logo" src="./assets/logo.png">
|
<keep-alive exclude="Detail">
|
||||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
<router-view/>
|
||||||
|
</keep-alive>
|
||||||
|
<MainTabBar/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HelloWorld from './components/HelloWorld.vue'
|
import MainTabBar from "components/content/mainTabbar/MainTabBar";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
HelloWorld
|
MainTabBar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#app {
|
@import "./assets/css/base.css";
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
text-align: center;
|
|
||||||
color: #2c3e50;
|
|
||||||
margin-top: 60px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -0,0 +1,341 @@
|
|||||||
|
/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */
|
||||||
|
|
||||||
|
/* Document
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the line height in all browsers.
|
||||||
|
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the margin in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the gray background on active links in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Remove the bottom border in Chrome 57-
|
||||||
|
* 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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Change the font styles in all browsers.
|
||||||
|
* 2. Remove the margin in Firefox and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: inherit; /* 1 */
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
margin: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type="button"],
|
||||||
|
[type="reset"],
|
||||||
|
[type="submit"] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the padding in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
padding: 0.35em 0.75em 0.625em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the default vertical scrollbar in IE 10+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 in Chrome and Safari on macOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="search"]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interactive
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
details {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Misc
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
After Width: | Height: | Size: 410 B |
After Width: | Height: | Size: 566 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 881 B |
After Width: | Height: | Size: 881 B |
After Width: | Height: | Size: 902 B |
After Width: | Height: | Size: 902 B |
After Width: | Height: | Size: 937 B |
After Width: | Height: | Size: 937 B |
After Width: | Height: | Size: 924 B |
After Width: | Height: | Size: 924 B |
Before Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,38 @@
|
|||||||
|
import {debounce} from "@/common/utils";
|
||||||
|
|
||||||
|
export const itemListenerMixin={
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
itemImgListener:null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted(){
|
||||||
|
const refresh = debounce(this.$refs.scroll.refresh,500)
|
||||||
|
|
||||||
|
this.itemImgListener=()=>{
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$bus.$on('itemImgLoad',this.itemImgListener)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const backTopMixin={
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
isShowBackTop:false,
|
||||||
|
tabOffsetTop:0,
|
||||||
|
isTabFixed:false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
backClick(){
|
||||||
|
this.$refs.scroll.scrollTo(0,0)
|
||||||
|
},
|
||||||
|
contentScoll(position){
|
||||||
|
this.isShowBackTop=(-position.y)>1000
|
||||||
|
this.isTabFixed=(-position.y)>this.tabOffsetTop
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
export function debounce(func,delay){
|
||||||
|
let timer=null
|
||||||
|
//...args多个参数 delay是延迟执行 但timer已经赋值 再次传入timer清空
|
||||||
|
return function (...args){
|
||||||
|
if(timer) clearTimeout(timer)
|
||||||
|
|
||||||
|
timer=setTimeout(()=>{
|
||||||
|
func.apply(this,args)
|
||||||
|
},delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatDate(date, fmt) {
|
||||||
|
if (/(y+)/.test(fmt)) {
|
||||||
|
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
|
||||||
|
}
|
||||||
|
let o = {
|
||||||
|
'M+': date.getMonth() + 1,
|
||||||
|
'd+': date.getDate(),
|
||||||
|
'h+': date.getHours(),
|
||||||
|
'm+': date.getMinutes(),
|
||||||
|
's+': date.getSeconds()
|
||||||
|
};
|
||||||
|
for (let k in o) {
|
||||||
|
if (new RegExp(`(${k})`).test(fmt)) {
|
||||||
|
let str = o[k] + '';
|
||||||
|
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function padLeftZero (str) {
|
||||||
|
return ('00' + str).substr(str.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hello">
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
<p>
|
|
||||||
For a guide and recipes on how to configure / customize this project,<br>
|
|
||||||
check out the
|
|
||||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
|
||||||
</p>
|
|
||||||
<h3>Installed CLI Plugins</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Essential Links</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
|
||||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
|
||||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
|
||||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
|
||||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Ecosystem</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
|
||||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
|
||||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'HelloWorld',
|
|
||||||
props: {
|
|
||||||
msg: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
h3 {
|
|
||||||
margin: 40px 0 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<div class="wrapper" ref="wrapper">
|
||||||
|
<div class="content">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BScroll from 'better-scroll'
|
||||||
|
export default {
|
||||||
|
name: "Scroll",
|
||||||
|
props:{
|
||||||
|
probeType:{
|
||||||
|
type:Number,
|
||||||
|
default:0
|
||||||
|
},
|
||||||
|
pullUpLoad:{
|
||||||
|
type:Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
scroll:null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.scroll=new BScroll(this.$refs.wrapper,{
|
||||||
|
click:true,
|
||||||
|
probeType:this.probeType,
|
||||||
|
pullUpLoad: this.pullUpLoad
|
||||||
|
})
|
||||||
|
this.scroll.on('scroll',(position)=>{
|
||||||
|
this.$emit('scroll',position)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.scroll.on('pullingUp',()=>{
|
||||||
|
this.$emit('pullingUp')
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.scroll.scrollTo(0,0)
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
scrollTo(x,y,time=3000){
|
||||||
|
this.scroll && this.scroll.scrollTo(x,y,time)
|
||||||
|
},
|
||||||
|
finishPullUp(){
|
||||||
|
this.scroll && this.scroll.finishPullUp()
|
||||||
|
},
|
||||||
|
refresh(){
|
||||||
|
this.scroll && this.scroll.refresh()
|
||||||
|
},
|
||||||
|
getScrolly(){
|
||||||
|
return this.scroll ? this.scroll.y : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<div class="nav-bar">
|
||||||
|
<div class="left"><slot name="left"></slot></div>
|
||||||
|
<div class="center"><slot name="center"></slot></div>
|
||||||
|
<div class="right"><slot name="right"></slot></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "NavBar"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.nav-bar{
|
||||||
|
display: flex;
|
||||||
|
line-height: 44px;
|
||||||
|
height: 44px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 1px 1px rgba(100,100,100,.1);
|
||||||
|
}
|
||||||
|
.left,.right{
|
||||||
|
width:60px;
|
||||||
|
}
|
||||||
|
.center{
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,371 @@
|
|||||||
|
<template>
|
||||||
|
<div id="hy-swiper">
|
||||||
|
<div class="swiper" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
<slot name="indicator">
|
||||||
|
</slot>
|
||||||
|
<div class="indicator">
|
||||||
|
<slot name="indicator" v-if="showIndicator && slideCount>1">
|
||||||
|
<div v-for="(item, index) in slideCount" class="indi-item" :class="{active: index === currentIndex-1}" :key="index"></div>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Swiper",
|
||||||
|
props: {
|
||||||
|
interval: {
|
||||||
|
type: Number,
|
||||||
|
default: 3000
|
||||||
|
},
|
||||||
|
animDuration: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
moveRatio: {
|
||||||
|
type: Number,
|
||||||
|
default: 0.25
|
||||||
|
},
|
||||||
|
showIndicator: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
slideCount: 0, // 元素个数
|
||||||
|
totalWidth: 0, // swiper的宽度
|
||||||
|
swiperStyle: {}, // swiper样式
|
||||||
|
currentIndex: 1, // 当前的index
|
||||||
|
scrolling: false, // 是否正在滚动
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
// 1.操作DOM, 在前后添加Slide
|
||||||
|
setTimeout(() => {
|
||||||
|
this.handleDom();
|
||||||
|
// 2.开启定时器
|
||||||
|
this.startTimer();
|
||||||
|
}, 500)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 定时器操作
|
||||||
|
*/
|
||||||
|
startTimer: function () {
|
||||||
|
this.playTimer = window.setInterval(() => {
|
||||||
|
this.currentIndex++;
|
||||||
|
this.scrollContent(-this.currentIndex * this.totalWidth);
|
||||||
|
}, this.interval)
|
||||||
|
},
|
||||||
|
stopTimer: function () {
|
||||||
|
window.clearInterval(this.playTimer);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滚动到正确的位置
|
||||||
|
*/
|
||||||
|
scrollContent: function (currentPosition) {
|
||||||
|
// 0.设置正在滚动
|
||||||
|
this.scrolling = true;
|
||||||
|
|
||||||
|
// 1.开始滚动动画
|
||||||
|
this.swiperStyle.transition ='transform '+ this.animDuration + 'ms';
|
||||||
|
this.setTransform(currentPosition);
|
||||||
|
|
||||||
|
// 2.判断滚动到的位置
|
||||||
|
this.checkPosition();
|
||||||
|
|
||||||
|
// 4.滚动完成
|
||||||
|
this.scrolling = false
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验正确的位置
|
||||||
|
*/
|
||||||
|
checkPosition: function () {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
// 1.校验正确的位置
|
||||||
|
this.swiperStyle.transition = '0ms';
|
||||||
|
if (this.currentIndex >= this.slideCount + 1) {
|
||||||
|
this.currentIndex = 1;
|
||||||
|
this.setTransform(-this.currentIndex * this.totalWidth);
|
||||||
|
} else if (this.currentIndex <= 0) {
|
||||||
|
this.currentIndex = this.slideCount;
|
||||||
|
this.setTransform(-this.currentIndex * this.totalWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.结束移动后的回调
|
||||||
|
this.$emit('transitionEnd', this.currentIndex-1);
|
||||||
|
}, this.animDuration)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置滚动的位置
|
||||||
|
*/
|
||||||
|
setTransform: function (position) {
|
||||||
|
this.swiperStyle.transform = `translate3d(${position}px, 0, 0)`;
|
||||||
|
this.swiperStyle['-webkit-transform'] = `translate3d(${position}px), 0, 0`;
|
||||||
|
this.swiperStyle['-ms-transform'] = `translate3d(${position}px), 0, 0`;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作DOM, 在DOM前后添加Slide
|
||||||
|
*/
|
||||||
|
handleDom: function () {
|
||||||
|
// 1.获取要操作的元素
|
||||||
|
let swiperEl = document.querySelector('.swiper');
|
||||||
|
let slidesEls = swiperEl.getElementsByClassName('slide');
|
||||||
|
// 2.保存个数
|
||||||
|
this.slideCount = slidesEls.length;
|
||||||
|
|
||||||
|
// 3.如果大于1个, 那么在前后分别添加一个slide
|
||||||
|
if (this.slideCount > 1) {
|
||||||
|
let cloneFirst = slidesEls[0].cloneNode(true);
|
||||||
|
let cloneLast = slidesEls[this.slideCount - 1].cloneNode(true);
|
||||||
|
swiperEl.insertBefore(cloneLast, slidesEls[0]);
|
||||||
|
swiperEl.appendChild(cloneFirst);
|
||||||
|
this.totalWidth = swiperEl.offsetWidth;
|
||||||
|
this.swiperStyle = swiperEl.style;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.让swiper元素, 显示第一个(目前是显示前面添加的最后一个元素)
|
||||||
|
this.setTransform(-this.totalWidth);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拖动事件的处理
|
||||||
|
*/
|
||||||
|
touchStart: function (e) {
|
||||||
|
// 1.如果正在滚动, 不可以拖动
|
||||||
|
if (this.scrolling) return;
|
||||||
|
|
||||||
|
// 2.停止定时器
|
||||||
|
this.stopTimer();
|
||||||
|
|
||||||
|
// 3.保存开始滚动的位置
|
||||||
|
this.startX = e.touches[0].pageX;
|
||||||
|
},
|
||||||
|
|
||||||
|
touchMove: function (e) {
|
||||||
|
// 1.计算出用户拖动的距离
|
||||||
|
this.currentX = e.touches[0].pageX;
|
||||||
|
this.distance = this.currentX - this.startX;
|
||||||
|
let currentPosition = -this.currentIndex * this.totalWidth;
|
||||||
|
let moveDistance = this.distance + currentPosition;
|
||||||
|
|
||||||
|
// 2.设置当前的位置
|
||||||
|
this.setTransform(moveDistance);
|
||||||
|
},
|
||||||
|
|
||||||
|
touchEnd: function (e) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 1.获取移动的距离
|
||||||
|
let currentMove = Math.abs(this.distance);
|
||||||
|
|
||||||
|
// 2.判断最终的距离
|
||||||
|
if (this.distance === 0) {
|
||||||
|
return
|
||||||
|
} else if (this.distance > 0 && currentMove > this.totalWidth * this.moveRatio) { // 右边移动超过0.5
|
||||||
|
this.currentIndex--
|
||||||
|
} else if (this.distance < 0 && currentMove > this.totalWidth * this.moveRatio) { // 向左移动超过0.5
|
||||||
|
this.currentIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.移动到正确的位置
|
||||||
|
this.scrollContent(-this.currentIndex * this.totalWidth);
|
||||||
|
|
||||||
|
// 4.移动完成后重新开启定时器
|
||||||
|
this.startTimer();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制上一个, 下一个
|
||||||
|
*/
|
||||||
|
previous: function () {
|
||||||
|
this.changeItem(-1);
|
||||||
|
},
|
||||||
|
|
||||||
|
next: function () {
|
||||||
|
this.changeItem(1);
|
||||||
|
},
|
||||||
|
|
||||||
|
changeItem: function (num) {
|
||||||
|
// 1.移除定时器
|
||||||
|
this.stopTimer();
|
||||||
|
|
||||||
|
// 2.修改index和位置
|
||||||
|
this.currentIndex += num;
|
||||||
|
this.scrollContent(-this.currentIndex * this.totalWidth);
|
||||||
|
|
||||||
|
// 3.添加定时器
|
||||||
|
this.startTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
#hy-swiper {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indicator {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indi-item {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #fff;
|
||||||
|
line-height: 8px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indi-item.active {
|
||||||
|
background-color: rgba(212,62,46,1.0);
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div class="slide">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Slide"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.slide {
|
||||||
|
width: 100%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,6 @@
|
|||||||
|
import Swiper from './Swiper'
|
||||||
|
import SwiperItem from './SwiperItem'
|
||||||
|
|
||||||
|
export {
|
||||||
|
Swiper, SwiperItem
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<template>
|
||||||
|
<div id="tab-bar">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TabBar"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
#tab-bar{
|
||||||
|
display: flex;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom:0;
|
||||||
|
box-shadow: 0 -3px 1px rgba(100,100,100,.1);
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tab-bar-item" @click="itemClick">
|
||||||
|
<div v-if="!isActive"><slot name="item-icon"></slot></div>
|
||||||
|
<div v-else><slot name="item-icon-active"></slot></div>
|
||||||
|
<div :style="activeStyle"><slot name="item-text"></slot></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TabBarItem",
|
||||||
|
props:{
|
||||||
|
path:String,
|
||||||
|
activeColor:{
|
||||||
|
type:String,
|
||||||
|
default:'red'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
// isActive:true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
isActive(){
|
||||||
|
return this.$route.path.indexOf(this.path)!==-1
|
||||||
|
},
|
||||||
|
activeStyle(){
|
||||||
|
return this.isActive ? {color:this.activeColor} : {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
itemClick(){
|
||||||
|
this.$router.replace(this.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.tab-bar-item{
|
||||||
|
flex:1;
|
||||||
|
text-align: center;
|
||||||
|
height: 49px;
|
||||||
|
}
|
||||||
|
.tab-bar-item img{
|
||||||
|
width:24px;
|
||||||
|
height:24px;
|
||||||
|
margin-top: 3px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<div class="back-Top" >
|
||||||
|
<img src="@/assets/img/common/top.png" alt="">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "backTop",
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.back-Top{
|
||||||
|
position: fixed;
|
||||||
|
right: 8px;
|
||||||
|
bottom: 55px;
|
||||||
|
}
|
||||||
|
.back-Top img{
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<div class="goods">
|
||||||
|
<GoodsListItem v-for="(item, index) in goods" :key="index" :goodsItem="item"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import GoodsListItem from "@/components/content/goods/GoodsListItem";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "GoodsList",
|
||||||
|
components:{
|
||||||
|
GoodsListItem
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
goods:{
|
||||||
|
type:Array,
|
||||||
|
default(){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.goods{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<div class="goods-items" @click="itemClick">
|
||||||
|
<img :src="showImage" alt="" @load="imageLoad">
|
||||||
|
<div class="goods-info">
|
||||||
|
<p>{{goodsItem.title}}</p>
|
||||||
|
<span class="price">{{goodsItem.price}}</span>
|
||||||
|
<span class="collect">{{goodsItem.cfav}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "GoodsListItem",
|
||||||
|
props:{
|
||||||
|
goodsItem:{
|
||||||
|
type:Object,
|
||||||
|
default(){
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
imageLoad(){
|
||||||
|
this.$bus.$emit('itemImageLoad')
|
||||||
|
},
|
||||||
|
itemClick(){
|
||||||
|
this.$router.push('/detail/'+this.goodsItem.iid)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
showImage(){
|
||||||
|
return this.goodsItem.image || this.goodsItem.show.img
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.goods-items {
|
||||||
|
padding-bottom: 40px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width:48%;
|
||||||
|
}
|
||||||
|
.goods-items img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-info {
|
||||||
|
font-size: 12px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-info p {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-info .price {
|
||||||
|
color: var(--color-high-text);
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-info .collect {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods-info .collect::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: -15px;
|
||||||
|
top: 0;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
background: url("~assets/img/common/collect.svg") 0 0/14px 14px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<tab-bar>
|
||||||
|
<tab-bar-item path="/home" activeColor="red">
|
||||||
|
<img slot="item-icon" src="~assets/img/tabbar/home.svg" alt="">
|
||||||
|
<img slot="item-icon-active" src="~assets/img/tabbar/home_active.svg" alt="">
|
||||||
|
<div slot="item-text">首页</div>
|
||||||
|
</tab-bar-item>
|
||||||
|
<tab-bar-item path="/category" activeColor="red">
|
||||||
|
<img slot="item-icon" src="~assets/img/tabbar/category.svg" alt="">
|
||||||
|
<img slot="item-icon-active" src="~assets/img/tabbar/category_active.svg" alt="">
|
||||||
|
<div slot="item-text">分类</div>
|
||||||
|
</tab-bar-item>
|
||||||
|
<tab-bar-item path="/cart" activeColor="red">
|
||||||
|
<img slot="item-icon" src="~assets/img/tabbar/cart.svg" alt="">
|
||||||
|
<img slot="item-icon-active" src="~assets/img/tabbar/cart_active.svg" alt="">
|
||||||
|
<div slot="item-text">购物车</div>
|
||||||
|
</tab-bar-item>
|
||||||
|
<tab-bar-item path="/profile" activeColor="red">
|
||||||
|
<img slot="item-icon" src="~assets/img/tabbar/profile.svg" alt="">
|
||||||
|
<img slot="item-icon-active" src="~assets/img/tabbar/profile_active.svg" alt="">
|
||||||
|
<div slot="item-text">我的</div>
|
||||||
|
</tab-bar-item>
|
||||||
|
</tab-bar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TabBar from "@/components/common/tabbar/TabBar";
|
||||||
|
import TabBarItem from "@/components/common/tabbar/TabBarItem";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
name: "MainTabBar",
|
||||||
|
components:{
|
||||||
|
TabBar,
|
||||||
|
TabBarItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tab-control">
|
||||||
|
<div v-for="(item,index) in titles"
|
||||||
|
class="tab-control-item" :class="{active:index===currentIndex}" @click="itemclick(index)">
|
||||||
|
<span>{{item}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TabControl",
|
||||||
|
props:{
|
||||||
|
titles:{
|
||||||
|
type:Array,
|
||||||
|
default(){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
currentIndex:0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
itemclick(index){
|
||||||
|
this.currentIndex=index;
|
||||||
|
this.$emit('tabClick',index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.tab-control{
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 15px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
background-color: #fff;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
.tab-control-item{
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
.tab-control-item span{
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active span{
|
||||||
|
border-bottom: 3px solid var(--color-tint);
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,8 +1,11 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
import router from './router'
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
Vue.prototype.$bus = new Vue()
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
render: h => h(App),
|
render: h => h(App),
|
||||||
|
router,
|
||||||
}).$mount('#app')
|
}).$mount('#app')
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
import {request} from "@/network/request";
|
||||||
|
|
||||||
|
export function getDetail(iid){
|
||||||
|
return request({
|
||||||
|
url:'/detail',
|
||||||
|
params:{
|
||||||
|
iid
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRecommend(){
|
||||||
|
return request({
|
||||||
|
url:'/recommend'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Goods{
|
||||||
|
constructor(itemInfo, columns, services) {
|
||||||
|
this.title = itemInfo.title;
|
||||||
|
this.desc = itemInfo.desc;
|
||||||
|
this.newPrice = itemInfo.price;
|
||||||
|
this.oldPrice = itemInfo.oldPrice;
|
||||||
|
this.discount = itemInfo.discountDesc;
|
||||||
|
this.columns = columns;
|
||||||
|
this.services = services;
|
||||||
|
this.nowPrice = itemInfo.highNowPrice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Shop {
|
||||||
|
constructor(shopInfo) {
|
||||||
|
this.logo = shopInfo.shopLogo;
|
||||||
|
this.name = shopInfo.name;
|
||||||
|
this.fans = shopInfo.cFans;
|
||||||
|
this.sells = shopInfo.cSells;
|
||||||
|
this.score = shopInfo.score;
|
||||||
|
this.goodsCount = shopInfo.cGoods
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GoodsParam {
|
||||||
|
constructor(info, rule) {
|
||||||
|
// 注: images可能没有值(某些商品有值, 某些没有值)
|
||||||
|
this.image = info.images ? info.images[0] : '';
|
||||||
|
this.infos = info.set;
|
||||||
|
this.sizes = rule.tables;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
import {request} from "@/network/request";
|
||||||
|
|
||||||
|
export function getHomeMutidata(){
|
||||||
|
return request({
|
||||||
|
url:'/home/multidata'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getHomeGoods(type,page){
|
||||||
|
return request({
|
||||||
|
url:'/home/data',
|
||||||
|
params:{
|
||||||
|
type,
|
||||||
|
page
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export function request(config){
|
||||||
|
const instance =axios.create({
|
||||||
|
baseURL:'http://152.136.185.210:8000/api/w6',
|
||||||
|
timeout:5000
|
||||||
|
})
|
||||||
|
|
||||||
|
// //拦截
|
||||||
|
// instance.interceptors.request.use(config=>{
|
||||||
|
// console.log(config);
|
||||||
|
// return config
|
||||||
|
// },
|
||||||
|
// err=>{
|
||||||
|
// // console.log(err)
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// instance.interceptors.request.use(res=>{
|
||||||
|
// return res.get
|
||||||
|
// },err=>{
|
||||||
|
// console.log(err);
|
||||||
|
// })
|
||||||
|
|
||||||
|
return instance(config)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Router from 'vue-router'
|
||||||
|
|
||||||
|
const Home=()=>import('../views/home/Home')
|
||||||
|
const Category=()=>import('../views/category/Category')
|
||||||
|
const Cart=()=>import('../views/cart/Cart')
|
||||||
|
const Profile=()=>import('../views/profile/Profile')
|
||||||
|
const Detail=()=>import('../views/detail/Detail')
|
||||||
|
Vue.use(Router)
|
||||||
|
|
||||||
|
const routes=[
|
||||||
|
{
|
||||||
|
path:'',
|
||||||
|
redirect:'/home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/home',
|
||||||
|
component:Home
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/category',
|
||||||
|
component:Category
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/cart',
|
||||||
|
component:Cart
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/profile',
|
||||||
|
component: Profile
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/detail/:iid',
|
||||||
|
component: Detail
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const router =new Router({
|
||||||
|
routes,
|
||||||
|
mode:'history'
|
||||||
|
})
|
||||||
|
export default router
|
@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h2>购物车</h2>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Home"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,152 @@
|
|||||||
|
<template>
|
||||||
|
<div class="wrapper" ref="aaaa">
|
||||||
|
<ul >
|
||||||
|
<button @click="btnClick">按钮</button>
|
||||||
|
<li>分类列表1</li>
|
||||||
|
<li>分类列表2</li>
|
||||||
|
<li>分类列表3</li>
|
||||||
|
<li>分类列表4</li>
|
||||||
|
<li>分类列表5</li>
|
||||||
|
<li>分类列表6</li>
|
||||||
|
<li>分类列表7</li>
|
||||||
|
<li>分类列表8</li>
|
||||||
|
<li>分类列表9</li>
|
||||||
|
<li>分类列表10</li>
|
||||||
|
<li>分类列表11</li>
|
||||||
|
<li>分类列表12</li>
|
||||||
|
<li>分类列表13</li>
|
||||||
|
<li>分类列表14</li>
|
||||||
|
<li>分类列表15</li>
|
||||||
|
<li>分类列表16</li>
|
||||||
|
<li>分类列表17</li>
|
||||||
|
<li>分类列表18</li>
|
||||||
|
<li>分类列表19</li>
|
||||||
|
<li>分类列表20</li>
|
||||||
|
<li>分类列表21</li>
|
||||||
|
<li>分类列表22</li>
|
||||||
|
<li>分类列表23</li>
|
||||||
|
<li>分类列表24</li>
|
||||||
|
<li>分类列表25</li>
|
||||||
|
<li>分类列表26</li>
|
||||||
|
<li>分类列表27</li>
|
||||||
|
<li>分类列表28</li>
|
||||||
|
<li>分类列表29</li>
|
||||||
|
<li>分类列表30</li>
|
||||||
|
<li>分类列表31</li>
|
||||||
|
<li>分类列表32</li>
|
||||||
|
<li>分类列表33</li>
|
||||||
|
<li>分类列表34</li>
|
||||||
|
<li>分类列表35</li>
|
||||||
|
<li>分类列表36</li>
|
||||||
|
<li>分类列表37</li>
|
||||||
|
<li>分类列表38</li>
|
||||||
|
<li>分类列表39</li>
|
||||||
|
<li>分类列表40</li>
|
||||||
|
<li>分类列表41</li>
|
||||||
|
<li>分类列表42</li>
|
||||||
|
<li>分类列表43</li>
|
||||||
|
<li>分类列表44</li>
|
||||||
|
<li>分类列表45</li>
|
||||||
|
<li>分类列表46</li>
|
||||||
|
<li>分类列表47</li>
|
||||||
|
<li>分类列表48</li>
|
||||||
|
<li>分类列表49</li>
|
||||||
|
<li>分类列表50</li>
|
||||||
|
<li>分类列表51</li>
|
||||||
|
<li>分类列表52</li>
|
||||||
|
<li>分类列表53</li>
|
||||||
|
<li>分类列表54</li>
|
||||||
|
<li>分类列表55</li>
|
||||||
|
<li>分类列表56</li>
|
||||||
|
<li>分类列表57</li>
|
||||||
|
<li>分类列表58</li>
|
||||||
|
<li>分类列表59</li>
|
||||||
|
<li>分类列表60</li>
|
||||||
|
<li>分类列表61</li>
|
||||||
|
<li>分类列表62</li>
|
||||||
|
<li>分类列表63</li>
|
||||||
|
<li>分类列表64</li>
|
||||||
|
<li>分类列表65</li>
|
||||||
|
<li>分类列表66</li>
|
||||||
|
<li>分类列表67</li>
|
||||||
|
<li>分类列表68</li>
|
||||||
|
<li>分类列表69</li>
|
||||||
|
<li>分类列表70</li>
|
||||||
|
<li>分类列表71</li>
|
||||||
|
<li>分类列表72</li>
|
||||||
|
<li>分类列表73</li>
|
||||||
|
<li>分类列表74</li>
|
||||||
|
<li>分类列表75</li>
|
||||||
|
<li>分类列表76</li>
|
||||||
|
<li>分类列表77</li>
|
||||||
|
<li>分类列表78</li>
|
||||||
|
<li>分类列表79</li>
|
||||||
|
<li>分类列表80</li>
|
||||||
|
<li>分类列表81</li>
|
||||||
|
<li>分类列表82</li>
|
||||||
|
<li>分类列表83</li>
|
||||||
|
<li>分类列表84</li>
|
||||||
|
<li>分类列表85</li>
|
||||||
|
<li>分类列表86</li>
|
||||||
|
<li>分类列表87</li>
|
||||||
|
<li>分类列表88</li>
|
||||||
|
<li>分类列表89</li>
|
||||||
|
<li>分类列表90</li>
|
||||||
|
<li>分类列表91</li>
|
||||||
|
<li>分类列表92</li>
|
||||||
|
<li>分类列表93</li>
|
||||||
|
<li>分类列表94</li>
|
||||||
|
<li>分类列表95</li>
|
||||||
|
<li>分类列表96</li>
|
||||||
|
<li>分类列表97</li>
|
||||||
|
<li>分类列表98</li>
|
||||||
|
<li>分类列表99</li>
|
||||||
|
<li>分类列表100</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BScroll from 'better-scroll'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Category",
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
scroll:null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.scroll=new BScroll(document.querySelector('.wrapper'),{
|
||||||
|
probeType:3,
|
||||||
|
pullUpLoad:true,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.scroll.on('scroll',(position)=>{
|
||||||
|
// console.log(position);
|
||||||
|
})
|
||||||
|
|
||||||
|
this.scroll.on('pullingUp',()=>{
|
||||||
|
console.log('上拉加载更多');
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
btnClick(){
|
||||||
|
console.log('ctnClick');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.wrapper{
|
||||||
|
height: 150px;
|
||||||
|
background-color: red;
|
||||||
|
|
||||||
|
/*overflow: hidden;*/
|
||||||
|
overflow-y:scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,168 @@
|
|||||||
|
<template>
|
||||||
|
<div id="detail" >
|
||||||
|
<DetailNewBar class="detail-nav" @titleClick="titleClick" ref="nav"/>
|
||||||
|
<scroll class="content"
|
||||||
|
ref="scroll"
|
||||||
|
@scroll="totalScroll"
|
||||||
|
:probe-type="3" >
|
||||||
|
<DetailSwiper :top-images="topImages"/>
|
||||||
|
<DetailBaseInfo :goods="goods"/>
|
||||||
|
<DetailShopInfo :shop="shop" />
|
||||||
|
<DetailGoodsInfo :detail-info="detailInfo" @detailImageload="detailImageload"/>
|
||||||
|
<DetailParamInfo ref="params" :param-info="paramInfo"/>
|
||||||
|
<DetailCommentInfo ref="comment" :comment-info="commentInfo"/>
|
||||||
|
<GoodsList ref="recommend" :goods="recommends"></GoodsList>
|
||||||
|
</scroll>
|
||||||
|
<back-top @click.native="backClick" v-show="isShowBackTop"/>
|
||||||
|
<detail-bottom-bar @addToCart="addToCart"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DetailNewBar from "@/views/detail/childComps/DetailNewBar";
|
||||||
|
import DetailSwiper from "@/views/detail/childComps/DetailSwiper";
|
||||||
|
import DetailBaseInfo from "@/views/detail/childComps/DetailBaseInfo";
|
||||||
|
import DetailShopInfo from "@/views/detail/childComps/DetailShopInfo";
|
||||||
|
import DetailGoodsInfo from "@/views/detail/childComps/DetailGoodsInfo";
|
||||||
|
import DetailParamInfo from "@/views/detail/childComps/DetailParamInfo";
|
||||||
|
import DetailCommentInfo from "@/views/detail/childComps/DetailCommentInfo";
|
||||||
|
import DetailBottomBar from "@/views/detail/childComps/DetailBottomBar";
|
||||||
|
|
||||||
|
import backTop from "@/components/content/backTop/backTop";
|
||||||
|
import GoodsList from "@/components/content/goods/GoodsList";
|
||||||
|
import scroll from "@/components/common/Scroll/Scroll";
|
||||||
|
|
||||||
|
import {itemListenerMixin,backTopMixin} from "@/common/mixin";
|
||||||
|
import {debounce} from "@/common/utils";
|
||||||
|
|
||||||
|
import {getDetail, Goods, Shop, GoodsParam, getRecommend} from "@/network/detail";
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Detail",
|
||||||
|
components: {
|
||||||
|
DetailNewBar,
|
||||||
|
DetailSwiper,
|
||||||
|
DetailBaseInfo,
|
||||||
|
DetailShopInfo,
|
||||||
|
DetailGoodsInfo,
|
||||||
|
DetailParamInfo,
|
||||||
|
DetailCommentInfo,
|
||||||
|
DetailBottomBar,
|
||||||
|
|
||||||
|
backTop,
|
||||||
|
GoodsList,
|
||||||
|
scroll,
|
||||||
|
|
||||||
|
},
|
||||||
|
mixins: [itemListenerMixin,backTopMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
iid: null,
|
||||||
|
topImages: [],
|
||||||
|
goods: {},
|
||||||
|
shop: {},
|
||||||
|
detailInfo: {},
|
||||||
|
paramInfo: {},
|
||||||
|
commentInfo: {},
|
||||||
|
recommends: [],
|
||||||
|
themeTopYs: [],
|
||||||
|
getThemeTopY: null,
|
||||||
|
currentIndex:0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
//home主页传入iid
|
||||||
|
this.iid = this.$route.params.iid
|
||||||
|
//数据的展示
|
||||||
|
getDetail(this.iid).then(res => {
|
||||||
|
const data = res.data.result
|
||||||
|
//轮播图的切换
|
||||||
|
this.topImages = data.itemInfo.topImages
|
||||||
|
//商品介绍
|
||||||
|
this.goods = new Goods(data.itemInfo, data.columns, data.shopInfo.services)
|
||||||
|
//店铺名的展示
|
||||||
|
this.shop = new Shop(data.shopInfo)
|
||||||
|
//穿着展示
|
||||||
|
this.detailInfo = data.detailInfo
|
||||||
|
//商品推荐的展示
|
||||||
|
this.paramInfo = new GoodsParam(data.itemParams.info, data.itemParams.rule)
|
||||||
|
|
||||||
|
if (data.rate.list) {
|
||||||
|
this.commentInfo = data.rate.list[0];
|
||||||
|
}
|
||||||
|
//导航栏点击切换
|
||||||
|
this.getThemeTopY = debounce(() => {
|
||||||
|
this.themeTopYs = []
|
||||||
|
this.themeTopYs.push(0);
|
||||||
|
this.themeTopYs.push(this.$refs.params.$el.offsetTop)
|
||||||
|
this.themeTopYs.push(this.$refs.comment.$el.offsetTop)
|
||||||
|
this.themeTopYs.push(this.$refs.recommend.$el.offsetTop)
|
||||||
|
this.themeTopYs.push(Number.MAX_VALUE)
|
||||||
|
}, 500)
|
||||||
|
|
||||||
|
})
|
||||||
|
//获取评论的数据
|
||||||
|
getRecommend().then(res => {
|
||||||
|
this.recommends = res.data.data.list
|
||||||
|
})
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
//无keep-live时activated无法使用
|
||||||
|
this.$bus.$off('itemImgLoad', this.itemImgListener)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//上拉图片加载
|
||||||
|
detailImageload() {
|
||||||
|
this.itemImgListener()
|
||||||
|
this.getThemeTopY()
|
||||||
|
},
|
||||||
|
//导航栏点击切换
|
||||||
|
titleClick(index) {
|
||||||
|
this.$refs.scroll.scrollTo(0, -this.themeTopYs[index], 1000);
|
||||||
|
},
|
||||||
|
//位置移动时导航栏跟着移动
|
||||||
|
positionScroll(position) {
|
||||||
|
const positionY = -position.y
|
||||||
|
let length = this.themeTopYs.length
|
||||||
|
for (let i = 0; i < length-1; i++) {
|
||||||
|
if(this.currentIndex!==i&&(positionY>=this.themeTopYs[i]&&positionY<this.themeTopYs[i+1]))
|
||||||
|
{
|
||||||
|
this .currentIndex=i;
|
||||||
|
this.$refs.nav.currentIndex=this.currentIndex
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//mixin混入回退顶部的按钮
|
||||||
|
totalScroll(position){
|
||||||
|
this.positionScroll(position)
|
||||||
|
this.contentScoll(position)
|
||||||
|
},
|
||||||
|
//加入购物车
|
||||||
|
addToCart(){
|
||||||
|
console.log('----');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
#detail{
|
||||||
|
position: relative;
|
||||||
|
z-index: 9;
|
||||||
|
background-color: #ffffff;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
.detail-nav{
|
||||||
|
position: relative;
|
||||||
|
z-index: 9;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
.content{
|
||||||
|
height: calc(100% - 96px);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="Object.keys(goods).length !== 0" class="base-info">
|
||||||
|
<div class="info-title">{{goods.title}}</div>
|
||||||
|
<div class="info-price">
|
||||||
|
<span class="n-price">{{goods.newPrice}}</span>
|
||||||
|
<span class="o-price">{{goods.oldPrice}}</span>
|
||||||
|
<span class="discount">{{goods.discount}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-other">
|
||||||
|
<span>{{goods.columns[0]}}</span>
|
||||||
|
<span>{{goods.columns[1]}}</span>
|
||||||
|
<span>{{goods.services[goods.services.length-1].name}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-service">
|
||||||
|
<span class="info-service-item" v-for="index in goods.services.length-1" :key="index">
|
||||||
|
<img :src="goods.services[index-1].icon">
|
||||||
|
<span>{{goods.services[index-1].name}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailBaseInfo",
|
||||||
|
props: {
|
||||||
|
goods: {
|
||||||
|
type: Object,
|
||||||
|
default(){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.base-info {
|
||||||
|
margin-top: 15px;
|
||||||
|
padding: 0 8px;
|
||||||
|
color: #999;
|
||||||
|
border-bottom: 5px solid #f2f5f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-title {
|
||||||
|
color: #222
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-price {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-price .n-price {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--color-high-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-price .o-price {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-left: 5px;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-price .discount {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: var(--color-high-text);
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-left: 5px;
|
||||||
|
|
||||||
|
/*让元素上浮一些: 使用相对定位即可*/
|
||||||
|
position: relative;
|
||||||
|
top: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-other {
|
||||||
|
margin-top: 15px;
|
||||||
|
line-height: 30px;
|
||||||
|
display: flex;
|
||||||
|
font-size: 13px;
|
||||||
|
border-bottom: 1px solid rgba(100,100,100,.1);
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-service {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-service-item img {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-service-item span {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bottom-bar">
|
||||||
|
<div class="bar-item bar-left">
|
||||||
|
<div>
|
||||||
|
<i class="icon service"></i>
|
||||||
|
<span class="text">客服</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i class="icon shop"></i>
|
||||||
|
<span class="text">店铺</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i class="icon select"></i>
|
||||||
|
<span class="text">收藏</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bar-item bar-right">
|
||||||
|
<div class="cart" @click="addToCart">加入购物车</div>
|
||||||
|
<div class="buy">购买</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailBottomBar",
|
||||||
|
methods: {
|
||||||
|
addToCart() {
|
||||||
|
this.$emit('addToCart')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.bottom-bar {
|
||||||
|
height: 58px;
|
||||||
|
position: fixed;
|
||||||
|
background-color: #fff;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-item>div {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-left .text {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-left .icon {
|
||||||
|
display: block;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
margin: 10px auto 3px;
|
||||||
|
background: url("~assets/img/detail/detail_bottom.png") 0 0/100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-left .service {
|
||||||
|
background-position:0 -54px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-left .shop {
|
||||||
|
background-position:0 -98px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-right {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 58px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-right .cart {
|
||||||
|
background-color: #ffe817;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-right .buy {
|
||||||
|
background-color: #f69;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="Object.keys(commentInfo).length !== 0" class="comment-info">
|
||||||
|
<div class="info-header">
|
||||||
|
<div class="header-title">用户评价</div>
|
||||||
|
<div class="header-more">
|
||||||
|
更多
|
||||||
|
<i class="arrow-right"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-user">
|
||||||
|
<img :src="commentInfo.user.avatar" alt="">
|
||||||
|
<span>{{commentInfo.user.uname}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-detail">
|
||||||
|
<p>{{commentInfo.content}}</p>
|
||||||
|
<div class="info-other">
|
||||||
|
<span class="date">{{commentInfo.created | showDate}}</span>
|
||||||
|
<span>{{commentInfo.style}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-imgs">
|
||||||
|
<img :src="item" v-for="(item, index) in commentInfo.images">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {formatDate} from "@/common/utils";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "DetailCommentInfo",
|
||||||
|
props: {
|
||||||
|
commentInfo: {
|
||||||
|
type: Object,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
showDate: function (value) {
|
||||||
|
let date = new Date(value*1000);
|
||||||
|
return formatDate(date, 'yyyy-MM-dd')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.comment-info {
|
||||||
|
padding: 5px 12px;
|
||||||
|
color: #333;
|
||||||
|
border-bottom: 5px solid #f2f5f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-header {
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
border-bottom: 1px solid rgba(0,0,0,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
float: left;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-more {
|
||||||
|
float: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user {
|
||||||
|
padding: 10px 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user img {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user span {
|
||||||
|
position: relative;
|
||||||
|
font-size: 15px;
|
||||||
|
top: -15px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-detail {
|
||||||
|
padding: 0 5px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-detail p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #777;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-detail .info-other {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-other .date {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-imgs {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-imgs img {
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="Object.keys(detailInfo).length !== 0" class="goods-info" >
|
||||||
|
<div class="info-desc clear-fix">
|
||||||
|
<div class="start">
|
||||||
|
</div>
|
||||||
|
<div class="desc">{{detailInfo.desc}}</div>
|
||||||
|
<div class="end"></div>
|
||||||
|
</div>
|
||||||
|
<div class="info-key">{{detailInfo.detailImage[0].key}}</div>
|
||||||
|
<div class="info-list">
|
||||||
|
<img v-for="(item, index) in detailInfo.detailImage[0].list" :key="index" :src="item" alt="" @load="imgLoad">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailGoodsInfo",
|
||||||
|
props: {
|
||||||
|
detailInfo: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
rounter:0,
|
||||||
|
imagesLength:0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
imgLoad() {
|
||||||
|
this.$emit('detailImageload')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.goods-info {
|
||||||
|
padding: 20px 0;
|
||||||
|
border-bottom: 5px solid #f2f5f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-desc {
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-desc .start, .info-desc .end {
|
||||||
|
width: 90px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: #a3a3a5;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-desc .start {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-desc .end {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-desc .start::before, .info-desc .end::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
background-color: #333;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-desc .end::after {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-desc .desc {
|
||||||
|
padding: 15px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-key {
|
||||||
|
margin: 10px 0 10px 15px;
|
||||||
|
color: #333;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-list img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<nav-bar>
|
||||||
|
<div slot="left" class="back" @click="backClick">
|
||||||
|
<img src="~assets/img/common/back.svg" alt="">
|
||||||
|
</div>
|
||||||
|
<div slot="center" class="title">
|
||||||
|
<div v-for="(item,index) in titles"
|
||||||
|
class="title-item"
|
||||||
|
:class="{active:index===currentIndex}" @click="titleClick(index)">
|
||||||
|
{{item}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav-bar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import NavBar from "@/components/common/navbar/NavBar";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "DetailNewBar",
|
||||||
|
components: {
|
||||||
|
NavBar
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
titles:['商品','参数','评论','推荐'],
|
||||||
|
currentIndex:0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
titleClick(index){
|
||||||
|
this.currentIndex=index;
|
||||||
|
this.$emit('titleClick',index)
|
||||||
|
},
|
||||||
|
backClick(){
|
||||||
|
this.$router.back()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.title{
|
||||||
|
display: flex;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.title-item{
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
.active{
|
||||||
|
color: var(--color-high-text);
|
||||||
|
}
|
||||||
|
.back img{
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<div class="param-info" v-if="Object.keys(paramInfo).length !== 0">
|
||||||
|
<table v-for="(table, index) in paramInfo.sizes"
|
||||||
|
class="info-size" :key="index">
|
||||||
|
<tr v-for="(tr, indey) in table" :key="indey">
|
||||||
|
<td v-for="(td, indez) in tr" :key="indez">{{td}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table class="info-param">
|
||||||
|
<tr v-for="(info, index) in paramInfo.infos">
|
||||||
|
<td class="info-param-key">{{info.key}}</td>
|
||||||
|
<td class="param-value">{{info.value}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="info-img" v-if="paramInfo.image.length !== 0">
|
||||||
|
<img :src="paramInfo.image" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailParamInfo",
|
||||||
|
props: {
|
||||||
|
paramInfo: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.param-info {
|
||||||
|
padding: 20px 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
border-bottom: 5px solid #f2f5f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.param-info table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.param-info table tr {
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.param-info table tr td {
|
||||||
|
border-bottom: 1px solid rgba(100,100,100,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-param-key {
|
||||||
|
/*当value的数据量比较大的时候, 会挤到key,所以给一个固定的宽度*/
|
||||||
|
width: 95px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-param {
|
||||||
|
border-top: 1px solid rgba(0,0,0,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.param-value {
|
||||||
|
color: #eb4868
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-img img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,157 @@
|
|||||||
|
<template>
|
||||||
|
<div class="shop-info">
|
||||||
|
<div class="shop-top">
|
||||||
|
<img :src="shop.logo">
|
||||||
|
<span class="title">{{shop.name}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="shop-middle">
|
||||||
|
<div class="shop-middle-item shop-middle-left">
|
||||||
|
<div class="info-sells">
|
||||||
|
<div class="sells-count">
|
||||||
|
{{shop.sells | sellCountFilter}}
|
||||||
|
</div>
|
||||||
|
<div class="sells-text">总销量</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-goods">
|
||||||
|
<div class="goods-count">
|
||||||
|
{{shop.goodsCount}}
|
||||||
|
</div>
|
||||||
|
<div class="goods-text">全部宝贝</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shop-middle-item shop-middle-right">
|
||||||
|
<table>
|
||||||
|
<tr v-for="(item, index) in shop.score" :key="index">
|
||||||
|
<td>{{item.name}}</td>
|
||||||
|
<td class="score" :class="{'score-better': item.isBetter}">{{item.score}}</td>
|
||||||
|
<td class="better" :class="{'better-more': item.isBetter}"><span>{{item.isBetter ? '高':'低'}}</span></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shop-bottom">
|
||||||
|
<div class="enter-shop">进店逛逛</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "DetailShopInfo",
|
||||||
|
props: {
|
||||||
|
shop: {
|
||||||
|
type: Object,
|
||||||
|
default(){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
sellCountFilter: function (value) {
|
||||||
|
if (value < 10000) return value;
|
||||||
|
return (value/10000).toFixed(1) + '万'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.shop-info {
|
||||||
|
padding: 25px 8px;
|
||||||
|
border-bottom: 5px solid #f2f5f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-top {
|
||||||
|
line-height: 45px;
|
||||||
|
/* 让元素垂直中心对齐 */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-top img {
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid rgba(0,0,0,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-top .title {
|
||||||
|
margin-left: 10px;
|
||||||
|
vertical-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle {
|
||||||
|
margin-top: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-item {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-left {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
border-right: 1px solid rgba(0,0,0,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sells-count, .goods-count {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sells-text, .goods-text {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-right {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-right table {
|
||||||
|
width: 120px;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-right table td {
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-right .score {
|
||||||
|
color: #5ea732;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-right .score-better {
|
||||||
|
color: #f13e3a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-right .better span {
|
||||||
|
background-color: #5ea732;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-middle-right .better-more span {
|
||||||
|
background-color: #f13e3a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-bottom {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enter-shop {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #f2f5f8;
|
||||||
|
width: 150px;
|
||||||
|
height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<swiper class="swiper-item">
|
||||||
|
<swiper-item v-for="(item,index) in topImages">
|
||||||
|
<img :src="item" :key="index" alt="">
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {Swiper,SwiperItem} from '@/components/common/swiper'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "DetailSwiper",
|
||||||
|
props:{
|
||||||
|
topImages:{
|
||||||
|
type:Array,
|
||||||
|
default(){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components:{
|
||||||
|
SwiperItem,
|
||||||
|
Swiper,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.swiper-item{
|
||||||
|
height: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div class="recommends">
|
||||||
|
<div v-for="item in recommends" class="recommends-item">
|
||||||
|
<a :href="item.link">
|
||||||
|
<img :src="item.image" alt="">
|
||||||
|
<div>{{item.title}}</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "HomeRecommendView",
|
||||||
|
props:{
|
||||||
|
recommends:{
|
||||||
|
type:Array,
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.recommends{
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 10px 0 20px;
|
||||||
|
border-bottom: 8px solid #eee;
|
||||||
|
}
|
||||||
|
.recommends-item{
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
.recommends-item img{
|
||||||
|
width: 65px;
|
||||||
|
height: 65px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<swiper>
|
||||||
|
<swiperItem v-for="item in banners">
|
||||||
|
<a :href="item.link" >
|
||||||
|
<img :src="item.image" alt="" @load="imageLoad">
|
||||||
|
</a>
|
||||||
|
</swiperItem>
|
||||||
|
</swiper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {Swiper, SwiperItem} from "@/components/common/swiper/index"
|
||||||
|
export default {
|
||||||
|
name: "HomeSwiper",
|
||||||
|
components:{
|
||||||
|
Swiper,
|
||||||
|
SwiperItem
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
banners:{
|
||||||
|
type:Array,
|
||||||
|
default(){
|
||||||
|
return[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
isLoad:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
imageLoad(){
|
||||||
|
if(!this.isLoad) {
|
||||||
|
this.$emit('swiperImageLoad')
|
||||||
|
this.isLoad=true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div class="feature">
|
||||||
|
<a href="https://act.mogujie.com/zzlx67">
|
||||||
|
<img src="@/assets/img/home/recommend_bg.jpg" alt="">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "HomefeatureView"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.feature img{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h2>我的</h2>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Profile"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,13 @@
|
|||||||
|
module.exports={
|
||||||
|
configureWebpack:{
|
||||||
|
resolve:{
|
||||||
|
alias:{
|
||||||
|
'assets':'@/assets',
|
||||||
|
'common':'@/common',
|
||||||
|
'components':'@/components',
|
||||||
|
'network':'@/network',
|
||||||
|
'views':'@/views',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|