c
This commit is contained in:
parent
3ac5e9147c
commit
caa654ec65
@ -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>
|
53
src/components/SearchGoodsBox.vue
Normal file
53
src/components/SearchGoodsBox.vue
Normal 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>
|
@ -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);
|
||||
|
||||
|
@ -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
3
src/style.less
Normal file
@ -0,0 +1,3 @@
|
||||
.text-center{
|
||||
text-align:center;
|
||||
}
|
130
src/views/Cart.vue
Normal file
130
src/views/Cart.vue
Normal 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>
|
@ -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 {
|
||||
|
@ -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: '提示',
|
||||
|
@ -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
13
src/views/Orders.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<h1>订单列表</h1>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Orders"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -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>
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user