├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── babel.config.js ├── get_data ├── cateList.js ├── cateList2.js ├── detail.js ├── item.js ├── maketDesc.js ├── manufacturer.js └── topic.js ├── mock ├── banner_1.json ├── cateList.json ├── comment_1.json ├── comment_2.json ├── comment_3.json ├── comment_4.json ├── comment_tag.json ├── goodsDetail.json ├── index.js ├── indexPage_arrivals.json ├── indexPage_categoryGoods.json ├── indexPage_channels.json ├── indexPage_hotSellProduct.json ├── indexPage_popularRecommend.json ├── itemLists_1.json ├── itemLists_2.json ├── itemLists_3.json ├── itemLists_4.json ├── itemLists_5.json ├── itemLists_6.json ├── itemLists_7.json ├── itemLists_8.json ├── manufacturer.json ├── market_desc.json ├── rcmd.json ├── search_kds.json ├── topic.json └── util.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── preset-default-vue-cli-3.js ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── api │ ├── cateList.js │ ├── comment.js │ ├── common.js │ ├── goodsDetail.js │ ├── index.js │ ├── items.js │ ├── manufacturer.js │ ├── marketDesc.js │ ├── middleware.js │ ├── search.js │ ├── topic.js │ └── user.js ├── assets │ ├── css │ │ ├── mixin.scss │ │ ├── productList.scss │ │ └── reset.scss │ ├── font │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ └── img │ │ └── logo.png ├── components │ ├── common │ │ ├── Banner.vue │ │ ├── CategoryGoodsBlock.vue │ │ ├── CategoryNav.vue │ │ ├── CommentModule.vue │ │ ├── GoTop.vue │ │ ├── ProductCard.vue │ │ ├── ProductShowContainer.vue │ │ ├── ProductTag.vue │ │ ├── SpaceModule.vue │ │ ├── SpecificationLabel.vue │ │ └── ThroughLineTitle.vue │ └── market │ │ ├── GuessYouLike.vue │ │ └── OptimalTo.vue ├── layout │ ├── footer │ │ ├── BuyFooter.vue │ │ └── Footer.vue │ └── header │ │ ├── OnlySearchHeader.vue │ │ ├── SimpleHeader.vue │ │ └── TopHeader.vue ├── main.js ├── page │ ├── cart │ │ └── index.vue │ ├── cateList │ │ └── index.vue │ ├── comment │ │ ├── comment.vue │ │ └── index.js │ ├── goodsDetail │ │ ├── GoodsArgument.vue │ │ ├── GoodsComment.vue │ │ ├── GoodsInfo.vue │ │ ├── GoodsSpecification.vue │ │ ├── goodsDetail.vue │ │ └── index.js │ ├── index │ │ ├── BrandMade.vue │ │ ├── FastArrival.vue │ │ ├── FreshmanModule.vue │ │ ├── HotSell.vue │ │ ├── PopularRecommend.vue │ │ ├── ShoppingChannle.vue │ │ ├── index.js │ │ └── index.vue │ ├── items │ │ ├── ItemProductBlock.vue │ │ ├── index.js │ │ └── items.vue │ ├── login │ │ └── index.vue │ ├── manufacturer │ │ └── index.vue │ ├── marketDesc │ │ └── index.vue │ ├── notFound.vue │ ├── search │ │ ├── index.js │ │ └── search.vue │ └── topic │ │ └── index.vue ├── router.js ├── store │ ├── index.js │ ├── modules │ │ ├── cateList.js │ │ ├── comment.js │ │ ├── common.js │ │ ├── goodsDetail.js │ │ ├── home.js │ │ ├── items.js │ │ ├── manufacturer.js │ │ ├── marketDesc.js │ │ ├── search.js │ │ └── topic.js │ └── mutation-types.js └── utils │ └── index.js ├── static └── img │ ├── brand │ ├── brand_1.png │ ├── brand_2.png │ ├── brand_3.png │ └── brand_4.png │ ├── group.png │ ├── new_bag.png │ └── well.png ├── tests └── unit │ ├── .eslintrc.js │ └── example.spec.js └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: [ 7 | "plugin:vue/essential", 8 | ], 9 | rules: { 10 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 11 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", 12 | }, 13 | parserOptions: { 14 | parser: "babel-eslint" 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | { 3 | "postcss": { 4 | "cssnano": { 5 | "preset": "advanced", 6 | "autoprefixer": false, 7 | "postcss-zindex": false 8 | } 9 | }, 10 | "plugins": { 11 | "postcss-import": {}, 12 | "postcss-url": {}, 13 | "postcss-aspect-ratio-mini": {}, 14 | "postcss-write-svg": { 15 | utf8: false 16 | }, 17 | "postcss-cssnext": {}, 18 | "postcss-px-to-viewport": { 19 | viewportWidth: 375, 20 | viewportHeight: 1334, 21 | unitPrecision: 3, 22 | viewportUnit: 'vw', 23 | selectorBlackList: ['.ignore', '.hairlines'], 24 | minPixelValue: 1, 25 | mediaQuery: false 26 | }, 27 | "postcss-viewport-units":{ 28 | filterRule: rule => rule.nodes.findIndex(i => i.prop === 'content') === -1 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ### 关于 3 | 适配多种设备视口是移动端所面对的场景,之前开发项目中多采用rem、media查询、flex百分比等布局,最近研究vw(视口单位)实现适配布局过程中,决定采用vue写仿网易严选项目练习下 4 | - - - 5 | 注:讲解几种适配大法比较好的文章[https://juejin.im/post/5bc07ebf6fb9a05d026119a9] 6 | 7 | ### 关于兼容 8 | 由于精力有限,只测试了vivo、6p、xr机型部分浏览器。由于vw针对视口逐步放大,暂未解决pc下字体和盒子元素过大的问题 9 | 10 | #### 关于后端 11 | 暂未开发后台,留待以后开发node + mongodb的简单后台。开发环境采用简单mock数据,生产环境采用axios请求固定数据源。目前跟登录、购物相关页面暂未开发 12 | 13 | ### 技术栈 14 | vue2 + vuex + vue-router + webpack + ES6 + axios + sass 15 | 16 | ### 运行 17 | ``` 18 | git clone https://github.com/lusteng/vue-yanxuan.git   19 | 20 | cd vue-yanxuan 21 | 22 | npm i 或者 yarn 23 | 24 | npm run serve 25 | 26 | ``` 27 | 28 | ### Demo 29 | 30 | [http://www.liubaitong.com/view/?site=yanxuan](http://www.liubaitong.com/view/?site=yanxuan) 31 | 32 | ### 部分页面截图 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | ### 目录结构 41 | 42 | ``` 43 | 44 | ├── mock //dev 开发环境 mock数据 45 | ├── public 46 | ├── src 47 | | ├── api //请求接口集合 48 | | | ├── cateList.js 49 | | | ├── comment.js 50 | | | ├── common.js 51 | | | ├── goodsDetail.js 52 | | | ├── index.js 53 | | | ├── items.js 54 | | | ├── manufacturer.js 55 | | | ├── marketDesc.js 56 | | | ├── middleware.js 57 | | | ├── search.js 58 | | | ├── topic.js 59 | | | └── user.js 60 | | ├── App.vue 61 | | ├── assets //logo、样式、字体集合 62 | | | ├── css 63 | | | ├── font 64 | | | └── img 65 | | ├── components //公共组件 66 | | | ├── common 67 | | | └── market 68 | | ├── layout //布局组件 69 | | | ├── footer 70 | | | └── header 71 | | ├── main.js 72 | | ├── page //页面 73 | | | ├── cart 74 | | | ├── cateList 75 | | | ├── comment 76 | | | ├── goodsDetail 77 | | | ├── index 78 | | | ├── items 79 | | | ├── login 80 | | | ├── manufacturer 81 | | | ├── marketDesc 82 | | | ├── notFound.vue 83 | | | ├── search 84 | | | └── topic 85 | | ├── router.js 86 | | ├── store //数据源 87 | | | ├── index.js 88 | | | └── mutation-types.js 89 | | └── utils //工具方法 90 | | └── index.js 91 | ├── static //静态资源 92 | | └── img 93 | ├── tests 94 | ├── .postcssrc.js //配置vw文件 95 | . 96 | . 97 | 98 | ``` 99 | 100 | ### TODO 101 | + node + mongodb 模仿数据后台 102 | + 登录系统、用户系统 103 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"], 3 | plugins: [ 4 | ['import', { 5 | libraryName: 'vant', 6 | libraryDirectory: 'es', 7 | style: true 8 | }, 'vant'] 9 | ] 10 | }; 11 | -------------------------------------------------------------------------------- /get_data/cateList.js: -------------------------------------------------------------------------------- 1 | let 2 | json = {}, 3 | nav = [] 4 | 5 | $.each($('.m-cateNavVert .item'), function(){ 6 | nav.push({ 7 | name: $(this).find('a').text() 8 | }) 9 | }) 10 | 11 | json.nav = nav 12 | 13 | console.log(JSON.stringify(json)) -------------------------------------------------------------------------------- /get_data/cateList2.js: -------------------------------------------------------------------------------- 1 | let json = {}; 2 | json.banner = $('.m-subCateContainer .banner').css('background-image').match(/url\(\"(\S*?)\"\)/)[1] 3 | let list = []; 4 | 5 | $.each($('.m-subCateContainer .cateList'), function(){ 6 | let cates = []; 7 | $.each($(this).find('.cateItem'), function(){ 8 | cates.push( 9 | { 10 | picUrl: $(this).find('img').attr('src'), 11 | text: $(this).find('.name').text() 12 | } 13 | ) 14 | }); 15 | list.push({ 16 | til: $(this).find('.hd').length > 0 ? $(this).find('.hd').text() : '', 17 | cates 18 | }) 19 | }) 20 | 21 | json.list = list 22 | 23 | console.log(JSON.stringify(json)) -------------------------------------------------------------------------------- /get_data/detail.js: -------------------------------------------------------------------------------- 1 | var json = {} 2 | 3 | var banner = [] 4 | $.each($('.swiper-wrapper .swiper-slide'), function(){ 5 | banner.push({ 6 | 'picUrl' : $(this).find('img').attr('src') 7 | }) 8 | }) 9 | 10 | json.banner = banner 11 | 12 | var characteristic = [] 13 | 14 | $.each($('.m-characteristic .item'), function(){ 15 | characteristic.push({ 16 | picUrl: $(this).find('img').attr('src'), 17 | text1: $(this).find('.right .text:first').text(), 18 | text2: $(this).find('.right .text:last').text() 19 | }) 20 | }) 21 | 22 | json.characteristic = characteristic 23 | 24 | var price = { 25 | origin_p: $('.m-detailBaseInfo .currentPrice span:last').text(), 26 | super_p: $('.m-detailBaseInfo .spmcBanner span:first').text(), 27 | title: $('.m-detailBaseInfo .baseInfo .name').text(), 28 | desc: $('.m-detailBaseInfo .desc').text(), 29 | reputatio: $('.m-detailBaseInfo .wrap .num').text(), 30 | } 31 | 32 | json.price = price 33 | 34 | var comment = { 35 | comment_n: $('.m-detailComment').find('.title span:nth-of-type(2)').text(), 36 | rate: $('.m-detailComment').find('.comment-checkAll .rate').text(), 37 | result:[{ 38 | "skuInfo": ["M", "黑色"], 39 | "frontUserName": "耳****", 40 | "content": "穿着非常有气质,显腿长,显腰细,哈哈,奥黛丽赫本风,超级喜欢", 41 | "createTime": 1525892551248, 42 | "picList": ["https://yanxuan.nosdn.127.net/5ef9c6bc390c823119ccf4a5cb759447.jpg", "https://yanxuan.nosdn.127.net/a9f8daa562d828349ad6eb5fd8982475.jpg", "https://yanxuan.nosdn.127.net/93bce4c659fd8804678b904dfae8b656.jpg", "https://yanxuan.nosdn.127.net/d6515036d240e0733aa5e172c1b0645b.jpg"], 43 | "frontUserAvatar": "http://thirdqq.qlogo.cn/qqapp/1104949895/3314E1893F4B4F5EF077B296EFFBFD2D/100", 44 | "commentReplyVO": null, 45 | "memberLevel": 2, 46 | "appendCommentVO": null, 47 | "star": 5, 48 | "itemId": 1447011, 49 | "commentItemTagVO": { 50 | "type": 1, 51 | "schemeUrl": "https://m.you.163.com/topic/v1/look/list" 52 | } 53 | }] 54 | } 55 | json.comment = comment 56 | 57 | 58 | var arg = [] 59 | $.each($('.m-itemDetail .dt-section .item'), function(){ 60 | arg.push({ 61 | name: $(this).find('.left').text(), 62 | cnt: $(this).find('.right .con').text() 63 | }) 64 | }) 65 | 66 | json.arg = arg 67 | 68 | json.html = $('.m-detailHtml').html(); 69 | 70 | console.log(JSON.stringify(json)) -------------------------------------------------------------------------------- /get_data/item.js: -------------------------------------------------------------------------------- 1 | var json = {} 2 | json.banner_img = $('.m-banner').css('background').match(/rgba\(0, 0, 0, 0\) url\(\"(\S*?)\"\) repeat scroll 50% 50% \/ cover padding-box border-box/)[1]; 3 | var lists = []; 4 | $.each($('ul.list .f-mb20'), function(item, index){ 5 | if(item > 3){ 6 | return ; 7 | } 8 | var list = []; 9 | $.each($(this).find('.m-goodGrid').find('li.item'), function(){ 10 | list.push({ 11 | "title": $(this).find('.name span').text(), 12 | "sub_title": "", 13 | "picUrl": $(this).find('.m-lazyload img').attr('src'), 14 | "tag": $(this).find('.gradientPrice').text(), 15 | "spec": $(this).find('.specification').text(), 16 | "price": $(this).find('.priceInner span:first span:last').text(), 17 | "discount": $(this).find('.counterPrice span:last').text(), 18 | "desc": $(this).find('.desc span:last').text() 19 | }) 20 | }); 21 | lists.push({ 22 | title: $(this).find('header.hd .name').text(), 23 | sub_title: $(this).find('header.hd .desc').text(), 24 | list 25 | }) 26 | }) 27 | json.list = lists; 28 | console.log(JSON.stringify(json)) 29 | 30 | -------------------------------------------------------------------------------- /get_data/maketDesc.js: -------------------------------------------------------------------------------- 1 | 2 | $('.cyclopes-module').html() 3 | //TODO: 去空格," 转成 ' -------------------------------------------------------------------------------- /get_data/manufacturer.js: -------------------------------------------------------------------------------- 1 | var json = {} 2 | json.mr = { 3 | img: $('.m-manufacturer-itemlist .imgWraper img').attr('src'), 4 | title: $('.m-manufacturer-itemlist .header .banner').text(), 5 | desc: [], 6 | } 7 | 8 | $.each($('.m-manufacturer-itemlist .desc div'), function(){ 9 | json.mr.desc.push($(this).text()) 10 | }) 11 | 12 | 13 | var list = []; 14 | $.each($('.m-goodGrid li.item'), function(item, index){ 15 | list.push({ 16 | "title": $(this).find('.name span').text(), 17 | "sub_title": "", 18 | "picUrl": $(this).find('.m-lazyload img').attr('src'), 19 | "tag": $(this).find('.gradientPrice').text(), 20 | "spec": $(this).find('.specification').text(), 21 | "price": $(this).find('.priceInner span:first span:last').text(), 22 | "discount": $(this).find('.counterPrice span:last').text(), 23 | "desc": $(this).find('.desc span:last').text() 24 | }) 25 | }) 26 | json.list = list; 27 | console.log(JSON.stringify(json)) 28 | 29 | -------------------------------------------------------------------------------- /get_data/topic.js: -------------------------------------------------------------------------------- 1 | var json = { 2 | "errCode":"0", 3 | "data": [] 4 | } 5 | $.each($('.m-main-content').find('.m-tpls'), function(){ 6 | json.data.push( 7 | { 8 | til: $(this).find('.u-name span:last-child').text(), 9 | tip: $(this).find('.u-name span:first-child img').attr('src'), 10 | desc: $(this).find('.title').text(), 11 | pic: $(this).find('.u-pic img').attr('src'), 12 | look: $(this).find('.u-rcount span').text() 13 | } 14 | ) 15 | }) 16 | 17 | console.log(JSON.stringify(json)) -------------------------------------------------------------------------------- /mock/banner_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "errCode": 0, 3 | "data": [ 4 | { 5 | "src": "https://yanxuan.nosdn.127.net/9b48e1e9e3002bad26cec13d9d9febf4.jpg?imageView&quality=75&thumbnail=750x0", 6 | "link": "" 7 | }, 8 | { 9 | "src": "https://yanxuan.nosdn.127.net/d12d444efc98621ad288352506740f07.jpg?imageView&quality=75&thumbnail=750x0", 10 | "link": "" 11 | }, 12 | { 13 | "src": "https://yanxuan.nosdn.127.net/4e8dcdf8b85d240f505177d45db7b108.jpg?imageView&quality=75&thumbnail=750x0", 14 | "link": "" 15 | }, 16 | { 17 | "src": "https://yanxuan.nosdn.127.net/f1ac500da5ce732ff3da189d5bb44efe.jpeg?imageView&quality=75&thumbnail=750x0", 18 | "link": "" 19 | }, 20 | { 21 | "src": "https://yanxuan.nosdn.127.net/0266e997e1b26ce222d5f02d2a819350.jpg?imageView&quality=75&thumbnail=750x0", 22 | "link": "" 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /mock/comment_1.json: -------------------------------------------------------------------------------- 1 | {"errCode":"0","data":{"pagination":{"page":1,"size":10,"totalPage":43,"total":426,"lastPage":false},"result":[{"skuInfo":["M","黑色"],"frontUserName":"耳****","content":"穿着非常有气质,显腿长,显腰细,哈哈,奥黛丽赫本风,超级喜欢","createTime":1525892551248,"picList":["https://yanxuan.nosdn.127.net/5ef9c6bc390c823119ccf4a5cb759447.jpg","https://yanxuan.nosdn.127.net/a9f8daa562d828349ad6eb5fd8982475.jpg","https://yanxuan.nosdn.127.net/93bce4c659fd8804678b904dfae8b656.jpg","https://yanxuan.nosdn.127.net/d6515036d240e0733aa5e172c1b0645b.jpg"],"frontUserAvatar":"http://thirdqq.qlogo.cn/qqapp/1104949895/3314E1893F4B4F5EF077B296EFFBFD2D/100","commentReplyVO":null,"memberLevel":2,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":{"type":1,"schemeUrl":"https://m.you.163.com/topic/v1/look/list"}},{"skuInfo":["M","黑色"],"frontUserName":"A****","content":"被包装惊艳到了,裙子穿上特别显身材,面料略厚,空调房里可以穿","createTime":1527120142609,"picList":["https://yanxuan.nosdn.127.net/07beeb1cf6bf19797f0e6c49e360386c.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/dc4d89af2baeb53c8cbb36936559a9b0.jpg","commentReplyVO":{"id":20138940,"replyContent":"收到您的评价严选万分欣喜,您的需求与满意就是我们不断前进的动力,我们会继续努力给您带来更佳的购物体验,望您持续关注网易严选,祝开心快乐每一天!","createTime":"2018-05-24 10:04:33"},"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"w****c","content":"包装好,衣服质量超好,有质感垂感,穿在身上很有气质,两三百能买到这么好的衣服,真的性价比超高~不过衣服略厚,夏天太热肯定穿不了","createTime":1526877480962,"picList":["https://yanxuan.nosdn.127.net/484acbbbf0dc4334232d17c3c40a66b9.jpg","https://yanxuan.nosdn.127.net/8ee0b3e89d269d04266ee0fdf75c85d3.jpg","https://yanxuan.nosdn.127.net/43542baba46ce4c50641a12d36aed1d5.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/75ebaece30849c5df7acf171ba576f97.jpg","commentReplyVO":{"id":20137515,"replyContent":"o(≧v≦)o感谢您的支持与认可,严选竭力追求为客户提供超高性价比的商品,期待您的再次选购,祝您生活愉快!","createTime":"2018-05-21 21:00:11"},"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"p****1","content":"拿到手,感觉沉甸甸的啊。份量好重,厚实!款式简洁,不会过时。超赞!","createTime":1543913225907,"picList":["https://yanxuan.nosdn.127.net/be6bf64db89d3d0222d2241ebab5c1f9.jpg"],"frontUserAvatar":"http://yanxuan.nosdn.127.net/f23fab1b5a89ece5b5d9a57863dc2476","commentReplyVO":null,"memberLevel":3,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["XL","黑色"],"frontUserName":"霞****天","content":"请忽略拍照技术 实物好看 沉甸甸的 很有质感","createTime":1550490725462,"picList":["https://yanxuan.nosdn.127.net/d60d7d5c17835f986f12a847f1431042.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/6f6da8466319c869a26d9541fdee66e1.jpg","commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["L","黑色"],"frontUserName":"m****6","content":"非常显瘦!裙摆有垂感。稍厚,不会皱。总体评价100分!","createTime":1544349500374,"picList":["https://yanxuan.nosdn.127.net/160fbdbc7bc07e087e8ca704c67b9d07.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"张****玲","content":"裙子垂感不错,有赫本风,但有点厚,只能秋天再穿了。这包装实在太帅了","createTime":1528026892063,"picList":["https://yanxuan.nosdn.127.net/f8e8474ca42273922e929ce86a1173f7.jpg","https://yanxuan.nosdn.127.net/79520a48365baec229989974d77c6efb.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/68c7e61fef2dec8803f0c7810be30bc8","commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"扬****","content":"很厚实的针织裙。只是不知道洗过后如何整形处理。版型相当不错。显瘦,显腰细。高跟鞋效果应该更好。","createTime":1526979550957,"picList":["https://yanxuan.nosdn.127.net/4a59942ea8840c4c686e6cefe9fd5fe4.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/2a08fac3917cb13d88b90bee1660b0f0","commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"熊****仙","content":"款式很不错,束腰显瘦,今年的流行款,老婆穿着很nice。颜色可选只有黑色,少了点,期待更多的颜色","createTime":1526017551836,"picList":["https://yanxuan.nosdn.127.net/175e563d81ea4bac86af1800799e5538.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/aa722664acb5b3499f5f5f19d64c51f7.jpg","commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["XL","黑色"],"frontUserName":"f****","content":"小胖子穿上也很显瘦,严选质量太赞\uD83D\uDC4D\uD83C\uDFFB同事都被圈粉了 准备再入手个衬衫","createTime":1521958071787,"picList":["https://yanxuan.nosdn.127.net/1ed872874ed259fb7ab28c3bbd660760.jpg"],"frontUserAvatar":"http://yanxuan.nosdn.127.net/80ce726dc7380620c44bb55643a633ee","commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null}],"relatedItemCommentTag":null}} -------------------------------------------------------------------------------- /mock/comment_2.json: -------------------------------------------------------------------------------- 1 | {"errCode":"0","data":{"pagination":{"page":2,"size":10,"totalPage":43,"total":430,"lastPage":false},"result":[{"skuInfo":["S","黑色"],"frontUserName":"ゞ****…","content":"裙子真的很好看,质量很好,穿上很显气质又修身。","createTime":1526269044801,"picList":["https://yanxuan.nosdn.127.net/c7c2e11d1acaabc6e81f6a46d619db4a.jpg","https://yanxuan.nosdn.127.net/9b98de44db5cde68f96a4da8f57b2c86.jpg"],"frontUserAvatar":"http://q.qlogo.cn/qqapp/1104949895/7BB2B6BB9E60854257F3E41D8878CBCC/100","commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"☆****ヤ","content":"这个包装惊艳了我,裙子质量很好。","createTime":1526425472843,"picList":["https://yanxuan.nosdn.127.net/ceff0fb4a126d17668f8d2b40627ecb1.jpg"],"frontUserAvatar":"http://q.qlogo.cn/qqapp/1104949895/C19124345A8C7E9CE27EAFD02D78C6A9/100","commentReplyVO":null,"memberLevel":3,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"m****1","content":"穿上真是太美了 本身宽肩 但穿上这件散摆的裙子 完全不显了 材质也超垂坠 超喜欢的 束腰的设计真是太美 现在每天都要看严选的新品推荐 已然成为了严选的死忠粉!","createTime":1526379771011,"picList":["https://yanxuan.nosdn.127.net/30b878c5729c8453595d259c806cda76.jpg","https://yanxuan.nosdn.127.net/e1f8c483fe0e04054eb8312461f752df.jpg","https://yanxuan.nosdn.127.net/9ac0244aeea05431ae39ac59be98d481.jpg","https://yanxuan.nosdn.127.net/ebb2be982694d832b9a50e87614c3ccf.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/8032e97cbc50052f7962a52810717224.jpg","commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"2****7","content":"天气还凉,暂时没试过后追评","createTime":1519570762183,"picList":[],"frontUserAvatar":"https://yanxuan.nosdn.127.net/177a143462646354c6703f4c488f8989.jpg","commentReplyVO":null,"memberLevel":6,"appendCommentVO":{"id":38816628,"createTime":1522389577691,"content":"今天天气不错终于有机会穿了,真的很好,修身显瘦,质量好","picList":["https://yanxuan.nosdn.127.net/13b4820ed6d7bd059482b4a9ebe43e78.jpg"],"commentReplyVO":null},"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"尘****","content":"包装的好,衣服漂亮,年轻好几岁。严选\uD83D\uDC4C","createTime":1525072811063,"picList":["https://yanxuan.nosdn.127.net/6af79e578466d7850b5e029d8dbd64df.jpg","https://yanxuan.nosdn.127.net/30170827d317b6e8b939efca519f21f9.jpg","https://yanxuan.nosdn.127.net/f0163a938e457290b7303ebd5a2d1abe.jpg","https://yanxuan.nosdn.127.net/e709acbbaff79cfd45314b4632a46656.jpg"],"frontUserAvatar":"http://q.qlogo.cn/qqapp/101330628/2B8CF1AB54991890F21A23B99D300FF6/100","commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"m****5","content":"很不错的一款裙子","createTime":1524994727338,"picList":["https://yanxuan.nosdn.127.net/7ff10450bb4455cdb39591864eb3acc1.jpg","https://yanxuan.nosdn.127.net/668c105ba9db7b63552cde8c15b89026.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"S****h","content":"衣服很漂亮,材质跟only类似的一款材质基本一样,很重","createTime":1524287083931,"picList":[],"frontUserAvatar":"https://yanxuan.nosdn.127.net/bae25552236c9812717cf81ff79efef5","commentReplyVO":null,"memberLevel":5,"appendCommentVO":{"id":39560089,"createTime":1524319340050,"content":"挺喜欢的","picList":["https://yanxuan.nosdn.127.net/49337683d1e22d12e0460035f7b5bfa0.jpg"],"commentReplyVO":null},"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"t****t","content":"老婆很喜欢,裙子比较显身材,很合身,材质也不错。","createTime":1523876777912,"picList":["https://yanxuan.nosdn.127.net/0d15c6f2460abb80d72ca9c0e564a2bc.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["L","黑色"],"frontUserName":"l****2","content":"看妈妈穿着多好看","createTime":1524018081632,"picList":["https://yanxuan.nosdn.127.net/9d7c5591465cc6da05389a1fa1dda32b.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["XL","黑色"],"frontUserName":"m****8","content":"这个裙子高挑的人穿起来真的很好看。","createTime":1522368222258,"picList":["https://yanxuan.nosdn.127.net/6f9f3b04b09dbeb92de61479d2d62cf3.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null}],"relatedItemCommentTag":null}} -------------------------------------------------------------------------------- /mock/comment_3.json: -------------------------------------------------------------------------------- 1 | {"errCode": "0","data":{"pagination":{"page":3,"size":10,"totalPage":43,"total":430,"lastPage":false},"result":[{"skuInfo":["L","黑色"],"frontUserName":"y****0","content":"手感不错,质地柔软,穿上修身,挺满意的","createTime":1522678666440,"picList":["https://yanxuan.nosdn.127.net/ea6e88f16aaa8a5213937f2896312e2d.jpg","https://yanxuan.nosdn.127.net/51a94eb80ffab324b33e66fb32f03a7f.jpg","https://yanxuan.nosdn.127.net/5b8d901964a064c85eeac6e9e46b4364.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/9ed9e10d10179ecb0307f677afc31609.jpg","commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"丽****","content":"买了没试 应该不错","createTime":1522115034664,"picList":["https://yanxuan.nosdn.127.net/d888b628bfc2c7faf5786faaf1f3cc79.jpg"],"frontUserAvatar":"http://q.qlogo.cn/qqapp/101330628/9E04177F5DA722ED11BC88507077BB10/100","commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"m****1","content":"","createTime":1521728581740,"picList":["https://yanxuan.nosdn.127.net/dd6f461931cd232e9603fcb0a0699517.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"h****y","content":"棒棒哒","createTime":1521556436057,"picList":["https://yanxuan.nosdn.127.net/49e470c8b49bfec7a47c721a15c04202.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"m****6","content":"质量很不错 沉甸甸的 暖一点就可以穿了","createTime":1521184720990,"picList":["https://yanxuan.nosdn.127.net/de68fbbd71f6a934c767fd558b6c6bcd.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["L","黑色"],"frontUserName":"倩****","content":"这个还没穿,我们这里好热,试了试应该款式大小可以,就是不知道质量!穿过了再来评价!","createTime":1520831873405,"picList":["https://yanxuan.nosdn.127.net/6ca1bcf2e73dc0e01fbc3cb1a2c176af.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/ab54c449f5679f045f5260cb81ea5aa8.jpg","commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":4,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"m****3","content":"太棒了,客服推荐的尺码非常合适,身高160体重108M码。衣服弹性很好,垂感好,还没下水,希望不掉色。","createTime":1519182244726,"picList":["https://yanxuan.nosdn.127.net/ae155b1c5327c424602893e5cdd281f8.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["L","黑色"],"frontUserName":"周****","content":"哇,配上暗红色的高跟鞋,穿上人很精神。料子针织,很有分量,黑色和款式都遮住了我的游泳圈。\uD83D\uDC4D","createTime":1520088589008,"picList":["https://yanxuan.nosdn.127.net/d204b1fcc3ef63a51a36b994230fb02e.jpg"],"frontUserAvatar":"http://yanxuan.nosdn.127.net/5a4068ff0d0adff3a3b43dbe429c9ebb","commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"m****1","content":"和nine west一款一样除了小圆领,最好搭配的小黑裙随便都能配","createTime":1519564503000,"picList":["https://yanxuan.nosdn.127.net/f6aceea8126173078f09c41a0f63f6f7.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"y****1","content":"刚刚收到货就迫不及待的拆开来看,裙子有垂坠质感,值得拥有的小黑裙","createTime":1519349855482,"picList":["https://yanxuan.nosdn.127.net/654426cd05d44477aaf594146c270375.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null}],"relatedItemCommentTag":null}} -------------------------------------------------------------------------------- /mock/comment_4.json: -------------------------------------------------------------------------------- 1 | {"errCode": "0","data":{"pagination":{"page":4,"size":10,"totalPage":43,"total":430,"lastPage":false},"result":[{"skuInfo":["L","黑色"],"frontUserName":"1****9","content":"很漂亮的裙子,我买了平时穿的号小了换了,建议买大一号穿着更舒服一些","createTime":1551588467821,"picList":[],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"s****j","content":"买的东西太多,评价不过来了。总之,在网易严选买东西省时省力,质量一如既往的好、价格实惠,看到自己需要的装车。","createTime":1552059028234,"picList":[],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"m****7","content":"心仪很久的裙子,这次碰到活动就下手了,质量很好,穿起来藏肚子,显腰身,很漂亮。","createTime":1546602109717,"picList":[],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"再****娆","content":"这件绝对好评,穿上后气质一下就体现出来了,想买的下手吧,不用犹豫","createTime":1546871166764,"picList":[],"frontUserAvatar":"http://q.qlogo.cn/qqapp/101330628/2816A757A7BB1C437F614DCF9F8FEE73/100","commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"C****","content":"很棒很棒很棒很棒很棒很棒很棒,老婆说可以的","createTime":1553196064049,"picList":[],"frontUserAvatar":"https://yanxuan.nosdn.127.net/c53b73a789d921c35f8f6f5dc1db9622.jpg","commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"m****8","content":"还是很有质感的裙子,穿上效果不错,必购小黑裙,留下了~","createTime":1552185956185,"picList":[],"frontUserAvatar":"null","commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["M","黑色"],"frontUserName":"马****","content":"修身,质量不错,就是裙摆有点大","createTime":1520518659204,"picList":["https://yanxuan.nosdn.127.net/a38acefdd769ad5723ce407e3379eec2.png"],"frontUserAvatar":"http://yanxuan.nosdn.127.net/be035df09038595be8a2fd64c48a1097","commentReplyVO":null,"memberLevel":4,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["S","黑色"],"frontUserName":"W****i","content":"不错 很大牌 很修身 老公也说好看","createTime":1520087590368,"picList":["https://yanxuan.nosdn.127.net/29620e828cbf6e15752f62800057b657.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/aa461b2f3125bbbc21746dbbbb96a8e1","commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["L","黑色"],"frontUserName":"z****1","content":"很修身!~买大了一码","createTime":1519965449622,"picList":["https://yanxuan.nosdn.127.net/36148bd22e9af199cc0aaa17cf9438d1.jpg"],"frontUserAvatar":null,"commentReplyVO":null,"memberLevel":5,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null},{"skuInfo":["L","黑色"],"frontUserName":"D****","content":"光线有点暗,衣服很舒服,167,57公斤,L码合适。","createTime":1518624580315,"picList":["https://yanxuan.nosdn.127.net/4cf251c9a242e031d640d8f4986868a0.jpg"],"frontUserAvatar":"https://yanxuan.nosdn.127.net/451a16df9d390464b0c9391e6eeca6de.jpg","commentReplyVO":null,"memberLevel":6,"appendCommentVO":null,"star":5,"itemId":1447011,"commentItemTagVO":null}],"relatedItemCommentTag":null}} -------------------------------------------------------------------------------- /mock/comment_tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "errCode": "0", 3 | "data": [{ 4 | "name": "全部", 5 | "strCount": "522", 6 | "type": "1" 7 | }, { 8 | "name": "有图", 9 | "strCount": "39", 10 | "type": "0" 11 | }, { 12 | "name": "追评", 13 | "strCount": "11", 14 | "type": "0" 15 | }, { 16 | "name": "漂亮精致", 17 | "strCount": "53", 18 | "type": "0" 19 | }, { 20 | "name": "质量上乘", 21 | "strCount": "40", 22 | "type": "0" 23 | }, { 24 | "name": "显瘦", 25 | "strCount": "21", 26 | "type": "0" 27 | }, { 28 | "name": "款式不错", 29 | "strCount": "9", 30 | "type": "0" 31 | }, { 32 | "name": "修身", 33 | "strCount": "8", 34 | "type": "0" 35 | }, { 36 | "name": "厚重", 37 | "strCount": "6", 38 | "type": "0" 39 | }] 40 | } -------------------------------------------------------------------------------- /mock/index.js: -------------------------------------------------------------------------------- 1 | const Mock = require('mockjs') 2 | const util = require('./util') 3 | const url = require('url') 4 | const qs = require('querystring') 5 | 6 | 7 | module.exports = function(app){ 8 | //监听http请求 9 | app.get('/banner', function (req, res) { 10 | let 11 | index = qs.parse(url.parse(req.url).query)['index'], 12 | json = util.getJsonFile(`./banner_${index}.json`); 13 | //将json传入 Mock.mock 方法中,生成的数据返回给浏览器 14 | res.json(Mock.mock(json)); 15 | }); 16 | 17 | app.get('/channels', function (req, res) { 18 | let 19 | json = util.getJsonFile(`./indexPage_channels.json`); 20 | res.json(Mock.mock(json)); 21 | }); 22 | 23 | app.get('/hotSalls', function(req, res){ 24 | let 25 | json = util.getJsonFile(`./indexPage_hotSellProduct.json`); 26 | res.json(Mock.mock(json)); 27 | }) 28 | 29 | app.get('/populars', function(req, res){ 30 | let 31 | json = util.getJsonFile(`./indexPage_popularRecommend.json`); 32 | res.json(Mock.mock(json)); 33 | }) 34 | 35 | app.get('/arrival', function(req, res){ 36 | let 37 | json = util.getJsonFile(`./indexPage_arrivals.json`); 38 | res.json(Mock.mock(json)); 39 | }) 40 | 41 | app.get('/categoryGoods', function(req, res){ 42 | let 43 | json = util.getJsonFile(`./indexPage_categoryGoods.json`); 44 | res.json(Mock.mock(json)); 45 | }) 46 | 47 | app.get('/items', function(req, res){ 48 | let 49 | index = qs.parse(url.parse(req.url).query)['index'], 50 | json = util.getJsonFile(`./itemLists_${index}.json`); 51 | res.json(Mock.mock(json)); 52 | }) 53 | 54 | app.get('/detail', function(req, res){ 55 | let 56 | json = util.getJsonFile(`./goodsDetail.json`); 57 | res.json(Mock.mock(json)); 58 | }) 59 | 60 | app.get('/rcmd', function(req, res){ 61 | let 62 | json = util.getJsonFile(`./rcmd.json`); 63 | res.json(Mock.mock(json)); 64 | }) 65 | 66 | app.get('/comments', function(req, res){ 67 | let 68 | page = qs.parse(url.parse(req.url).query)['page'], 69 | json = util.getJsonFile(`./comment_${page}.json`); 70 | res.json(Mock.mock(json)); 71 | }) 72 | 73 | app.get('/tags', function(req, res){ 74 | let 75 | json = util.getJsonFile(`./comment_tag.json`); 76 | res.json(Mock.mock(json)); 77 | }) 78 | 79 | app.get('/search_kds', function(req, res){ 80 | let 81 | json = util.getJsonFile(`./search_kds.json`); 82 | res.json(Mock.mock(json)); 83 | }) 84 | 85 | app.get('/cate_list', function(req, res){ 86 | let 87 | json = util.getJsonFile(`./cateList.json`); 88 | res.json(Mock.mock(json)); 89 | }) 90 | 91 | app.get('/market_desc', function(req, res){ 92 | let 93 | json = util.getJsonFile(`./market_desc.json`); 94 | res.json(Mock.mock(json)); 95 | }) 96 | 97 | app.get('/topic', function(req, res){ 98 | let 99 | json = util.getJsonFile(`./topic.json`); 100 | res.json(Mock.mock(json)); 101 | }) 102 | 103 | app.get('/manufacturer', function(req, res){ 104 | let 105 | json = util.getJsonFile(`./manufacturer.json`); 106 | res.json(Mock.mock(json)); 107 | }) 108 | } 109 | -------------------------------------------------------------------------------- /mock/indexPage_arrivals.json: -------------------------------------------------------------------------------- 1 | { 2 | "errCode": 0, 3 | "data": [ 4 | { 5 | "title": "网易智造低压海盐热敷腰带", 6 | "sub_title": "", 7 | "picUrl": "http://yanxuan.nosdn.127.net/f642d93131227b12600ef3b9c60e3c59.png?imageView&quality=65&thumbnail=330x330", 8 | "tag": "", 9 | "price":"199" 10 | }, 11 | { 12 | "title": "2019明前特级西湖龙井 ...", 13 | "sub_title": "", 14 | "picUrl": "http://yanxuan.nosdn.127.net/24320570a1ea380d50deb1e509afb522.png?imageView&quality=65&thumbnail=330x330", 15 | "tag": "预售好价", 16 | "price":"159" 17 | }, 18 | { 19 | "title": "3色可选 日本制造 吸附...", 20 | "sub_title": "", 21 | "picUrl": "http://yanxuan.nosdn.127.net/d9e41913161dd7a12dd21d70058a6e69.png?imageView&quality=65&thumbnail=330x330", 22 | "tag": "", 23 | "price":"139", 24 | "spec": "日本制造" 25 | }, 26 | { 27 | "title": "男式经典三防商务休闲裤", 28 | "sub_title": "", 29 | "picUrl": "http://yanxuan.nosdn.127.net/7ee4a33a4448721ae5ccfcaad6d9a400.png?imageView&quality=65&thumbnail=330x330", 30 | "tag": "", 31 | "price":"199", 32 | "spec": "3色可选" 33 | }, 34 | { 35 | "title": "男士舒软透气商务便鞋", 36 | "sub_title": "", 37 | "picUrl": "http://yanxuan.nosdn.127.net/52168d5019d95ab60aad6876a5960541.png?imageView&quality=65&thumbnail=330x330", 38 | "tag": "", 39 | "price":"339", 40 | "spec": "2色可选" 41 | }, 42 | { 43 | "title": "网易智造2U充电器+苹果数...", 44 | "sub_title": "", 45 | "picUrl": "http://yanxuan.nosdn.127.net/4513dccee6c97b78f4b391a2866d3130.png?imageView&quality=65&thumbnail=330x330", 46 | "tag": "", 47 | "price":"69" 48 | } 49 | ] 50 | } 51 | 52 | -------------------------------------------------------------------------------- /mock/indexPage_channels.json: -------------------------------------------------------------------------------- 1 | { 2 | "errCode": 0, 3 | "data": [ 4 | { 5 | "name": "居家生活", 6 | "picUrl": "http://yanxuan.nosdn.127.net/fede8b110c502ec5799702d5ec824792.png", 7 | "sequen": 1 8 | }, 9 | { 10 | "name": "服饰鞋包", 11 | "picUrl": "http://yanxuan.nosdn.127.net/fb9dde0c1593536c18c8e12b6f49eb17.png", 12 | "sequen": 2 13 | }, 14 | { 15 | "name": "美食酒水", 16 | "picUrl": "http://yanxuan.nosdn.127.net/d916591adea776351e084016335e5820.png", 17 | "sequen": 3 18 | }, 19 | { 20 | "name": "个护清洁", 21 | "picUrl": "http://yanxuan.nosdn.127.net/6c3bd9d885c818b1f73e497335a68b47.png", 22 | "sequen": 4 23 | },{ 24 | "name": "母婴亲子", 25 | "picUrl": "http://yanxuan.nosdn.127.net/559d2a240ec20b096590a902217009ff.png", 26 | "sequen": 5 27 | },{ 28 | "name": "运动旅行", 29 | "picUrl": "http://yanxuan.nosdn.127.net/23be40a05926faf2f2a81a08a1c53164.png", 30 | "sequen": 6 31 | },{ 32 | "name": "数码家电", 33 | "picUrl": "http://yanxuan.nosdn.127.net/fbca8e1f2948f0c09fc7672c2c125384.png", 34 | "sequen": 7 35 | },{ 36 | "name": "礼品特色", 37 | "picUrl": "http://yanxuan.nosdn.127.net/e83bd330713b66a8d4e8eb0cefed8996.png", 38 | "sequen": 8 39 | }, 40 | { 41 | "name": "限时购", 42 | "picUrl": "http://yanxuan.nosdn.127.net/63682bd2df06963251b2715e20f98a75.png", 43 | "sequen": 9 44 | }, 45 | { 46 | "name": "超级会员", 47 | "picUrl": "http://yanxuan.nosdn.127.net/51f5a91f10ba745ec68340b98315acf5.png", 48 | "sequen": 10 49 | } 50 | ] 51 | } 52 | 53 | -------------------------------------------------------------------------------- /mock/indexPage_hotSellProduct.json: -------------------------------------------------------------------------------- 1 | { 2 | "errCode": 0, 3 | "data": { 4 | "hot": [ 5 | { 6 | "name": "热销榜", 7 | "picUrl": "http://yanxuan.nosdn.127.net/3e18c31adcdbb08cc69e46afb46d084e.png?imageView&quality=65&thumbnail=200x200" 8 | }, 9 | { 10 | "name": "好评榜", 11 | "picUrl": "http://yanxuan.nosdn.127.net/a5fd7f29a950a7ef996a4ff49d8e68bb.png?imageView&quality=65&thumbnail=200x200" 12 | } 13 | ], 14 | "ranks": [ 15 | { 16 | "name": "居家生活榜", 17 | "picUrl": "http://yanxuan.nosdn.127.net/d78a90f7f496656b79e4559935031958.png?imageView&quality=65&thumbnail=200x200" 18 | }, 19 | { 20 | "name": "服饰鞋包榜", 21 | "picUrl": "http://yanxuan.nosdn.127.net/63c5f749c41c193731ffec74cb846642.png?imageView&quality=65&thumbnail=200x200" 22 | }, 23 | { 24 | "name": "美食酒水榜", 25 | "picUrl": "http://yanxuan.nosdn.127.net/1979054e3a1c8409f10191242165e674.png?imageView&quality=65&thumbnail=200x200" 26 | }, 27 | { 28 | "name": "个护清洁榜", 29 | "picUrl": "http://yanxuan.nosdn.127.net/dfe93936f47b66f4b8a4f1869f0ce828.png?imageView&quality=65&thumbnail=200x200" 30 | }, 31 | { 32 | "name": "母婴亲子榜", 33 | "picUrl": "http://yanxuan.nosdn.127.net/914ba4d6fbacf9a4a143f1d10e16eb3f.png?imageView&quality=65&thumbnail=200x200" 34 | }, 35 | { 36 | "name": "运动旅行榜", 37 | "picUrl": "http://yanxuan.nosdn.127.net/8d7a619fe512f9a100bd3b3ebe20ae9c.png?imageView&quality=65&thumbnail=200x200" 38 | }, 39 | { 40 | "name": "数码家电榜", 41 | "picUrl": "http://yanxuan.nosdn.127.net/da8ba5cd1fb0cfd689ebbe905a330913.png?imageView&quality=65&thumbnail=200x200" 42 | }, 43 | { 44 | "name": "礼品特色榜", 45 | "picUrl": "http://yanxuan.nosdn.127.net/55425f24345d01992d61a1646325ac94.png?imageView&quality=65&thumbnail=200x200" 46 | } 47 | ] 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /mock/indexPage_popularRecommend.json: -------------------------------------------------------------------------------- 1 | { 2 | "errCode": 0, 3 | "data": { 4 | "main_d": { 5 | "title": "网易智造R1智能折叠跑步机", 6 | "sub_title": "App智跑,家庭私人教练", 7 | "picUrl": "http://yanxuan.nosdn.127.net/0d551bd5cee1656127985e1003926672.png?imageView&quality=65&thumbnail=280x280", 8 | "tag": "满折", 9 | "price":"1200" 10 | }, 11 | "sub_d": [ 12 | { 13 | "title": "酸牛奶", 14 | "sub_title": "", 15 | "picUrl": "http://yanxuan.nosdn.127.net/605c286e89e479a969c74ed2af3c3f00.png?imageView&quality=65&thumbnail=330x330", 16 | "tag": "", 17 | "price":"95" 18 | }, 19 | { 20 | "title": "智能马桶盖", 21 | "sub_title": "", 22 | "picUrl": "http://yanxuan.nosdn.127.net/73a065d6fc8c32197b54421808c54788.png?imageView&quality=65&thumbnail=330x330", 23 | "tag": "超级闪购", 24 | "price":"1199" 25 | }, 26 | { 27 | "title": "酸牛奶", 28 | "sub_title": "升级款95%白鹅绒秋冬加厚", 29 | "picUrl": "http://yanxuan.nosdn.127.net/fb53b989d34b32366f138b5e563ccd0a.png?imageView&quality=65&thumbnail=330x330", 30 | "tag": "女王节特惠", 31 | "price":"896" 32 | } 33 | ] 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /mock/manufacturer.json: -------------------------------------------------------------------------------- 1 | { 2 | "errCode": 0, 3 | "data": { 4 | "mr": { 5 | "img": "https://yanxuan.nosdn.127.net/f023a22559b81374d3bd5cb563b9af0b.png", 6 | "title": "Nine West制造商", 7 | "desc": ["为打造一双优雅舒适的高跟鞋,", "严选选择美国Nine West玖熙品牌的制造商,", "让美丽绽放在足尖。"] 8 | }, 9 | "list": [{ 10 | "title": "女式凡尔赛典雅高跟鞋", 11 | "sub_title": "", 12 | "picUrl": "https://yanxuan.nosdn.127.net/4a75f2f819c31f689cee44295b88ee78.png?imageView&quality=65&thumbnail=330x330", 13 | "tag": "7月画册特惠", 14 | "spec": "2色可选", 15 | "price": "212", 16 | "discount": "259", 17 | "desc": "优雅小牛皮,7cm的风度" 18 | }, { 19 | "title": "女式日系蝴蝶结平底鞋", 20 | "sub_title": "", 21 | "picUrl": "https://yanxuan.nosdn.127.net/baa1ff8b6c8dc764b60d4384cf44ff1d.png?imageView&quality=65&thumbnail=330x330", 22 | "tag": "", 23 | "spec": "3色可选", 24 | "price": "219", 25 | "discount": "", 26 | "desc": "甜美通勤,轻松搭配" 27 | }, { 28 | "title": "女式羊反绒复古粗跟鞋", 29 | "sub_title": "", 30 | "picUrl": "https://yanxuan.nosdn.127.net/5baeedd69bc9bb3e670d9231cfdce62e.png?imageView&quality=65&thumbnail=330x330", 31 | "tag": "奥莱特惠", 32 | "spec": "3色可选", 33 | "price": "114", 34 | "discount": "229", 35 | "desc": "时尚小方头,体验不一样的风情" 36 | }, { 37 | "title": "女式丝感雪花扣平底鞋", 38 | "sub_title": "", 39 | "picUrl": "https://yanxuan.nosdn.127.net/d877cdc0c980e1ae080e1d5f24f92265.png?imageView&quality=65&thumbnail=330x330", 40 | "tag": "奥莱特惠", 41 | "spec": "3色可选", 42 | "price": "179", 43 | "discount": "219", 44 | "desc": "如真丝般鞋面,视觉顺滑触感温柔" 45 | }, { 46 | "title": "丝感雪花扣高跟女鞋", 47 | "sub_title": "", 48 | "picUrl": "https://yanxuan.nosdn.127.net/629901d0718ab0c069ad45c3a169b18e.png?imageView&quality=65&thumbnail=330x330", 49 | "tag": "奥莱特惠", 50 | "spec": "4色可选", 51 | "price": "188", 52 | "discount": "239", 53 | "desc": "闪烁星光,女人必备的“战鞋”" 54 | }, { 55 | "title": "女式英伦牛皮乐福鞋", 56 | "sub_title": "", 57 | "picUrl": "https://yanxuan.nosdn.127.net/d84f357ca19b4fc79865c420c2804a00.png?imageView&quality=65&thumbnail=330x330", 58 | "tag": "7月画册特惠", 59 | "spec": "2色可选", 60 | "price": "271", 61 | "discount": "339", 62 | "desc": "进口头层牛皮,经典中性风" 63 | }, { 64 | "title": "女式一字带粗跟凉鞋", 65 | "sub_title": "", 66 | "picUrl": "https://yanxuan.nosdn.127.net/2a72165059c26cf269a2e1f18e1faef4.png?imageView&quality=65&thumbnail=330x330", 67 | "tag": "奥莱特惠", 68 | "spec": "2色可选", 69 | "price": "188", 70 | "discount": "269", 71 | "desc": "优雅一字带,清凉整个夏天" 72 | }, { 73 | "title": "女式尖头搭带粗跟凉鞋", 74 | "sub_title": "", 75 | "picUrl": "https://yanxuan.nosdn.127.net/6a0ac2df86a0aa4f9959b63be4eaa5a7.png?imageView&quality=65&thumbnail=330x330", 76 | "tag": "奥莱特惠", 77 | "spec": "2色可选", 78 | "price": "149", 79 | "discount": "299", 80 | "desc": "4.5cm小方根,稳稳的幸福感" 81 | }, { 82 | "title": "女式羊皮方头粗跟凉鞋", 83 | "sub_title": "", 84 | "picUrl": "https://yanxuan.nosdn.127.net/7c125dc74f73e1bf3f4240266d659d1a.png?imageView&quality=65&thumbnail=330x330", 85 | "tag": "7月画册特惠", 86 | "spec": "3色可选", 87 | "price": "215", 88 | "discount": "269", 89 | "desc": "稳稳小粗跟,时尚小方头" 90 | }, { 91 | "title": "女式舒雅方扣平底凉拖鞋", 92 | "sub_title": "", 93 | "picUrl": "https://yanxuan.nosdn.127.net/45837d5a753d27117a89e68250adc195.png?imageView&quality=65&thumbnail=330x330", 94 | "tag": "奥莱特惠", 95 | "spec": "2色可选", 96 | "price": "121", 97 | "discount": "269", 98 | "desc": "牛皮鞋面,有质感的慵懒随意" 99 | }, { 100 | "title": "丝感清凉 女式珍珠粗跟凉鞋", 101 | "sub_title": "", 102 | "picUrl": "https://yanxuan.nosdn.127.net/627322159fc246da932847cb21dd9576.png?imageView&quality=65&thumbnail=330x330", 103 | "tag": "满2免1", 104 | "spec": "2色可选", 105 | "price": "269", 106 | "discount": "", 107 | "desc": "柔滑细腻丝绸布,7cm平稳粗跟" 108 | }, { 109 | "title": "女式尖头后空猫跟女巫鞋", 110 | "sub_title": "", 111 | "picUrl": "https://yanxuan.nosdn.127.net/8d3a1a8735579be8129f3e9e8229821d.png?imageView&quality=65&thumbnail=330x330", 112 | "tag": "奥莱特惠", 113 | "spec": "2色可选", 114 | "price": "134", 115 | "discount": "299", 116 | "desc": "深V女巫鞋,拉长腿型利器" 117 | }, { 118 | "title": "女式蝴蝶结羊皮穆勒鞋", 119 | "sub_title": "", 120 | "picUrl": "https://yanxuan.nosdn.127.net/a756da0a19de3e4e74c3ba8289d469cd.png?imageView&quality=65&thumbnail=330x330", 121 | "tag": "奥莱特惠", 122 | "spec": "2色可选", 123 | "price": "134", 124 | "discount": "299", 125 | "desc": "真丝般的触感,如轻风拂过脚面" 126 | }, { 127 | "title": "女式羊皮搭带高跟鞋", 128 | "sub_title": "", 129 | "picUrl": "https://yanxuan.nosdn.127.net/26f6c88549db78f4100ae91b694f4f3c.png?imageView&quality=65&thumbnail=330x330", 130 | "tag": "满2免1", 131 | "spec": "2色可选", 132 | "price": "319", 133 | "discount": "", 134 | "desc": "柔软羊皮搭带,行走不易掉跟" 135 | }, { 136 | "title": "女式经典尖头搭带高跟鞋", 137 | "sub_title": "", 138 | "picUrl": "https://yanxuan.nosdn.127.net/794a9f41a2cd6c0f92783de99b10b4b4.png?imageView&quality=65&thumbnail=330x330", 139 | "tag": "7月画册特惠", 140 | "spec": "3色可选", 141 | "price": "209", 142 | "discount": "299", 143 | "desc": "羊反绒鞋面,温柔贴己也懂你" 144 | }, { 145 | "title": "女式金属环尖头平底鞋", 146 | "sub_title": "", 147 | "picUrl": "https://yanxuan.nosdn.127.net/0579f60980fcf3704a3e2388e31f1d3c.png?imageView&quality=65&thumbnail=330x330", 148 | "tag": "奥莱特惠", 149 | "spec": "3色可选", 150 | "price": "191", 151 | "discount": "319", 152 | "desc": "隐藏小粗跟,显高不累" 153 | }, { 154 | "title": "女式羊皮尖头女巫凉鞋", 155 | "sub_title": "", 156 | "picUrl": "https://yanxuan.nosdn.127.net/831d7e5379e0b265391d8717e4645de4.png?imageView&quality=65&thumbnail=330x330", 157 | "tag": "奥莱特惠", 158 | "spec": "2色可选", 159 | "price": "134", 160 | "discount": "299", 161 | "desc": "头层羊皮,气场全开女巫鞋" 162 | }, { 163 | "title": "女式蝴蝶结尖头平底鞋", 164 | "sub_title": "", 165 | "picUrl": "https://yanxuan.nosdn.127.net/69839d1684af3942f10cc404167c771e.png?imageView&quality=65&thumbnail=330x330", 166 | "tag": "满2免1", 167 | "spec": "2色可选", 168 | "price": "319", 169 | "discount": "", 170 | "desc": "人手一双的尖头平底鞋" 171 | }, { 172 | "title": "女式金属跟高跟鞋2.0", 173 | "sub_title": "", 174 | "picUrl": "https://yanxuan.nosdn.127.net/bda93db0acb80a919985926ee44324db.png?imageView&quality=65&thumbnail=330x330", 175 | "tag": "奥莱特惠", 176 | "spec": "3色可选", 177 | "price": "191", 178 | "discount": "319", 179 | "desc": "5cm金属跟,羊猄触感温柔" 180 | }, { 181 | "title": "女式花边羊皮圆头平底鞋", 182 | "sub_title": "", 183 | "picUrl": "https://yanxuan.nosdn.127.net/8ac01db0cb08f206dc2d67a21bdde3be.png?imageView&quality=65&thumbnail=330x330", 184 | "tag": "满2免1", 185 | "spec": "2色可选", 186 | "price": "299", 187 | "discount": "", 188 | "desc": "每个女孩心中的梦" 189 | }, { 190 | "title": "女式尖头蝴蝶结高跟鞋", 191 | "sub_title": "", 192 | "picUrl": "https://yanxuan.nosdn.127.net/022522c4fa1ab5691954bc309f96e117.png?imageView&quality=65&thumbnail=330x330", 193 | "tag": "奥莱特惠", 194 | "spec": "2色可选", 195 | "price": "213", 196 | "discount": "329", 197 | "desc": "细腻羊猄皮,给你温柔守护" 198 | }, { 199 | "title": "女式满天星尖头平底鞋", 200 | "sub_title": "", 201 | "picUrl": "https://yanxuan.nosdn.127.net/47df469f85c3f32df9fadfef54c8db51.png?imageView&quality=65&thumbnail=330x330", 202 | "tag": "奥莱特惠", 203 | "spec": "2色可选", 204 | "price": "143", 205 | "discount": "319", 206 | "desc": "羊猄材料,星星点点带你入秋" 207 | }, { 208 | "title": "女式韩国绒羊皮搭带粗跟鞋", 209 | "sub_title": "", 210 | "picUrl": "https://yanxuan.nosdn.127.net/deba421cbb5051e4c10f9c6418fc4d3c.png?imageView&quality=65&thumbnail=330x330", 211 | "tag": "奥莱特惠", 212 | "spec": "2色可选", 213 | "price": "144", 214 | "discount": "289", 215 | "desc": "头层羊皮搭带,5cm舒适中跟" 216 | }, { 217 | "title": "女式捷克水钻高跟鞋", 218 | "sub_title": "", 219 | "picUrl": "https://yanxuan.nosdn.127.net/51004260c2cf1182ff2de58f22c8a3a9.png?imageView&quality=65&thumbnail=330x330", 220 | "tag": "", 221 | "spec": "", 222 | "price": "329", 223 | "discount": "", 224 | "desc": "楦头热销几万双" 225 | }, { 226 | "title": "女式头层牛反绒乐福鞋", 227 | "sub_title": "", 228 | "picUrl": "https://yanxuan.nosdn.127.net/6db387891ec460c10bead5f48758d2d5.png?imageView&quality=65&thumbnail=330x330", 229 | "tag": "奥莱特惠", 230 | "spec": "4色可选", 231 | "price": "194", 232 | "discount": "299", 233 | "desc": "色彩优美,触感轻、柔、软" 234 | }] 235 | } 236 | } -------------------------------------------------------------------------------- /mock/util.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs');//引入文件系统模块 2 | const path = require('path');//引入path模块 3 | 4 | module.exports = { 5 | //读取json文件 6 | getJsonFile:function (filePath) { 7 | //读取指定json文件 8 | var json = fs.readFileSync(path.resolve(__dirname,filePath), 'utf-8'); 9 | //解析并返回 10 | return JSON.parse(json); 11 | } 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-pinduoduo", 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 | "test:unit": "vue-cli-service test:unit" 10 | }, 11 | "dependencies": { 12 | "axios": "^0.18.0", 13 | "better-scroll": "^1.15.1", 14 | "cssnano": "^4.1.8", 15 | "cssnano-preset-advanced": "^4.0.6", 16 | "fastclick": "^1.0.6", 17 | "moment": "^2.24.0", 18 | "postcss-aspect-ratio-mini": "^1.0.1", 19 | "postcss-cssnext": "^3.1.0", 20 | "postcss-discard-unused": "^4.0.1", 21 | "postcss-import": "^12.0.1", 22 | "postcss-px-to-viewport": "0.0.3", 23 | "postcss-url": "^8.0.0", 24 | "postcss-viewport-units": "^0.1.6", 25 | "postcss-zindex": "^4.0.1", 26 | "vant": "^1.6.5", 27 | "vue": "^2.5.21", 28 | "vue-awesome-swiper": "^3.1.3", 29 | "vue-router": "^3.0.1", 30 | "vuex": "^3.0.1" 31 | }, 32 | "devDependencies": { 33 | "@vue/cli-plugin-babel": "^3.2.2", 34 | "@vue/cli-plugin-eslint": "^3.2.2", 35 | "@vue/cli-plugin-unit-mocha": "^3.2.2", 36 | "@vue/cli-service": "^3.2.3", 37 | "@vue/eslint-config-prettier": "^4.0.1", 38 | "@vue/test-utils": "^1.0.0-beta.20", 39 | "babel-eslint": "^10.0.1", 40 | "babel-plugin-import": "^1.11.0", 41 | "chai": "^4.1.2", 42 | "eslint": "^5.8.0", 43 | "eslint-plugin-vue": "^5.0.0", 44 | "mockjs": "^1.0.1-beta3", 45 | "node-sass": "^4.9.0", 46 | "postcss-write-svg": "^3.0.1", 47 | "sass-loader": "^7.0.1", 48 | "sass-resources-loader": "^2.0.1", 49 | "vue-template-compiler": "^2.5.21" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /preset-default-vue-cli-3.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/preset-default-vue-cli-3.js -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 网易严选 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 17 | -------------------------------------------------------------------------------- /src/api/cateList.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchCateList(params){ 5 | let uri = `/cate_list` 6 | return axios.get(uri); 7 | }, 8 | } -------------------------------------------------------------------------------- /src/api/comment.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchComments(params){ 5 | let uri = '/comments' 6 | let config = { 7 | params 8 | } 9 | return axios.get(uri, config); 10 | }, 11 | fetchCommentTags(params){ 12 | let uri = `/tags?id=${params.id}` 13 | return axios.get(uri); 14 | }, 15 | } -------------------------------------------------------------------------------- /src/api/common.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchRecommendGoods(params){ 5 | let uri = `/rcmd?id=${params.id}` 6 | return axios.get(uri); 7 | }, 8 | } -------------------------------------------------------------------------------- /src/api/goodsDetail.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchGoodsDetailInfo(params){ 5 | let uri = `/detail` 6 | return axios.get(uri); 7 | }, 8 | } -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchBannerData(params){ 5 | let uri = `/banner?index=${params.index}` 6 | return axios.get(uri, params); 7 | }, 8 | fetchShoppingChannel(params){ 9 | let uri = `/channels` 10 | return axios.get(uri, params); 11 | }, 12 | fetchHotSallProduct(params){ 13 | let uri = `/hotSalls` 14 | return axios.get(uri, params); 15 | }, 16 | fetchPopularRecommends(params){ 17 | let uri = `/populars` 18 | return axios.get(uri, params); 19 | }, 20 | fetchFastArrivals(params){ 21 | let uri = `/arrival` 22 | return axios.get(uri, params); 23 | }, 24 | fetchCategoryGoods(params){ 25 | let uri = `/categoryGoods` 26 | return axios.get(uri, params); 27 | }, 28 | } -------------------------------------------------------------------------------- /src/api/items.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchItemsData(params){ 5 | let uri = `/items?index=${params.index}` 6 | return axios.get(uri, params); 7 | }, 8 | } -------------------------------------------------------------------------------- /src/api/manufacturer.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchManufacturerData(params){ 5 | let uri = `/manufacturer` 6 | return axios.get(uri); 7 | }, 8 | } -------------------------------------------------------------------------------- /src/api/marketDesc.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchMarketDesc(params){ 5 | let uri = `/market_desc?id=${params.id}` 6 | return axios.get(uri, params); 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /src/api/middleware.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import axios from 'axios' 3 | // import JSCookie from 'js-cookie' 4 | import { logout } from './user' 5 | import { Toast } from 'vant' 6 | 7 | const BaseMessage = "服务器开小差了,请重试!"; 8 | //设置baseURI 9 | // axios.defaults.baseURL = './../mock/'; 10 | 11 | //axios request 拦截器 12 | // axios.interceptors.request.use( 13 | // config => { 14 | // const Authorization = JSCookie.get('YF_AUTHORIZATION'); 15 | // if(Authorization){ //if has login, set Authorization in headers 16 | // config.headers['Authorization'] = Authorization; 17 | // } 18 | // return config 19 | // }, 20 | // error => { 21 | // console.log(`error: ${error}`) // for debug 22 | // Promise.reject(error) 23 | // } 24 | // ) 25 | 26 | //axios response 27 | axios.interceptors.response.use( 28 | response => { 29 | const data = response.data; 30 | // headers = response.headers, 31 | // authorization = headers ? headers.authorization : undefined, 32 | // authorization_cookie = JSCookie.get("YF_AUTHORIZATION"); 33 | //update token when backend return different this cookie token 34 | // if(authorization && authorization !== authorization_cookie){ 35 | // //有效期一天 36 | // JSCookie.set("YF_AUTHORIZATION", authorization, { 37 | // expires: 1 38 | // }); 39 | // data.data && data.data.email && JSCookie.set("YF_USERNAME", data.data.email, { 40 | // expires: 1 41 | // }); 42 | // } 43 | if(data && data.errCode == '100005'){ //login overdue 44 | logout(); 45 | Toast.fail('请重新登录!'); 46 | }else if(data && data.errCode != 0){ //other error 47 | Toast.fail(data.error_msg || BaseMessage); 48 | } 49 | 50 | return Object.assign({}, data, { 51 | status: (data && data.errCode == 0) ? true : false // Redefiny status 52 | }); 53 | }, 54 | // Do something with response error 55 | error => { 56 | console.log(`error: ${error}`) // for debug 57 | let message = BaseMessage; 58 | if(error && error.response){ 59 | switch(error.response.status){ 60 | case 400: 61 | message = '错误请求' 62 | break; 63 | case 401: 64 | logout(); 65 | message = '登录超时,请重新登录' 66 | break; 67 | case 403: 68 | message = '拒绝访问' 69 | break; 70 | case 404: 71 | message = '请求错误,未找到该资源' 72 | break; 73 | case 405: 74 | message = '请求方法未允许' 75 | break; 76 | case 408: 77 | message = '请求超时' 78 | break; 79 | case 500: 80 | message = '服务器端出错' 81 | break; 82 | case 501: 83 | message = '网络未实现' 84 | break; 85 | case 502: 86 | message = '网络错误' 87 | break; 88 | case 503: 89 | message = '服务不可用' 90 | break; 91 | case 504: 92 | message = '网络超时' 93 | break; 94 | case 505: 95 | message = 'http版本不支持该请求' 96 | break; 97 | default: 98 | error.response.data && error.response.data.error_msg && (message = error.response.data.error_msg) 99 | } 100 | } 101 | Toast.fail(message); 102 | return Promise.reject(error); 103 | } 104 | ); 105 | 106 | 107 | export default axios 108 | -------------------------------------------------------------------------------- /src/api/search.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchSearchKeywords(params){ 5 | let uri = '/search_kds' 6 | return axios.get(uri); 7 | }, 8 | } -------------------------------------------------------------------------------- /src/api/topic.js: -------------------------------------------------------------------------------- 1 | import axios from './middleware' 2 | 3 | export default { 4 | fetchTopicData(params){ 5 | let uri = '/topic' 6 | return axios.get(uri); 7 | }, 8 | } -------------------------------------------------------------------------------- /src/api/user.js: -------------------------------------------------------------------------------- 1 | //登录 2 | export function login(){ 3 | 4 | } 5 | 6 | //登出 7 | export function logout(){ 8 | 9 | } 10 | 11 | //注册 12 | export function register(){ 13 | 14 | } 15 | 16 | //验证码 17 | export function fetchCaptchaImage(){ 18 | 19 | } -------------------------------------------------------------------------------- /src/assets/css/mixin.scss: -------------------------------------------------------------------------------- 1 | $white: #fff; 2 | $black: #333; 3 | $gray: #d9d9d9; 4 | $gray_light: #7f7f7f; 5 | $gray_dark: #666; 6 | $gyBackgroud: #f5f5f5; 7 | $yx_theme: #b4282d; 8 | 9 | @mixin block($width, $height){ 10 | width: $width; 11 | height: $height; 12 | display: inline-block; 13 | } 14 | 15 | @mixin flex($justify: space-between, $align: center){ 16 | display: flex; 17 | justify-content:$justify; 18 | align-items: $align; 19 | } 20 | 21 | 22 | /** position **/ 23 | @mixin posFixed($zIndex: 1, $top: 0, $left: 0){ 24 | position: fixed; 25 | top: $top; 26 | left: $left; 27 | z-index: $zIndex; 28 | } 29 | 30 | /** black Font **/ 31 | @mixin blackFont($fontSize: 14px){ 32 | color: $black; 33 | font-size: $fontSize; 34 | } 35 | 36 | @mixin point($color: $yx_theme, $w: 4px, $h: 4px){ 37 | content: ""; 38 | width: $w; 39 | height: $h; 40 | background: $color; 41 | border-radius: 100%; 42 | } 43 | 44 | 45 | /** 46 | * @Desc 1px match iphone 47 | * @Use @extend scale-1px 48 | **/ 49 | .scale-1px{ 50 | position: relative; 51 | border: none; 52 | &:after{ 53 | content: ''; 54 | position: absolute; 55 | height: 1px; 56 | width: 100%; 57 | bottom: 0; 58 | transform: scaleY(.5); 59 | transform-origin: 0, 0; 60 | } 61 | } -------------------------------------------------------------------------------- /src/assets/css/productList.scss: -------------------------------------------------------------------------------- 1 | .p-list{ 2 | display: flex; 3 | padding: 0 10px; 4 | flex-wrap: wrap; 5 | .goodsBox{ 6 | width: 50%; 7 | padding-bottom: 16px; 8 | &:nth-of-type(2n+1){ 9 | padding-right: 5px; 10 | } 11 | &:nth-of-type(2n){ 12 | padding-left: 5px; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/assets/css/reset.scss: -------------------------------------------------------------------------------- 1 | *, :after, :before { 2 | margin: 0; 3 | padding: 0; 4 | outline: 0; 5 | -webkit-box-sizing: border-box; 6 | -moz-box-sizing: border-box; 7 | box-sizing: border-box; 8 | -webkit-tap-highlight-color: transparent; 9 | } 10 | body{ 11 | font-family: PingFangSC-Light,helvetica,'Heiti SC'; 12 | background-color: #F4F4F4; 13 | font-size: 12px; 14 | } 15 | router-view{ 16 | text-decoration: none; 17 | } 18 | a{ 19 | text-decoration: none; 20 | color: #666; 21 | } 22 | b, em, h1, h2, h3, h4, h5, h6, strong { 23 | font-weight: 400; 24 | } 25 | i, em{ 26 | font-style: normal; 27 | } 28 | img{ 29 | width: 100%; height: 100%; border: none; 30 | } 31 | li{ 32 | list-style: none; 33 | } 34 | input, button{ 35 | border: none; 36 | outline: none; 37 | display: block; 38 | border-radius: 0; 39 | -webkit-appearance: none; 40 | border: 0; 41 | outline: 0; 42 | } 43 | .clearfix:after{ 44 | content:""; 45 | display: block; 46 | clear:both; 47 | } 48 | .clearfix{ 49 | zoom:1; 50 | } 51 | .fl{ 52 | float: left; 53 | } 54 | .fr{ 55 | float: right; 56 | } 57 | 58 | .text-center{ 59 | text-align: center; 60 | } 61 | 62 | .text-overflow { 63 | white-space: nowrap; 64 | text-overflow: ellipsis; 65 | -o-text-overflow: ellipsis; 66 | overflow: hidden; 67 | } 68 | 69 | /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ 70 | ::-webkit-scrollbar 71 | { 72 | width: 0px; 73 | height: 0px; 74 | background-color: #F5F5F5; 75 | } 76 | 77 | /*定义滚动条轨道 内阴影+圆角*/ 78 | ::-webkit-scrollbar-track 79 | { 80 | -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,0); 81 | border-radius: 10px; 82 | background-color: #F5F5F5; 83 | } 84 | 85 | /*定义滑块 内阴影+圆角*/ 86 | ::-webkit-scrollbar-thumb 87 | { 88 | border-radius: 10px; 89 | -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); 90 | background-color: #555; 91 | } 92 | 93 | 94 | img[lazy=loading] { 95 | background-color:#f5f5f5; 96 | // width: 100%; 97 | // height: auto; 98 | } 99 | 100 | .space-left{padding-left:1.5px;} 101 | .space-right{padding-right:1.5px;} 102 | .space-top{padding-top:1.5px;} 103 | .space-bottom{padding-bottom:1.5px;} 104 | 105 | 106 | 107 | ::-webkit-input-placeholder { 108 | color: #999 109 | } 110 | 111 | :-moz-placeholder { 112 | color: #999 113 | } 114 | 115 | ::-moz-placeholder { 116 | color: #999 117 | } 118 | 119 | :-ms-input-placeholder { 120 | color: #999 121 | } -------------------------------------------------------------------------------- /src/assets/font/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1561109686663'); /* IE9 */ 3 | src: url('iconfont.eot?t=1561109686663#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), 5 | url('iconfont.woff?t=1561109686663') format('woff'), 6 | url('iconfont.ttf?t=1561109686663') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1561109686663#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-65:before { 19 | content: "\e649"; 20 | } 21 | 22 | .icon-zhankai:before { 23 | content: "\e809"; 24 | } 25 | 26 | .icon-sousuo-copy:before { 27 | content: "\e62b"; 28 | } 29 | 30 | .icon-10:before { 31 | content: "\e609"; 32 | } 33 | 34 | .icon-gouwuche:before { 35 | content: "\e602"; 36 | } 37 | 38 | .icon-shouye1:before { 39 | content: "\e611"; 40 | } 41 | 42 | .icon-shouye:before { 43 | content: "\e61e"; 44 | } 45 | 46 | .icon-fenlei:before { 47 | content: "\e6b8"; 48 | } 49 | 50 | .icon-shanchu:before { 51 | content: "\e621"; 52 | } 53 | 54 | .icon-shangla:before { 55 | content: "\e65b"; 56 | } 57 | 58 | .icon-xiala:before { 59 | content: "\e600"; 60 | } 61 | 62 | .icon-kefu:before { 63 | content: "\e88f"; 64 | } 65 | 66 | .icon-tubiao-:before { 67 | content: "\e64f"; 68 | } 69 | 70 | .icon-geren:before { 71 | content: "\e608"; 72 | } 73 | 74 | .icon-tupian:before { 75 | content: "\e63a"; 76 | } 77 | 78 | .icon-airudiantubiaohuizhi-zhuanqu_yiwutong:before { 79 | content: "\e69d"; 80 | } 81 | 82 | .icon-chakan:before { 83 | content: "\e642"; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/src/assets/font/iconfont.eot -------------------------------------------------------------------------------- /src/assets/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/src/assets/font/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/src/assets/font/iconfont.woff -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/src/assets/font/iconfont.woff2 -------------------------------------------------------------------------------- /src/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/src/assets/img/logo.png -------------------------------------------------------------------------------- /src/components/common/Banner.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 46 | 47 | 71 | -------------------------------------------------------------------------------- /src/components/common/CategoryGoodsBlock.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc 展示多商品类目框 3 | */ 4 | 5 | 29 | 30 | 57 | 58 | 86 | -------------------------------------------------------------------------------- /src/components/common/CategoryNav.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 73 | 74 | 170 | -------------------------------------------------------------------------------- /src/components/common/CommentModule.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc: 商品评论展示块 3 | */ 4 | 5 | 37 | 38 | 69 | 70 | 121 | 122 | -------------------------------------------------------------------------------- /src/components/common/GoTop.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 72 | 73 | 90 | -------------------------------------------------------------------------------- /src/components/common/ProductCard.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc: 商品展示块 3 | */ 4 | 5 | 38 | 39 | 68 | 69 | 116 | -------------------------------------------------------------------------------- /src/components/common/ProductShowContainer.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 3 | * @Desc: 首页商品展示框 4 | */ 5 | 6 | 19 | 20 | 37 | 38 | 59 | -------------------------------------------------------------------------------- /src/components/common/ProductTag.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 42 | 43 | 44 | 63 | -------------------------------------------------------------------------------- /src/components/common/SpaceModule.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc: 顶部空白10px布局块 3 | */ 4 | 5 | 10 | 11 | 16 | 17 | 23 | 24 | -------------------------------------------------------------------------------- /src/components/common/SpecificationLabel.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc 商品竖状说明标签 3 | */ 4 | 5 | 10 | 11 | 19 | 20 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/components/common/ThroughLineTitle.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc: 带中划线标题 3 | */ 4 | 5 | 12 | 13 | 25 | 26 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/components/market/GuessYouLike.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc: 猜你喜欢板块 3 | */ 4 | 5 | 28 | 29 | 57 | 58 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/components/market/OptimalTo.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 39 | 40 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /src/layout/footer/BuyFooter.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc: 购买商品footer 3 | */ 4 | //TODO 实现购买流程 5 | 17 | 18 | 27 | 28 | 56 | -------------------------------------------------------------------------------- /src/layout/footer/Footer.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 50 | 51 | 82 | -------------------------------------------------------------------------------- /src/layout/header/OnlySearchHeader.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | 23 | 24 | 51 | -------------------------------------------------------------------------------- /src/layout/header/SimpleHeader.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 33 | 34 | 35 | 83 | -------------------------------------------------------------------------------- /src/layout/header/TopHeader.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 30 | 31 | 68 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import Vue from "vue"; 4 | import App from "./App.vue"; 5 | import router from "./router"; 6 | import store from "./store/"; 7 | 8 | 9 | import VueAwesomeSwiper from 'vue-awesome-swiper' 10 | import 'swiper/dist/css/swiper.css' 11 | import { Toast, Lazyload, Rate, List, } from 'vant' 12 | import 'vant/lib/index.css' 13 | 14 | import Fastclick from 'fastclick' 15 | Fastclick.attach(document.body); 16 | 17 | Vue.use(VueAwesomeSwiper) 18 | .use(Lazyload, { 19 | // loading: "http://yanxuan.nosdn.127.net/1769a954d4d5c7a6b25da57f15fc5a1d.png" 20 | }) 21 | .use(Rate) 22 | .use(List) 23 | 24 | Vue.config.productionTip = false; 25 | 26 | new Vue({ 27 | router, 28 | store, 29 | render: h => h(App) 30 | }).$mount("#app"); 31 | -------------------------------------------------------------------------------- /src/page/cart/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 23 | 24 | 25 | 27 | -------------------------------------------------------------------------------- /src/page/cateList/index.vue: -------------------------------------------------------------------------------- 1 | 41 | 158 | 159 | 226 | 227 | -------------------------------------------------------------------------------- /src/page/comment/comment.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 135 | 136 | 167 | -------------------------------------------------------------------------------- /src/page/comment/index.js: -------------------------------------------------------------------------------- 1 | import Comment from "./comment.vue" 2 | export default Comment -------------------------------------------------------------------------------- /src/page/goodsDetail/GoodsArgument.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 34 | 35 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/page/goodsDetail/GoodsComment.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 47 | 48 | 66 | 67 | -------------------------------------------------------------------------------- /src/page/goodsDetail/GoodsInfo.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 127 | 128 | 240 | -------------------------------------------------------------------------------- /src/page/goodsDetail/GoodsSpecification.vue: -------------------------------------------------------------------------------- 1 | 2 | 66 | 67 | 78 | 79 | 128 | -------------------------------------------------------------------------------- /src/page/goodsDetail/goodsDetail.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 66 | 67 | 72 | 73 | -------------------------------------------------------------------------------- /src/page/goodsDetail/index.js: -------------------------------------------------------------------------------- 1 | import GoodsDetail from './goodsDetail' 2 | export default GoodsDetail -------------------------------------------------------------------------------- /src/page/index/BrandMade.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 71 | 72 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/page/index/FastArrival.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 38 | 39 | 54 | 55 | -------------------------------------------------------------------------------- /src/page/index/FreshmanModule.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 70 | 71 | 181 | -------------------------------------------------------------------------------- /src/page/index/HotSell.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 63 | 64 | 128 | -------------------------------------------------------------------------------- /src/page/index/PopularRecommend.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 50 | 51 | 89 | 90 | -------------------------------------------------------------------------------- /src/page/index/ShoppingChannle.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 50 | 51 | 98 | -------------------------------------------------------------------------------- /src/page/index/index.js: -------------------------------------------------------------------------------- 1 | import Index from "./index.vue" 2 | export default Index -------------------------------------------------------------------------------- /src/page/index/index.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 63 | -------------------------------------------------------------------------------- /src/page/items/ItemProductBlock.vue: -------------------------------------------------------------------------------- 1 | /* 2 | * @Desc: 展示同类商品 3 | */ 4 | 5 | 22 | 23 | 44 | 45 | 63 | -------------------------------------------------------------------------------- /src/page/items/index.js: -------------------------------------------------------------------------------- 1 | import Items from "./items.vue" 2 | export default Items -------------------------------------------------------------------------------- /src/page/items/items.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 56 | 57 | 64 | 65 | -------------------------------------------------------------------------------- /src/page/login/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 23 | 24 | 25 | 27 | -------------------------------------------------------------------------------- /src/page/manufacturer/index.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 59 | 60 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/page/marketDesc/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 28 | 29 | 44 | 45 | -------------------------------------------------------------------------------- /src/page/notFound.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 36 | 37 | 80 | 81 | -------------------------------------------------------------------------------- /src/page/search/index.js: -------------------------------------------------------------------------------- 1 | import Search from './search' 2 | export default Search -------------------------------------------------------------------------------- /src/page/search/search.vue: -------------------------------------------------------------------------------- 1 | 73 | 74 | 135 | 136 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /src/page/topic/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 40 | 41 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Router from "vue-router"; 3 | import Index from "__page__/index"; 4 | 5 | 6 | Vue.use(Router); 7 | 8 | export default new Router({ 9 | // mode: "history", 10 | base: process.env.BASE_URL, 11 | routes: [ 12 | { 13 | path: "/", 14 | name: "index", 15 | component: Index 16 | }, 17 | { 18 | path: "/item/:index", 19 | name: "items", 20 | component: () => import("__page__/items") 21 | }, 22 | { 23 | path: "/detail/:id", 24 | name: "detail", 25 | component: () => import("__page__/goodsDetail") 26 | }, 27 | { 28 | path: "/comment/:id", 29 | name: "comment", 30 | component: () => import("__page__/comment") 31 | }, 32 | { 33 | path: "/search", 34 | name: "search", 35 | component: () => import("__page__/search") 36 | }, 37 | { 38 | path: "/catelist", 39 | name: "catelist", 40 | component: () => import("__page__/cateList") 41 | }, 42 | { 43 | path: "/marketdesc/:id", 44 | name: "marketdesc", 45 | component: () => import("__page__/marketDesc") 46 | }, 47 | { 48 | path: "/topic", 49 | name: "topic", 50 | component: () => import("__page__/topic") 51 | }, 52 | { 53 | path: "/manufacturer/:id", 54 | name: "manufacturer", 55 | component: () => import("__page__/manufacturer") 56 | }, 57 | { 58 | path: "/cart", 59 | name: "cart", 60 | component: () => 61 | import("__page__/cart") 62 | }, 63 | { 64 | path: "/login", 65 | name: "login", 66 | component: () => 67 | import("__page__/login") 68 | }, 69 | { 70 | path: "/404", 71 | name: "NotFound", 72 | component: () => 73 | import("__page__/notFound") 74 | }, 75 | { 76 | path: "*", 77 | redirect: "/404" 78 | } 79 | ], 80 | scrollBehavior (to, from, savedPosition) { 81 | return { x: 0, y: 0 } 82 | }, 83 | }); 84 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import Vuex from "vuex" 3 | import Common from './modules/common' 4 | import Home from './modules/home' 5 | import Items from './modules/items' 6 | import GoodsDetail from './modules/goodsDetail' 7 | import Comment from './modules/comment' 8 | import Search from './modules/search' 9 | import CateList from './modules/cateList' 10 | import MarketDesc from './modules/marketDesc' 11 | import Topic from './modules/topic' 12 | import Manufacturer from './modules/manufacturer' 13 | import * as mutations from './mutation-types' 14 | 15 | 16 | Vue.use(Vuex); 17 | 18 | const debug = process.env.NODE_ENV !== 'production' 19 | 20 | export default new Vuex.Store({ 21 | modules: { 22 | Common, 23 | Home, 24 | Items, 25 | GoodsDetail, 26 | Comment, 27 | Search, 28 | CateList, 29 | MarketDesc, 30 | Topic, 31 | Manufacturer, 32 | }, 33 | strict: debug 34 | }); 35 | -------------------------------------------------------------------------------- /src/store/modules/cateList.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/cateList' 3 | 4 | const state = { 5 | cateLists: { 6 | nav: [], 7 | rightCnt: {} 8 | } 9 | } 10 | 11 | const getters = { 12 | cateLists: state => state.cateLists, 13 | } 14 | 15 | const actions = { 16 | fetchCateList({commit}, condition){ 17 | api.fetchCateList().then(reply => { 18 | if(reply.errCode == 0){ 19 | commit(types.FETCH_CATE_LIST, reply.data) 20 | condition.cb && condition.cb() 21 | } 22 | }) 23 | }, 24 | }; 25 | 26 | 27 | 28 | const mutations = { 29 | [types.FETCH_CATE_LIST](state, data){ 30 | state.cateLists = data 31 | } 32 | }; 33 | 34 | export default { 35 | state, 36 | getters, 37 | actions, 38 | mutations 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/store/modules/comment.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/comment' 3 | import { shuffle } from '@/utils' 4 | 5 | const state = { 6 | product_cmts: [], 7 | product_cmt_tags: [], 8 | } 9 | 10 | const getters = { 11 | product_cmts: state => state.product_cmts, 12 | product_cmt_tags: state => state.product_cmt_tags, 13 | } 14 | 15 | const actions = { 16 | fetchComments({commit}, condition){ 17 | api.fetchComments(condition.params).then(reply => { 18 | if(reply.errCode == 0){ 19 | commit(types.FETCH_COMMENTS, { 20 | data: reply.data, 21 | reset: condition.reset 22 | }) 23 | condition.cb && condition.cb() 24 | }else{ 25 | condition.errCb && condition.errCb() 26 | } 27 | }).catch(() => { 28 | condition.errCb && condition.errCb() 29 | }) 30 | }, 31 | fetchCommentTags({commit}, condition){ 32 | api.fetchCommentTags(condition).then(reply => { 33 | if(reply.errCode == 0){ 34 | commit(types.FETCH_COMMENT_TAGS, reply.data) 35 | } 36 | }) 37 | }, 38 | }; 39 | 40 | 41 | 42 | const mutations = { 43 | [types.FETCH_COMMENTS](state, data){ 44 | if(data.reset){ 45 | //随机取几项数据充当标签筛选数据 Will Delete 46 | let 47 | result = data.data.result, 48 | max = 10, 49 | new_result = shuffle(result), 50 | radom_result = new_result.slice(0, Math.floor(Math.random() * max)); 51 | state.product_cmts = radom_result 52 | // state.product_cmts = data.data.result; //Will Use 53 | }else{ 54 | let product_cmts = state.product_cmts 55 | state.product_cmts = product_cmts.concat(data.data.result) 56 | } 57 | }, 58 | [types.FETCH_COMMENT_TAGS](state, data){ 59 | state.product_cmt_tags = data 60 | } 61 | }; 62 | 63 | export default { 64 | state, 65 | getters, 66 | actions, 67 | mutations 68 | } 69 | 70 | -------------------------------------------------------------------------------- /src/store/modules/common.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/common' 3 | 4 | const state = { 5 | rcmd_goods: [], 6 | } 7 | 8 | const getters = { 9 | rcmd_goods: state => state.rcmd_goods 10 | } 11 | 12 | const actions = { 13 | fetchRecommendGoods({commit}, condition){ 14 | api.fetchRecommendGoods(condition).then(reply => { 15 | if(reply.errCode == 0){ 16 | commit(types.FETCH_RECOMMEND_GOODS, reply.data) 17 | } 18 | }) 19 | }, 20 | }; 21 | 22 | 23 | 24 | const mutations = { 25 | [types.FETCH_RECOMMEND_GOODS](state, data){ 26 | state.rcmd_goods = data.items 27 | } 28 | }; 29 | 30 | export default { 31 | state, 32 | getters, 33 | actions, 34 | mutations 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/store/modules/goodsDetail.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/goodsDetail' 3 | 4 | const state = { 5 | detailInfo: {}, 6 | } 7 | 8 | const getters = { 9 | detailInfo: state => state.detailInfo 10 | } 11 | 12 | const actions = { 13 | fetchGoodsDetailInfo({commit}, condition){ 14 | api.fetchGoodsDetailInfo().then(reply => { 15 | if(reply.errCode == 0){ 16 | commit(types.FETCH_GOODS_DETAIL_INFO, reply.data) 17 | } 18 | }) 19 | }, 20 | }; 21 | 22 | 23 | 24 | const mutations = { 25 | [types.FETCH_GOODS_DETAIL_INFO](state, data){ 26 | state.detailInfo = data 27 | } 28 | }; 29 | 30 | export default { 31 | state, 32 | getters, 33 | actions, 34 | mutations 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/store/modules/home.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/index' 3 | 4 | const state = { 5 | bannerDatas: [], 6 | topNavOptions: [ 7 | { 8 | name: "推荐", 9 | link: "" 10 | }, 11 | { 12 | name: "居家生活", 13 | link: "" 14 | }, 15 | { 16 | name: "服饰鞋包", 17 | link: "" 18 | }, 19 | { 20 | name: "美食酒水", 21 | link: "" 22 | }, 23 | { 24 | name: "个护清洁", 25 | link: "" 26 | }, 27 | { 28 | name: "母婴亲子", 29 | link: "" 30 | }, 31 | { 32 | name: "运动旅行", 33 | link: "" 34 | }, 35 | { 36 | name: "数码家电", 37 | link: "" 38 | }, 39 | { 40 | name: "礼品特色", 41 | link: "" 42 | } 43 | ], 44 | channelDatas: [], 45 | hotSalls: {}, 46 | populars: {}, 47 | arrivals:[], 48 | cateGoods: [] 49 | } 50 | 51 | const getters = { 52 | bannerDatas: state => state.bannerDatas 53 | ,channelDatas: state => state.channelDatas 54 | ,hotSalls: state => state.hotSalls 55 | ,populars: state => state.populars 56 | ,arrivals: state => state.arrivals 57 | ,cateGoods: state => state.cateGoods 58 | } 59 | 60 | const actions = { 61 | fetchBannerData({commit}, condition){ 62 | api.fetchBannerData(condition).then(reply => { 63 | if(reply.errCode == 0){ 64 | commit(types.FETCH_BANNER_DATA, reply.data) 65 | } 66 | }) 67 | }, 68 | fetchShoppingChannel({commit}, condition){ 69 | api.fetchShoppingChannel(condition).then(reply => { 70 | if(reply.errCode == 0){ 71 | commit(types.FETCH_SHOPPING_CHANNEL, reply.data) 72 | } 73 | }) 74 | }, 75 | fetchHotSallProduct({commit}, condition){ 76 | api.fetchHotSallProduct(condition).then(reply => { 77 | if(reply.errCode == 0){ 78 | commit(types.FETCH_HOT_SALL_PRODUCT, reply.data) 79 | } 80 | }) 81 | }, 82 | fetchPopularRecommends({commit}, condition){ 83 | api.fetchPopularRecommends(condition).then(reply => { 84 | if(reply.errCode == 0){ 85 | commit(types.FETCH_POPULAR_RECOMMENDS, reply.data) 86 | } 87 | }) 88 | }, 89 | fetchFastArrivals({commit}, condition){ 90 | api.fetchFastArrivals(condition).then(reply => { 91 | if(reply.errCode == 0){ 92 | commit(types.FETCH_FAST_ARRIVALS, reply.data) 93 | } 94 | }) 95 | }, 96 | fetchCategoryGoods({commit}, condition){ 97 | api.fetchCategoryGoods(condition).then(reply => { 98 | if(reply.errCode == 0){ 99 | commit(types.FETCH_CATEGORY_GOODS, reply.data) 100 | } 101 | }) 102 | }, 103 | 104 | }; 105 | 106 | 107 | 108 | const mutations = { 109 | [types.FETCH_BANNER_DATA](state, data){ 110 | state.bannerDatas = data 111 | }, 112 | [types.FETCH_SHOPPING_CHANNEL](state, data){ 113 | state.channelDatas = data 114 | }, 115 | [types.FETCH_HOT_SALL_PRODUCT](state, data){ 116 | state.hotSalls = data 117 | }, 118 | [types.FETCH_POPULAR_RECOMMENDS](state, data){ 119 | state.populars = data 120 | }, 121 | [types.FETCH_FAST_ARRIVALS](state, data){ 122 | state.arrivals = data 123 | }, 124 | [types.FETCH_CATEGORY_GOODS](state, data){ 125 | state.cateGoods = data 126 | } 127 | }; 128 | 129 | export default { 130 | state, 131 | getters, 132 | actions, 133 | mutations 134 | } 135 | 136 | -------------------------------------------------------------------------------- /src/store/modules/items.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/items' 3 | 4 | const state = { 5 | cateData: [], 6 | } 7 | 8 | const getters = { 9 | cateData: state => state.cateData 10 | } 11 | 12 | const actions = { 13 | fetchItemsData({commit}, condition){ 14 | api.fetchItemsData(condition).then(reply => { 15 | if(reply.errCode == 0){ 16 | commit(types.FETCH_ITEMS_DATA, reply.data) 17 | } 18 | }) 19 | }, 20 | }; 21 | 22 | 23 | 24 | const mutations = { 25 | [types.FETCH_ITEMS_DATA](state, data){ 26 | state.cateData = data 27 | } 28 | }; 29 | 30 | export default { 31 | state, 32 | getters, 33 | actions, 34 | mutations 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/store/modules/manufacturer.js: -------------------------------------------------------------------------------- 1 | 2 | import * as types from '../mutation-types' 3 | import api from '@/api/manufacturer' 4 | 5 | const state = { 6 | mrData: {}, 7 | } 8 | 9 | const getters = { 10 | mrData: state => state.mrData, 11 | } 12 | 13 | const actions = { 14 | fetchManufacturerData({commit}, condition){ 15 | api.fetchManufacturerData(condition).then(reply => { 16 | if(reply.errCode == 0){ 17 | commit(types.FETCH_MANU_FACTURER_DATA, reply.data) 18 | condition.cb && condition.cb() 19 | } 20 | }) 21 | }, 22 | }; 23 | 24 | 25 | 26 | const mutations = { 27 | [types.FETCH_MANU_FACTURER_DATA](state, data){ 28 | state.mrData = data 29 | } 30 | }; 31 | 32 | export default { 33 | state, 34 | getters, 35 | actions, 36 | mutations 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/store/modules/marketDesc.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/marketDesc' 3 | 4 | const state = { 5 | marketDescHtml: "", 6 | } 7 | 8 | const getters = { 9 | marketDescHtml: state => state.marketDescHtml 10 | } 11 | 12 | const actions = { 13 | fetchMarketDesc({commit}, condition){ 14 | api.fetchMarketDesc(condition).then(reply => { 15 | if(reply.errCode == 0){ 16 | commit(types.FETCH_MARKET_DESC, reply.data) 17 | } 18 | }) 19 | }, 20 | }; 21 | 22 | 23 | 24 | const mutations = { 25 | [types.FETCH_MARKET_DESC](state, data){ 26 | state.marketDescHtml = data 27 | } 28 | }; 29 | 30 | export default { 31 | state, 32 | getters, 33 | actions, 34 | mutations 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/store/modules/search.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/search' 3 | 4 | const state = { 5 | search_kd: [], 6 | search_hot: [ 7 | '拉杆箱 7.8折起', '薄款家居服7折起', '春夏床品8折起', '酒水饮料 低至54折', '陶瓷煲 底价买赠', '挂烫机直降230', '即食燕窝8折', '明前龙井 限时特惠', '新品女包 39元起' 8 | ] 9 | } 10 | 11 | const getters = { 12 | search_kd: state => state.search_kd, 13 | search_hot: state => state.search_hot, 14 | } 15 | 16 | const actions = { 17 | fetchSearchKeywords({commit}){ 18 | api.fetchSearchKeywords().then(reply => { 19 | if(reply.errCode == 0){ 20 | commit(types.FETCH_SEARCH_KEYWORDS, reply.data) 21 | } 22 | }) 23 | }, 24 | }; 25 | 26 | 27 | 28 | const mutations = { 29 | [types.FETCH_SEARCH_KEYWORDS](state, data){ 30 | state.search_kd = data 31 | } 32 | }; 33 | 34 | export default { 35 | state, 36 | getters, 37 | actions, 38 | mutations 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/store/modules/topic.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import api from '@/api/topic' 3 | 4 | const state = { 5 | topicList: [], 6 | } 7 | 8 | const getters = { 9 | topicList: state => state.topicList, 10 | } 11 | 12 | const actions = { 13 | fetchTopicData({commit}){ 14 | api.fetchTopicData().then(reply => { 15 | if(reply.errCode == 0){ 16 | commit(types.FETCH_TOPIC_DATA, reply.data) 17 | } 18 | }) 19 | }, 20 | }; 21 | 22 | 23 | 24 | const mutations = { 25 | [types.FETCH_TOPIC_DATA](state, data){ 26 | state.topicList = data 27 | } 28 | }; 29 | 30 | export default { 31 | state, 32 | getters, 33 | actions, 34 | mutations 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | //index 2 | export const FETCH_BANNER_DATA = 'FETCH_BANNER_DATA' 3 | 4 | export const FETCH_SHOPPING_CHANNEL = 'FETCH_SHOPPING_CHANNEL' 5 | 6 | export const FETCH_HOT_SALL_PRODUCT = 'FETCH_HOT_SALL_PRODUCT' 7 | 8 | export const FETCH_POPULAR_RECOMMENDS = 'FETCH_POPULAR_RECOMMENDS' 9 | 10 | export const FETCH_FAST_ARRIVALS = 'FETCH_FAST_ARRIVALS' 11 | 12 | export const FETCH_CATEGORY_GOODS = 'FETCH_CATEGORY_GOODS' 13 | 14 | 15 | //items 16 | export const FETCH_ITEMS_DATA = 'FETCH_ITEMS_DATA' 17 | 18 | //detail 19 | export const FETCH_GOODS_DETAIL_INFO = 'FETCH_GOODS_DETAIL_INFO' 20 | 21 | //recommend 22 | export const FETCH_RECOMMEND_GOODS = 'FETCH_RECOMMEND_GOODS' 23 | 24 | //comments 25 | export const FETCH_COMMENTS = 'FETCH_COMMENTS' 26 | 27 | export const FETCH_COMMENT_TAGS = 'FETCH_COMMENT_TAGS' 28 | 29 | //search 30 | export const FETCH_SEARCH_KEYWORDS = 'FETCH_SEARCH_KEYWORDS' 31 | 32 | //catelist 33 | export const FETCH_CATE_LIST = 'FETCH_CATE_LIST' 34 | 35 | //marketDesc 36 | export const FETCH_MARKET_DESC = 'FETCH_MARKET_DESC' 37 | 38 | //topic 39 | export const FETCH_TOPIC_DATA = 'FETCH_TOPIC_DATA' 40 | //manufacturer 41 | export const FETCH_MANU_FACTURER_DATA = 'FETCH_MANU_FACTURER_DATA' 42 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | //Verifies one item exists in a array 2 | export function oneOf(val, args){ 3 | return args.some(arg => { 4 | return arg === val 5 | }) 6 | } 7 | 8 | //打乱数组(洗牌) 9 | export function shuffle(arr){ 10 | let 11 | len = arr.length, 12 | random_ind, 13 | exchangeItem; 14 | while(len){ 15 | random_ind = Math.floor(Math.random() * len --) 16 | exchangeItem = arr[len] 17 | arr[len] = arr[random_ind] 18 | arr[random_ind] = exchangeItem 19 | } 20 | return arr 21 | } 22 | 23 | //节流 降低事件执行频率 提高高频触发场景性能 24 | export function throttle(fn, interval = 300, immediate = false){ 25 | let 26 | timeout, 27 | st = 0 28 | 29 | return function () { 30 | let _context = this, 31 | args = arguments 32 | 33 | if(immediate){ //时间段开头执行 34 | let nt = + new Date(); 35 | if(nt - st > interval){ 36 | fn.apply(_context, args) 37 | st = nt 38 | } 39 | }else{ //时间段末位执行 40 | if(!timeout){ 41 | timeout = setTimeout(() => { 42 | fn.apply(_context, args) 43 | timeout = null 44 | }, interval) 45 | } 46 | 47 | } 48 | } 49 | } 50 | 51 | //防抖 限制规定时间内才能继续执行事件,常用场景请求后端接口 52 | export function debounce(fn, wait = 1000, immediate = false){ 53 | let timeout 54 | 55 | return function(){ 56 | let _context = this, 57 | arg = arguments 58 | 59 | timeout && clearTimeout(timeout) //清楚上次执行 60 | 61 | if(immediate){ //立即执行 62 | let canRun = !timeout 63 | //wait时间后timeout为空,fn可再次执行 64 | timeout = setTimeout(() => { 65 | timeout = null 66 | }, wait) 67 | 68 | canRun && fn.apply(_context, arg) 69 | }else{ 70 | timeout = setTimeout(() => { 71 | fn.apply(_context, arg) 72 | }, wait) 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /static/img/brand/brand_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/static/img/brand/brand_1.png -------------------------------------------------------------------------------- /static/img/brand/brand_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/static/img/brand/brand_2.png -------------------------------------------------------------------------------- /static/img/brand/brand_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/static/img/brand/brand_3.png -------------------------------------------------------------------------------- /static/img/brand/brand_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/static/img/brand/brand_4.png -------------------------------------------------------------------------------- /static/img/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/static/img/group.png -------------------------------------------------------------------------------- /static/img/new_bag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/static/img/new_bag.png -------------------------------------------------------------------------------- /static/img/well.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusteng/vue-yanxuan/a6bf67952d2742e26026488c50380d8a9ba82c66/static/img/well.png -------------------------------------------------------------------------------- /tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | mocha: true 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { shallowMount } from "@vue/test-utils"; 3 | import HelloWorld from "@/components/HelloWorld.vue"; 4 | 5 | describe("HelloWorld.vue", () => { 6 | it("renders props.msg when passed", () => { 7 | const msg = "new message"; 8 | const wrapper = shallowMount(HelloWorld, { 9 | propsData: { msg } 10 | }); 11 | expect(wrapper.text()).to.include(msg); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const 2 | path = require('path'); 3 | function resolve (dir) { 4 | return path.join(__dirname, dir) 5 | } 6 | module.exports = { 7 | devServer: { 8 | port: '1212', 9 | before: require('./mock/index') 10 | }, 11 | publicPath: './', 12 | lintOnSave: true, 13 | chainWebpack: (config)=>{ 14 | config.resolve.alias 15 | .set('@', resolve('src')) 16 | .set('__page__', resolve('src/page')) 17 | .set('assets',resolve('src/assets')) 18 | .set('components',resolve('src/components')) 19 | .set('layout',resolve('src/layout')) 20 | .set('base',resolve('src/base')) 21 | .set('static',resolve('static')) 22 | 23 | const oneOfsMap = config.module.rule('scss').oneOfs.store 24 | oneOfsMap.forEach(item => { 25 | item 26 | .use('sass-resources-loader') 27 | .loader('sass-resources-loader') 28 | .options({ 29 | // Or array of paths 30 | resources: [ 31 | resolve('src/assets/css/mixin.scss'), 32 | resolve('src/assets/css/reset.scss') 33 | ] 34 | }) 35 | .end() 36 | }) 37 | }, 38 | 39 | } 40 | --------------------------------------------------------------------------------