├── src ├── common │ ├── mixin.js │ ├── const.js │ ├── common.txt │ ├── rem.js │ └── utils.js ├── store │ ├── getters.js │ ├── index.js │ ├── actions.js │ └── mutations.js ├── components │ ├── common │ │ ├── common.txt │ │ ├── Loading.vue │ │ ├── TabFooter.vue │ │ └── scroll │ │ │ └── Scroll.vue │ └── content │ │ ├── content.txt │ │ ├── ReturnTop.vue │ │ ├── goods │ │ ├── GoodsList.vue │ │ └── GoodsListItem.vue │ │ └── TabControl.vue ├── assets │ ├── css │ │ ├── base2.css │ │ ├── base.css │ │ └── normalize.css │ └── img │ │ ├── gouwuc.jpg │ │ ├── vuelogo.png │ │ ├── common │ │ ├── top.png │ │ ├── placeholder.png │ │ ├── arrow-left.svg │ │ ├── back.svg │ │ └── collect.svg │ │ ├── detail │ │ ├── cart.png │ │ └── detail_bottom.png │ │ ├── home │ │ └── recommend_bg.jpg │ │ ├── cart │ │ └── tick.svg │ │ ├── tabbar │ │ ├── shopcart.svg │ │ ├── shopcart_active.svg │ │ ├── category.svg │ │ ├── category_active.svg │ │ ├── profile.svg │ │ ├── home.svg │ │ ├── profile_active.svg │ │ └── home_active.svg │ │ └── profile │ │ ├── message.svg │ │ ├── avatar.svg │ │ ├── phone.svg │ │ ├── pointer.svg │ │ ├── cart.svg │ │ ├── vip.svg │ │ └── shopping.svg ├── views │ ├── views.txt │ ├── category │ │ ├── childComps │ │ │ ├── cartgoryTab.vue │ │ │ └── categoryContent.vue │ │ └── Category.vue │ ├── detail │ │ ├── childComps │ │ │ ├── DetailSwiper.vue │ │ │ ├── DetailFooterBar.vue │ │ │ ├── DetailCommentInfo.vue │ │ │ ├── DetailParamsInfo.vue │ │ │ ├── DetailImageInfo.vue │ │ │ ├── DetailBaseInfo.vue │ │ │ └── DetailShopInfo.vue │ │ └── Detail.vue │ ├── home │ │ ├── childComps │ │ │ ├── FeatureView.vue │ │ │ ├── HomeSwiper.vue │ │ │ └── Recommend.vue │ │ └── Home.vue │ ├── cart │ │ ├── childComps │ │ │ └── cartPay.vue │ │ └── Cart.vue │ └── profile │ │ └── Profile.vue ├── network │ ├── category.js │ ├── home.js │ ├── request.js │ └── detail.js ├── App.vue ├── vue.config.js ├── pluginunit │ └── vant.js ├── main.js ├── registerServiceWorker.js └── router │ └── index.js ├── .browserslistrc ├── public ├── robots.txt ├── favicon.ico ├── img │ └── icons │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── msapplication-icon-144x144.png │ │ ├── android-chrome-maskable-192x192.png │ │ ├── android-chrome-maskable-512x512.png │ │ └── safari-pinned-tab.svg └── index.html ├── babel.config.js ├── .gitignore ├── package.json └── README.md /src/common/mixin.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/common/const.js: -------------------------------------------------------------------------------- 1 | // 这里面放一些公共的 js常量 -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /src/common/common.txt: -------------------------------------------------------------------------------- 1 | common 这个文件夹主要是放一些 公共的js文件; -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /src/store/getters.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | } -------------------------------------------------------------------------------- /src/components/common/common.txt: -------------------------------------------------------------------------------- 1 | 这个里面放的是一些可以用在其他项目的公共组件; -------------------------------------------------------------------------------- /src/components/content/content.txt: -------------------------------------------------------------------------------- 1 | 这个文件夹放的是一些 仅用在当前项目的组件; -------------------------------------------------------------------------------- /src/assets/css/base2.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0px; 3 | padding: 0px; 4 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/img/gouwuc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/src/assets/img/gouwuc.jpg -------------------------------------------------------------------------------- /src/assets/img/vuelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/src/assets/img/vuelogo.png -------------------------------------------------------------------------------- /src/assets/img/common/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/src/assets/img/common/top.png -------------------------------------------------------------------------------- /src/assets/img/detail/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/src/assets/img/detail/cart.png -------------------------------------------------------------------------------- /src/views/views.txt: -------------------------------------------------------------------------------- 1 | views主要是用来放一些大的视图,比如首页视图,购物车视图,等等; 2 | https://blog.csdn.net/wuyxinu/article/details/103684950 -------------------------------------------------------------------------------- /public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /src/assets/img/common/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/src/assets/img/common/placeholder.png -------------------------------------------------------------------------------- /src/assets/img/home/recommend_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/src/assets/img/home/recommend_bg.jpg -------------------------------------------------------------------------------- /src/assets/img/detail/detail_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/src/assets/img/detail/detail_bottom.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-maskable-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/android-chrome-maskable-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-maskable-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sirfuao/vue_shop/HEAD/public/img/icons/android-chrome-maskable-512x512.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ], 5 | // vant 组件样式 自动按需引入; 6 | plugins: [ 7 | ['import', { 8 | libraryName: 'vant', 9 | libraryDirectory: 'es', 10 | style: true 11 | }, 'vant'] 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/components/content/ReturnTop.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /src/network/category.js: -------------------------------------------------------------------------------- 1 | import {request} from './request' 2 | 3 | export function getCategory(){ 4 | return request({ 5 | url:'/category' 6 | }); 7 | } 8 | 9 | export function getSubCategory(maitKey) { 10 | return request({ 11 | url:'/subcategory', 12 | params:{ 13 | maitKey 14 | } 15 | }); 16 | } -------------------------------------------------------------------------------- /src/network/home.js: -------------------------------------------------------------------------------- 1 | import {request} from './request.js' 2 | 3 | export function getHomeMultidata() { 4 | return request({ 5 | url:'home/multidata' 6 | }) 7 | } 8 | 9 | export function getHomeGoods(type,page){ 10 | return request({ 11 | url:'/home/data', 12 | params:{ 13 | type, 14 | page 15 | } 16 | }); 17 | } -------------------------------------------------------------------------------- /src/assets/img/cart/tick.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | //1、安装插件 5 | Vue.use(Vuex) 6 | 7 | import mutations from './mutations.js' //导入mutations 对象 8 | import actions from './actions.js' // 导入actions 对象 9 | 10 | //2、创建store对象 11 | export default new Vuex.Store({ 12 | state: { 13 | //商品的数组 14 | cartList:[] 15 | }, 16 | mutations, 17 | actions, 18 | modules: { 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /src/components/common/Loading.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | -------------------------------------------------------------------------------- /src/views/category/childComps/cartgoryTab.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/img/common/arrow-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/common/rem.js: -------------------------------------------------------------------------------- 1 | // 设计稿自定义为375px 利用测量的px大小除以50px 即可得到所需rem值 2 | (function () { 3 | remLayout(); 4 | function remLayout() { 5 | // 获取屏幕宽度 6 | var w = document.documentElement.clientWidth; 7 | w = w > 768 ? 768 : w; 8 | w = w <= 320 ? 320 : w; 9 | // document.documentElement 获取到的html标签 10 | document.documentElement.style.fontSize = w / 7.5 + 'px'; 11 | } 12 | // resize 监听页面变化 13 | window.addEventListener('resize', function () { 14 | remLayout(); 15 | }, false); 16 | })(); -------------------------------------------------------------------------------- /src/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | configureWebpack: { 3 | resolve: { 4 | alias: { 5 | //配置别名 6 | 'assets': '@/assets', 7 | 'common': '@/common', 8 | 'components': '@/components', 9 | 'network': '@/network', 10 | 'views': '@/views', 11 | 'pluginunit':'@/pluginunit' 12 | } 13 | } 14 | }, 15 | devServer: { 16 | host: '192.168.1.6', //本机电脑 ip 地址 17 | port: 8080, //端口号 18 | } 19 | } -------------------------------------------------------------------------------- /src/assets/img/common/back.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/store/actions.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // 因为 addProduct 这个函数完成的是两个 任务 所以最好写在actions中; 3 | addProduct(context,obj) { 4 | let oldProduct = null; 5 | //查找之前数组中是否有这个商品 6 | for(let item of context.state.cartList){ 7 | if(item.iid===obj.iid){ 8 | oldProduct = item; 9 | } 10 | } 11 | if(oldProduct){ 12 | //当商品已添加时 13 | // oldProduct.count += 1 14 | context.commit('addCounter',oldProduct) 15 | }else{ 16 | //当商品没有添加时,给oldProduct 添加一个记录商品件数的 属性 17 | obj.count = 1; 18 | // state.cartList.push(obj); 19 | context.commit("addToCart",obj) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/pluginunit/vant.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { 3 | Button, 4 | NavBar, 5 | Tabbar, 6 | TabbarItem, 7 | Swipe, 8 | SwipeItem, 9 | Sticky, 10 | GoodsAction, 11 | GoodsActionIcon, 12 | GoodsActionButton, 13 | Toast, 14 | Card, 15 | SubmitBar, 16 | Checkbox, 17 | Icon, 18 | Loading, 19 | } from 'vant' 20 | 21 | Vue.use(Button); 22 | Vue.use(NavBar); 23 | Vue.use(Tabbar); 24 | Vue.use(TabbarItem); 25 | Vue.use(Swipe); 26 | Vue.use(SwipeItem); 27 | Vue.use(Sticky); 28 | Vue.use(GoodsAction); 29 | Vue.use(GoodsActionIcon); 30 | Vue.use(GoodsActionButton); 31 | Vue.use(Toast); 32 | Vue.use(Card); 33 | Vue.use(SubmitBar); 34 | Vue.use(Checkbox); 35 | Vue.use(Icon); 36 | Vue.use(Loading); 37 | -------------------------------------------------------------------------------- /src/common/utils.js: -------------------------------------------------------------------------------- 1 | //这里面放一些 js 公共的方法 2 | 3 | //时间格式化 4 | export function dateFormat(fmt, date) { 5 | let ret; 6 | const opt = { 7 | "y+": date.getFullYear().toString(), // 年 8 | "M+": (date.getMonth() + 1).toString(), // 月 9 | "d+": date.getDate().toString(), // 日 10 | "h+": date.getHours().toString(), // 时 11 | "m+": date.getMinutes().toString(), // 分 12 | "s+": date.getSeconds().toString() // 秒 13 | // 有其他格式化字符需求可以继续添加,必须转化成字符串 14 | }; 15 | for (let k in opt) { 16 | ret = new RegExp("(" + k + ")").exec(fmt); 17 | if (ret) { 18 | fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) 19 | }; 20 | }; 21 | return fmt; 22 | } -------------------------------------------------------------------------------- /src/views/detail/childComps/DetailSwiper.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/content/goods/GoodsList.vue: -------------------------------------------------------------------------------- 1 | 7 | 28 | -------------------------------------------------------------------------------- /src/network/request.js: -------------------------------------------------------------------------------- 1 | import { Toast } from 'vant'; 2 | import axios from "axios"; 3 | 4 | // 引入 axios 5 | export function request(config) { 6 | // 1、创建 axios 实例 7 | const instance = axios.create({ 8 | baseURL:'要接口找老师', 9 | timeout:5000 10 | }); 11 | // 2、axios 的拦截 12 | // 2、1 请求拦截 13 | instance.interceptors.request.use((config)=>{ 14 | Toast.loading({ 15 | message: '加载中...', 16 | forbidClick: true, 17 | loadingType: 'spinner' 18 | }); 19 | return config 20 | },(err)=>{ 21 | console.log(err) 22 | }); 23 | // 2、2响应拦截器 24 | instance.interceptors.response.use((res)=>{ 25 | Toast.clear(); 26 | return res.data 27 | },(err)=>{ 28 | console.log(err) 29 | }); 30 | //3、发送真正的网络请求 31 | return instance(config); //返回一个Promise 32 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import './registerServiceWorker' 4 | import router from './router' 5 | import store from './store' 6 | import '@/assets/css/base2.css' 7 | import Vconsole from 'vconsole' 8 | //引入 vant ui 9 | import './pluginunit/vant.js' 10 | //图片懒加载 11 | import VueLazyLoad from 'vue-lazyload' 12 | //移动端适配处理 13 | import './common/rem.js' 14 | //引入fastclick (移动端300毫秒延迟处理) 15 | import FastClick from 'fastclick' 16 | //添加事件总线 17 | Vue.prototype.$bus = new Vue(); 18 | 19 | //解决移动端300毫秒延迟 20 | FastClick.attach(document.body); 21 | 22 | if(process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development'){ 23 | const vConsole = new Vconsole(); 24 | } 25 | 26 | //图片懒加载 27 | Vue.use(VueLazyLoad); 28 | Vue.config.productionTip = false 29 | 30 | new Vue({ 31 | router, 32 | store, 33 | render: h => h(App) 34 | }).$mount('#app') 35 | -------------------------------------------------------------------------------- /src/store/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // addProduct(state,obj) { 3 | // state.cartList.forEach((item,index)=>{ 4 | // //如果商品已经添加 5 | // if(item.iid==obj.iid){ 6 | // // 则商品数量加 1 7 | // item.count ++; 8 | // console.log("1") 9 | // }else{ 10 | // // 如果商品还没有添加,则将商品添加到 cartList 数组中; 11 | // state.cartList.push(obj); 12 | // console.log("2") 13 | // } 14 | // }); 15 | // console.log("3") 16 | // } 17 | 18 | //mutations 唯一的目的就是修改state中状态 19 | //mutations 中的每个方法尽可能完成的事件比较单一 一点; 20 | addCounter(state, obj) { 21 | obj.count++ //这两个事件分开写 22 | }, // 就能更好的追踪 它们的变化 23 | addToCart(state, newObj) { 24 | newObj.isCheck = true; 25 | state.cartList.push(newObj) 26 | } 27 | } -------------------------------------------------------------------------------- /src/views/detail/childComps/DetailFooterBar.vue: -------------------------------------------------------------------------------- 1 | 12 | 23 | -------------------------------------------------------------------------------- /src/views/home/childComps/FeatureView.vue: -------------------------------------------------------------------------------- 1 | 8 | 26 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/shopcart.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue_shop", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --open", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "axios": "^0.19.2", 11 | "better-scroll": "^1.15.2", 12 | "core-js": "^3.6.4", 13 | "fastclick": "^1.0.6", 14 | "register-service-worker": "^1.6.2", 15 | "vant": "^2.5.1", 16 | "vconsole": "^3.3.4", 17 | "vue": "^2.6.11", 18 | "vue-lazyload": "^1.3.3", 19 | "vue-router": "^3.1.5", 20 | "vuex": "^3.1.2" 21 | }, 22 | "devDependencies": { 23 | "@vue/cli-plugin-babel": "^4.2.0", 24 | "@vue/cli-plugin-pwa": "^4.2.0", 25 | "@vue/cli-plugin-router": "^4.2.0", 26 | "@vue/cli-plugin-vuex": "^4.2.0", 27 | "@vue/cli-service": "^4.2.0", 28 | "babel-plugin-import": "^1.13.0", 29 | "less": "^3.0.4", 30 | "less-loader": "^5.0.0", 31 | "vue-template-compiler": "^2.6.11" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/shopcart_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/components/common/TabFooter.vue: -------------------------------------------------------------------------------- 1 | 16 | 29 | -------------------------------------------------------------------------------- /src/views/home/childComps/HomeSwiper.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 25 | 26 | 41 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/category.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 14 | 16 | 18 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/category_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 14 | 16 | 18 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/profile_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/views/home/childComps/Recommend.vue: -------------------------------------------------------------------------------- 1 | 10 | 31 | -------------------------------------------------------------------------------- /src/assets/img/profile/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/tabbar/home_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 9 | 10 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from 'register-service-worker' 4 | 5 | if (process.env.NODE_ENV === 'production') { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready () { 8 | console.log( 9 | 'App is being served from cache by a service worker.\n' + 10 | 'For more details, visit https://goo.gl/AFskqB' 11 | ) 12 | }, 13 | registered () { 14 | console.log('Service worker has been registered.') 15 | }, 16 | cached () { 17 | console.log('Content has been cached for offline use.') 18 | }, 19 | updatefound () { 20 | console.log('New content is downloading.') 21 | }, 22 | updated () { 23 | console.log('New content is available; please refresh.') 24 | }, 25 | offline () { 26 | console.log('No internet connection found. App is running in offline mode.') 27 | }, 28 | error (error) { 29 | console.error('Error during service worker registration:', error) 30 | } 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | 4 | 5 | Vue.use(VueRouter) 6 | 7 | const routes = [ 8 | { 9 | path:'/', 10 | redirect:'/home' 11 | }, 12 | { 13 | name:'Home', 14 | path:'/home', 15 | component: ()=> import('@/views/home/Home.vue') 16 | }, 17 | { 18 | name:'Category', 19 | path:'/category', 20 | component: ()=> import('@/views/category/Category.vue') 21 | }, 22 | { 23 | name:'Cart', 24 | path:'/cart', 25 | component: ()=>import('@/views/cart/Cart.vue') 26 | }, 27 | { 28 | name:'Profile', 29 | path:'/Profile', 30 | component: ()=>import('@/views/profile/Profile.vue') 31 | }, 32 | { 33 | name:'Detail', 34 | path:'/Detail/:iid', 35 | component: ()=>import('@/views/detail/Detail.vue') 36 | } 37 | ] 38 | 39 | const router = new VueRouter({ 40 | mode: 'history', // 路由模式 41 | base: process.env.BASE_URL, 42 | routes 43 | }) 44 | 45 | export default router 46 | -------------------------------------------------------------------------------- /src/views/category/Category.vue: -------------------------------------------------------------------------------- 1 | 7 | 36 | -------------------------------------------------------------------------------- /src/network/detail.js: -------------------------------------------------------------------------------- 1 | import {request} from './request.js' 2 | 3 | export function getDetail(iid){ 4 | return request({ 5 | url:'/detail', 6 | params:{ 7 | iid 8 | } 9 | }); 10 | } 11 | 12 | //用商品推荐接口请求 13 | export function getRecommend(){ 14 | return request({ 15 | url:'/recommend' 16 | }); 17 | } 18 | 19 | //将服务器返回的杂乱数据整合; 抽离数据 20 | //基本信息数据 21 | export class Goods{ 22 | constructor(itemInfo,columns,services){ 23 | this.title = itemInfo.title; 24 | this.desc = itemInfo.desc; 25 | this.newPrice = itemInfo.price; 26 | this.oldPrice = itemInfo.oldPrice 27 | this.discount = itemInfo.discountDesc; 28 | this.columns = columns; 29 | this.services = services; 30 | this.realPrice = itemInfo.lowNowPrice; 31 | } 32 | } 33 | 34 | //店铺信息数据 35 | 36 | export class Shop{ 37 | constructor(shopInfo){ 38 | this.logo = shopInfo.shopLogo; 39 | this.name = shopInfo.name; 40 | this.fans = shopInfo.cFans; 41 | this.sells = shopInfo.cSells; 42 | this.score = shopInfo.score; 43 | this.goodsCount = shopInfo.cGoods; 44 | } 45 | } 46 | 47 | // 商品图片详细信息 48 | 49 | -------------------------------------------------------------------------------- /src/assets/css/base.css: -------------------------------------------------------------------------------- 1 | @import "./normalize.css"; /**引入normalize.css/ 2 | 3 | /*:root -> 获取根元素html*/ 4 | :root { 5 | --color-text: #666; 6 | --color-high-text: #ff5777; 7 | --color-tint: #ff8198; 8 | --color-background: #fff; 9 | --font-size: 14px; 10 | --line-height: 1.5; 11 | } 12 | 13 | *, 14 | *::before, 15 | *::after { 16 | margin: 0; 17 | padding: 0; 18 | box-sizing: border-box; 19 | } 20 | 21 | body { 22 | font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; 23 | user-select: none; /* 禁止用户鼠标在页面上选中文字/图片等 */ 24 | -webkit-tap-highlight-color: transparent; /* webkit是苹果浏览器引擎,tap点击,highlight背景高亮,color颜色,颜色用数值调节 */ 25 | background: var(--color-background); 26 | color: var(--color-text); 27 | /* rem vw/vh */ 28 | width: 100vw; 29 | } 30 | 31 | a { 32 | color: var(--color-text); 33 | text-decoration: none; 34 | } 35 | 36 | 37 | .clear-fix::after { 38 | clear: both; 39 | content: ''; 40 | display: block; 41 | width: 0; 42 | height: 0; 43 | visibility: hidden; 44 | } 45 | 46 | .clear-fix { 47 | zoom: 1; 48 | } 49 | 50 | .left { 51 | float: left; 52 | } 53 | 54 | .right { 55 | float: right; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/components/content/TabControl.vue: -------------------------------------------------------------------------------- 1 | 6 | 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 这是一个vue电商实战项目,非常适合需要实战经验的小伙伴学习 3 | ## 项目主要分为 四个部分 首页 分类页 购物车 我的, 请各位大佬动动发财的小手 点个 star 4 | ### 注意: 5 | + 有时候,页面刚加载的时候,可能会出现滚动条,但这种情况我在手机上测试的时候是没有出现的,可以在浏览器上切换到 ipad模式下,然后再切换回iPhone X的模式下,就没有滚动条了。 6 | + 好多小伙伴都在问我项目跑不起来,在启动项目前一定先要 npm install 7 | + 还有由于我是用的 vue-cli3 所以运行项目的命令不是 npm run dev 是**npm run serve** 8 | + 可能还有些小毛病,我正在努力维护,谢谢! 9 | 10 | ### 首页: 11 | ![首页](https://github.com/sirfuao/imgages/blob/master/shouye.png) 12 | 13 | ##### 图二 14 | 15 | ![首页2](https://github.com/sirfuao/imgages/blob/master/shouye2.png) 16 | 17 | ### 分类页 18 | ![分类1](https://github.com/sirfuao/imgages/blob/master/fenlei.png) 19 | 20 | ##### 图二 21 | 22 | ![分类2](https://github.com/sirfuao/imgages/blob/master/fenlei2.png) 23 | 24 | ### 商品详情 25 | ![商品商品详情1](https://github.com/sirfuao/imgages/blob/master/xq.png) 26 | 27 | ##### 图二 28 | 29 | ![商品详情2](https://github.com/sirfuao/imgages/blob/master/xq2.png) 30 | 31 | ##### 图三 32 | 33 | ![商品详情3](https://github.com/sirfuao/imgages/blob/master/xq2.png) 34 | 35 | ### 购物车 36 | ![空购物车](https://github.com/sirfuao/imgages/blob/master/gwc1.png) 37 | 38 | ##### 图二 39 | 40 | ![有数据购物车](https://github.com/sirfuao/imgages/blob/master/gwc2.png) 41 | 42 | ### 我的 43 | ![我的](https://github.com/sirfuao/imgages/blob/master/my.png) 44 | 45 | #### 能看到这里,说明你一定是一个想从事前端,也是一个非常有目标的人,一起加油吧,陌生人! 46 | -------------------------------------------------------------------------------- /src/assets/img/profile/avatar.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/profile/phone.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/content/goods/GoodsListItem.vue: -------------------------------------------------------------------------------- 1 | 11 | 38 | -------------------------------------------------------------------------------- /src/views/cart/childComps/cartPay.vue: -------------------------------------------------------------------------------- 1 | 8 | 63 | -------------------------------------------------------------------------------- /src/components/common/scroll/Scroll.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 65 | 66 | -------------------------------------------------------------------------------- /src/assets/img/common/collect.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/profile/pointer.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/profile/cart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/detail/childComps/DetailCommentInfo.vue: -------------------------------------------------------------------------------- 1 | 19 | 44 | -------------------------------------------------------------------------------- /src/views/detail/childComps/DetailParamsInfo.vue: -------------------------------------------------------------------------------- 1 | 18 | 32 | -------------------------------------------------------------------------------- /src/views/detail/childComps/DetailImageInfo.vue: -------------------------------------------------------------------------------- 1 | 20 | 35 | -------------------------------------------------------------------------------- /src/views/detail/childComps/DetailBaseInfo.vue: -------------------------------------------------------------------------------- 1 | 20 | 36 | -------------------------------------------------------------------------------- /src/views/category/childComps/categoryContent.vue: -------------------------------------------------------------------------------- 1 | 16 | 53 | 54 | -------------------------------------------------------------------------------- /src/assets/img/profile/vip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/profile/shopping.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/cart/Cart.vue: -------------------------------------------------------------------------------- 1 | 29 | 54 | -------------------------------------------------------------------------------- /src/views/detail/childComps/DetailShopInfo.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 45 | 46 | -------------------------------------------------------------------------------- /src/views/home/Home.vue: -------------------------------------------------------------------------------- 1 | 24 | 129 | -------------------------------------------------------------------------------- /src/views/profile/Profile.vue: -------------------------------------------------------------------------------- 1 | 56 | 61 | -------------------------------------------------------------------------------- /src/views/detail/Detail.vue: -------------------------------------------------------------------------------- 1 | 29 | 158 | -------------------------------------------------------------------------------- /src/assets/css/normalize.css: -------------------------------------------------------------------------------- 1 | /* Normalize支持包括手机浏览器在内的超多浏览器,解决了不同浏览器对html标签显示的差异 2 | 同时对HTML5元素、排版、列表、嵌入的内容、表单和表哥都进行了一般化。 */ 3 | 4 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 5 | 6 | /* Document 7 | ========================================================================== */ 8 | 9 | /** 10 | * 1. Correct the line height in all browsers. 11 | * 2. Prevent adjustments of font size after orientation changes in iOS. 12 | */ 13 | 14 | html { 15 | line-height: 1.15; /* 1 */ 16 | -webkit-text-size-adjust: 100%; /* 2 */ 17 | } 18 | 19 | /* Sections 20 | ========================================================================== */ 21 | 22 | /** 23 | * Remove the margin in all browsers. 24 | */ 25 | 26 | body { 27 | margin: 0; 28 | } 29 | 30 | /** 31 | * Render the `main` element consistently in IE. 32 | */ 33 | 34 | main { 35 | display: block; 36 | } 37 | 38 | /** 39 | * Correct the font size and margin on `h1` elements within `section` and 40 | * `article` contexts in Chrome, Firefox, and Safari. 41 | */ 42 | 43 | h1 { 44 | font-size: 2em; 45 | margin: 0.67em 0; 46 | } 47 | 48 | /* Grouping content 49 | ========================================================================== */ 50 | 51 | /** 52 | * 1. Add the correct box sizing in Firefox. 53 | * 2. Show the overflow in Edge and IE. 54 | */ 55 | 56 | hr { 57 | box-sizing: content-box; /* 1 */ 58 | height: 0; /* 1 */ 59 | overflow: visible; /* 2 */ 60 | } 61 | 62 | /** 63 | * 1. Correct the inheritance and scaling of font size in all browsers. 64 | * 2. Correct the odd `em` font sizing in all browsers. 65 | */ 66 | 67 | pre { 68 | font-family: monospace, monospace; /* 1 */ 69 | font-size: 1em; /* 2 */ 70 | } 71 | 72 | /* Text-level semantics 73 | ========================================================================== */ 74 | 75 | /** 76 | * Remove the gray background on active links in IE 10. 77 | */ 78 | 79 | a { 80 | background-color: transparent; 81 | } 82 | 83 | /** 84 | * 1. Remove the bottom border in Chrome 57- 85 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 86 | */ 87 | 88 | abbr[title] { 89 | border-bottom: none; /* 1 */ 90 | text-decoration: underline; /* 2 */ 91 | text-decoration: underline dotted; /* 2 */ 92 | } 93 | 94 | /** 95 | * Add the correct font weight in Chrome, Edge, and Safari. 96 | */ 97 | 98 | b, 99 | strong { 100 | font-weight: bolder; 101 | } 102 | 103 | /** 104 | * 1. Correct the inheritance and scaling of font size in all browsers. 105 | * 2. Correct the odd `em` font sizing in all browsers. 106 | */ 107 | 108 | code, 109 | kbd, 110 | samp { 111 | font-family: monospace, monospace; /* 1 */ 112 | font-size: 1em; /* 2 */ 113 | } 114 | 115 | /** 116 | * Add the correct font size in all browsers. 117 | */ 118 | 119 | small { 120 | font-size: 80%; 121 | } 122 | 123 | /** 124 | * Prevent `sub` and `sup` elements from affecting the line height in 125 | * all browsers. 126 | */ 127 | 128 | sub, 129 | sup { 130 | font-size: 75%; 131 | line-height: 0; 132 | position: relative; 133 | vertical-align: baseline; 134 | } 135 | 136 | sub { 137 | bottom: -0.25em; 138 | } 139 | 140 | sup { 141 | top: -0.5em; 142 | } 143 | 144 | /* Embedded content 145 | ========================================================================== */ 146 | 147 | /** 148 | * Remove the border on images inside links in IE 10. 149 | */ 150 | 151 | img { 152 | border-style: none; 153 | } 154 | 155 | /* Forms 156 | ========================================================================== */ 157 | 158 | /** 159 | * 1. Change the font styles in all browsers. 160 | * 2. Remove the margin in Firefox and Safari. 161 | */ 162 | 163 | button, 164 | input, 165 | optgroup, 166 | select, 167 | textarea { 168 | font-family: inherit; /* 1 */ 169 | font-size: 100%; /* 1 */ 170 | line-height: 1.15; /* 1 */ 171 | margin: 0; /* 2 */ 172 | } 173 | 174 | /** 175 | * Show the overflow in IE. 176 | * 1. Show the overflow in Edge. 177 | */ 178 | 179 | button, 180 | input { /* 1 */ 181 | overflow: visible; 182 | } 183 | 184 | /** 185 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 186 | * 1. Remove the inheritance of text transform in Firefox. 187 | */ 188 | 189 | button, 190 | select { /* 1 */ 191 | text-transform: none; 192 | } 193 | 194 | /** 195 | * Correct the inability to style clickable types in iOS and Safari. 196 | */ 197 | 198 | button, 199 | [type="button"], 200 | [type="reset"], 201 | [type="submit"] { 202 | -webkit-appearance: button; 203 | } 204 | 205 | /** 206 | * Remove the inner border and padding in Firefox. 207 | */ 208 | 209 | button::-moz-focus-inner, 210 | [type="button"]::-moz-focus-inner, 211 | [type="reset"]::-moz-focus-inner, 212 | [type="submit"]::-moz-focus-inner { 213 | border-style: none; 214 | padding: 0; 215 | } 216 | 217 | /** 218 | * Restore the focus styles unset by the previous rule. 219 | */ 220 | 221 | button:-moz-focusring, 222 | [type="button"]:-moz-focusring, 223 | [type="reset"]:-moz-focusring, 224 | [type="submit"]:-moz-focusring { 225 | outline: 1px dotted ButtonText; 226 | } 227 | 228 | /** 229 | * Correct the padding in Firefox. 230 | */ 231 | 232 | fieldset { 233 | padding: 0.35em 0.75em 0.625em; 234 | } 235 | 236 | /** 237 | * 1. Correct the text wrapping in Edge and IE. 238 | * 2. Correct the color inheritance from `fieldset` elements in IE. 239 | * 3. Remove the padding so developers are not caught out when they zero out 240 | * `fieldset` elements in all browsers. 241 | */ 242 | 243 | legend { 244 | box-sizing: border-box; /* 1 */ 245 | color: inherit; /* 2 */ 246 | display: table; /* 1 */ 247 | max-width: 100%; /* 1 */ 248 | padding: 0; /* 3 */ 249 | white-space: normal; /* 1 */ 250 | } 251 | 252 | /** 253 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 254 | */ 255 | 256 | progress { 257 | vertical-align: baseline; 258 | } 259 | 260 | /** 261 | * Remove the default vertical scrollbar in IE 10+. 262 | */ 263 | 264 | textarea { 265 | overflow: auto; 266 | } 267 | 268 | /** 269 | * 1. Add the correct box sizing in IE 10. 270 | * 2. Remove the padding in IE 10. 271 | */ 272 | 273 | [type="checkbox"], 274 | [type="radio"] { 275 | box-sizing: border-box; /* 1 */ 276 | padding: 0; /* 2 */ 277 | } 278 | 279 | /** 280 | * Correct the cursor style of increment and decrement buttons in Chrome. 281 | */ 282 | 283 | [type="number"]::-webkit-inner-spin-button, 284 | [type="number"]::-webkit-outer-spin-button { 285 | height: auto; 286 | } 287 | 288 | /** 289 | * 1. Correct the odd appearance in Chrome and Safari. 290 | * 2. Correct the outline style in Safari. 291 | */ 292 | 293 | [type="search"] { 294 | -webkit-appearance: textfield; /* 1 */ 295 | outline-offset: -2px; /* 2 */ 296 | } 297 | 298 | /** 299 | * Remove the inner padding in Chrome and Safari on macOS. 300 | */ 301 | 302 | [type="search"]::-webkit-search-decoration { 303 | -webkit-appearance: none; 304 | } 305 | 306 | /** 307 | * 1. Correct the inability to style clickable types in iOS and Safari. 308 | * 2. Change font properties to `inherit` in Safari. 309 | */ 310 | 311 | ::-webkit-file-upload-button { 312 | -webkit-appearance: button; /* 1 */ 313 | font: inherit; /* 2 */ 314 | } 315 | 316 | /* Interactive 317 | ========================================================================== */ 318 | 319 | /* 320 | * Add the correct display in Edge, IE 10+, and Firefox. 321 | */ 322 | 323 | details { 324 | display: block; 325 | } 326 | 327 | /* 328 | * Add the correct display in all browsers. 329 | */ 330 | 331 | summary { 332 | display: list-item; 333 | } 334 | 335 | /* Misc 336 | ========================================================================== */ 337 | 338 | /** 339 | * Add the correct display in IE 10+. 340 | */ 341 | 342 | template { 343 | display: none; 344 | } 345 | 346 | /** 347 | * Add the correct display in IE 10. 348 | */ 349 | 350 | [hidden] { 351 | display: none; 352 | } -------------------------------------------------------------------------------- /public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | --------------------------------------------------------------------------------