├── src ├── store │ ├── actions.js │ ├── state.js │ ├── getters.js │ ├── mutation-types.js │ ├── index.js │ └── mutations.js ├── .DS_Store ├── assets │ └── logo.png ├── components │ ├── .DS_Store │ └── NoPage.vue ├── api │ ├── upload.js │ ├── category.js │ ├── product.js │ ├── address.js │ ├── cart.js │ ├── user.js │ └── order.js ├── mixins │ └── dataMixin.js ├── lang │ ├── index.js │ ├── zh.js │ └── en.js ├── utils │ ├── strategies.js │ └── axios.js ├── App.vue ├── views │ ├── Home │ │ └── index.vue │ ├── member │ │ ├── Set.vue │ │ ├── Member.vue │ │ ├── Register.vue │ │ ├── Login.vue │ │ └── Info.vue │ ├── address │ │ ├── Address.vue │ │ └── AddAddress.vue │ ├── category │ │ └── Category.vue │ ├── product │ │ └── Product.vue │ ├── order │ │ ├── Order.vue │ │ └── OrderWait.vue │ ├── detail │ │ └── Detail.vue │ └── cart │ │ └── Cart.vue ├── main.js └── router.js ├── .browserslistrc ├── .DS_Store ├── id_rsa.enc ├── public ├── favicon.ico ├── img │ ├── favicon.png │ └── github.png ├── less │ ├── variable.less │ └── base.less └── index.html ├── postcss.config.js ├── babel.config.js ├── .gitignore ├── server.js ├── .eslintrc.js ├── .travis.yml ├── LICENSE ├── README.md ├── package.json └── vue.config.js /src/store/actions.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/.DS_Store -------------------------------------------------------------------------------- /id_rsa.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/id_rsa.enc -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/public/img/favicon.png -------------------------------------------------------------------------------- /public/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/public/img/github.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/components/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czero1995/fancy-store/HEAD/src/components/.DS_Store -------------------------------------------------------------------------------- /src/store/state.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | user: { user: "", avatar: "" } 3 | }; 4 | export default state; 5 | -------------------------------------------------------------------------------- /src/api/upload.js: -------------------------------------------------------------------------------- 1 | import axios from "../utils/axios"; 2 | 3 | export function apiGetQiNiuToken() { 4 | return axios.post("token/qiniu"); 5 | } 6 | -------------------------------------------------------------------------------- /src/api/category.js: -------------------------------------------------------------------------------- 1 | import axios from "../utils/axios"; 2 | 3 | export function apiGetCategoryMenu() { 4 | return axios.get(`category/all`); 5 | } 6 | -------------------------------------------------------------------------------- /public/less/variable.less: -------------------------------------------------------------------------------- 1 | @theme_background: #6495ed; 2 | @theme_hover: #6495ed; 3 | @theme_color: #6495ed; 4 | @base_color: white; 5 | @base_textSize: 14px; 6 | @base_textColor: black; 7 | @base_boder: 1px solid #ccc; 8 | -------------------------------------------------------------------------------- /src/mixins/dataMixin.js: -------------------------------------------------------------------------------- 1 | export const dataMixin = { 2 | data() { 3 | return { 4 | title: "" 5 | }; 6 | }, 7 | components: { 8 | Nopage: () => import("../components/NoPage") 9 | }, 10 | computed: {}, 11 | methods: {} 12 | }; 13 | -------------------------------------------------------------------------------- /src/store/getters.js: -------------------------------------------------------------------------------- 1 | export const goods = state => state.goods; 2 | export const orders = state => state.orders; 3 | export const orderStatus = state => state.orderStatus; 4 | export const user = state => state.user; 5 | export const address = state => state.address; 6 | export const addressStatus = state => state.addressStatus; 7 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"], 3 | plugins: [ 4 | [ 5 | "import", 6 | { 7 | libraryName: "vant", 8 | libraryDirectory: "es", 9 | style: true 10 | }, 11 | "vant" 12 | ] 13 | ] 14 | }; 15 | -------------------------------------------------------------------------------- /src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | export const SET_GOODS = "SET_GOODS"; 2 | export const SET_ORDERS = "SET_ORDERS"; 3 | export const SET_ORDERS_STATUS = "SET_ORDERS_STATUS"; 4 | export const SET_USER = "SET_USER"; 5 | export const SET_ADDRESS = "SET_ADDRESS"; 6 | export const SET_ADDRESS_STATUS = "SET_ADDRESS_STATUS"; 7 | export const SET_RESET = "SET_RESET"; 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | .idea 5 | .editorconfig 6 | .project 7 | # local env files 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw* 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/lang/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import VueI18n from "vue-i18n"; 3 | Vue.use(VueI18n); 4 | export default new VueI18n({ 5 | locale: localStorage.getItem("lang") || "zh", // 语言标识 6 | //this.$i18n.locale // 通过切换locale的值来实现语言切换 7 | messages: { 8 | zh: require("./zh"), // 中文语言包 9 | en: require("./en") // 英文语言包 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /src/api/product.js: -------------------------------------------------------------------------------- 1 | import axios from "../utils/axios"; 2 | 3 | export function apiGetProduct(pageNum, categoryUid) { 4 | return axios.get(`product/all?pageNum=${pageNum}&categoryUid=${categoryUid}`); 5 | } 6 | export function apiGetBanner() { 7 | return axios.get(`banner/all`); 8 | } 9 | export function apiGetDetail(uid) { 10 | return axios.get(`product/detail?uid=${uid}`); 11 | } 12 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var http = require("http"); 2 | var fs = require("fs"); 3 | 4 | var myServer = http.createServer(function(req, res) { 5 | var html = fs.readFileSync("./dist/index.html"); 6 | res.write(html); 7 | res.end(); 8 | }); 9 | 10 | myServer.listen("3100", function(err) { 11 | if (err) { 12 | console.log(err); 13 | throw err; 14 | } 15 | console.log("服务器3100"); 16 | }); 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "eslint:recommended"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", 10 | "no-mixed-spaces-and-tabs": "off" 11 | }, 12 | parserOptions: { 13 | parser: "babel-eslint" 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /src/api/address.js: -------------------------------------------------------------------------------- 1 | import axios from "../utils/axios"; 2 | 3 | export function apiAddAddress(paramsInfo) { 4 | return axios.post(`address/add`, { ...paramsInfo }); 5 | } 6 | 7 | export function apiUpdateAddress(addressInfo, uid) { 8 | return axios.post(`address/update`, { params: { ...addressInfo }, uid }); 9 | } 10 | 11 | export function apiGetAddress() { 12 | return axios.get(`address/all`); 13 | } 14 | 15 | export function apiDeleteAddress(uid) { 16 | return axios.post(`address/delete`, { uid }); 17 | } 18 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | import * as actions from "./actions"; 4 | import * as getters from "./getters"; 5 | import state from "./state"; 6 | import mutations from "./mutations"; 7 | import createLogger from "vuex/dist/logger"; 8 | const debug = process.env.NODE_ENV !== "production"; 9 | 10 | Vue.use(Vuex); 11 | export default new Vuex.Store({ 12 | actions, 13 | getters, 14 | state, 15 | mutations, 16 | strice: debug, 17 | plugins: debug ? [createLogger()] : [] 18 | }); 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 11.9.0 4 | branchs: 5 | only: 6 | - master 7 | before_install: 8 | - openssl aes-256-cbc -K $encrypted_87bf11d507f0_key -iv $encrypted_87bf11d507f0_iv 9 | -in id_rsa.enc -out ~/.ssh/id_rsa -d 10 | - chmod 600 ~/.ssh/id_rsa 11 | - echo -e "Host 47.98.240.154\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config 12 | script: 13 | - npm install -g cnpm --registry=https://registry.npm.taobao.org 14 | - cnpm install 15 | - npm run build 16 | - scp -r dist root@47.98.240.154:/var/www/html/fancy 17 | -------------------------------------------------------------------------------- /src/api/cart.js: -------------------------------------------------------------------------------- 1 | import axios from "../utils/axios"; 2 | 3 | export function apiActionCart(uid, action) { 4 | return axios.post(`cart/action`, { productId: uid, action }); 5 | } 6 | export function apiAddCart(uid) { 7 | return axios.post(`cart/add`, { productId: uid }); 8 | } 9 | export function apiCutCart(uid) { 10 | return axios.post(`cart/cut`, { productId: uid }); 11 | } 12 | export function apiDeleteCart(productId) { 13 | return axios.post(`cart/delete`, { productId }); 14 | } 15 | 16 | export function apiGetCart() { 17 | return axios.get(`cart/all`); 18 | } 19 | -------------------------------------------------------------------------------- /src/api/user.js: -------------------------------------------------------------------------------- 1 | import axios from "../utils/axios"; 2 | 3 | export function apiLogin(user, pwd) { 4 | return axios.post(`/user/login`, { user, pwd }); 5 | } 6 | 7 | export function apiRegister(user, pwd) { 8 | return axios.post(`/user/register`, { user, pwd }); 9 | } 10 | 11 | export function apiGetUser() { 12 | return axios.get(`/user/info`); 13 | } 14 | 15 | export function apiEditUser(params) { 16 | return axios.post(`user/update`, { 17 | params: params 18 | }); 19 | } 20 | 21 | export function apiLogOut() { 22 | return axios.post(`user/logout`); 23 | } 24 | -------------------------------------------------------------------------------- /src/utils/strategies.js: -------------------------------------------------------------------------------- 1 | export let strategies = { 2 | isNonEmpty(value, errorMsg) { 3 | if (value == "" || value == null) { 4 | return errorMsg; 5 | } 6 | }, 7 | isMobile(value, errorMsg) { 8 | if (!/(^1[3|4|5|7|8][0-9]{9}$)/.test(value)) { 9 | return errorMsg; 10 | } 11 | }, 12 | minLength(value, length, errorMsg) { 13 | if (value.length < length) { 14 | return errorMsg; 15 | } 16 | }, 17 | isEqual(valueOne, valueTwo, errMsg) { 18 | if (valueOne != valueTwo) { 19 | return errMsg; 20 | } 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /src/api/order.js: -------------------------------------------------------------------------------- 1 | import axios from "../utils/axios"; 2 | 3 | export function apiAddOrder(productIds, address, price, status) { 4 | return axios.post(`order/add`, { 5 | productIds: productIds, 6 | address: address, 7 | price: price, 8 | status: status 9 | }); 10 | } 11 | 12 | export function apiGetOrder(status) { 13 | return axios.get(`order/all?status=${status}`); 14 | } 15 | 16 | export function apiDeleteOrder(uid) { 17 | return axios.post(`order/delete`, { uid }); 18 | } 19 | export function apiUpdateOrder(uid, status) { 20 | console.log("uid", uid); 21 | return axios.post(`order/update`, { 22 | uid: uid, 23 | params: { status } 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /src/store/mutations.js: -------------------------------------------------------------------------------- 1 | import * as types from "./mutation-types"; 2 | const matutaions = { 3 | [types.SET_ORDERS](state, orders) { 4 | state.orders = orders; 5 | }, 6 | [types.SET_ORDERS_STATUS](state, orderStatus) { 7 | state.orderStatus = orderStatus; 8 | }, 9 | [types.SET_USER](state, user) { 10 | state.user = user; 11 | }, 12 | [types.SET_ADDRESS](state, address) { 13 | state.address = address; 14 | }, 15 | [types.SET_ADDRESS_STATUS](state, addressStatus) { 16 | state.addressStatus = addressStatus; 17 | }, 18 | [types.SET_RESET](state) { 19 | state.carts = []; 20 | state.user = {}; 21 | state.cartsLength = 0; 22 | state.orderStatus = "paying"; 23 | state.orders = []; 24 | state.addressStatus = ""; 25 | state.address = {}; 26 | } 27 | }; 28 | export default matutaions; 29 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 20 | 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Rick 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | <% for (var i in 13 | htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %> 14 | 15 | 16 | <% } %> 17 | 18 | FancyStore 19 | 20 | 21 | 22 | 26 |
27 | 28 | <% for (var i in 29 | htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %> 30 | 31 | <% } %> 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/components/NoPage.vue: -------------------------------------------------------------------------------- 1 | 10 | 39 | 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 在线预览: 2 | 3 | [https://www.fancystore.cn](https://www.fancystore.cn) 4 | 5 | ![](https://user-gold-cdn.xitu.io/2019/5/17/16ac5dbf00191132?w=374&h=666&f=gif&s=1528988) 6 | 7 | ### 手机直接扫描二维码真机体验: 8 | 9 | ![](https://user-gold-cdn.xitu.io/2019/5/17/16ac3f6e813f1c21?w=256&h=256&f=png&s=6784) 10 | 11 | # 项目详情介绍: 12 | 13 | [https://juejin.im/post/5cdca7595188257cf051a06a](https://juejin.im/post/5cdca7595188257cf051a06a) 14 | 15 | ## 历史版本 16 | 17 | 1. 基于 Vue-CLI2.0:[点我查看](https://github.com/czero1995/fancy-store/tree/vue-cli2.0) 18 | 19 | `这个分支版本是一两年前的,基于Vue-CLI2.0写的,数据请求是Mock,纯前端的项目。` 20 | 21 | 2. 基于 Vue-CLI3.0:[点我查看](https://github.com/czero1995/fancy-store/tree/vue-cli3--mock) 22 | 23 | `这个分支版本是基于Vue-CLI3.0的,将脚手架从2.0迁移升级到了3.0,遇到的一些问题和坑也都填完了~也是纯Web端Mock模拟数据的项目。` 24 | 25 | # Github: 26 | 27 | 前端: [https://github.com/czero1995/fancy-store](https://github.com/czero1995/fancy-store) 28 | 29 | 服务端: [https://github.com/czero1995/fancy-store-server.git](https://github.com/czero1995/fancy-store-server.git) 30 | 31 | 后台管理 CMS: [https://github.com/czero1995/fancy-store-admin.git](https://github.com/czero1995/fancy-store-admin.git) 32 | 33 | # 使用说明 34 | 35 | ### 克隆项目 36 | 37 | https://github.com/czero1995/fancy-store.git 38 | 39 | ### 安装依赖 40 | 41 | # 预渲染需要安装PrerenderSPAPlugin库,npm install会无法安装Chromuim,建议使用cnpm 42 | npm install -g cnpm --registry=https://registry.npm.taobao.org 43 | cnpm install 44 | 45 | ### 启动服务 46 | 47 | npm run serve 48 | 49 | ### 构建生产环境 50 | 51 | npm run build 52 | -------------------------------------------------------------------------------- /src/views/Home/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 46 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import router from "./router"; 4 | import store from "./store"; 5 | import i18n from "./lang"; 6 | import axios from "./utils/axios"; 7 | import Vconsole from "vconsole"; 8 | import fastclick from "fastclick"; 9 | import MetaInfo from "vue-meta-info"; 10 | import { Lazyload } from "vant"; 11 | import Raven from "raven-js"; 12 | import RavenVue from "raven-js/plugins/vue"; 13 | import "amfe-flexible"; 14 | import { Dialog } from "vant"; 15 | 16 | const isPc = !/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent); 17 | if (isPc) { 18 | Dialog({ 19 | message: `请在移动端打开,或者开启调试模式,进入移动端查看。` 20 | }); 21 | } 22 | 23 | // 控制台插件 24 | let vConsole = null; 25 | process.env.NODE_ENV == "development" && (vConsole = new Vconsole()); 26 | export default vConsole; 27 | // axios全局拦截 28 | Vue.prototype.$http = axios; 29 | Vue.use(Lazyload); 30 | Vue.use(MetaInfo); 31 | // mock模拟数据 32 | 33 | // 去除移动端点击200ms延迟 34 | fastclick.attach(document.body); 35 | 36 | // Sentry错误日志监控 37 | Raven.config("https://ce431a99e0884612a053541eef0f2810@sentry.io/1245961", { 38 | release: process.env.RELEASE_VERSION, 39 | debug: true 40 | }) 41 | .addPlugin(RavenVue, Vue) 42 | .install(); 43 | 44 | Vue.config.productionTip = false; 45 | 46 | Vue.mixin({ 47 | methods: { 48 | onBack() { 49 | this.$router.back(); 50 | } 51 | } 52 | }); 53 | new Vue({ 54 | router, 55 | store, 56 | i18n, 57 | render: h => h(App), 58 | mounted() { 59 | document.dispatchEvent(new Event("render-event")); 60 | } 61 | }).$mount("#app"); 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fancy-store", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "precommit": "lint-staged" 10 | }, 11 | "dependencies": { 12 | "amfe-flexible": "^2.2.1", 13 | "axios": "^0.18.0", 14 | "babel-plugin-import": "^1.11.0", 15 | "compression-webpack-plugin": "^2.0.0", 16 | "fastclick": "^1.0.6", 17 | "husky": "^1.3.1", 18 | "less": "^3.9.0", 19 | "less-loader": "^4.1.0", 20 | "lint-staged": "^8.1.1", 21 | "mockjs": "^1.0.1-beta3", 22 | "postcss-px2rem": "^0.3.0", 23 | "postcss-pxtorem": "^4.0.1", 24 | "prerender-spa-plugin": "^3.4.0", 25 | "prettier": "^1.13.7", 26 | "qiniu-js": "^2.5.4", 27 | "raven-js": "^3.27.0", 28 | "swiper": "^4.4.6", 29 | "terser": "^3.14.1", 30 | "vant": "^1.6.15", 31 | "vconsole": "^3.2.2", 32 | "vue": "^2.5.21", 33 | "vue-i18n": "^8.7.0", 34 | "vue-meta-info": "^0.1.7", 35 | "vue-router": "^3.0.1", 36 | "vuex": "^3.0.1", 37 | "webpack-bundle-analyzer": "^3.0.3" 38 | }, 39 | "devDependencies": { 40 | "@vue/cli-plugin-babel": "^3.3.0", 41 | "@vue/cli-plugin-eslint": "^3.3.0", 42 | "@vue/cli-service": "^3.3.0", 43 | "babel-eslint": "^10.0.1", 44 | "eslint": "^5.8.0", 45 | "eslint-plugin-vue": "^5.0.0", 46 | "husky": "^1.3.1", 47 | "vue-template-compiler": "^2.5.21" 48 | }, 49 | "lint-staged": { 50 | "*.{js,json,css,vue}": [ 51 | "prettier --tab-width 4 --print-width 200 --write", 52 | "git add" 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/views/member/Set.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/utils/axios.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { Toast } from "vant"; 3 | import store from "../store"; 4 | const http = axios.create({ 5 | baseURL: process.env.NODE_ENV == "development" ? "" : "https://www.fancystore.cn/api/", 6 | timeout: 20000 // request timeout 7 | }); 8 | // http request 拦截器 9 | http.interceptors.request.use( 10 | config => { 11 | config.headers["sessionId"] = localStorage.getItem("sessionId"); 12 | return config; 13 | }, 14 | error => { 15 | return Promise.reject(error); 16 | } 17 | ); 18 | 19 | // http response 拦截器 20 | http.interceptors.response.use( 21 | response => { 22 | const status = response.status; 23 | let msg = ""; 24 | if (status < 200 || status >= 300) { 25 | // 处理http错误,抛到业务代码 26 | msg = showStatus(status); 27 | if (typeof response.data === "string") { 28 | response.data = { msg }; 29 | } else { 30 | response.data.msg = msg; 31 | } 32 | } 33 | if (response.data.code == -1) { 34 | store.commit("SET_RESET"); 35 | Toast({ 36 | message: response.data.msg, 37 | position: "bottom" 38 | }); 39 | } 40 | return response; 41 | }, 42 | error => { 43 | Toast({ 44 | message: `${error.response.status}:${error.response.data}`, 45 | position: "bottom" 46 | }); 47 | error.data = {}; 48 | error.data.msg = "请求超时或服务器异常,请检查网络或联系管理员!"; 49 | return Promise.reject(error); 50 | } 51 | ); 52 | 53 | export default http; 54 | 55 | // 根据不同的状态码,生成不同的提示信息 56 | const showStatus = status => { 57 | let message = ""; 58 | // 这一坨代码可以使用策略模式进行优化 59 | switch (status) { 60 | case 400: 61 | message = "请求错误(400)"; 62 | break; 63 | case 401: 64 | message = "未授权,请重新登录(401)"; 65 | break; 66 | case 403: 67 | message = "拒绝访问(403)"; 68 | break; 69 | case 404: 70 | message = "请求出错(404)"; 71 | break; 72 | case 408: 73 | message = "请求超时(408)"; 74 | break; 75 | case 500: 76 | message = "服务器错误(500)"; 77 | break; 78 | case 501: 79 | message = "服务未实现(501)"; 80 | break; 81 | case 502: 82 | message = "网络错误(502)"; 83 | break; 84 | case 503: 85 | message = "服务不可用(503)"; 86 | break; 87 | case 504: 88 | message = "网络超时(504)"; 89 | break; 90 | case 505: 91 | message = "HTTP版本不受支持(505)"; 92 | break; 93 | default: 94 | message = `连接出错(${status})!`; 95 | } 96 | return `${message},请检查网络或联系管理员!`; 97 | }; 98 | -------------------------------------------------------------------------------- /src/views/member/Member.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 73 | 74 | 101 | -------------------------------------------------------------------------------- /src/views/address/Address.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 82 | 83 | 104 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Router from "vue-router"; 3 | import store from "./store/index.js"; 4 | Vue.use(Router); 5 | 6 | const router = new Router({ 7 | mode: "history", 8 | routes: [ 9 | { 10 | path: "/", 11 | component: () => import("./views/Home/index.vue"), 12 | redirect: "/product", 13 | 14 | children: [ 15 | { 16 | path: "/product", 17 | component: () => import("./views/product/Product.vue"), 18 | meta: { 19 | keepAlive: true // 是否缓存组件 20 | } 21 | }, 22 | { 23 | path: "/category", 24 | component: () => import("./views/category/Category.vue"), 25 | meta: { 26 | keepAlive: true // 是否缓存组件 27 | } 28 | }, 29 | { 30 | path: "/cart", 31 | component: () => import("./views/cart/Cart.vue"), 32 | meta: { 33 | keepAlive: false // 是否缓存组件 34 | } 35 | }, 36 | { 37 | path: "/member", 38 | component: () => import("./views/member/Member.vue"), 39 | meta: { 40 | keepAlive: false // 是否缓存组件 41 | } 42 | } 43 | ] 44 | }, 45 | 46 | { 47 | path: "/register", 48 | component: () => import("./views/member/Register.vue") 49 | }, 50 | { 51 | path: "/login", 52 | component: () => import("./views/member/Login.vue") 53 | }, 54 | { 55 | path: "/info", 56 | component: () => import("./views/member/Info.vue") 57 | }, 58 | { 59 | path: "/order", 60 | component: () => import("./views/order/Order.vue") 61 | }, 62 | { 63 | path: "/address", 64 | component: () => import("./views/address/Address.vue") 65 | }, 66 | { 67 | path: "/addaddress", 68 | component: () => import("./views/address/AddAddress.vue") 69 | }, 70 | { 71 | path: "/detail", 72 | component: () => import("./views/detail/Detail.vue") 73 | }, 74 | { 75 | path: "/orderwait", 76 | component: () => import("./views/order/OrderWait.vue") 77 | }, 78 | { 79 | path: "/set", 80 | component: () => import("./views/member/Set.vue") 81 | } 82 | ] 83 | }); 84 | // 全局路由钩子函数 对全局有效 85 | router.beforeEach((to, from, next) => { 86 | let auth = to.meta.auth; 87 | let token = store.getters["login/token"]; 88 | 89 | if (auth) { 90 | // 需要登录 91 | if (token) { 92 | next(); 93 | } else { 94 | next({ 95 | path: "/login", 96 | query: { 97 | redirect: to.fullPath 98 | } 99 | }); 100 | } 101 | } else { 102 | next(); 103 | } 104 | }); 105 | export default router; 106 | -------------------------------------------------------------------------------- /src/views/member/Register.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 80 | 81 | 100 | -------------------------------------------------------------------------------- /src/views/member/Login.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 90 | 91 | 115 | -------------------------------------------------------------------------------- /src/views/category/Category.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 107 | 108 | 142 | -------------------------------------------------------------------------------- /public/less/base.less: -------------------------------------------------------------------------------- 1 | @import './variable.less'; 2 | @theme_hover: red; 3 | 4 | /* reset */ 5 | 6 | html, 7 | body, 8 | h1, 9 | h2, 10 | h3, 11 | h4, 12 | h5, 13 | h6, 14 | div, 15 | dl, 16 | dt, 17 | dd, 18 | ul, 19 | ol, 20 | li, 21 | p, 22 | blockquote, 23 | pre, 24 | hr, 25 | figure, 26 | table, 27 | caption, 28 | th, 29 | td, 30 | form, 31 | fieldset, 32 | legend, 33 | input, 34 | button, 35 | textarea, 36 | menu { 37 | margin: 0; 38 | padding: 0; 39 | } 40 | 41 | header, 42 | footer, 43 | section, 44 | article, 45 | aside, 46 | nav, 47 | hgroup, 48 | address, 49 | figure, 50 | figcaption, 51 | menu, 52 | details { 53 | display: block; 54 | } 55 | 56 | table { 57 | border-collapse: collapse; 58 | border-spacing: 0; 59 | } 60 | 61 | caption, 62 | th { 63 | text-align: left; 64 | font-weight: normal; 65 | } 66 | 67 | html, 68 | body, 69 | fieldset, 70 | img, 71 | iframe, 72 | abbr { 73 | border: 0; 74 | } 75 | 76 | i, 77 | cite, 78 | em, 79 | var, 80 | address, 81 | dfn { 82 | font-style: normal; 83 | } 84 | 85 | [hidefocus], 86 | summary { 87 | outline: 0; 88 | } 89 | 90 | li { 91 | list-style: none; 92 | } 93 | 94 | h1, 95 | h2, 96 | h3, 97 | h4, 98 | h5, 99 | h6, 100 | small { 101 | font-size: 100%; 102 | } 103 | 104 | q:before, 105 | q:after { 106 | content: none; 107 | } 108 | 109 | textarea { 110 | overflow: auto; 111 | resize: none; 112 | } 113 | 114 | label, 115 | summary { 116 | cursor: default; 117 | } 118 | 119 | a, 120 | button { 121 | cursor: pointer; 122 | } 123 | 124 | h1, 125 | h2, 126 | h3, 127 | h4, 128 | h5, 129 | h6, 130 | em, 131 | strong, 132 | b { 133 | font-weight: bold; 134 | } 135 | 136 | body { 137 | background: @base_color; 138 | font-size: @base_textSize; 139 | } 140 | 141 | body, 142 | html { 143 | height: 100%; 144 | } 145 | 146 | a { 147 | text-decoration: none; 148 | border: none; 149 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 150 | -webkit-tap-highlight-color: transparent; 151 | outline: none; 152 | } 153 | [v-cloak] { 154 | display: none; 155 | } 156 | div { 157 | box-sizing: border-box; 158 | } 159 | .model { 160 | position: absolute; 161 | top: 0%; 162 | left: 0%; 163 | background: rgba(0, 0, 0, 0.3); 164 | width: 100%; 165 | height: 100%; 166 | position: fixed; 167 | z-index: 9999; 168 | } 169 | 170 | .baseConfig { 171 | font-size: @base_textSize; 172 | color: @base_textColor; 173 | } 174 | 175 | .flex { 176 | display: flex; 177 | align-items: center; 178 | } 179 | 180 | .flex-center { 181 | .flex(); 182 | justify-content: center; 183 | } 184 | 185 | .flex-around { 186 | .flex(); 187 | justify-content: space-around; 188 | } 189 | 190 | .flex-space { 191 | .flex(); 192 | justify-content: space-between; 193 | } 194 | 195 | .flex-align { 196 | .flex(); 197 | align-items: flex-start; 198 | } 199 | 200 | .flex-align-end { 201 | .flex(); 202 | align-items: flex-end; 203 | } 204 | 205 | .flex-wrap { 206 | flex-wrap: wrap; 207 | } 208 | 209 | .goods-name { 210 | font-size: 14px; 211 | margin-bottom: 10px; 212 | } 213 | 214 | .goods-num { 215 | font-size: 13px; 216 | margin-top: 10px; 217 | } 218 | 219 | .product-price-origin { 220 | color: #ccc; 221 | font-size: 12px; 222 | text-decoration: line-through; 223 | margin-left: 10px; 224 | // margin: 20px 0; 225 | } 226 | 227 | .slide-up-enter-active, 228 | .slide-up-leave-active { 229 | transition: all 0.5s; 230 | } 231 | 232 | .slide-up-enter, 233 | .slide-up-leave-to { 234 | opacity: 0; 235 | transform: translate3d(0, 100%, 0); 236 | } 237 | 238 | .slide-go-enter-active, 239 | .slide-go-leave-active { 240 | transition: all 0.3s; 241 | } 242 | 243 | .slide-go-enter, 244 | .slide-go-leave-to { 245 | transition: all 0.3s; 246 | transform: translate3d(0, 0, 0); 247 | } 248 | 249 | .slide-back-enter-active, 250 | .slide-back-leave-active { 251 | transition: all 0.5s; 252 | } 253 | 254 | .slide-back-enter, 255 | .slide-back-leave-to { 256 | transition: all 0.5s; 257 | transform: translate3d(-100%, 0, 0); 258 | } 259 | 260 | .bullet-enter-active, 261 | .bullet-leave-active { 262 | transition: 1s all cubic-bezier(0.83, 0.97, 0.05, 1.44); 263 | } 264 | 265 | .bullet-enter, 266 | .bullet-leave-to { 267 | opacity: 0; 268 | transform: translate3d(0, 0, -100%); 269 | } 270 | 271 | .text-ellipsis { 272 | overflow: hidden; 273 | text-overflow: ellipsis; 274 | white-space: nowrap; 275 | } 276 | 277 | .page { 278 | display: flex; 279 | flex-direction: column; 280 | height: 100vh; 281 | background: #f5f5f5; 282 | } 283 | 284 | .container { 285 | flex: 1; 286 | font-size: 14px; 287 | } 288 | .overflow_hidden { 289 | overflow: hidden; 290 | } 291 | .product_title { 292 | overflow: hidden; 293 | text-overflow: ellipsis; 294 | white-space: nowrap; 295 | font-size: 15px; 296 | } 297 | .price_pre { 298 | margin-right: 4px; 299 | } 300 | .product_price { 301 | color: red; 302 | margin-top: 4px; 303 | font-size: 14px; 304 | } 305 | .detailPic { 306 | img { 307 | width: 100% !important; 308 | margin: 10px 0; 309 | } 310 | } -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; 3 | const isProduction = process.env.NODE_ENV === "production"; 4 | const CompressionWebpackPlugin = require("compression-webpack-plugin"); 5 | const autoprefixer = require("autoprefixer"); 6 | const pxtorem = require("postcss-pxtorem"); 7 | const PrerenderSPAPlugin = require("prerender-spa-plugin"); 8 | const Renderer = PrerenderSPAPlugin.PuppeteerRenderer; 9 | 10 | // cdn预加载使用 11 | const externals = { 12 | vue: "Vue", 13 | "vue-router": "VueRouter", 14 | "vue-i18n": "VueI18n", 15 | vuex: "Vuex", 16 | axios: "axios", 17 | Vconsole: "vconsole" 18 | }; 19 | 20 | const cdn = { 21 | // 开发环境 22 | dev: { 23 | css: [""], 24 | js: [] 25 | }, 26 | // 生产环境 27 | build: { 28 | css: [""], 29 | js: [ 30 | "https://cdn.bootcss.com/vue/2.6.6/vue.min.js", 31 | "https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js", 32 | "https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js", 33 | "https://cdn.bootcss.com/axios/0.18.0/axios.min.js", 34 | "https://cdn.bootcss.com/vue-i18n/8.11.1/vue-i18n.min.js", 35 | "https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js" 36 | ] 37 | } 38 | }; 39 | function resolve(dir) { 40 | return path.join(__dirname, dir); 41 | } 42 | module.exports = { 43 | publicPath: "/", 44 | devServer: { 45 | open: true, // 启动服务后是否打开浏览器 46 | https: false, 47 | hotOnly: false, 48 | proxy: "http://localhost:9093/api/" 49 | }, 50 | configureWebpack: config => { 51 | if (isProduction) { 52 | // externals里的模块不打包 53 | Object.assign(config, { 54 | externals: externals 55 | }); 56 | // 移除console.log 57 | config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true; 58 | // 开启gzip压缩 59 | const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; 60 | config.plugins.push( 61 | new CompressionWebpackPlugin({ 62 | filename: "[path].gz[query]", 63 | algorithm: "gzip", 64 | test: productionGzipExtensions, 65 | threshold: 10240, 66 | minRatio: 0.8 67 | }), 68 | new PrerenderSPAPlugin({ 69 | // 生成文件的路径,也可以与webpakc打包的一致。 70 | // 下面这句话非常重要!!! 71 | // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。 72 | staticDir: path.join(__dirname, "dist"), 73 | // 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。 74 | routes: ["/", "/product", "/category", "/cart", "/member", "/register", "/login", "/info", "/order", "/address", "/addaddress", "/detail", "/orderwait", "/set"], 75 | // 这个很重要,如果没有配置这段,也不会进行预编译 76 | renderer: new Renderer({ 77 | inject: { 78 | foo: "bar" 79 | }, 80 | headless: true, 81 | // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。 82 | renderAfterDocumentEvent: "render-event" 83 | }) 84 | }) 85 | ); 86 | // 打包后模块大小分析//npm run build --report 87 | if (process.env.npm_config_report) { 88 | config.plugins.push(new BundleAnalyzerPlugin()); 89 | } 90 | } 91 | config.devtool = "source-map"; 92 | }, 93 | lintOnSave: true, 94 | productionSourceMap: false, 95 | chainWebpack: config => { 96 | // 添加CDN参数到htmlWebpackPlugin配置中 97 | config.plugin("html").tap(args => { 98 | if (process.env.NODE_ENV === "production") { 99 | args[0].cdn = cdn.build; 100 | } 101 | if (process.env.NODE_ENV === "development") { 102 | args[0].cdn = cdn.dev; 103 | } 104 | return args; 105 | }); 106 | config.resolve.alias 107 | .set("@$", resolve("src")) 108 | .set("assets", resolve("src/assets")) 109 | .set("api", resolve("src/api")) 110 | .set("mixins", resolve("src/mixins")) 111 | .set("components", resolve("src/components")) 112 | .set("views", resolve("src/views")); 113 | }, 114 | css: { 115 | // 是否使用css分离插件 ExtractTextPlugin 116 | extract: isProduction ? true : false, 117 | // 开启 CSS source maps? 118 | sourceMap: false, 119 | // css预设器配置项 120 | // 启用 CSS modules for all css / pre-processor files. 121 | modules: false, 122 | loaderOptions: { 123 | postcss: { 124 | plugins: [ 125 | autoprefixer(), 126 | pxtorem({ 127 | rootValue: 37.5, 128 | propList: ["*"] 129 | }) 130 | ] 131 | } 132 | } 133 | } 134 | }; 135 | -------------------------------------------------------------------------------- /src/lang/zh.js: -------------------------------------------------------------------------------- 1 | export const m = { 2 | local: "中文", 3 | header: { 4 | home: "Fancy Store", 5 | category: "分类", 6 | carts: "购物车", 7 | me: "我的", 8 | detail: "商品详情", 9 | memberInfo: "个人信息", 10 | login: "登录", 11 | back: "返回", 12 | set: "设置", 13 | myOrder: "我的订单", 14 | orderDetail: "订单详情" 15 | }, 16 | meta: { 17 | product: { 18 | title: "FancyStore 首页", 19 | name: "FancyStore 商品", 20 | content: "FancyStore 首页商品热门推荐" 21 | }, 22 | category: { 23 | title: "FancyStore 分类", 24 | name: "FancyStore 分类", 25 | content: "FancyStore 分类商品" 26 | }, 27 | cart: { 28 | title: "FancyStore 购物车", 29 | name: "FancyStore 购物车", 30 | content: "FancyStore 购物车商品" 31 | }, 32 | member: { 33 | title: "FancyStore 个人信息", 34 | name: "FancyStore 个人信息", 35 | content: "FancyStore 个人信息" 36 | }, 37 | register: { 38 | title: "FancyStore 注册", 39 | name: "FancyStore 注册", 40 | content: "FancyStore 注册" 41 | }, 42 | login: { 43 | title: "FancyStore 登录", 44 | name: "FancyStore 登录", 45 | content: "FancyStore 登录" 46 | }, 47 | info: { 48 | title: "FancyStore 用户信息", 49 | name: "FancyStore 用户信息", 50 | content: "FancyStore 用户信息" 51 | }, 52 | order: { 53 | title: "FancyStore 我的订单", 54 | name: "FancyStore 我的订单", 55 | content: "FancyStore 我的订单" 56 | }, 57 | address: { 58 | title: "FancyStore 我的地址", 59 | name: "FancyStore 我的地址", 60 | content: "FancyStore 我的地址" 61 | }, 62 | addaddress: { 63 | title: "FancyStore 新增地址", 64 | name: "FancyStore 新增地址", 65 | content: "FancyStore 新增地址" 66 | }, 67 | detail: { 68 | title: "FancyStore 商品详情", 69 | name: "FancyStore 商品详情", 70 | content: "FancyStore 商品详情" 71 | }, 72 | orderwait: { 73 | title: "FancyStore 订单状态", 74 | name: "FancyStore 订单状态", 75 | content: "FancyStore 订单状态" 76 | }, 77 | set: { 78 | title: "FancyStore 设置", 79 | name: "FancyStore 设置", 80 | content: "FancyStore 设置" 81 | } 82 | }, 83 | product: { 84 | recommentTitle: "热门推荐" 85 | }, 86 | login: { 87 | noLogin: "未登陆,请登录~", 88 | login: "登录", 89 | name: "用户名", 90 | nameHolder: "请输入用户名", 91 | pwd: "密码", 92 | pwdHolder: "请输入密码" 93 | }, 94 | register: { 95 | register: "注册", 96 | name: "用户名", 97 | nameHolder: "请输入用户名", 98 | pwd: "密码", 99 | pwdHolder: "请输入密码", 100 | pwdConfirm: "确认密码", 101 | pwdConfirmHolder: "输入确认密码" 102 | }, 103 | address: { 104 | myAddress: "我的地址", 105 | addAddressTitle: "添加地址", 106 | editAddressTitle: "编辑地址", 107 | noAddressTip: "地址控控如也,请前往添加", 108 | name: "姓名", 109 | nameHolder: "请输入姓名", 110 | phone: "手机号码", 111 | phoneHolder: "请输入手机号码", 112 | port: "邮编", 113 | portHolder: "请输入邮编号码", 114 | address: "地址", 115 | addressHolder: "请选择地址", 116 | detailAddress: "详细地址", 117 | detailAddressHolder: "请输入详细地址", 118 | isDefault: "设置为默认", 119 | edit: "编辑", 120 | add: "添加" 121 | }, 122 | carts: { 123 | submitOrder: "提交订单", 124 | noCarts: "购物车暂无数据,请前往添加~", 125 | addCarts: "加入购物车", 126 | buyNow: "立即购买", 127 | cutSuccess: "减少成功" 128 | }, 129 | order: { 130 | orderNum: "订单号", 131 | payed: "已支付", 132 | paying: "待付款", 133 | done: "已完成", 134 | waitPack: "待收货", 135 | all: "全部", 136 | noOrderState: "暂无该订单状态数据", 137 | chooseAddress: "选择地址", 138 | submitOrder: "提交订单", 139 | pay: "付款", 140 | confirmPack: "确定收货", 141 | orderConfirm: "是否现在结算该订单?", 142 | choiceConfirm: "请选择订单" 143 | }, 144 | footer: { 145 | product: "产品", 146 | category: "分类", 147 | carts: "购物车", 148 | me: "我的" 149 | }, 150 | strategies: { 151 | name: "姓名不可为空", 152 | account: "用户名不可为空", 153 | tel: "电话不可为空", 154 | address: "地址不可为空", 155 | pwdLenth: "密码长度不可小于4位", 156 | pwdNotConfirm: "两次输入密码不相等", 157 | 158 | orderDone: "订单已完成", 159 | orderPayed: "订单已付款" 160 | }, 161 | message: { 162 | deleteSure: "确定删除?", 163 | addSuccess: "添加成功~", 164 | userLogOut: "用户已退出" 165 | }, 166 | tip: { 167 | noUserToRegister: "还没有账号?进行注册...", 168 | haveUserToLogin: "已有账号?前往登录..." 169 | }, 170 | member: { 171 | info: "个人信息", 172 | order: "我的订单", 173 | address: "我的地址", 174 | set: "设置" 175 | }, 176 | set: { 177 | lang: "语言", 178 | logout: "退出登录" 179 | }, 180 | info: { 181 | name: "用户名", 182 | sex: "性别" 183 | } 184 | }; 185 | -------------------------------------------------------------------------------- /src/views/product/Product.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 114 | 115 | 165 | -------------------------------------------------------------------------------- /src/lang/en.js: -------------------------------------------------------------------------------- 1 | export const m = { 2 | local: "English", 3 | header: { 4 | home: "Fancy Store", 5 | category: "Category", 6 | carts: "Carts", 7 | me: "Me", 8 | detail: "Product Info", 9 | memberInfo: "My Info", 10 | login: "login", 11 | back: "back", 12 | set: "set", 13 | myOrder: "myOrder", 14 | orderDetail: "Order Detail" 15 | }, 16 | meta: { 17 | product: { 18 | title: "FancyStore Home", 19 | name: "FancyStore Product", 20 | content: "FancyStore Home Hot Topic Recommend" 21 | }, 22 | category: { 23 | title: "FancyStore Category", 24 | name: "FancyStore Category", 25 | content: "FancyStore Category Product" 26 | }, 27 | cart: { 28 | title: "FancyStore Cart", 29 | name: "FancyStore Cart", 30 | content: "FancyStore Cart Product" 31 | }, 32 | member: { 33 | title: "FancyStore MyInfo", 34 | name: "FancyStore MyInfo", 35 | content: "FancyStore MyInfo" 36 | }, 37 | register: { 38 | title: "FancyStore Register", 39 | name: "FancyStore Register", 40 | content: "FancyStore Register" 41 | }, 42 | login: { 43 | title: "FancyStore Login", 44 | name: "FancyStore Login", 45 | content: "FancyStore Login" 46 | }, 47 | info: { 48 | title: "FancyStore Info", 49 | name: "FancyStore Info", 50 | content: "FancyStore Info" 51 | }, 52 | order: { 53 | title: "FancyStore MyOrder", 54 | name: "FancyStore MyOrder", 55 | content: "FancyStore MyOrder" 56 | }, 57 | address: { 58 | title: "FancyStore MyAddress", 59 | name: "FancyStore MyAddress", 60 | content: "FancyStore MyAddress" 61 | }, 62 | addaddress: { 63 | title: "FancyStore AddAddress", 64 | name: "FancyStore AddAddress", 65 | content: "FancyStore AddAddress" 66 | }, 67 | detail: { 68 | title: "FancyStore Product Detail", 69 | name: "FancyStore Product Detail", 70 | content: "FancyStore Product Detail" 71 | }, 72 | orderwait: { 73 | title: "FancyStore OrderStatus", 74 | name: "FancyStore OrderSTATUS", 75 | content: "FancyStore OrderSTATUS" 76 | }, 77 | set: { 78 | title: "FancyStore Set", 79 | name: "FancyStore Set", 80 | content: "FancyStore Set" 81 | } 82 | }, 83 | product: { 84 | recommentTitle: "Hot Topic" 85 | }, 86 | login: { 87 | noLogin: "Going to login, please~", 88 | login: "login", 89 | name: "userAccount", 90 | nameHolder: "please input userAccount", 91 | pwd: "password", 92 | pwdHolder: "please input password" 93 | }, 94 | register: { 95 | register: "register", 96 | name: "userAccount", 97 | nameHolder: "please input userAccount", 98 | pwd: "password", 99 | pwdHolder: "please input password", 100 | pwdConfirm: "passwordComfirm", 101 | pwdConfirmHolder: "please input passwordComfirm" 102 | }, 103 | address: { 104 | myAddress: "myAddress", 105 | addAddressTitle: "add address", 106 | editAddressTitle: "edit address", 107 | noAddressTip: "not have addres,go to add", 108 | name: "name", 109 | nameHolder: "please input name", 110 | phone: "phone", 111 | phoneHolder: "please input phone", 112 | port: "port", 113 | portHolder: "please input port", 114 | address: "address", 115 | addressHolder: "please input address", 116 | detailAddress: "addressDetail", 117 | detailAddressHolder: "please input addressDetail", 118 | isDefault: "set defalut", 119 | edit: "edit", 120 | add: "add" 121 | }, 122 | carts: { 123 | submitOrder: "submitOrder", 124 | noCarts: "carts no data,go to shoping", 125 | addCarts: "addCarts", 126 | buyNow: "buyNow", 127 | cutSuccess: "cutSuccess" 128 | }, 129 | order: { 130 | orderNum: "orderNumber", 131 | payed: "payed", 132 | paying: "paying", 133 | done: "done", 134 | waitPack: "waitPack", 135 | all: "all", 136 | noOrderState: "no order state", 137 | chooseAddress: "chooseAddress", 138 | submitOrder: "submitOrder", 139 | pay: "pay", 140 | confirmPack: "confirmPack", 141 | orderConfirm: "Paying Order Now?", 142 | choiceConfirm: "Please Choice" 143 | }, 144 | footer: { 145 | product: "product", 146 | category: "category", 147 | carts: "carts", 148 | me: "me" 149 | }, 150 | strategies: { 151 | name: "name not empty", 152 | account: "account not empty", 153 | tel: "tel not empty", 154 | address: "address not empty", 155 | pwdLenth: "password length more than four", 156 | pwdNotConfirm: "password not equal passwordConfirm", 157 | orderDone: "OrderDown", 158 | orderPayed: "OrderPayed" 159 | }, 160 | message: { 161 | deleteSure: "deleteSure?", 162 | addSuccess: "addSuccess~", 163 | userLogOut: "userLogOut" 164 | }, 165 | tip: { 166 | noUserToRegister: "noUserToRegister...", 167 | haveUserToLogin: "haveUserToLogin..." 168 | }, 169 | member: { 170 | info: "info", 171 | order: "order", 172 | address: "address", 173 | set: "set" 174 | }, 175 | set: { 176 | lang: "lang", 177 | logout: "LogOut" 178 | }, 179 | info: { 180 | name: "userName", 181 | sex: "sex" 182 | } 183 | }; 184 | -------------------------------------------------------------------------------- /src/views/address/AddAddress.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 135 | 136 | 154 | -------------------------------------------------------------------------------- /src/views/member/Info.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 168 | 169 | 202 | -------------------------------------------------------------------------------- /src/views/order/Order.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 182 | 183 | 220 | -------------------------------------------------------------------------------- /src/views/detail/Detail.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 154 | 155 | 247 | -------------------------------------------------------------------------------- /src/views/cart/Cart.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 201 | 202 | 260 | -------------------------------------------------------------------------------- /src/views/order/OrderWait.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 217 | 218 | 254 | --------------------------------------------------------------------------------