pull/1/head
林华焜 5 years ago
parent fadf85592d
commit c665f64213

21
package-lock.json generated

@ -2612,9 +2612,9 @@
}
},
"better-scroll": {
"version": "1.13.2",
"resolved": "https://registry.npm.taobao.org/better-scroll/download/better-scroll-1.13.2.tgz",
"integrity": "sha1-MebgiM8tI85I5S+tbMWRNP/rL1Y=",
"version": "1.15.2",
"resolved": "https://registry.npm.taobao.org/better-scroll/download/better-scroll-1.15.2.tgz?cache=0&sync_timestamp=1603173316390&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbetter-scroll%2Fdownload%2Fbetter-scroll-1.15.2.tgz",
"integrity": "sha1-Zf/GBYuLT/M3uN+tS8szTXaZzrY=",
"requires": {
"babel-runtime": "^6.0.0"
}
@ -5093,6 +5093,11 @@
"integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=",
"dev": true
},
"fastclick": {
"version": "1.0.6",
"resolved": "https://registry.npm.taobao.org/fastclick/download/fastclick-1.0.6.tgz",
"integrity": "sha1-FhYlsnsaWAZAWTa9qaLBkm0Gvmo="
},
"faye-websocket": {
"version": "0.10.0",
"resolved": "https://registry.npm.taobao.org/faye-websocket/download/faye-websocket-0.10.0.tgz",
@ -10380,6 +10385,11 @@
"integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
"dev": true
},
"vue-lazyload": {
"version": "1.3.3",
"resolved": "https://registry.npm.taobao.org/vue-lazyload/download/vue-lazyload-1.3.3.tgz",
"integrity": "sha1-TfUKJxvem3TDyveiKNbgr1DVaC8="
},
"vue-loader": {
"version": "15.9.3",
"resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.9.3.tgz?cache=0&sync_timestamp=1600850425972&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.9.3.tgz",
@ -10440,6 +10450,11 @@
"integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=",
"dev": true
},
"vuex": {
"version": "3.1.0",
"resolved": "https://registry.npm.taobao.org/vuex/download/vuex-3.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvuex%2Fdownload%2Fvuex-3.1.0.tgz",
"integrity": "sha1-Y0uBUVzwz+l2vR/+lgF1XlH4Q7k="
},
"watchpack": {
"version": "1.7.4",
"resolved": "https://registry.npm.taobao.org/watchpack/download/watchpack-1.7.4.tgz?cache=0&sync_timestamp=1600385622765&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz",

@ -8,10 +8,13 @@
},
"dependencies": {
"axios": "^0.18.0",
"better-scroll": "^1.13.2",
"better-scroll": "^1.15.2",
"core-js": "^3.6.5",
"fastclick": "^1.0.6",
"vue": "^2.6.11",
"vue-router": "^3.0.2"
"vue-lazyload": "^1.3.3",
"vue-router": "^3.0.2",
"vuex": "^3.1.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.0",

@ -1,5 +1,6 @@
<template>
<div id="app">
<!-- exclude不包括哪几个组件-->
<keep-alive exclude="Detail">
<router-view/>
</keep-alive>

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="16px" height="16px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M908.288 127.488l-537.6 537.6-254.976-254.976L0 525.824l254.976 254.976 115.712 115.712L486.4 780.8l537.6-537.6z" fill="#ffffff" p-id="2923"/></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="16px" height="16px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M908.288 127.488l-537.6 537.6-254.976-254.976L0 525.824l254.976 254.976 115.712 115.712L486.4 780.8l537.6-537.6z" fill="#ffffff"/></svg>

Before

Width:  |  Height:  |  Size: 410 B

After

Width:  |  Height:  |  Size: 399 B

@ -0,0 +1,5 @@
export const BACKTOP_DISTANCE = 1000
export const POP = 'pop';
export const NEW = 'new';
export const SELL = 'sell';

Binary file not shown.

@ -1,4 +1,5 @@
import {debounce} from "@/common/utils";
import {POP, NEW, SELL} from "@/common/const";
export const itemListenerMixin={
data(){
@ -8,7 +9,7 @@ export const itemListenerMixin={
},
mounted(){
const refresh = debounce(this.$refs.scroll.refresh,500)
const refresh = debounce(this.$refs.scroll.refresh,300)
this.itemImgListener=()=>{
refresh()
@ -36,3 +37,28 @@ export const backTopMixin={
},
}
}
export const tabControlMixin = {
data: function () {
return {
currentType: POP
}
},
methods: {
tabClick(index) {
switch (index) {
case 0:
this.currentType = POP
break
case 1:
this.currentType = NEW
break
case 2:
this.currentType = SELL
break
}
}
}
}

@ -18,7 +18,7 @@ export default {
pullUpLoad:{
type:Boolean,
default: false
}
},
},
data(){
return{
@ -29,7 +29,8 @@ export default {
this.scroll=new BScroll(this.$refs.wrapper,{
click:true,
probeType:this.probeType,
pullUpLoad: this.pullUpLoad
pullUpLoad: this.pullUpLoad,
useTransition:false,
})
this.scroll.on('scroll',(position)=>{
this.$emit('scroll',position)
@ -44,8 +45,8 @@ export default {
this.scroll.scrollTo(0,0)
},
methods:{
scrollTo(x,y,time=3000){
this.scroll && this.scroll.scrollTo(x,y,time)
scrollTo(x,y,timer=3000){
this.scroll && this.scroll.scrollTo(x,y,timer)
},
finishPullUp(){
this.scroll && this.scroll.finishPullUp()
@ -53,7 +54,7 @@ export default {
refresh(){
this.scroll && this.scroll.refresh()
},
getScrolly(){
getScrollY(){
return this.scroll ? this.scroll.y : 0
}
}

@ -0,0 +1,71 @@
<template>
<div class="grid-view" ref="gridView">
<slot></slot>
</div>
</template>
<script>
export default {
name: "GridView",
props: {
cols: {
type: Number,
default: 2
},
hMargin: {
type: Number,
default: 8
},
vMargin: {
type: Number,
default: 8
},
itemSpace: {
type: Number,
default: 8
},
lineSpace: {
type: Number,
default: 8
}
},
mounted: function () {
setTimeout(this._autoLayout, 200)
},
updated: function () {
this._autoLayout()
},
methods: {
_autoLayout: function () {
// 1.gridElchildren
// : document.querySelector?
// : , grid-view, .
let gridEl = this.$refs.gridView;
let children = gridEl&&gridEl.children;
// 2.gridEl
gridEl.style.padding = `${this.vMargin}px ${this.hMargin}px`
// 3.item
let itemWidth = (gridEl.clientWidth - 2 * this.hMargin - (this.cols - 1) * this.itemSpace) / this.cols;
for (let i = 0; i < children.length; i++) {
let item = children[i];
item.style.width = itemWidth + 'px';
if ((i+1) % this.cols !== 0) {
item.style.marginRight = this.itemSpace + 'px'
}
if (i >= this.cols) {
item.style.marginTop = this.lineSpace + 'px'
}
}
}
}
}
</script>
<style scoped>
.grid-view {
display: flex;
flex-wrap: wrap;
}
</style>

@ -19,6 +19,8 @@ name: "NavBar"
height: 44px;
text-align: center;
box-shadow: 0 1px 1px rgba(100,100,100,.1);
position: relative;
z-index: 10;
}
.left,.right{
width:60px;

@ -118,9 +118,9 @@
handleDom: function () {
// 1.
let swiperEl = document.querySelector('.swiper');
let slidesEls = swiperEl.getElementsByClassName('slide');
let slidesEls = swiperEl&&swiperEl.getElementsByClassName('slide');
// 2.
this.slideCount = slidesEls.length;
this.slideCount = slidesEls&&slidesEls.length;
// 3.1, slide
if (this.slideCount > 1) {

@ -0,0 +1,40 @@
<template>
<div class="toast" v-show="isShow">
<div >{{message}}</div>
</div>
</template>
<script>
export default {
name: "Toast",
data(){
return{
message:'',
isShow:false
}
},
methods:{
show(message='默认文字',duration=2000){
this.isShow=true
this.message=message
setTimeout(()=>{
this.isShow=false
this.message=''
},duration)
}
},
}
</script>
<style scoped>
.toast{
position: fixed;
top:50%;
left:50%;
padding: 8px 10px;
transform: translate(-50%);
background-color: rgba(0,0,0,7.5);
color: #fff;
z-index: 999;
}
</style>

@ -0,0 +1,16 @@
import Toast from "@/components/common/toast/Toast";
const obj={}
obj.install = function (Vue){
//1、创建组件构造器
const toastContrustor=Vue.extend(Toast)
//2、new的方式根据组件构造器可以创建出来一个对象
const toast=new toastContrustor()
//3、将组件对象手动挂载到某一个元素上
toast.$mount(document.createElement('div'))
//4、toast.$el对应的就是div
document.body.appendChild(toast.$el)
Vue.prototype.$toast=toast;
}
export default obj

@ -0,0 +1,28 @@
<template>
<div class="check-button" :class="{check:isCheck}" @click="">
<img src="@/assets/img/cart/tick.svg" alt="">
</div>
</template>
<script>
export default {
name: "CheckButton",
props:{
isCheck:{
type: Boolean,
default:false
}
}
}
</script>
<style scoped>
.check-button{
border-radius: 50%;
border:2px solid #aaa;
}
.check{
background-color: red;
border-color: red;
}
</style>

@ -1,6 +1,6 @@
<template>
<div class="goods-items" @click="itemClick">
<img :src="showImage" alt="" @load="imageLoad">
<img v-lazy="showImage" alt="" @load="imageLoad">
<div class="goods-info">
<p>{{goodsItem.title}}</p>
<span class="price">{{goodsItem.price}}</span>
@ -30,7 +30,7 @@ name: "GoodsListItem",
},
computed:{
showImage(){
return this.goodsItem.image || this.goodsItem.show.img
return this.goodsItem.img||this.goodsItem.image || this.goodsItem.show.img
}
}
}

@ -40,7 +40,7 @@ export default {
height: 40px;
line-height: 40px;
background-color: #fff;
z-index: 9;
position: relative;
}
.tab-control-item{
flex:1;

@ -1,11 +1,24 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from "@/store";
import FastClick from 'fastclick'
import VueLazyload from "vue-lazyload";
import toast from'@/components/common/toast'
Vue.config.productionTip = false
Vue.prototype.$bus = new Vue()
Vue.use(toast)
Vue.use(VueLazyload,{
loading:require('./assets/img/common/placeholder.png')
})
FastClick.attach(document.body)
new Vue({
render: h => h(App),
router,
store,
}).$mount('#app')

@ -0,0 +1,27 @@
import {request} from "@/network/request";
export function getCategory() {
return request({
url: '/category'
})
}
export function getSubcategory(maitKey){
return request({
url:'/subcategory',
params:{
maitKey
}
})
}
export function getCategoryDetail(miniWallkey,type){
return request({
url:'/subcategory/detail',
params:{
miniWallkey,
type
}
})
}

@ -6,6 +6,8 @@ export function request(config){
timeout:5000
})
///http://152.136.185.210:8000/api/w6/category
// //拦截
// instance.interceptors.request.use(config=>{
// console.log(config);

@ -6,6 +6,7 @@ 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=[
@ -36,6 +37,6 @@ const routes=[
]
const router =new Router({
routes,
mode:'history'
mode:'history',
})
export default router

@ -0,0 +1,29 @@
import {
ADD_COUNTER,
ADD_TO_CHAR,
} from "@/store/mutation-type";
export default {
addCart(context,payLoad){
//payLoad新添加的商品
// let oldProduct=null;
// for(let item of state.cartList){
// if(item.iid===payLoad.iid){
// oldProduct=item
// }
// }
return new Promise(((resolve, reject) => {
let product=context.state.cartList.find(item=>item.iid === payLoad.iid)
if(product){
context.commit('ADD_COUNTER',product)
resolve('当前的商品数量+1')
}else {
payLoad.count=1
context.commit('ADD_TO_CHAR',payLoad)
resolve('添加了新的商品')
}
}))
}
}

@ -0,0 +1,8 @@
export default {
cartLength(state) {
return state.cartList.length
},
cartList(state){
return state.cartList
}
}

@ -0,0 +1,21 @@
import Vue from 'vue'
import Vuex from'vuex'
import mutations from "@/store/mutations";
import actions from "@/store/actions";
import getters from "@/store/getters";
Vue.use(Vuex)
const state={
cartList:[],
counter:0,
number:0,
}
const store = new Vuex.Store({
state,
mutations,
actions,
getters
})
export default store

@ -0,0 +1,2 @@
export const ADD_COUNTER='add_counter'
export const ADD_TO_CHAR='add_to_char'

@ -0,0 +1,15 @@
import {
ADD_COUNTER,
ADD_TO_CHAR,
} from "@/store/mutation-type";
export default {
ADD_COUNTER(state,payload){
payload.count++
},
ADD_TO_CHAR(state,payload){
payload.checked=true
state.cartList.push(payload)
}
}

@ -1,15 +1,51 @@
<template>
<div>
<h2>购物车</h2>
<div class="cart">
<NavBar class="nav-bar">
<div slot="center" >购物车({{length}})</div>
</NavBar>
<CartList ></CartList>
<CartBottomBar></CartBottomBar>
</div>
</template>
<script>
import CartList from "@/views/cart/childComps/CartList";
import CartBottomBar from "@/views/cart/childComps/CartBottomBar";
import NavBar from "@/components/common/navbar/NavBar";
import {mapGetters} from 'vuex'
export default {
name: "Home"
name: "Cart",
components:{
CartBottomBar,
NavBar,
CartList,
},
computed:{
// ...mapGetters(['cartLength','cartList'])
...mapGetters({
length:'cartLength',
list:'cartList'
})
},
}
</script>
<style scoped>
.cart {
/*position: relative;*/
height: 100vh;
}
.nav-bar {
background-color: var(--color-tint);
font-weight: 700;
color: #fff;
}
</style>

@ -0,0 +1,101 @@
<template>
<div class="bottom-menu">
<CheckButton class="select-all" @checkBtnClick="checkBtnClick" v-model="isSelectAll"></CheckButton>
<span>全选</span>
<span class="total-price">合计: {{totalPrice}}</span>
<span class="buy-product" @click="btnclick" >去计算({{$store.getters.cartLength}})</span>
</div>
</template>
<script>
import CheckButton from './CheckButton'
import {mapGetters} from 'vuex'
export default {
name: "BottomBar",
components: {
CheckButton
},
computed: {
...mapGetters(['cartList']),
totalPrice(){
return '¥'+this.cartList.filter(item=>{
return item.checked
}).reduce((preValue,item)=>{
return preValue+item.price*item.count
},0).toFixed(2)
},
checkLength(){
return !this.cartList.filter(item=>item.checked).length
},
isSelectAll () {
if(this.cartList.length === 0)
return false
return !this.cartList.find(item=>!item.checked)
}
},
methods: {
checkBtnClick: function () {
// 1.
let isSelectAll = this.$store.getters.cartList.find(item => !item.checked);
// 2.,
if (isSelectAll) {
this.$store.state.cartList.forEach(item => {
item.checked = true;
});
} else {
this.$store.state.cartList.forEach(item => {
item.checked = false;
});
}
},
btnclick(){
if(!this.isSelectAll)
this.$toast.show('请选购商品',2000)
}
}
}
</script>
<style scoped>
.bottom-menu {
width: 100%;
height: 44px;
background-color: #eee;
position: fixed;
bottom: 50px;
left: 0;
box-shadow: 0 -2px 3px rgba(0, 0, 0, .2);
font-size: 14px;
color: #888;
line-height: 44px;
padding-left: 35px;
box-sizing: border-box;
}
.bottom-menu .select-all {
position: absolute;
line-height: 0;
left: 12px;
top: 13px;
}
.bottom-menu .total-price {
margin-left: 15px;
font-size: 16px;
color: #666;
}
.bottom-menu .buy-product {
background-color: orangered;
color: #fff;
width: 100px;
height: 44px;
text-align: center;
line-height: 44px;
float: right;
}
</style>

@ -0,0 +1,43 @@
<template>
<div class="cart">
<scroll class="content" ref="scroll">
<CartListItem v-for="(item,index) in list"
:key="index"
:item-info="item">{{item}}>
</CartListItem>
</scroll>
</div>
</template>
<script>
import Scroll from "@/components/common/Scroll/Scroll";
import CartListItem from "@/views/cart/childComps/CartListItem";
import {mapGetters} from 'vuex'
export default {
name: "CartList",
components: {
Scroll,
CartListItem
},
computed: {
// ...mapGetters(['cartLength','cartList'])
...mapGetters({
list: 'cartList'
})
},
activated(){
this.$refs.scroll.refresh()
}
}
</script>
<style scoped>
.content{
height: calc(100% - 44px - 49px - 40px);
overflow: hidden;
}
</style>

@ -0,0 +1,103 @@
<template>
<div id="shop-item">
<div class="item-selector">
<CheckButton :is-check="itemInfo.checked" @click.native="checkClick"></CheckButton>
</div>
<div class="item-img">
<img :src="itemInfo.image" alt="商品图片">
</div>
<div class="item-info">
<div class="item-title">{{itemInfo.title}}</div>
<div class="item-desc">商品描述: {{itemInfo.desc}}</div>
<div class="info-bottom">
<div class="item-price left">¥{{itemInfo.price}}</div>
<div class="item-count right">x{{itemInfo.count}}</div>
</div>
</div>
</div>
</template>
<script>
import CheckButton from "@/components/content/CheckButton/CheckButton";
export default {
name: "CartListItem",
components: {
CheckButton
},
props:{
itemInfo:{
type:Object,
default(){
return {}
}
}
},
methods:{
checkClick(){
this.itemInfo.checked=!this.itemInfo.checked
}
}
}
</script>
<style scoped>
#shop-item {
width: 100%;
display: flex;
font-size: 0;
padding: 5px;
border-bottom: 1px solid #ccc;
}
.item-selector {
width: 14%;
display: flex;
justify-content: center;
align-items: center;
}
.item-title, .item-desc {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-img {
padding: 5px;
/*border: 1px solid #ccc;*/
}
.item-img img {
width: 80px;
height: 100px;
display: block;
border-radius: 5px;
}
.item-info {
font-size: 17px;
color: #333;
padding: 5px 10px;
position: relative;
overflow: hidden;
}
.item-info .item-desc {
font-size: 14px;
color: #666;
margin-top: 15px;
}
.info-bottom {
margin-top: 10px;
position: absolute;
bottom: 10px;
left: 10px;
right: 10px;
}
.info-bottom .item-price {
color: orangered;
}
</style>

@ -0,0 +1,51 @@
<template>
<div>
<div class="icon-selector" :class="{'selector-active': checked}" @click="selectItem">
<img src="~/assets/img/cart/tick.svg" alt="">
</div>
</div>
</template>
<script>
export default {
name: "CheckButton",
props: {
value: {
type: Boolean,
default: true
}
},
data: function () {
return {
checked: this.value
}
},
methods: {
selectItem: function () {
this.$emit('checkBtnClick')
}
},
watch: {
value: function (newValue) {
this.checked = newValue;
}
}
}
</script>
<style scoped>
.icon-selector {
position: relative;
margin: 0;
width: 18px;
height: 18px;
border-radius: 50%;
border: 2px solid #ccc;
cursor: pointer;
}
.selector-active {
background-color: #ff8198;
border-color: #ff8198;
}
</style>

@ -1,152 +1,196 @@
<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 id="category" >
<NavBar class="nav-bar"><div slot="center">商品分类</div></NavBar>
<div class="content">
<TabMenu :categories="categories"
@selectItem="selectItem">
</TabMenu>
<div id="home">
<scroll id="tab-content"
:data="[categoryData]"
ref="scroll"
:probe-type="3">
<tab-content-category :subcategories="showSubcategory" ></tab-content-category>
<tab-control
:titles="['综合','新品','销量']"
@tabClick="tabClick"
ref="tabControl"></tab-control>
<tab-content-detail :category-detail="showCategoryDetail"></tab-content-detail>
</scroll>
</div>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
import TabMenu from "@/views/category/childComps/TabMenu";
import TabContentDetail from "@/views/category/childComps/TabContentDetail";
import TabContentCategory from "@/views/category/childComps/TabContentCategory";
import Scroll from "@/components/common/Scroll/Scroll";
import NavBar from "@/components/common/navbar/NavBar";
import TabControl from "@/components/content/tabControl/TabControl";
import {getCategory, getSubcategory,getCategoryDetail} from "@/network/category";
import {POP, SELL, NEW} from "@/common/const"
import {tabControlMixin,itemListenerMixin} from "@/common/mixin";
export default {
name: "Category",
components:{
TabMenu,
TabContentDetail,
TabContentCategory,
Scroll,
NavBar,
TabControl,
},
mixins:[tabControlMixin,itemListenerMixin],
data(){
return {
scroll:null
return{
categoryData:{
},
currentIndex:-1,
categories:[],
saveY:0,
}
},
created() {
this._getCategory()
},
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('上拉加载更多');
})
},
computed:{
showSubcategory() {
//
if (this.currentIndex === -1) return {}
return this.categoryData[this.currentIndex].subcategories
},
showCategoryDetail() {
//40
if (this.currentIndex === -1) return []
return this.categoryData[this.currentIndex].categoryDetail[this.currentType]
},
},
methods:{
btnClick(){
console.log('ctnClick');
_getCategory(){
//
getCategory().then(res => {
this.categories = res.data.data.category.list
for (let i = 0; i < this.categories.length; i++) {
this.categoryData[i] = {
//subcategories subclass+category
subcategories: {},
categoryDetail: {
'pop': [],
'new': [],
'sell': []
}
}
}
//index=0
this._getSubcategories(0)
})
},
_getSubcategories(index){
this.currentIndex=index;
const mailKey=this.categories[index].maitKey;
getSubcategory(mailKey).then(res=>{
//
this.categoryData[index].subcategories=res.data.data
//...
this.categoryData={...this.categoryData}
this._getCategoryDetail(POP)
this._getCategoryDetail(SELL)
this._getCategoryDetail(NEW)
})
},
_getCategoryDetail(type) {
// 1.miniWallkey
const miniWallkey = this.categories[this.currentIndex].miniWallkey;
// 2.,miniWallkeytype
getCategoryDetail(miniWallkey, type).then(res => {
// 3.40
this.categoryData[this.currentIndex].categoryDetail[type] = res.data
this.categoryData = {...this.categoryData}
})
},
selectItem(index) {
switch (index) {
case 0:
this.currentType = 'pop'
break
case 1:
this.currentType = 'new'
break
case 2:
this.currentType = 'sell'
break
}
//
this._getSubcategories(index)
}
}
},
activated(){
this.$refs.scroll.refresh()
this.$refs.scroll.scrollTo(0,this.saveY,0)
},
deactivated(){
this.saveY = this.$refs.scroll.getScrollY()
//
this.$bus.$off('itemImgLoad',this.itemImgListener)
}
}
</script>
<style scoped>
.wrapper{
height: 150px;
background-color: red;
#category {
height: 100vh;
position: relative;
}
.nav-bar {
background-color: var(--color-tint);
font-weight: 700;
color: #fff;
}
.content {
position: absolute;
left: 0;
right: 0;
top: 44px;
bottom: 49px;
overflow: hidden;
display: flex;
}
#home{
height: 100vh;
flex: 1;
position: relative;
}
#tab-content {
left: 0;
right: 0;
top:0;
bottom: 49px;
overflow: hidden;
position: absolute;
}
.tab-control{
z-index: 100;
flex: 1;
position: relative;
/*overflow: hidden;*/
overflow-y:scroll;
}
</style>

@ -0,0 +1,60 @@
<template>
<div>
<grid-view :cols="3" :lineSpace="15" :v-margin="20" v-if="subcategories.list">
<div class="item" v-for="(item, index) in subcategories.list" :key="index" >
<a :href="item.link" >
<img class="item-img" :src="item.image" alt="" >
<div class="item-text">{{item.title}}</div>
</a>
</div>
</grid-view>
</div>
</template>
<script>
import GridView from "@/components/common/gridView/GridView";
export default {
name: "TabContentCategory",
components: {
GridView
},
data(){
return{
isLoad:false,
visible: false,
ImgKey: '',
number:0
}
},
props: {
subcategories: {
type: Object,
default() {
return []
}
}
},
methods:{
},
}
</script>
<style scoped>
.panel img {
width: 100%;
}
.item {
text-align: center;
font-size: 12px;
}
.item-img {
width: 80%;
}
.item-text {
margin-top: 15px;
}
</style>

@ -0,0 +1,30 @@
<template>
<Grid-view>
<Goods-list-item v-for="(item, index) in categoryDetail" :key="index" :goods-item="item"></Goods-list-item>
</Grid-view>
</template>
<script>
import GridView from "@/components/common/gridView/GridView";
import GoodsListItem from "@/components/content/goods/GoodsListItem";
export default {
name: "TabContentDetail",
components: {
GridView,
GoodsListItem
},
props: {
categoryDetail: {
type: Array,
default() {
return []
}
}
},
}
</script>
<style scoped>
</style>

@ -0,0 +1,62 @@
<template>
<scroll id="tab-menu">
<div class="menu-list">
<div class="menu-list-item"
:class="{active: index===currentIndex}"
v-for="(item, index) in categories"
:key="index"
@click="itemClick(index)">
{{item.title}}
</div>
</div>
</scroll>
</template>
<script>
import Scroll from "@/components/common/Scroll/Scroll";
export default {
name: "TabMenu",
components: {
Scroll
},
props: {
categories: Array
},
data() {
return {
currentIndex: 0
}
},
methods: {
itemClick(index) {
this.$store.state.counter=0
this.currentIndex = index
this.$emit('selectItem', index)
}
}
}
</script>
<style scoped>
#tab-menu {
background-color: #f6f6f6;
height: 100%;
width: 100px;
box-sizing: border-box;
}
.menu-list-item {
height: 45px;
line-height: 45px;
text-align: center;
font-size: 14px;
}
.menu-list-item.active {
font-weight: 700;
color: var(--color-high-text);
background-color: #fff;
border-left: 3px solid var(--color-high-text);
}
</style>

@ -5,16 +5,17 @@
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>
<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>
<detail-bottom-bar class="bottom-nav" @addToCart="addToCart"/>
<back-top @click.native="backClick" v-show="isShowBackTop"/>
<detail-bottom-bar @addToCart="addToCart"/>
</div>
</template>
@ -69,6 +70,9 @@ export default {
themeTopYs: [],
getThemeTopY: null,
currentIndex:0,
message:'',
show:false
}
},
created() {
@ -132,7 +136,6 @@ export default {
{
this .currentIndex=i;
this.$refs.nav.currentIndex=this.currentIndex
}
}
},
@ -143,7 +146,16 @@ export default {
},
//
addToCart(){
console.log('----');
//西
const product={}
product.image=this.topImages[0];
product.title=this.detailInfo.title;
product.desc=this.detailInfo.desc;
product.price=this.goods.nowPrice;
product.iid=this.iid;
this.$store.dispatch('addCart',product).then(res=>{
this.$toast.show(res,2000)
})
}
}
}

@ -29,7 +29,7 @@ name: "DetailSwiper",
<style scoped>
.swiper-item{
height: 200px;
height: 400px;
overflow: hidden;
}
</style>

@ -126,11 +126,11 @@ export default {
},
//
activated(){
this.$refs.scroll.scrollTo(0,this.saveY,0)
this.$refs.scroll.refresh()
this.$refs.scroll.scrollTo(0,this.saveY,0)
},
deactivated(){
this.saveY = this.$refs.scroll.getScrolly()
this.saveY = this.$refs.scroll.getScrollY()
//
this.$bus.$off('itemImgLoad',this.itemImgListener)
}
@ -168,6 +168,6 @@ export default {
/*}*/
.tab-control{
position: relative;
z-index: 9;
z-index: 24;
}
</style>

@ -1,15 +1,109 @@
<template>
<div>
<h2>我的</h2>
<div id="profile">
<nav-bar class="nav-bar"><div slot="center">小码哥商城</div></nav-bar>
<!--1.单独封装一个组件: 利用slot知识点-->
<UserInfo></UserInfo>
<!--2.没有单独封装: 不同的地方太多, 需要传过多的参数-->
<section class="account">
<div class="account-item">
<div class="number">
<span class="balance">0.00</span>
</div>
<div class="account-info">我的余额</div>
</div>
<div class="account-item">
<div class="number">
<span class="balance">0</span>
</div>
<div class="account-info">我的优惠</div>
</div>
<div class="account-item">
<div class="number">
<span class="balance">0</span>
</div>
<div class="account-info">我的积分</div>
</div>
</section>
<!--3.封装成一个整体-->
<list-view :list-data="orderList" class="order-list"></list-view>
<list-view :list-data="serviceList" class="service-list"></list-view>
</div>
</template>
<script>
export default {
name: "Profile"
}
import UserInfo from './childComps/UserInfo'
import ListView from './childComps/ListView'
import NavBar from "@/components/common/navbar/NavBar";
export default {
name: "Profile",
components: {
UserInfo, ListView, NavBar
},
data: function () {
return {
orderList: [
{icon: '#order', iconColor: '#ff8198', info: '我的消息'},
{icon: '#point', iconColor: '#fc7b53', info: '积分商城'},
{icon: '#vip', iconColor: '#ffc636', info: '会员卡'},
],
serviceList: [
{icon: '#service', iconColor: '#ff8198', info: '我的购物车'},
{icon: '#download', iconColor: '#ff8198', info: '下载购物APP'},
]
}
},
mounted: function () {
}
}
</script>
<style scoped>
#profile {
background-color: #f2f2f2;
}
.nav-bar {
background-color: var(--color-tint);
font-weight: 700;
color: #fff;
}
.account {
display: flex;
}
.account-item {
width: 100%;
background-color: #fff;
margin-right: 1px;
text-align: center;
}
.account-item:last-of-type {
margin-right: 0;
}
.account-item {
color: #666;
font-size: 13px;
padding: 18px;
}
.account-item .balance {
font-size: 24px;
font-weight: 700;
color: #ff5f3e;
}
.account-info {
margin-top: 6px;
}
.order-list, .service-list {
margin-top: 12px;
}
</style>

@ -0,0 +1,60 @@
<template>
<div id="list">
<div v-for="(item, index) in listData" :key="index" class="item">
<span class="icon">
<svg :fill="item.iconColor"><use :xlink:href="item.icon"></use></svg>
</span>
<div class="info">{{item.info}}</div>
</div>
</div>
</template>
<script>
export default {
name: "ListView",
props: {
listData: {
type: Array,
default: function () {
return []
}
}
}
}
</script>
<style scoped>
#list {
background-color: #fff;
font-size: 15px;
color: #333;
}
#list .item {
height: 44px;
line-height: 44px;
position: relative;
}
.icon svg {
width: 18px;
height: 18px;
}
.item .icon {
margin-top: 10px;
position: absolute;
left: 16px;
top: -7px;
}
.item .info {
margin-left: 40px;
border-bottom: 1px solid rgba(100, 100, 100, .1);
padding-left: 5px;
}
.item:last-of-type .info {
border-bottom: none;
}
</style>

@ -0,0 +1,76 @@
<template>
<div id="user-info">
<a href="#" class="clear-fix">
<slot name="user-icon">
<svg class="privateImage-svg left">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#avatar-default"></use>
</svg>
</slot>
<div class="login-info left">
<slot name="user-nickname">
<div>登录/注册</div>
</slot>
<div class="phone">
<span>
<svg data-v-735ff1be="" fill="#fff" class="icon-mobile"><use data-v-735ff1be="" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#mobile"></use></svg>
</span>
<slot name="user-phone">暂无绑定手机号</slot>
</div>
</div>
<svg data-v-735ff1be="" fill="#fff" class="arrow-svg right"><use data-v-735ff1be="" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#arrow-right"></use></svg>
</a>
</div>
</template>
<script>
export default {
name: "UserInfo"
}
</script>
<style scoped>
#user-info {
background-color: var(--color-tint);
padding: 15px;
margin-top: -5px;
}
#user-info .privateImage-svg {
width: 60px;
height: 60px;
background-color: #fff;
border-radius: 30px;
}
.left {
float: left;
}
#user-info .arrow-svg {
width: 11px;
height: 22px;
margin-top: 18px;
}
#user-info .login-info {
color: #fff;
margin: 10px 0 0 10px;
}
#user-info .login-info .phone {
position: relative;
font-size: 13px;
margin-top: 5px;
margin-left: 15px;
font-weight: 300;
}
#user-info .login-info .phone .icon-mobile {
position: absolute;
width: 12px;
height: 18px;
left: -15px;
top: 0px;
}
</style>
Loading…
Cancel
Save