├── .babelrc ├── views ├── index.jade ├── error.jade └── layout.jade ├── app ├── images │ ├── footer_cart.png │ ├── footer_class.png │ ├── footer_shop.png │ ├── footer_cart_on.png │ ├── footer_class_on.png │ ├── footer_service.png │ ├── footer_shop_on.png │ └── footer_service_on.png ├── main.js ├── components │ ├── App.js │ ├── Index.jsx │ ├── footer.sass │ ├── HeadSwiper.jsx │ ├── css.sass │ ├── Sections.jsx │ └── footer.js ├── sass │ └── base.sass ├── index.html └── test.js ├── .gitignore ├── routes ├── index.js └── users.js ├── README.md ├── server.js ├── app.js ├── package.json ├── bin └── www ├── index.html ├── webpack.config.js └── webpack.config.prod.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"] 3 | } -------------------------------------------------------------------------------- /views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | -------------------------------------------------------------------------------- /app/images/footer_cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_cart.png -------------------------------------------------------------------------------- /app/images/footer_class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_class.png -------------------------------------------------------------------------------- /app/images/footer_shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_shop.png -------------------------------------------------------------------------------- /app/images/footer_cart_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_cart_on.png -------------------------------------------------------------------------------- /app/images/footer_class_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_class_on.png -------------------------------------------------------------------------------- /app/images/footer_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_service.png -------------------------------------------------------------------------------- /app/images/footer_shop_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_shop_on.png -------------------------------------------------------------------------------- /app/images/footer_service_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunkun12/react-mishop/HEAD/app/images/footer_service_on.png -------------------------------------------------------------------------------- /views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .sass-cache 3 | node_modules/ 4 | *.swp 5 | *.swo 6 | *.swn 7 | .idea 8 | scripts/* 9 | .sass-cache 10 | npm-debug.log 11 | ftp/* 12 | -------------------------------------------------------------------------------- /views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content 8 | -------------------------------------------------------------------------------- /app/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './components/App' 4 | setTimeout(function(){ 5 | ReactDOM.render(,document.getElementById('app')); 6 | },300); -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 技术栈: `Webpack`+`React`+`Sass` 4 | 5 | * 运行 `npm install` 安装依赖 6 | * 开发环境运行 `npm start` 访问 7 | * 生产环境 `npm run bulld` 生成的生产环境代码在build目录下 8 | * 开发环境支持热更新 9 | * ES6 10 | * 多屏适配 rem解决方案 11 | * Sass、postcss 12 | * 里面中用到的相关数据均为模拟测试数据。 13 | * [在线预览](http://kunkun12.com/react-mishop/) 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/components/App.js: -------------------------------------------------------------------------------- 1 | import {} from '../sass/base.sass'; 2 | import React from 'react'; 3 | import Index from './Index' 4 | import Data from '../test.js' 5 | class App extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | this.state=Data; 9 | } 10 | render() { 11 | return ( 12 |
13 | 14 |
15 | ); 16 | } 17 | } 18 | 19 | 20 | export default App; -------------------------------------------------------------------------------- /app/components/Index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import HeadSwiper from './HeadSwiper' 3 | import Sections from './Sections' 4 | import Footer from './Footer' 5 | class Index extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | this.state=this.props; 9 | } 10 | render() { 11 | return ( 12 |
13 | 14 | 15 |
16 |
17 | ); 18 | } 19 | } 20 | 21 | export default Index; 22 | -------------------------------------------------------------------------------- /app/sass/base.sass: -------------------------------------------------------------------------------- 1 | body,h1,h2,h3,p,dl,dd,ol,ul,th,td,form,fieldset,input,button,textarea 2 | margin: 0 3 | padding: 0 4 | html 5 | -webkit-text-size-adjust: none 6 | word-wrap: break-word 7 | h1,h2,h3 8 | font-size: 100% 9 | ol,ul 10 | list-style: none 11 | table 12 | border-collapse: collapse 13 | border-spacing: 0 14 | empty-cells: show 15 | font-size: inherit 16 | fieldset,img 17 | border: 0 18 | cite,em,s,i,b 19 | font-style: normal 20 | input,button,textarea,select 21 | font-size: 100% 22 | body,input,button,textarea,select,option 23 | font-size: normal 24 | a,input,textarea 25 | text-decoration: none 26 | outline: 0 27 | -webkit-tap-highlight-color: rgba(0,0,0,0) 28 | li,img,label,input 29 | vertical-align: middle 30 | var 31 | font-style: normal 32 | ins 33 | text-decoration: none 34 | 35 | html,body 36 | height: 100% 37 | font-size: (20rem/100) 38 | font-family: Arial, Verdana, Sans-serif 39 | .viewport 40 | width: 100% 41 | max-width: (720rem/100) 42 | margin: 0 auto 43 | -------------------------------------------------------------------------------- /app/components/footer.sass: -------------------------------------------------------------------------------- 1 | @import "compass/utilities" 2 | @import "compass/css3" 3 | 4 | 5 | .footer 6 | position: fixed 7 | bottom: 0 8 | left: 0 9 | right: 0 10 | background: #FFF 11 | z-index: 99 12 | border-top: 1px solid #e0e0e0 13 | ul 14 | display: flex 15 | justify-content:center 16 | .nav 17 | .ispr 18 | width: (40rem/100) 19 | height: (40rem/100) 20 | +background-size((40rem/100) (40rem/100)) 21 | overflow: hidden 22 | margin: 0 auto (8rem/100) 23 | &.ih 24 | background-image: url("../images/footer_shop.png") 25 | &.ic 26 | background-image: url("../images/footer_class.png") 27 | &.is 28 | background-image: url("../images/footer_cart.png") 29 | &.if 30 | background-image: url("../images/footer_service.png") 31 | p 32 | font-size: (22rem/100) 33 | line-height: 0.8 34 | color: #999999 35 | li 36 | flex: 1 37 | width: 100% 38 | text-align: center 39 | &>a 40 | display: block 41 | padding: (12rem/100) 0 -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const express = require('express'); 3 | const webpack = require('webpack'); 4 | const webpackMiddleware = require('webpack-dev-middleware'); 5 | const webpackHotMiddleware = require('webpack-hot-middleware'); 6 | const config = require('./webpack.config.js'); 7 | 8 | const isDeveloping = process.env.NODE_ENV !== 'production'; 9 | const port = isDeveloping ? 4000 : process.env.port; 10 | const app = express(); 11 | 12 | if (isDeveloping) { 13 | const compiler = webpack(config); 14 | const middleware = webpackMiddleware(compiler, { 15 | publicPath: config.output.publicPath, 16 | contentBase: 'build', 17 | stats: { 18 | colors: true, 19 | hash: false, 20 | timings: true, 21 | chunks: false, 22 | chunkModules: false, 23 | modules: false 24 | } 25 | }); 26 | 27 | app.use(middleware); 28 | app.use(webpackHotMiddleware(compiler)); 29 | // app.get('*', function response(req, res) { 30 | // res.write(middleware.fileSystem.readFileSync(path.join(__dirname, 'build/index.html'))); 31 | // res.end(); 32 | // }); 33 | } else { 34 | app.use(express.static(__dirname + '/build')); 35 | app.get('*', function response(req, res) { 36 | res.sendFile(path.join(__dirname, 'build/index.html')); 37 | }); 38 | } 39 | app.listen(port, '0.0.0.0', function onStart(err) { 40 | if (err) { 41 | console.log(err); 42 | } 43 | console.info('==> 🌎 Listening on port %s. Open up http://0.0.0.0:%s/ in your browser.', port, port); 44 | }); -------------------------------------------------------------------------------- /app/components/HeadSwiper.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactSwipe from 'react-swipe' 3 | import css from "./css.sass" 4 | class HeadSwiper extends React.Component { 5 | 6 | constructor(props) { 7 | super(props); 8 | this.state={ 9 | selectindex:0, 10 | swipecount:this.props.swipedata.length 11 | } 12 | } 13 | swipechanges(e){ 14 | var index=e%this.state.swipecount; 15 | this.setState({ 16 | selectindex:index 17 | }) 18 | 19 | } 20 | render() { 21 | var swipes=[]; 22 | var swipestyle={ 23 | height:"3.6rem", 24 | width:"7.2rem" 25 | }, 26 | swipeimg={ 27 | width: "100%" 28 | }; 29 | var navs=[]; 30 | this.props.swipedata.forEach((i,b)=>{ 31 | swipes.push(
) 32 | navs.push(
  • ); 33 | }); 34 | return ( 35 |
    36 | 37 | {swipes} 38 | 39 | 42 |
    43 | 44 | ); 45 | } 46 | } 47 | 48 | 49 | export default HeadSwiper; -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | 8 | var routes = require('./routes/index'); 9 | var users = require('./routes/users'); 10 | 11 | var app = express(); 12 | 13 | // view engine setup 14 | app.set('views', path.join(__dirname, 'views')); 15 | app.set('view engine', 'jade'); 16 | 17 | // uncomment after placing your favicon in /public 18 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 19 | app.use(logger('dev')); 20 | app.use(bodyParser.json()); 21 | app.use(bodyParser.urlencoded({ extended: false })); 22 | app.use(cookieParser()); 23 | app.use(express.static(path.join(__dirname, 'public'))); 24 | 25 | app.use('/', routes); 26 | app.use('/users', users); 27 | 28 | // catch 404 and forward to error handler 29 | app.use(function(req, res, next) { 30 | var err = new Error('Not Found'); 31 | err.status = 404; 32 | next(err); 33 | }); 34 | 35 | // error handlers 36 | 37 | // development error handler 38 | // will print stacktrace 39 | if (app.get('env') === 'development') { 40 | app.use(function(err, req, res, next) { 41 | res.status(err.status || 500); 42 | res.render('error', { 43 | message: err.message, 44 | error: err 45 | }); 46 | }); 47 | } 48 | 49 | // production error handler 50 | // no stacktraces leaked to user 51 | app.use(function(err, req, res, next) { 52 | res.status(err.status || 500); 53 | res.render('error', { 54 | message: err.message, 55 | error: {} 56 | }); 57 | }); 58 | 59 | 60 | module.exports = app; 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-tool", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "clean": "rimraf dist", 7 | "build:webpack": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js", 8 | "build": "npm run clean && npm run build:webpack&&NODE_ENV=production port=3000 node server.js", 9 | "start": "node server.js", 10 | "lint": "eslint src" 11 | }, 12 | "dependencies": { 13 | "gulp": "^3.9.1", 14 | "gulp-util": "^3.0.7", 15 | "react": "^0.14.7", 16 | "react-dom": "^0.14.7", 17 | "react-lazy-load": "^3.0.5", 18 | "react-swipe": "4.0.1" 19 | }, 20 | "devDependencies": { 21 | "autoprefixer": "^6.3.6", 22 | "babel-core": "^6.5.2", 23 | "babel-loader": "^6.2.3", 24 | "babel-preset-es2015": "^6.5.0", 25 | "babel-preset-react": "^6.5.0", 26 | "babel-preset-react-hmre": "^1.1.0", 27 | "babel-preset-stage-0": "^6.5.0", 28 | "body-parser": "~1.13.2", 29 | "compass-mixins": "^0.12.7", 30 | "cookie-parser": "~1.3.5", 31 | "cross-env": "^1.0.7", 32 | "css-loader": "^0.23.1", 33 | "debug": "~2.2.0", 34 | "express": "~4.13.1", 35 | "file-loader": "^0.8.5", 36 | "gulp-clean": "^0.3.2", 37 | "html-loader": "^0.4.3", 38 | "html-webpack-plugin": "^2.9.0", 39 | "jade": "^1.11.0", 40 | "jade-html-loader": "0.0.3", 41 | "morgan": "~1.6.1", 42 | "node-sass": "^3.4.2", 43 | "postcss-loader": "^0.8.2", 44 | "precss": "^1.4.0", 45 | "rimraf": "^2.5.2", 46 | "sass-loader": "^3.1.2", 47 | "serve-favicon": "~2.3.0", 48 | "style-loader": "^0.13.0", 49 | "url-loader": "^0.5.7", 50 | "webpack": "^1.12.2", 51 | "webpack-dev-middleware": "^1.2.0", 52 | "webpack-hot-middleware": "^2.2.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React-Mi-Shop 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 33 | 34 | 35 |
    36 |
    37 |
    38 | 39 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('css-tool:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /app/components/css.sass: -------------------------------------------------------------------------------- 1 | @import "compass/utilities" 2 | @import "compass/css3" 3 | .indexpage 4 | padding-bottom: 0.8rem 5 | .swapwrap 6 | position: relative; 7 | .swipe-nav 8 | position: absolute 9 | bottom: 0.1rem 10 | left: 0 11 | right: 0 12 | display: flex 13 | justify-content: center 14 | li 15 | width: .8em 16 | height: .8em 17 | margin: 0 (8em/20) 18 | +border-radius((20em/20)) 19 | background: #e5e5e5 20 | opacity: .8 21 | &.on 22 | background: #ccc 23 | .HeadSwiper 24 | position: relative 25 | 26 | .list 27 | transform: translate3d(0,0,0) 28 | background: #FFF 29 | .item 30 | display: flex 31 | align-items: center 32 | padding: (30rem/100) 0 33 | border-bottom: 1px solid #F2F2F2 34 | .section 35 | &:last-child 36 | .item 37 | border: none 38 | .info 39 | flex: 1 40 | margin-right: (20rem/100) 41 | .img 42 | width: (254rem/100) 43 | height: (145rem/100) 44 | position: relative 45 | .ico 46 | width: 100% 47 | .tag 48 | position: absolute 49 | width: (120rem/100) 50 | height: (120rem/100) 51 | bottom: 0 52 | left: (10rem/100) 53 | opacity: .9 !important 54 | z-index: 2 55 | .name 56 | font-size: (30rem/100) 57 | color: #000 58 | margin-bottom: (10rem/100) 59 | .brief 60 | font-size: (26rem/100) 61 | line-height: (34rem/100) 62 | color: #969696 63 | margin-bottom: (12rem/100) 64 | .price 65 | font-size: (28rem/100) 66 | color: #FE4900 67 | -------------------------------------------------------------------------------- /app/components/Sections.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactSwipe from 'react-swipe' 3 | import LazyLoad from 'react-lazy-load'; 4 | import css from "./css.sass" 5 | 6 | export default class Sections extends React.Component { 7 | constructor(props) { 8 | super(props); 9 | } 10 | render() { 11 | var items=this.props.Sections.map((item,i)=>{ 12 | var items=item.body.items; 13 | return items.map(function(a,b){ 14 | return(
    15 |
    16 | 17 | 18 | 19 | 20 | { 21 | a.product_tag?:"" 22 | } 23 |
    24 |
    25 |
    26 |

    {a.product_name}

    27 |
    28 |
    29 |

    {a.product_brief}

    30 |
    31 |
    32 |

    {a.product_price}

    33 |
    34 |
    35 |
    ) 36 | }) 37 | }); 38 | return ( 39 |
    40 |
    41 | {items} 42 |
    43 |
    44 | ); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | react-mishop 6 | 7 | 8 | 34 | 35 | 36 | 37 |
    44 | 45 |
    46 |
    47 |
    48 |
    49 |
    50 |
    51 |
    52 |
    53 | 54 |
    55 |
    56 |
    57 | 61 | 67 | 68 |
    69 | 70 | -------------------------------------------------------------------------------- /app/components/footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactSwipe from 'react-swipe' 3 | import css from "./footer.sass" 4 | 5 | export default class Footer extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | } 9 | render() { 10 | return ( < div className = 'footer' > 11 | 57 | < /div > 58 | ); 59 | } 60 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require("webpack"); 2 | var path = require('path'); 3 | var gutil = require("gulp-util"); 4 | var node_modules = path.resolve(__dirname, 'node_modules'); 5 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 6 | var precss = require('precss'); 7 | var autoprefixer = require('autoprefixer'); 8 | var myConfig = { 9 | debug: true, 10 | devtool: 'source-map', 11 | entry: ['webpack-hot-middleware/client?reload=true',path.resolve(__dirname, 'app/main.js')], 12 | context: path.resolve(process.cwd(), 'app'), 13 | output: { 14 | path: path.resolve(__dirname, 'build'), 15 | filename: 'main.js', 16 | publicPath: "" 17 | }, 18 | module: { 19 | loaders: [{ 20 | test: /\.jsx?$/, 21 | exclude: /node_modules/, 22 | loader: 'babel', 23 | query: { 24 | "presets": ["react", "es2015", "stage-0", "react-hmre"] 25 | } 26 | }, { 27 | test: /\.jade$/, 28 | loader: 'html!jade-html' 29 | }, { 30 | test: /\.css$/, 31 | loader: 'style!css' 32 | }, { 33 | test: /\.sass$/, 34 | loader: "style!css!postcss-loader!sass?indentedSyntax&includePaths[]=" + path.resolve(__dirname, "./node_modules/compass-mixins/lib") + "&includePaths[]=" + path.resolve(__dirname, "./mixins/app_mixins") 35 | }, { 36 | test: /\.(png|jpg)$/, 37 | loader: 'url-loader?limit=10000&name=[path][name]-[hash:8].[ext]' 38 | }] 39 | }, 40 | postcss: function () { 41 | return [precss, autoprefixer]; 42 | }, 43 | resolve: { 44 | root: [path.resolve(process.cwd(), 'app'), path.resolve(__dirname, 'node_modules')], //设置搜索目录 45 | alias: { 46 | images: './images' 47 | }, 48 | extensions: ['', '.js', '.jade', '.jsx'] 49 | }, 50 | plugins: [ 51 | new HtmlWebpackPlugin({ // Also generate a test.html 52 | filename: 'index.html', 53 | template: 'index.html', 54 | }), 55 | new webpack.NoErrorsPlugin(), 56 | new webpack.optimize.OccurenceOrderPlugin(), 57 | new webpack.HotModuleReplacementPlugin(), 58 | new webpack.DefinePlugin({ 59 | 'process.env.NODE_ENV': JSON.stringify('development') 60 | }), 61 | new webpack.ProgressPlugin(function handler(percentage, msg) { 62 | gutil.log(msg) 63 | }) 64 | ] 65 | }; 66 | 67 | 68 | module.exports = myConfig; -------------------------------------------------------------------------------- /webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | var webpack = require("webpack"); 2 | var path = require('path'); 3 | var gutil = require("gulp-util"); 4 | var node_modules = path.resolve(__dirname, 'node_modules'); 5 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 6 | var precss = require('precss'); 7 | var autoprefixer = require('autoprefixer'); 8 | var myConfig = { 9 | debug: true, 10 | devtool: 'source-map', 11 | entry: [path.resolve(__dirname, 'app/main.js')], 12 | context: path.resolve(process.cwd(), 'app'), 13 | output: { 14 | path: path.resolve(__dirname, 'build'), 15 | filename: '[name][hash].js', 16 | publicPath: "" 17 | }, 18 | module: { 19 | loaders: [{ 20 | test: /\.jsx?$/, 21 | exclude: /node_modules/, 22 | loader: 'babel', 23 | query: { 24 | "presets": ["react", "es2015", "stage-0"] 25 | }, 26 | include: path.join(__dirname, 'app') 27 | }, { 28 | test: /\.jade$/, 29 | loader: 'html!jade-html' 30 | }, { 31 | test: /\.css$/, 32 | loader: 'style!css!postcss-loader' 33 | }, { 34 | test: /\.sass$/, 35 | loader: "style!css!postcss-loader!sass?indentedSyntax&includePaths[]=" + path.resolve(__dirname, "./node_modules/compass-mixins/lib") + "&includePaths[]=" + path.resolve(__dirname, "./mixins/app_mixins") 36 | }, { 37 | test: /\.(png|jpg)$/, 38 | loader: 'url-loader?limit=10000&name=[path][name]-[hash:8].[ext]' 39 | }] 40 | }, 41 | postcss: function() { 42 | return [precss, autoprefixer]; 43 | }, 44 | resolve: { 45 | root: [path.resolve(process.cwd(), 'app'), path.resolve(__dirname, 'node_modules')], //设置搜索目录 46 | alias: { 47 | images: './images' 48 | }, 49 | extensions: ['', '.js', '.jade', '.jsx'] 50 | }, 51 | plugins: [ 52 | new HtmlWebpackPlugin({ // Also generate a test.html 53 | filename: 'index.html', 54 | template: 'index.html', 55 | }), 56 | new webpack.NoErrorsPlugin(), 57 | new webpack.optimize.OccurenceOrderPlugin(), 58 | new webpack.optimize.UglifyJsPlugin({ 59 | compressor: { 60 | warnings: false 61 | } 62 | }), 63 | new webpack.DefinePlugin({ 64 | 'process.env.NODE_ENV': JSON.stringify('production') 65 | }), 66 | new webpack.ProgressPlugin(function handler(percentage, msg) { 67 | gutil.log(msg) 68 | }) 69 | ] 70 | }; 71 | 72 | 73 | module.exports = myConfig; -------------------------------------------------------------------------------- /app/test.js: -------------------------------------------------------------------------------- 1 | var data={ 2 | "swipedata": [ 3 | { 4 | "img": "http://i8.mifile.cn/v1/a1/T1_jKgBbdT1RXrhCrK.jpg" 5 | }, 6 | { 7 | "img": "http://i8.mifile.cn/v1/a1/T1B4_jBsYT1RXrhCrK.jpg" 8 | }, 9 | { 10 | "img": "http://i8.mifile.cn/v1/a1/T1tXKgBgbv1RXrhCrK.jpg" 11 | }, 12 | { 13 | "img": "http://i8.mifile.cn/v1/a1/T1tXKgBgbv1RXrhCrK.jpg" 14 | } 15 | ], 16 | "Sections": [ 17 | { 18 | "body": { 19 | "items": [ 20 | { 21 | "img_url": "http://i8.mifile.cn/v1/a1/T14xJTByZ_1RXrhCrK.jpg", 22 | "product_brief": "骁龙820处理器 / 4GB 内存 / 128GB 闪存 / 4轴防抖相机 / 3D陶瓷机身 / 3月1日早10点首轮开售", 23 | "product_name": "小米手机5", 24 | "product_price": "1999元 起", 25 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/xp.png", 26 | "view_type": "" 27 | } 28 | ] 29 | }, 30 | "phone_type": "0", 31 | "view_type": "fast_recommend" 32 | }, 33 | { 34 | "body": { 35 | "items": [ 36 | { 37 | "img_url": "http://i8.mifile.cn/v1/a1/T1Z5bgBCYv1RXrhCrK.jpg", 38 | "product_brief": "骁龙808处理器 / 64GB大容量 / 指纹识别 / 全网通双卡双待 / 5英寸屏非凡手感 / 13MP相位对焦相机", 39 | "product_name": "小米手机4S", 40 | "product_price": "1699元", 41 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/xp.png", 42 | "view_type": "" 43 | } 44 | ] 45 | }, 46 | "phone_type": "0", 47 | "view_type": "fast_recommend" 48 | }, 49 | { 50 | "body": { 51 | "items": [ 52 | { 53 | "img_url": "http://i1.mifile.cn/v1/a1/T1RWWgBghT1RXrhCrK.jpg", 54 | "product_brief": "独立 HiFi 音乐系统 / 5.7英寸全高清屏幕 / 骁龙801四核处理器", 55 | "product_name": "小米Note", 56 | "product_price": "1499元 起", 57 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/d300.png", 58 | "view_type": "" 59 | } 60 | ] 61 | }, 62 | "phone_type": "0", 63 | "view_type": "fast_recommend" 64 | }, 65 | { 66 | "body": { 67 | "items": [ 68 | { 69 | "img_url": "http://i1.mifile.cn/v1/a1/T1TrdjBKLT1RXrhCrK.jpg", 70 | "product_brief": "Type-C 双面充电接口 / 红外遥控 / 5英寸全高清阳光屏 / 骁龙808六核处理器", 71 | "product_name": "小米手机4c", 72 | "product_price": "1299元", 73 | "product_tag": "", 74 | "view_type": "" 75 | } 76 | ] 77 | }, 78 | "phone_type": "0", 79 | "view_type": "fast_recommend" 80 | }, 81 | { 82 | "body": { 83 | "items": [ 84 | { 85 | "img_url": "http://i1.mifile.cn/v1/a1/T1WdJjBmdT1RXrhCrK.jpg", 86 | "product_brief": "4.7英寸视网膜屏 / 骁龙410四核处理器 / 800万像素相机 / 2GB内存+16GB容量 / 最高支持32GB扩展", 87 | "product_name": "红米2A高配双卡版", 88 | "product_price": "499元", 89 | "product_tag": "", 90 | "view_type": "" 91 | } 92 | ] 93 | }, 94 | "phone_type": "0", 95 | "view_type": "fast_recommend" 96 | }, 97 | { 98 | "body": { 99 | "items": [ 100 | { 101 | "img_url": "http://i1.mifile.cn/v1/a1/T1VNJjBsdT1RXrhCrK.jpg", 102 | "product_brief": "金属机身 / 指纹识别 / 4050mAh大电池 / 5.5英寸全高清屏", 103 | "product_name": "红米Note 3", 104 | "product_price": "899元 起", 105 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/xp.png", 106 | "view_type": "" 107 | } 108 | ] 109 | }, 110 | "phone_type": "0", 111 | "view_type": "fast_recommend" 112 | }, 113 | { 114 | "body": { 115 | "items": [ 116 | { 117 | "img_url": "http://i1.mifile.cn/v1/a1/T1LuWgBjhT1RXrhCrK.jpg", 118 | "product_brief": "金属机身 / 4100mAh大电池 / 5英寸阳光屏 / 骁龙616八核处理器 / 2GB内存+16GB容量", 119 | "product_name": "红米手机3", 120 | "product_price": "699元", 121 | "product_tag": "", 122 | "view_type": "" 123 | } 124 | ] 125 | }, 126 | "phone_type": "0", 127 | "view_type": "fast_recommend" 128 | }, 129 | { 130 | "body": { 131 | "items": [ 132 | { 133 | "img_url": "http://i1.mifile.cn/v1/a1/T1jFWjBjJT1RXrhCrK.jpg", 134 | "product_brief": "不锈钢边框 / 5英寸屏超窄边 / 骁龙801四核处理器 / MIUI、Win10 双系统", 135 | "product_name": "小米手机4", 136 | "product_price": "1299元 起", 137 | "product_tag": "", 138 | "view_type": "" 139 | } 140 | ] 141 | }, 142 | "phone_type": "0", 143 | "view_type": "fast_recommend" 144 | }, 145 | { 146 | "body": { 147 | "items": [ 148 | { 149 | "img_url": "http://i8.mifile.cn/v1/a1/T1GaJgB7hv1RXrhCrK.jpg", 150 | "product_brief": "5.5英寸全贴合大屏 / 骁龙410四核处理器 / 1300万像素相机 / 2GB内存+16GB容量 / 3200mAh大电池", 151 | "product_name": "红米Note 电信4G双卡增强版", 152 | "product_price": "799元", 153 | "product_tag": "", 154 | "view_type": "" 155 | } 156 | ] 157 | }, 158 | "phone_type": "0", 159 | "view_type": "fast_recommend" 160 | }, 161 | { 162 | "body": { 163 | "items": [ 164 | { 165 | "img_url": "http://i1.mifile.cn/v1/a1/T1lBYjBKdT1RXrhCrK.jpg", 166 | "product_brief": "4.7英寸舒适手感 / 高通64位处理器", 167 | "product_name": "红米手机2", 168 | "product_price": "599元 起", 169 | "product_tag": "", 170 | "view_type": "" 171 | } 172 | ] 173 | }, 174 | "phone_type": "0", 175 | "view_type": "fast_recommend" 176 | }, 177 | { 178 | "body": { 179 | "items": [ 180 | { 181 | "img_url": "http://i1.mifile.cn/v1/a1/T1RXWgBsCT1RXrhCrK.jpg", 182 | "product_brief": "全金属机身 / 7.9英寸视网膜屏幕 / 800万像素相机 / 6190mAh大电池 / 支持5V/2A快充", 183 | "product_name": "小米平板2", 184 | "product_price": "999元 起", 185 | "product_tag": "", 186 | "view_type": "" 187 | } 188 | ] 189 | }, 190 | "phone_type": "0", 191 | "view_type": "fast_recommend" 192 | }, 193 | { 194 | "body": { 195 | "items": [ 196 | { 197 | "img_url": "http://i1.mifile.cn/v1/a1/T1H0K_ByKv1RXrhCrK.jpg", 198 | "product_brief": "全金属轻薄机身 / 次世代分体电视", 199 | "product_name": "小米电视3", 200 | "product_price": "3999元起", 201 | "product_tag": "", 202 | "view_type": "" 203 | } 204 | ] 205 | }, 206 | "phone_type": "0", 207 | "view_type": "fast_recommend" 208 | }, 209 | { 210 | "body": { 211 | "items": [ 212 | { 213 | "img_url": "http://i1.mifile.cn/v1/a1/T1YKC_BC_v1RXrhCrK.jpg", 214 | "product_brief": "全新升级64位 4K网络机顶盒 / 标配小米蓝牙语音体感遥控器", 215 | "product_name": "小米盒子3", 216 | "product_price": "299元", 217 | "product_tag": "", 218 | "view_type": "" 219 | } 220 | ] 221 | }, 222 | "phone_type": "0", 223 | "view_type": "fast_recommend" 224 | }, 225 | { 226 | "body": { 227 | "items": [ 228 | { 229 | "img_url": "http://i1.mifile.cn/v1/a1/T14mdjBKxT1RXrhCrK.jpg", 230 | "product_brief": "高品质电芯 / 铝合金金属外壳", 231 | "product_name": "小米移动电源", 232 | "product_price": "49元 起", 233 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/hot.png", 234 | "view_type": "" 235 | } 236 | ] 237 | }, 238 | "phone_type": "0", 239 | "view_type": "fast_recommend" 240 | }, 241 | { 242 | "body": { 243 | "items": [ 244 | { 245 | "img_url": "http://i1.mifile.cn/v1/a1/T1aFDjB_ZT1RXrhCrK.jpg", 246 | "product_brief": "美国ADI传感器 / 30天超长续航", 247 | "product_name": "小米手环", 248 | "product_price": "69元 起", 249 | "product_tag": "", 250 | "view_type": "" 251 | } 252 | ] 253 | }, 254 | "phone_type": "0", 255 | "view_type": "fast_recommend" 256 | }, 257 | { 258 | "body": { 259 | "items": [ 260 | { 261 | "img_url": "http://i1.mifile.cn/v1/a1/T1R.xjBT_T1RXrhCrK.jpg", 262 | "product_brief": "22公里超长续航 / 轻、小、便携 / 重心驱动 / 15重安全保障", 263 | "product_name": "九号平衡车", 264 | "product_price": "1999元", 265 | "product_tag": "", 266 | "view_type": "" 267 | } 268 | ] 269 | }, 270 | "phone_type": "0", 271 | "view_type": "fast_recommend" 272 | }, 273 | { 274 | "body": { 275 | "items": [ 276 | { 277 | "img_url": "http://i8.mifile.cn/v1/a1/T1ktDgBgEv1RXrhCrK.jpg", 278 | "product_brief": "全新空气增压系统,净化能力高达310m³/h / 高效360°桶形净化滤芯 / 低分贝,低功耗 / 手机智能控制,一目了然", 279 | "product_name": "小米空气净化器2", 280 | "product_price": "699元", 281 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/by.png", 282 | "view_type": "" 283 | } 284 | ] 285 | }, 286 | "phone_type": "0", 287 | "view_type": "fast_recommend" 288 | }, 289 | { 290 | "body": { 291 | "items": [ 292 | { 293 | "img_url": "http://s1.mi.com/m/images/20151028/water.jpg", 294 | "product_brief": "400加仑大流量 / RO反渗透直出纯净水", 295 | "product_name": "小米净水器", 296 | "product_price": "1299元", 297 | "product_tag": "", 298 | "view_type": "" 299 | } 300 | ] 301 | }, 302 | "phone_type": "0", 303 | "view_type": "fast_recommend" 304 | }, 305 | { 306 | "body": { 307 | "items": [ 308 | { 309 | "img_url": "http://i1.mifile.cn/v1/a1/T12xLgBjZT1RXrhCrK.jpg", 310 | "product_brief": "3个USB充电口 / 支持2A快充 / 3重安全保护 / 隐藏式提示灯 / 超薄小插头 / 迷你设计,仅1个铅笔盒大小", 311 | "product_name": "小米插线板", 312 | "product_price": "49元", 313 | "product_tag": "", 314 | "view_type": "" 315 | } 316 | ] 317 | }, 318 | "phone_type": "0", 319 | "view_type": "fast_recommend" 320 | }, 321 | { 322 | "body": { 323 | "items": [ 324 | { 325 | "img_url": "http://i1.mifile.cn/v1/a1/T19IWjBvKT1RXrhCrK.jpg", 326 | "product_brief": "MFI认证产品 / 镀金C48端子头,镀锡工艺铜线 / 支持5V/2.4A电量输出", 327 | "product_name": "苹果Lightning to USB数据线", 328 | "product_price": "39元", 329 | "product_tag": "", 330 | "view_type": "" 331 | } 332 | ] 333 | }, 334 | "phone_type": "0", 335 | "view_type": "fast_recommend" 336 | }, 337 | { 338 | "body": { 339 | "items": [ 340 | { 341 | "img_url": "http://i1.mifile.cn/v1/a1/T1tTA_BsCT1RXrhCrK.jpg", 342 | "product_brief": "全金属外观 / 双USB智能输出 / 支持快充", 343 | "product_name": "小米车载充电器", 344 | "product_price": "49元", 345 | "product_tag": "", 346 | "view_type": "" 347 | } 348 | ] 349 | }, 350 | "phone_type": "0", 351 | "view_type": "fast_recommend" 352 | }, 353 | { 354 | "body": { 355 | "items": [ 356 | { 357 | "img_url": "http://i1.mifile.cn/v1/a1/T1mwV_Bydv1RXrhCrK.jpg", 358 | "product_brief": "表面蜂窝形设计,防刮花 / 高弹性静音轮胎 / 内饰采用亲肤纺织布料,环保安全", 359 | "product_name": "90分旅行箱 24寸", 360 | "product_price": "349元", 361 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/by.png", 362 | "view_type": "" 363 | } 364 | ] 365 | }, 366 | "phone_type": "0", 367 | "view_type": "fast_recommend" 368 | }, 369 | { 370 | "body": { 371 | "items": [ 372 | { 373 | "img_url": "http://i1.mifile.cn/v1/a1/T1Eyb_BXEv1RXrhCrK.jpg", 374 | "product_brief": "4重存储空间,可携带14寸电脑 / 填充EPE珍珠棉,减少双肩背部压力", 375 | "product_name": "小米极简都市双肩包", 376 | "product_price": "149元", 377 | "product_tag": "", 378 | "view_type": "" 379 | } 380 | ] 381 | }, 382 | "phone_type": "0", 383 | "view_type": "fast_recommend" 384 | }, 385 | { 386 | "body": { 387 | "items": [ 388 | { 389 | "img_url": "http://i8.mifile.cn/v1/a1/T1WbL_B5Vv1RXrhCrK.jpg", 390 | "product_brief": "播放音乐、车载充电二合一 / 蓝牙配对,一键连接 / 双口充电,8重电路保护", 391 | "product_name": "车载蓝牙播放器", 392 | "product_price": "69元", 393 | "product_tag": "", 394 | "view_type": "" 395 | } 396 | ] 397 | }, 398 | "phone_type": "0", 399 | "view_type": "fast_recommend" 400 | }, 401 | { 402 | "body": { 403 | "items": [ 404 | { 405 | "img_url": "http://i1.mifile.cn/v1/a1/T1alVjBQCT1RXrhCrK.jpg", 406 | "product_brief": "动圈+动铁 双发声单元 / 金属音腔 / 线控麦克风,清晰的通话质量", 407 | "product_name": "小米圈铁耳机", 408 | "product_price": "99元", 409 | "product_tag": "", 410 | "view_type": "" 411 | } 412 | ] 413 | }, 414 | "phone_type": "0", 415 | "view_type": "fast_recommend" 416 | }, 417 | { 418 | "body": { 419 | "items": [ 420 | { 421 | "img_url": "http://i1.mifile.cn/v1/a1/T1HTh_Bs_T1RXrhCrK.jpg", 422 | "product_brief": "进口高密度电芯 / 双USB输出 / 支持快速自充 / 便携轻便,仅338克", 423 | "product_name": "小米移动电源20000mAh", 424 | "product_price": "149元", 425 | "product_tag": "", 426 | "view_type": "" 427 | } 428 | ] 429 | }, 430 | "phone_type": "0", 431 | "view_type": "fast_recommend" 432 | }, 433 | { 434 | "body": { 435 | "items": [ 436 | { 437 | "img_url": "http://i1.mifile.cn/v1/a1/T1PLJgB_dT1RXrhCrK.jpg", 438 | "product_brief": "碱性10粒装5号环保电池,无汞无镉 / 防泄漏技术,双重安全保障 / 十种绚丽色彩,送收纳盒", 439 | "product_name": "彩虹5号电池", 440 | "product_price": "9.9元", 441 | "product_tag": "", 442 | "view_type": "" 443 | } 444 | ] 445 | }, 446 | "phone_type": "0", 447 | "view_type": "fast_recommend" 448 | }, 449 | { 450 | "body": { 451 | "items": [ 452 | { 453 | "img_url": "http://i1.mifile.cn/v1/a1/T16RE_BQxv1RXrhCrK.jpg", 454 | "product_brief": "12小时超长播放 / 金属机身外壳 / 轻巧便携 / 支持免提通话", 455 | "product_name": "小钢炮蓝牙音箱", 456 | "product_price": "99元", 457 | "product_tag": "", 458 | "view_type": "" 459 | } 460 | ] 461 | }, 462 | "phone_type": "0", 463 | "view_type": "fast_recommend" 464 | }, 465 | { 466 | "body": { 467 | "items": [ 468 | { 469 | "img_url": "http://i1.mifile.cn/v1/a1/T1mvb_ByAv1RXrhCrK.jpg", 470 | "product_brief": "仅270克,方便携带 / 完全充电,可持续使用8小时 / 支持Micro SD卡 / 支持免提通话", 471 | "product_name": "小米蓝牙音箱", 472 | "product_price": "199元", 473 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/by.png", 474 | "view_type": "" 475 | } 476 | ] 477 | }, 478 | "phone_type": "0", 479 | "view_type": "fast_recommend" 480 | }, 481 | { 482 | "body": { 483 | "items": [ 484 | { 485 | "img_url": "http://i1.mifile.cn/v1/a1/T1K3A_BsAT1RXrhCrK.jpg", 486 | "product_brief": "掌心大小 / PCB天线覆盖大,抗干扰 / 一键穿墙技术,自动提升信号强度", 487 | "product_name": "小米路由器青春版", 488 | "product_price": "79元", 489 | "product_tag": "", 490 | "view_type": "" 491 | } 492 | ] 493 | }, 494 | "phone_type": "0", 495 | "view_type": "fast_recommend" 496 | }, 497 | { 498 | "body": { 499 | "items": [ 500 | { 501 | "img_url": "http://i1.mifile.cn/v1/a1/T1RlE_BvDT1RXrhCrK.jpg", 502 | "product_brief": "小巧轻便 / 一步配对免安装 / 不用切换热点,自动选择最优信号 / 180°旋转的USB插口", 503 | "product_name": "小米Wifi放大器", 504 | "product_price": "39元", 505 | "product_tag": "http://c1.mifile.cn/f/i/f/mishop/iic/hot.png", 506 | "view_type": "" 507 | } 508 | ] 509 | }, 510 | "phone_type": "0", 511 | "view_type": "fast_recommend" 512 | }, 513 | { 514 | "body": { 515 | "items": [ 516 | { 517 | "img_url": "http://i1.mifile.cn/v1/a1/T13EL_B5hv1RXrhCrK.jpg", 518 | "product_brief": "100克,喝杯水都可感知的精准 / 高精度压力传感器 / 手机管理全家健康", 519 | "product_name": "小米体重秤", 520 | "product_price": "99元", 521 | "product_tag": "", 522 | "view_type": "" 523 | } 524 | ] 525 | }, 526 | "phone_type": "0", 527 | "view_type": "fast_recommend" 528 | }, 529 | { 530 | "body": { 531 | "items": [ 532 | { 533 | "img_url": "http://i1.mifile.cn/v1/a1/T17rh_BsVT1RXrhCrK.jpg", 534 | "product_brief": "原装三星真4K屏 / 四核1.4GHz CPU / 9.9mm全金属纤薄机身", 535 | "product_name": "小米电视2S 48英寸", 536 | "product_price": "2799元", 537 | "product_tag": "", 538 | "view_type": "" 539 | } 540 | ] 541 | }, 542 | "phone_type": "0", 543 | "view_type": "fast_recommend" 544 | }, 545 | { 546 | "body": { 547 | "items": [ 548 | { 549 | "img_url": "http://i1.mifile.cn/v1/a1/T17CxjBvET1RXrhCrK.jpg", 550 | "product_brief": "720P高清分辨率 / 111°广角 / 双向语音通话 / 4倍变焦,看到画面的每一个细节", 551 | "product_name": "小蚁智能摄像机", 552 | "product_price": "149元", 553 | "product_tag": "", 554 | "view_type": "" 555 | } 556 | ] 557 | }, 558 | "phone_type": "0", 559 | "view_type": "fast_recommend" 560 | }, 561 | { 562 | "body": { 563 | "items": [ 564 | { 565 | "img_url": "http://i1.mifile.cn/v1/a1/T1vrh_BsCT1RXrhCrK.jpg", 566 | "product_brief": "6.5克轻巧 / 蓝牙4.1高清通话音质 / 荣获德国IF设计大奖 / 低噪音硅麦,语音更清晰", 567 | "product_name": "小米蓝牙耳机", 568 | "product_price": "79元", 569 | "product_tag": "", 570 | "view_type": "" 571 | } 572 | ] 573 | }, 574 | "phone_type": "0", 575 | "view_type": "fast_recommend" 576 | } 577 | ] 578 | }; 579 | 580 | 581 | export default data; --------------------------------------------------------------------------------