This commit is contained in:
LittleBoy 2021-01-01 10:07:56 +08:00
parent 3ac5e9147c
commit caa654ec65
12 changed files with 306 additions and 241 deletions

View File

@ -1,10 +1,10 @@
<template>
<div>
<div id="app-content" style="padding-bottom:50px;">
<keep-alive>
<!-- <keep-alive>-->
<!-- 缓存加载过的界面 -->
<router-view />
</keep-alive>
<!-- </keep-alive>-->
</div>
<van-tabbar v-model="active">
<van-tabbar-item name="home" replace to="/" icon="home-o">首页</van-tabbar-item>
@ -15,11 +15,29 @@
</div>
</template>
<script>
const navKeys = {
'/':'home',
'/cate':'cate',
'/cart':'cart',
'/my':'my'
}
export default {
data(){
return {
active: 'home',
}
},
mounted() {
if(navKeys[this.$route.path]){
this.active = navKeys[this.$route.path];
}else{
this.active = 'home'
}
},
watch:{
// '$route'(){
//
// }
}
}
</script>

View File

@ -0,0 +1,53 @@
<template>
<div class="search-box">
<!-- left-icon="none" right-icon="search"-->
<van-search shape="round" v-model="searchValue" :placeholder="placeholder"/>
</div>
</template>
<script>
export default {
name: "SearchGoodsBox",
data() {
return {
index:0,
suggestList:['小米11','红米8A 8+128','RTX3090'],
searchValue: '',
placeholder: '',
timer:null,
interval:2000
}
},
mounted() {
this.show()
this.start()
},
methods:{
start(){
this.stop();
this.timer = setTimeout(()=>this.show(),this.interval)
},
show(){
let {index,suggestList} = this;
if(suggestList.length > 0){
if(index >= suggestList.length){
this.index = index = 0;
}
this.placeholder = suggestList[index];
this.index ++;
this.timer = setTimeout(()=>this.show(),this.interval)
}
},
stop(){
if(this.timer){
setTimeout(this.timer)
this.timer = null;
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,14 +1,13 @@
import Vue from 'vue'
import App from './App.vue'
import 'element-ui/lib/theme-chalk/index.css'
import ElementUI from "element-ui"
// import 'element-ui/lib/theme-chalk/index.css'
import router from './router'
import Vant from 'vant';
import 'vant/lib/index.css';
import './style.less';
import { Lazyload } from 'vant';
Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(Vant);
Vue.use(Lazyload);

View File

@ -8,49 +8,59 @@ import Vuex from 'vuex'
Vue.use(Vuex)
Vue.use(Router)
const router = new Router({
routes: [{
routes: [
{
path: '/',
component: Layout,
children: [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/cate',
name: 'Category',
component: () => import( /* webpackChunkName: "Category" */ './views/Category.vue')
},
{
path: '/cart',
name: 'Cart',
component: () => import( /* webpackChunkName: "Cart" */ './views/Cart.vue')
},
{
path: '/my',
name: 'Orders',
component: () => import( /* webpackChunkName: "Orders" */ './views/Orders.vue')
}
]
},
{
path: '/login',
name: 'Login',
component: () => import( /* webpackChunkName: "Login" */ './views/Login.vue')
},
{
path: '/goods-list',
name: 'GoodsList',
component: () => import( /* webpackChunkName: "GoodsList" */ './views/GoodsList.vue')
},
{
path: '/goods-detail',
name: 'GoodsDetail',
component: () => import( /* webpackChunkName: "GoodsDetail" */ './views/Detail.vue')
}
path: '/',
component: Layout,
children: [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/cate',
name: 'Category',
component: () => import( /* webpackChunkName: "Category" */ './views/Category.vue')
}
]
},
{
path: '/login',
name: 'Login',
component: () => import( /* webpackChunkName: "Login" */ './views/Login.vue')
},
{
path: '/goods-list',
name: 'GoodsList',
component: () => import( /* webpackChunkName: "GoodsList" */ './views/GoodsList.vue')
},
{
path: '/goods-detail',
name: 'GoodsDetail',
component: () => import( /* webpackChunkName: "GoodsDetail" */ './views/Detail.vue')
}
]
]
});
router.beforeEach((to, from, next) => {
// if(to.path != '/login'){
// if(store.state.user.userId < 1){
// next({path:'/login'});
// return;
// }
// }
next();
// if(to.path != '/login'){
// if(store.state.user.userId < 1){
// next({path:'/login'});
// return;
// }
// }
next();
});
export default router;

3
src/style.less Normal file
View File

@ -0,0 +1,3 @@
.text-center{
text-align:center;
}

130
src/views/Cart.vue Normal file
View File

@ -0,0 +1,130 @@
<template>
<div class="page-cart">
<van-nav-bar
title="购物车"
:fixed="true"
/>
<div style="height: 50px"></div>
<van-checkbox-group v-model="checkedGroup" ref="checkboxGroup">
<van-card
:price="item.sell_price"
:desc="item.desc"
v-for="(item,index) in goodsList"
:key="index"
>
<template slot="title"> <!-- 自定义标题部分主要是为了添加删除商品按钮 -->
<span>{{item.title}}</span>
<span style="float:right;" @click="remove(item)"><van-icon name="delete"/></span>
</template>
<template slot="thumb"> <!-- 自定义左侧部分为了添加左侧checkbox -->
<van-checkbox :name="item.id" checked-color="#b90505" icon-size="12px"></van-checkbox>
<van-image :src="item.picture"></van-image>
</template>
<template slot="bottom"> <!-- 自定义底部为了实现商品数量功能 -->
<div class="num">
<van-button size="small" @click="less(item)" :disabled="item.count <=1">-</van-button>
<!-- 数量小于1时禁用按钮 -->
{{item.count}}
<van-button size="small" @click="more(item)">+</van-button>
</div>
</template>
</van-card>
</van-checkbox-group>
<div style="height: 50px;"></div>
<van-submit-bar class="my-cart" :price="totalPrice" button-text="提交订单" @submit="onSubmit" :disabled="checkedGroup.length == 0">
<van-checkbox v-model="isCheckAll">全选</van-checkbox>
</van-submit-bar>
</div>
</template>
<script>
import {Dialog} from "vant";
import http from "../components/http";
export default {
name: "Cart",
data() {
let token = localStorage.getItem('gg_user_token');
return {
token,
checkedGroup: [],
goodsList: [],
checkedAllGoods:false,
}
},
computed:{
totalPrice(){
return 0;
},
isCheckAll:{
set(v){
this.$refs.checkboxGroup.toggleAll(v);
this.checkedAllGoods = 0;
},
get(){
return (this.goodsList.length == 0 || this.checkedGroup.length != this.goodsList.length)?false:true;
}
}
},
mounted() {
if(!this.token){
Dialog.alert({
title: '提示',
message: '请先登录一下下哟',
}).then(() => {
this.$router.push('/login?from=' + this.$route.fullPath);
});
return;
}
this.loadData();
},
methods: {
onSubmit(){
if(this.checkedGroup.length > 0){
}
},
checkAll(){
if(this.checkedGroup.length !== 0){ //
if(this.checkedGroup.length === this.goodsList.length){ //
this.$refs.checkboxGroup.toggleAll(false); //
}else{ //
this.$refs.checkboxGroup.toggleAll(true); //
}
}else{ //
this.$refs.checkboxGroup.toggleAll(true);
}
},
loadData(){
http.shop.get('/cart/query?token=' + this.token).then(gs=>{
this.goodsList = gs
}).catch(e=>{
Dialog.alert({
title: '提示',
message: e.message,
}).then(() => {
this.$router.back();
});
});
},
more(g) {
g.count ++
},
less(g) {
if(g.count > 1){
g.count --
}
},
remove(g) {
}
}
}
</script>
<style scoped>
.my-cart{
bottom:50px;
}
</style>

View File

@ -1,13 +1,6 @@
<template>
<div class="category" style="display: flex;flex-direction: column;height: calc(100vh - 50px);">
<van-nav-bar title="标题"
left-text="返回"
left-arrow
@click-left="$router.back()">
<template #title>
<van-search v-model="searchValue" placeholder="请输入搜索关键词" />
</template>
</van-nav-bar>
<search-goods-box />
<van-tree-select style="flex:1"
:items="items"
:active-id.sync="activeId"
@ -18,8 +11,10 @@
</template>
<script>
import SearchGoodsBox from "../components/SearchGoodsBox";
export default {
name: "Category",
components: {SearchGoodsBox},
data() {
return {

View File

@ -64,6 +64,17 @@
top: 1px;
}
}
.content{
padding:20px 10px;
}
.van-icon-checked{
font-size: 22px;
vertical-align: bottom;
}
.message-title{
color:#c90;
}
</style>
<template>
@ -99,6 +110,15 @@
</van-popup>
<div style="height:50px;"></div>
</div>
<van-action-sheet v-model="showSuccess" cancel-text="确定"
close-on-click-action>
<div class="content">
<div class="text-center message-title">
<i class="van-icon van-icon-checked"></i>
<span>添加到购物车成功</span>
</div>
</div>
</van-action-sheet>
<van-goods-action>
<van-goods-action-icon icon="chat-o" text="客服" @click="onClickIcon" />
<van-goods-action-icon icon="cart-o" text="购物车" @click="$router.push('/cart')" />
@ -137,7 +157,8 @@ export default {
g:{
title:'',
picture:''
}
},
showSuccess:true
};
},
filters: {
@ -185,7 +206,8 @@ export default {
return;
}
http.shop.post('/cart/add',{token:this.token,goodsId:this.id,count:1}).then(ret=>{
Notify({message: '添加到购物车成功',duration: 3000})
// Notify({message: '',duration: 3000})
this.showSuccess = true;
}).catch(e=>{
Dialog.alert({
title: '提示',

View File

@ -3,10 +3,9 @@
color: #fff;
font-size: 20px;
text-align: center;
height: 170px;
img{
width: 100%;
height: 170px;
/*height:calc(277px / (720px / 100%));*/
}
}
.page-home{
@ -16,10 +15,11 @@
<template>
<div class="page-home">
<search-goods-box />
<div class="swiper-wrapper">
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="(s, index) in swipes" :key="index">
<img v-lazy="s.img" />
<img :src="s.img" />
</van-swipe-item>
</van-swipe>
</div>
@ -37,12 +37,14 @@
// @ is an alias to /src
import http from "../components/http";
import GoodsList from '../components/GoodsList'
import SearchGoodsBox from "../components/SearchGoodsBox";
export default {
name: "home",
components:{GoodsList},
components:{SearchGoodsBox, GoodsList},
data() {
return {
swipes:[
{name:'24期免息',img:'//m.360buyimg.com/mobilecms/s700x280_jfs/t1/145540/4/18667/107221/5fd8c5a7Ed54a9545/14e408a6ee76c316.jpg!cr_1125x445_0_171!q70.jpg.dpg',url:'/goods-list?cate=显示器'},
{name:'茶油',img:'//m.360buyimg.com/mobilecms/s700x280_jfs/t1/149172/3/18184/263815/5fd5c4d5E1740ade6/a05ecfaaa05026a4.jpg!cr_1125x445_0_171!q70.jpg.dpg',url:'/goods-list?cate=茶油'},
@ -51,7 +53,8 @@ export default {
loading: false,
dataList: [],
total: 0,
pageSize: 15
pageSize: 15,
swipe_height:170
};
},
mounted() {

13
src/views/Orders.vue Normal file
View File

@ -0,0 +1,13 @@
<template>
<h1>订单列表</h1>
</template>
<script>
export default {
name: "Orders"
}
</script>
<style scoped>
</style>

View File

@ -1,88 +0,0 @@
<style lang="less">
.home {
width: 1000px;
margin: 50px auto;
.page-container{
margin-top: 10px;
}
}
</style>
<template>
<div class="home" v-loading="loading">
<img alt="Vue logo" src="../assets/logo.png">
<el-table :data="userList" style="width: 100%" border>
<el-table-column prop="userId" label="用户编号" width="150">
</el-table-column>
<el-table-column prop="userName" label="用户名" width="120">
</el-table-column>
<el-table-column prop="email" label="邮箱">
</el-table-column>
<el-table-column prop="salt" label="加密盐" width="120">
</el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button @click.native.prevent="resetPwd(scope.$index)" type="text" size="small">
重置密码
</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-container">
<el-pagination layout="prev, pager, next" @current-change="onPageChange" :total="total" :page-size="pageSize"></el-pagination>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import http from '../components/http';
export default {
name: "home",
data() {
return {
loading: false,
userList: [],
total: 0,
pageSize: 15
}
},
mounted() {
document.title = "用户列表";
this.loadData(1);
},
methods: {
onPageChange(page){
this.loadData(page);
},
loadData(page) {
this.loading = true;
http.get('/user/all?page=' + page).then(data => {
this.loading = false;
this.userList = data.list;
this.total = data.total;
this.pageSize = data.page_size;
}).catch(err => {
this.loading = false;
this.$message.error({
title: err
});
})
},
resetPwd(index) {
this.loading = true;
const user = this.userList[index];
setTimeout(() => {
this.loading = false;
this.$notify({
title: '提示',
message: user.userName + '的密码重置成功'
});
}, Math.ceil(Math.random() * 500) + 500);
}
}
};
</script>

View File

@ -1,93 +0,0 @@
<style lang="less">
.login {
width: 400px;
margin: 50px auto 0;
.display-block {
display: block;
width: 100%;
}
.error-notice {
color: #f56c6c;
font-size: 12px;
text-align: left;
}
}
</style>
<template>
<div class="login">
<el-form :model="loginForm" status-icon :rules="loginRule" ref="loginForm" label-width="0px" class="demo-ruleForm">
<el-form-item prop="userName">
<el-input type="text" placeholder="请输入用户名" @keyup.enter.native="submitForm('loginForm')" v-model="loginForm.userName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" @keyup.enter.native="submitForm('loginForm')" v-model="loginForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button class="display-block" :loading="loging" type="primary" @click="submitForm('loginForm')">提交</el-button>
</el-form-item>
<div class="error-notice">{{errorMessage}}</div>
</el-form>
</div>
</template>
<script>
import http from "../components/http";
import store from '../components/Store';
export default {
mounted() {
document.title = "登录";
},
data() {
return {
loginForm: {
userName: "",
password: "",
valicode: "m8k2"
},
errorMessage: "",
loging: false,
loginRule: {
userName: [{
required: true,
message: "请输入登录用户名",
trigger: "blur"
}],
password: [{
required: true,
message: "请输入登录密码",
trigger: "blur"
}]
}
};
},
methods: {
submitForm() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loging = true;
http
.post("/user/login", this.loginForm)
.then(ret => {
store.commit('login', ret);
this.$router.push('/');
})
.catch(err => {
this.loging = false;
this.errorMessage = err;
console.log(err);
});
} else {
console.log("表单填写错误");
return false;
}
});
},
resetForm() {}
}
};
</script>