├── .babelrc
├── .editorconfig
├── .gitignore
├── LICENSE
├── README.md
├── build
├── setup-dev-server.js
├── vue-loader.config.js
├── webpack.base.config.js
├── webpack.client.config.js
└── webpack.server.config.js
├── log
├── err.log
└── out.log
├── package-lock.json
├── package.json
├── pmlog.json
├── server.js
└── src
├── App.vue
├── app.js
├── assets
├── style
│ └── css.less
└── views
│ └── index.css
├── components
├── Banner.vue
├── BottomNav.vue
├── FloorOne.vue
└── Header.vue
├── entry-client.js
├── entry-server.js
├── index.template.html
├── public
├── conf.js
└── utils
│ ├── api.js
│ └── confUtils.js
├── router
└── index.js
├── static
├── img
│ ├── demo.jpeg
│ ├── favicon.ico
│ └── service-demo.jpeg
└── js
│ └── flexible.js
├── store
├── actions.js
├── getters.js
├── index.js
├── modules
│ ├── global.js
│ └── index.js
└── mutation-types.js
└── views
└── index
├── conf.js
├── index.vue
├── mock.js
└── service.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", { "modules": false }],
4 | "stage-2"
5 | ],
6 | "plugins": ["syntax-dynamic-import","transform-runtime"],
7 | "comments": false
8 | }
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log
5 | yarn-error.log
6 | .idea
7 | *.iml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 wangqi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-ssr node 服务端渲染工作流
2 |
3 | ## react 版本服务端渲染 [跳转](https://github.com/wqzwh/react-ssr)
4 |
5 | ## 解决问题
6 |
7 | - 【手机端首屏渲染问题】
8 | - 【SEO 解决搜索引擎抓取问题】
9 | - 【提高页面渲染性能】
10 |
11 | ### 统一的文件系统结构
12 |
13 | - 项目整体目录结构
14 |
15 | ```bash
16 | ├── LICENSE
17 | ├── README.md
18 | ├── build
19 | │ ├── setup-dev-server.js
20 | │ ├── vue-loader.config.js
21 | │ ├── webpack.base.config.js
22 | │ ├── webpack.client.config.js
23 | │ └── webpack.server.config.js
24 | ├── log
25 | │ ├── err.log
26 | │ └── out.log
27 | ├── package.json
28 | ├── pmlog.json
29 | ├── server.js
30 | └── src
31 | ├── App.vue
32 | ├── app.js
33 | ├── assets
34 | │ ├── images
35 | │ ├── style
36 | │ │ └── css.less
37 | │ └── views
38 | │ └── index.css
39 | ├── components
40 | │ ├── Banner.vue
41 | │ ├── BottomNav.vue
42 | │ ├── FloorOne.vue
43 | │ └── Header.vue
44 | ├── entry-client.js
45 | ├── entry-server.js
46 | ├── index.template.html
47 | ├── public
48 | │ ├── conf.js
49 | │ └── utils
50 | │ ├── api.js
51 | │ └── confUtils.js
52 | ├── router
53 | │ └── index.js
54 | ├── static
55 | │ ├── img
56 | │ │ └── favicon.ico
57 | │ └── js
58 | │ └── flexible.js
59 | ├── store
60 | │ ├── actions.js
61 | │ ├── getters.js
62 | │ ├── index.js
63 | │ ├── modules
64 | │ │ └── Home.js
65 | │ ├── mutationtypes.js
66 | │ └── state.js
67 | └── views
68 | └── index
69 | ├── conf.js
70 | ├── index.vue
71 | ├── mock.js
72 | └── service.js
73 |
74 | ```
75 |
76 | ### 统一的职责划分
77 |
78 | - views 文件夹下分模块文件,模块文件下下又分模块本身的.vue 文件(模版文件),index.js 文件(后台数据交互文件),mock.js(本模块的 mock 假数据),conf.js(配置本模块一些参数,请求路径,模块名称等信息)
79 | - components 公共组件文件夹
80 | - router 主要存放前端路由配置文件,写法规范按照 vue-router 官方例子即可。
81 | - store 主要是存放共享状态文件,里面包含 action.js,getter.js,mutationtype.js 等,后期会根据模块再细分这些。
82 | - public 主要存放公共组件代码和项目使用的公共文件代码,例如后期我们将 axios 封装成公共的 api 库文件等等
83 | - static 文件夹代表静态文件,不会被 webpack 打包的
84 | - pmlog.json 集成了 pm2 监控命令
85 | - app.js 是项目入口文件
86 | - App.vue 是项目入口文件
87 | - entry-client 和 entry-server 分别是客户端入口文件和服务端的入口文件
88 | - index.template.html 是整个项目的模版文件
89 | - server.js 服务端启动服务的入口文件
90 |
91 | ### 开发自动化
92 |
93 | - 自动化搭建本地研发环境,快速响应文件更改并自动刷新浏览器。
94 | - 自动化编译 ES6 或 CommonJS 标准的 JS 代码,自动化生成 source map 便于浏览器端调试。
95 | - 自动化编译 SASS/LESS => CSS 文件,自动化添加 CSS3 的各种浏览器前缀。
96 | - 服务端使用 express,前端使用 webpack 自动化构建打包。
97 |
98 | ## 安装使用
99 |
100 | ### 安装
101 |
102 | - Mac 系统推荐使用 [iterm2](http://iterm2.com/) 及 [oh my zsh](http://ohmyz.sh/)
103 | - 类 Unix 系统,请打开任意终端输入命令执行。
104 | - Windows 用户请先安装 [git](http://git-scm.com/),然后在 [Git Bash](http://git-for-windows.github.io/) 下执行命令
105 |
106 | #### 安装 Node 和 NPM
107 |
108 | - 详细过程参考官网 https://nodejs.org (中文网站 http://nodejs.cn/)
109 | - 支持所有 Node 的发行版本,建议使用最新稳定版 6.x 。
110 | - Ubuntu 用户使用 `apt-get` 安装 node 后,安装的程序名叫 `nodejs`,需要软链成 `node`
111 | - Windows 用户安装完成后需要在 CMD 下确认是否能执行 node 和 npm
112 |
113 | #### 全局安装 webpack 最新版本
114 |
115 | ```bash
116 | npm install webpack -g
117 | ```
118 |
119 | ### 运行 Demo 示例项目
120 |
121 | #### 安装 NPM 包
122 |
123 | - 进入项目 目录执行以下命令
124 |
125 | ```bash
126 | npm install
127 | ```
128 |
129 | #### 运行 Demo 示例
130 |
131 | - 在项目目录下执行
132 |
133 | ```bash
134 | // 打包命令
135 | npm run build
136 | ```
137 |
138 | ```bash
139 | // production模式下启动服务
140 | npm run start
141 | ```
142 |
143 | ```bash
144 | // dev模式下启动服务
145 | npm run dev
146 | ```
147 |
148 | npm run dev 启动服务路径http://localhost:6180
149 |
150 | ### 添加 mock 假数据测试
151 |
152 | ```javascript
153 | // /views/index/mock.js
154 | GET: {
155 | "code": 200,
156 | "data": [
157 | {
158 | name: '推荐',
159 | type: 0
160 | },
161 | {
162 | name: '居家',
163 | type: 1
164 | },
165 | {
166 | name: '餐厨',
167 | type: 2
168 | },
169 | {
170 | name: '服装',
171 | type: 3
172 | },
173 | {
174 | name: '电器',
175 | type: 4
176 | },
177 | {
178 | name: '洗护',
179 | type: 5
180 | },
181 | {
182 | name: '杂货',
183 | type: 6
184 | }
185 | ]
186 | },
187 | GETBOTTOM: {
188 | "code": 200,
189 | "data": [
190 | {
191 | href: '/',
192 | value: '首页',
193 | type: 'index'
194 | },
195 | {
196 | href: '/',
197 | value: '识物',
198 | type: 'topic'
199 | },
200 | {
201 | href: '/',
202 | value: '分类',
203 | type: 'cate'
204 | },
205 | {
206 | href: '/',
207 | value: '购物车',
208 | type: 'cart'
209 | },
210 | {
211 | href: '/',
212 | value: '个人',
213 | type: 'ucenter'
214 | }
215 | ]
216 | }
217 | ```
218 |
219 | ```javascript
220 | // views/index.vue
221 | serviceGet() {
222 | Service.get().then((data) => {
223 | this.headNavData = data;
224 | })
225 | Service.getBottom().then((data) => {
226 | this.botNavData = data;
227 | })
228 | }
229 | ```
230 |
231 | ### service workers 配置
232 |
233 | ```javascript
234 | // webpack.cliemt.config.js
235 | if (process.env.NODE_ENV === 'production') {
236 | config.plugins.push(
237 | // auto generate service worker
238 | new SWPrecachePlugin({
239 | cacheId: 'ga-vue',
240 | filename: 'service-worker.js',
241 | minify: true,
242 | dontCacheBustUrlsMatching: /\.\w{8}\./,
243 | staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/]
244 | })
245 | )
246 | }
247 | ```
248 |
249 | ```javascript
250 | // entry-client.js
251 | if ('serviceWorker' in navigator) {
252 | console.log('SW present !!! ')
253 | navigator.serviceWorker
254 | .register('/service-worker.js', {
255 | //scope: '/toto/'
256 | })
257 | .then(function(registration) {
258 | console.log('Service worker registered : ', registration.scope)
259 | })
260 | .catch(function(err) {
261 | console.log('Service worker registration failed : ', err)
262 | })
263 | }
264 | ```
265 |
266 | 
267 |
268 | ### 发布部署
269 |
270 | node 服务器通过 express/koa 搭建环境,通过 pm2 启动端口服务,一般会在项目目录新建 bin 文件夹,然后新建相应的 sh 脚本命令来启动 node 服务。
271 |
272 | 以下是最终效果截图
273 |
274 | 
275 |
--------------------------------------------------------------------------------
/build/setup-dev-server.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const MFS = require('memory-fs')
4 | const clientConfig = require('./webpack.client.config')
5 | const serverConfig = require('./webpack.server.config')
6 |
7 | const readFile = (fs, file) => {
8 | try {
9 | return fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
10 | } catch (e) {}
11 | }
12 |
13 | module.exports = function setupDevServer (app, cb) {
14 | let bundle, clientManifest
15 | let resolve
16 | const readyPromise = new Promise(r => { resolve = r })
17 | const ready = (...args) => {
18 | resolve()
19 | cb(...args)
20 | }
21 |
22 | // modify client config to work with hot middleware
23 | clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app]
24 | clientConfig.output.filename = '[name].js'
25 | clientConfig.plugins.push(
26 | new webpack.HotModuleReplacementPlugin(),
27 | new webpack.NoEmitOnErrorsPlugin()
28 | )
29 |
30 | // dev middleware
31 | const clientCompiler = webpack(clientConfig)
32 | const devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
33 | publicPath: clientConfig.output.publicPath,
34 | noInfo: true
35 | })
36 | app.use(devMiddleware)
37 | clientCompiler.plugin('done', stats => {
38 | stats = stats.toJson()
39 | stats.errors.forEach(err => console.error(err))
40 | stats.warnings.forEach(err => console.warn(err))
41 | if (stats.errors.length) return
42 |
43 | clientManifest = JSON.parse(readFile(
44 | devMiddleware.fileSystem,
45 | 'vue-ssr-client-manifest.json'
46 | ))
47 | if (bundle) {
48 | ready(bundle, {
49 | clientManifest
50 | })
51 | }
52 | })
53 |
54 | // hot middleware
55 | app.use(require('webpack-hot-middleware')(clientCompiler, { heartbeat: 5000 }))
56 |
57 | // watch and update server renderer
58 | const serverCompiler = webpack(serverConfig)
59 | const mfs = new MFS()
60 | serverCompiler.outputFileSystem = mfs
61 | serverCompiler.watch({}, (err, stats) => {
62 | if (err) throw err
63 | stats = stats.toJson()
64 | if (stats.errors.length) return
65 |
66 | // read bundle generated by vue-ssr-webpack-plugin
67 | bundle = JSON.parse(readFile(mfs, 'vue-ssr-server-bundle.json'))
68 | if (clientManifest) {
69 | ready(bundle, {
70 | clientManifest
71 | })
72 | }
73 | })
74 |
75 | return readyPromise
76 | }
77 |
--------------------------------------------------------------------------------
/build/vue-loader.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extractCSS: process.env.NODE_ENV === 'production',
3 | preserveWhitespace: false,
4 | postcss: [
5 | require('autoprefixer')({
6 | browsers: ['last 3 versions']
7 | })
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/build/webpack.base.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const vueConfig = require('./vue-loader.config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
6 |
7 | const isProd = process.env.NODE_ENV === 'production'
8 |
9 | module.exports = {
10 | devtool: isProd ?
11 | false :
12 | '#cheap-module-source-map',
13 | output: {
14 | path: path.resolve(__dirname, '../dist'),
15 | publicPath: '/dist/',
16 | filename: '[name].[chunkhash].js',
17 | chunkFilename: '[name].[chunkhash].js'
18 | },
19 | resolve: {
20 | extensions: ['.js', '.vue', '.json'],
21 | alias: {
22 | // 'echarts': 'echarts/dist/echarts.common.min.js',
23 | 'vue': 'vue/dist/vue.runtime.min.js',
24 | '@': path.resolve('src'),
25 | 'R': path.resolve('src/components')
26 | }
27 | },
28 | module: {
29 | noParse: /es6-promise\.js$/, // avoid webpack shimming process
30 | rules: [{
31 | test: /\.vue$/,
32 | loader: 'vue-loader',
33 | options: vueConfig
34 | },
35 | {
36 | test: /\.js$/,
37 | loader: 'babel-loader',
38 | exclude: /node_modules/
39 | },
40 | {
41 | test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
42 | loader: 'url-loader',
43 | options: {
44 | limit: 10000,
45 | name: '[name].[ext]?[hash]'
46 | }
47 | },
48 | {
49 | test: /\.(less|css)$/,
50 | use: isProd ?
51 | ExtractTextPlugin.extract({
52 | use: ['css-loader?minimize','less-loader'],
53 | fallback: 'vue-style-loader'
54 | }) :
55 | ['vue-style-loader', 'css-loader', 'less-loader']
56 | }
57 | ]
58 | },
59 | performance: {
60 | maxEntrypointSize: 300000,
61 | hints: isProd ? 'warning' : false
62 | },
63 | plugins: isProd ?
64 | [
65 | new webpack.optimize.UglifyJsPlugin({
66 | compress: {
67 | warnings: false,
68 | drop_debugger: true,
69 | drop_console: true
70 | },
71 | sourceMap: false // true
72 | }),
73 | new ExtractTextPlugin({
74 | filename: 'common.[chunkhash].css'
75 | }),
76 | new ExtractTextPlugin({
77 | filename: 'common.[chunkhash].less'
78 | })
79 | ] :
80 | [
81 | new FriendlyErrorsPlugin()
82 | ]
83 | }
84 |
--------------------------------------------------------------------------------
/build/webpack.client.config.js:
--------------------------------------------------------------------------------
1 | const glob = require('glob')
2 | const webpack = require('webpack')
3 | const merge = require('webpack-merge')
4 | const base = require('./webpack.base.config')
5 | const SWPrecachePlugin = require('sw-precache-webpack-plugin')
6 | const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
7 | const config = merge(base, {
8 | entry: {
9 | app: './src/entry-client.js',
10 | vendors: ['lodash', 'axios'],
11 | vues: ['vue', 'vuex', 'vue-router']
12 | },
13 | plugins: [
14 | // strip dev-only code in Vue source
15 | new webpack.DefinePlugin({
16 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
17 | 'process.env.STATS': JSON.stringify(process.env.NODE_ENV || 'dev'),
18 | 'process.env.VUE_ENV': '"client"'
19 | }),
20 | // extract vendor chunks for better caching
21 | // new webpack.optimize.CommonsChunkPlugin({
22 | // name: ['vendors'],
23 | // minChunks: function(module) {
24 | // // a module is extracted into the vendor chunk if...
25 | // return (
26 | // // it's inside node_modules
27 | // /node_modules/.test(module.context) &&
28 | // // and not a CSS file (due to extract-text-webpack-plugin limitation)
29 | // !/\.css$/.test(module.request)
30 | // )
31 | // }
32 | // }),
33 | new webpack.optimize.CommonsChunkPlugin({
34 | names: ['vendors', 'vues'],
35 | minChunks: 3
36 | }),
37 | // 重要信息:这将 webpack 运行时分离到一个引导 chunk 中,
38 | // 以便可以在之后正确注入异步 chunk。
39 | // 这也为你的 应用程序/vendor 代码提供了更好的缓存。
40 | new webpack.optimize.CommonsChunkPlugin({
41 | name: 'manifest',
42 | // minChunks: Infinity
43 | chunks: ['vendors', 'vues']
44 | }),
45 | // 此插件在输出目录中
46 | // 生成 `vue-ssr-client-manifest.json`。
47 | new VueSSRClientPlugin()
48 | ]
49 | })
50 |
51 | if (process.env.NODE_ENV === 'production') {
52 | config.plugins.push(
53 | // auto generate service worker
54 | new SWPrecachePlugin({
55 | cacheId: 'ga-vue',
56 | filename: 'service-worker.js',
57 | minify: true,
58 | dontCacheBustUrlsMatching: /\.\w{8}\./,
59 | staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/]
60 | })
61 | )
62 | }
63 |
64 | module.exports = config
65 |
--------------------------------------------------------------------------------
/build/webpack.server.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const merge = require('webpack-merge')
3 | const base = require('./webpack.base.config')
4 | const nodeExternals = require('webpack-node-externals')
5 | const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
6 |
7 | module.exports = merge(base, {
8 | // 这允许 webpack 以 Node 适用方式(Node-appropriate fashion)处理动态导入(dynamic import),
9 | // 并且还会在编译 Vue 组件时,
10 | // 告知 `vue-loader` 输送面向服务器代码(server-oriented code)。
11 | target: 'node',
12 | // 对 bundle renderer 提供 source map 支持
13 | devtool: '#source-map',
14 | entry: './src/entry-server.js',
15 | // 此处告知 server bundle 使用 Node 风格导出模块(Node-style exports)
16 | output: {
17 | filename: 'server-bundle.js',
18 | libraryTarget: 'commonjs2'
19 | },
20 | // 外置化应用程序依赖模块。可以使服务器构建速度更快,
21 | // 并生成较小的 bundle 文件。
22 | externals: nodeExternals({
23 | whitelist: /\.css$/
24 | }),
25 | plugins: [
26 | new webpack.DefinePlugin({
27 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
28 | 'process.env.VUE_ENV': '"server"'
29 | }),
30 | // 这是将服务器的整个输出
31 | // 构建为单个 JSON 文件的插件。
32 | // 默认文件名为 `vue-ssr-server-bundle.json`
33 | new VueSSRServerPlugin()
34 | ]
35 | })
36 |
--------------------------------------------------------------------------------
/log/err.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wqzwh/vue-ssr/cca3e361f4921312c02fdb6ad66af1cf7c95d2c1/log/err.log
--------------------------------------------------------------------------------
/log/out.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wqzwh/vue-ssr/cca3e361f4921312c02fdb6ad66af1cf7c95d2c1/log/out.log
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-ssr",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "app.js",
6 | "scripts": {
7 | "dev": "node server",
8 | "start": "cross-env NODE_ENV=production node server",
9 | "build": "rimraf dist && npm run build:client && npm run build:server",
10 | "build:client": "cross-env NODE_ENV=production webpack --config build/webpack.client.config.js --progress --hide-modules",
11 | "build:server": "cross-env NODE_ENV=production webpack --config build/webpack.server.config.js --progress --hide-modules"
12 | },
13 | "author": "wangqi",
14 | "license": "ISC",
15 | "dependencies": {
16 | "axios": "^0.19.0",
17 | "es6-promise": "^4.1.1",
18 | "express": "^4.15.4",
19 | "lodash": "^4.17.4",
20 | "q": "git+https://github.com/kriskowal/q.git",
21 | "qs": "^6.5.0",
22 | "vue": "^2.4.2",
23 | "vue-router": "^2.7.0",
24 | "vue-server-renderer": "^2.4.2",
25 | "vuex": "^2.3.1"
26 | },
27 | "devDependencies": {
28 | "autoprefixer": "^7.1.2",
29 | "babel-core": "^6.25.0",
30 | "babel-loader": "^7.1.1",
31 | "babel-plugin-syntax-dynamic-import": "^6.18.0",
32 | "babel-plugin-transform-runtime": "^6.22.0",
33 | "babel-preset-env": "^1.6.0",
34 | "babel-preset-stage-2": "^6.22.0",
35 | "compression": "^1.7.1",
36 | "cross-env": "^5.0.5",
37 | "css-loader": "^0.28.4",
38 | "extract-text-webpack-plugin": "^3.0.0",
39 | "file-loader": "^0.11.2",
40 | "friendly-errors-webpack-plugin": "^1.6.1",
41 | "glob": "^7.1.2",
42 | "less": "^2.7.2",
43 | "less-loader": "^2.2.3",
44 | "lru-cache": "^4.1.1",
45 | "mockjs": "^1.0.1-beta3",
46 | "style-loader": "^0.19.0",
47 | "sw-precache-webpack-plugin": "^0.11.4",
48 | "url-loader": "^0.5.9",
49 | "vue-loader": "^13.0.4",
50 | "vue-style-loader": "^3.0.3",
51 | "vue-template-compiler": "^2.4.2",
52 | "vuex-router-sync": "^4.2.0",
53 | "webpack": "^3.5.0",
54 | "webpack-dev-middleware": "^1.12.0",
55 | "webpack-hot-middleware": "^2.18.2",
56 | "webpack-merge": "^4.1.0",
57 | "webpack-node-externals": "^1.6.0"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/pmlog.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test",
3 | "script": "./server.js",
4 | "exec_mode": "cluster",
5 | "error_file": "./log/err.log",
6 | "out_file": "./log/out.log",
7 | "merge_logs": true,
8 | "log_data_format":"YYYY-MM-DD HH:mm: Z",
9 | "instances":4,
10 | "watch":true
11 | }
12 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const Vue = require('vue')
2 | const express = require('express')
3 | const path = require('path')
4 | const LRU = require('lru-cache')
5 | const resolve = file => path.resolve(__dirname, file)
6 | const { createBundleRenderer } = require('vue-server-renderer')
7 | const fs = require('fs')
8 | const net = require('net')
9 | const http = require('http');
10 | const compression = require('compression');
11 |
12 |
13 | const template = fs.readFileSync('./src/index.template.html', 'utf-8')
14 | const isProd = process.env.NODE_ENV === 'production'
15 |
16 | const server = express()
17 |
18 | function createRenderer (bundle, options) {
19 | return createBundleRenderer(bundle, Object.assign(options, {
20 | template: template,
21 | cache: LRU({
22 | max: 1000,
23 | maxAge: 1000 * 60 * 15
24 | }),
25 | basedir: resolve('./dist'),
26 | runInNewContext: false
27 | }))
28 | }
29 |
30 | let renderer;
31 |
32 | let readyPromise
33 | if (isProd) {
34 | const bundle = require('./dist/vue-ssr-server-bundle.json')
35 | const clientManifest = require('./dist/vue-ssr-client-manifest.json')
36 | renderer = createRenderer(bundle, {
37 | clientManifest
38 | })
39 | } else {
40 | readyPromise = require('./build/setup-dev-server')(server, (bundle, options) => {
41 | renderer = createRenderer(bundle, options)
42 | })
43 | }
44 |
45 |
46 | const serve = (path, cache) => express.static(resolve(path), {
47 | maxAge: cache && isProd ? 1000 * 60 * 60 * 24 * 30 : 0
48 | })
49 | server.use(compression())
50 | server.use('/dist', serve('./dist', true))
51 | server.use('/static', serve('./src/static', true))
52 | server.use('/service-worker.js', serve('./dist/service-worker.js'))
53 |
54 |
55 | server.get('*', (req, res) => {
56 | const context = {
57 | title: '网易严选',
58 | url: req.url
59 | }
60 | renderer.renderToString(context, (err, html) => {
61 | if (err) {
62 | res.status(500).end('Internal Server Error')
63 | return
64 | }
65 | res.end(html)
66 | })
67 | })
68 |
69 | function probe(port, callback) {
70 | let servers = net.createServer().listen(port)
71 | let calledOnce = false
72 | let timeoutRef = setTimeout(function() {
73 | calledOnce = true
74 | callback(false, port)
75 | }, 2000)
76 | timeoutRef.unref()
77 | let connected = false
78 |
79 | servers.on('listening', function() {
80 | clearTimeout(timeoutRef)
81 | if (servers)
82 | servers.close()
83 | if (!calledOnce) {
84 | calledOnce = true
85 | callback(true, port)
86 | }
87 | })
88 |
89 | servers.on('error', function(err) {
90 | clearTimeout(timeoutRef)
91 | let result = true
92 | if (err.code === 'EADDRINUSE')
93 | result = false
94 | if (!calledOnce) {
95 | calledOnce = true
96 | callback(result, port)
97 | }
98 | })
99 | }
100 | const checkPortPromise = new Promise((resolve) => {
101 | (function serverport(_port = 6180) {
102 | // let pt = _port || 8080;
103 | let pt = _port;
104 | probe(pt, function(bl, _pt) {
105 | // 端口被占用 bl 返回false
106 | // _pt:传入的端口号
107 | if (bl === true) {
108 | // console.log("\n Static file server running at" + "\n\n=> http://localhost:" + _pt + '\n');
109 | resolve(_pt);
110 | } else {
111 | serverport(_pt + 1)
112 | }
113 | })
114 | })()
115 |
116 | })
117 | checkPortPromise.then(data => {
118 | uri = 'http://localhost:' + data;
119 | console.log('启动服务路径'+uri)
120 | server.listen(data);
121 | });
122 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import { createRouter } from './router'
4 | import { createStore } from './store'
5 | import { sync } from 'vuex-router-sync'
6 | require('./assets/style/css.less');
7 | export function createApp () {
8 | // 创建 router 和 store 实例
9 | const router = createRouter()
10 | const store = createStore()
11 | // 同步路由状态(route state)到 store
12 | sync(store, router)
13 | // 创建应用程序实例,将 router 和 store 注入
14 | const app = new Vue({
15 | router,
16 | store,
17 | render: h => h(App)
18 | })
19 | // 暴露 app, router 和 store。
20 | return { app, router, store }
21 | }
--------------------------------------------------------------------------------
/src/assets/views/index.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | .m-ftWrap {
3 | border-top: 1px solid rgba(0, 0, 0, .15);
4 | background-color: #414141
5 | }
6 |
7 | .m-ft {
8 | text-align: center;
9 | padding: .72rem .26667rem .37333rem
10 | }
11 |
12 | .m-ft .goApp,
13 | .m-ft .goWeb {
14 | width: 2.29333rem;
15 | font-size: .32rem;
16 | color: #fff
17 | }
18 |
19 | .swiper-slide,
20 | .swiper-wrapper {
21 | width: 100%;
22 | height: 100%;
23 | position: relative
24 | }
25 |
26 | .m-ft .goApp {
27 | margin-right: .66667rem
28 | }
29 |
30 | .m-ft .copyright {
31 | margin-top: .48rem;
32 | font-size: .32rem;
33 | line-height: .42667rem;
34 | color: #999
35 | }
36 |
37 | .swiper-container {
38 | margin-left: auto;
39 | margin-right: auto;
40 | position: relative;
41 | overflow: hidden;
42 | z-index: 1
43 | }
44 |
45 | .swiper-container-no-flexbox .swiper-slide {
46 | float: left
47 | }
48 |
49 | .swiper-container-vertical>.swiper-wrapper {
50 | -webkit-box-orient: vertical;
51 | -moz-box-orient: vertical;
52 | -ms-flex-direction: column;
53 | -webkit-flex-direction: column;
54 | flex-direction: column
55 | }
56 |
57 | .swiper-wrapper {
58 | z-index: 1;
59 | display: -webkit-box;
60 | display: -moz-box;
61 | display: -ms-flexbox;
62 | display: -webkit-flex;
63 | display: flex;
64 | -webkit-transition-property: -webkit-transform;
65 | -moz-transition-property: -moz-transform;
66 | -o-transition-property: -o-transform;
67 | -ms-transition-property: -ms-transform;
68 | transition-property: -webkit-transform;
69 | transition-property: transform;
70 | transition-property: transform, -webkit-transform;
71 | -webkit-box-sizing: content-box;
72 | -moz-box-sizing: content-box;
73 | box-sizing: content-box
74 | }
75 |
76 | .swiper-container-android .swiper-slide,
77 | .swiper-wrapper {
78 | -webkit-transform: translate3d(0, 0, 0);
79 | -moz-transform: translate3d(0, 0, 0);
80 | -o-transform: translate(0, 0);
81 | -ms-transform: translate3d(0, 0, 0);
82 | transform: translate3d(0, 0, 0)
83 | }
84 |
85 | .swiper-container-multirow>.swiper-wrapper {
86 | -webkit-box-lines: multiple;
87 | -moz-box-lines: multiple;
88 | -ms-flex-wrap: wrap;
89 | -webkit-flex-wrap: wrap;
90 | flex-wrap: wrap
91 | }
92 |
93 | .swiper-container-free-mode>.swiper-wrapper {
94 | -webkit-transition-timing-function: ease-out;
95 | -moz-transition-timing-function: ease-out;
96 | -ms-transition-timing-function: ease-out;
97 | -o-transition-timing-function: ease-out;
98 | transition-timing-function: ease-out;
99 | margin: 0 auto
100 | }
101 |
102 | .swiper-slide {
103 | -webkit-flex-shrink: 0;
104 | -ms-flex: 0 0 auto;
105 | -ms-flex-negative: 0;
106 | flex-shrink: 0
107 | }
108 |
109 | .swiper-container-autoheight,
110 | .swiper-container-autoheight .swiper-slide {
111 | height: auto
112 | }
113 |
114 | .swiper-container-autoheight .swiper-wrapper {
115 | -webkit-box-align: start;
116 | -ms-flex-align: start;
117 | -webkit-align-items: flex-start;
118 | -ms-grid-row-align: flex-start;
119 | align-items: flex-start;
120 | -webkit-transition-property: -webkit-transform, height;
121 | -moz-transition-property: -moz-transform;
122 | -o-transition-property: -o-transform;
123 | -ms-transition-property: -ms-transform;
124 | transition-property: height, -webkit-transform;
125 | transition-property: transform, height;
126 | transition-property: transform, height, -webkit-transform
127 | }
128 |
129 | .swiper-container .swiper-notification {
130 | position: absolute;
131 | left: 0;
132 | top: 0;
133 | pointer-events: none;
134 | opacity: 0;
135 | z-index: -1000
136 | }
137 |
138 | .swiper-wp8-horizontal {
139 | -ms-touch-action: pan-y;
140 | touch-action: pan-y
141 | }
142 |
143 | .swiper-wp8-vertical {
144 | -ms-touch-action: pan-x;
145 | touch-action: pan-x
146 | }
147 |
148 | .swiper-button-next,
149 | .swiper-button-prev {
150 | position: absolute;
151 | top: 50%;
152 | width: 27px;
153 | height: 44px;
154 | margin-top: -22px;
155 | z-index: 10;
156 | cursor: pointer;
157 | -moz-background-size: 27px 44px;
158 | -webkit-background-size: 27px 44px;
159 | background-size: 27px 44px;
160 | background-position: center;
161 | background-repeat: no-repeat
162 | }
163 |
164 | .swiper-button-next.swiper-button-disabled,
165 | .swiper-button-prev.swiper-button-disabled {
166 | opacity: .35;
167 | cursor: auto;
168 | pointer-events: none
169 | }
170 |
171 | .swiper-button-prev,
172 | .swiper-container-rtl .swiper-button-next {
173 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");
174 | left: 10px;
175 | right: auto
176 | }
177 |
178 | .swiper-button-prev.swiper-button-black,
179 | .swiper-container-rtl .swiper-button-next.swiper-button-black {
180 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")
181 | }
182 |
183 | .swiper-button-prev.swiper-button-white,
184 | .swiper-container-rtl .swiper-button-next.swiper-button-white {
185 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")
186 | }
187 |
188 | .swiper-button-next,
189 | .swiper-container-rtl .swiper-button-prev {
190 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");
191 | right: 10px;
192 | left: auto
193 | }
194 |
195 | .swiper-button-next.swiper-button-black,
196 | .swiper-container-rtl .swiper-button-prev.swiper-button-black {
197 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")
198 | }
199 |
200 | .swiper-button-next.swiper-button-white,
201 | .swiper-container-rtl .swiper-button-prev.swiper-button-white {
202 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")
203 | }
204 |
205 | .swiper-pagination {
206 | position: absolute;
207 | text-align: center;
208 | -webkit-transition: .3s;
209 | -moz-transition: .3s;
210 | -o-transition: .3s;
211 | transition: .3s;
212 | -webkit-transform: translate3d(0, 0, 0);
213 | -ms-transform: translate3d(0, 0, 0);
214 | -o-transform: translate3d(0, 0, 0);
215 | transform: translate3d(0, 0, 0);
216 | z-index: 10
217 | }
218 |
219 | .swiper-pagination.swiper-pagination-hidden {
220 | opacity: 0
221 | }
222 |
223 | .swiper-container-horizontal>.swiper-pagination-bullets,
224 | .swiper-pagination-custom,
225 | .swiper-pagination-fraction {
226 | bottom: 10px;
227 | left: 0;
228 | width: 100%
229 | }
230 |
231 | .swiper-pagination-bullet {
232 | width: 8px;
233 | height: 8px;
234 | display: inline-block;
235 | border-radius: 100%;
236 | background: #000;
237 | opacity: .2
238 | }
239 |
240 | button.swiper-pagination-bullet {
241 | border: none;
242 | margin: 0;
243 | padding: 0;
244 | box-shadow: none;
245 | -moz-appearance: none;
246 | -ms-appearance: none;
247 | -webkit-appearance: none;
248 | appearance: none
249 | }
250 |
251 | .swiper-pagination-clickable .swiper-pagination-bullet {
252 | cursor: pointer
253 | }
254 |
255 | .swiper-pagination-white .swiper-pagination-bullet {
256 | background: #fff
257 | }
258 |
259 | .swiper-pagination-bullet-active {
260 | opacity: 1;
261 | background: #007aff
262 | }
263 |
264 | .swiper-pagination-white .swiper-pagination-bullet-active {
265 | background: #fff
266 | }
267 |
268 | .swiper-pagination-black .swiper-pagination-bullet-active {
269 | background: #000
270 | }
271 |
272 | .swiper-container-vertical>.swiper-pagination-bullets {
273 | right: 10px;
274 | top: 50%;
275 | -webkit-transform: translate3d(0, -50%, 0);
276 | -moz-transform: translate3d(0, -50%, 0);
277 | -o-transform: translate(0, -50%);
278 | -ms-transform: translate3d(0, -50%, 0);
279 | transform: translate3d(0, -50%, 0)
280 | }
281 |
282 | .swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet {
283 | margin: 5px 0;
284 | display: block
285 | }
286 |
287 | .swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet {
288 | margin: 0 5px
289 | }
290 |
291 | .swiper-pagination-progress {
292 | background: rgba(0, 0, 0, .25);
293 | position: absolute
294 | }
295 |
296 | .swiper-pagination-progress .swiper-pagination-progressbar {
297 | background: #007aff;
298 | position: absolute;
299 | left: 0;
300 | top: 0;
301 | width: 100%;
302 | height: 100%;
303 | -webkit-transform: scale(0);
304 | -ms-transform: scale(0);
305 | -o-transform: scale(0);
306 | transform: scale(0);
307 | -webkit-transform-origin: left top;
308 | -moz-transform-origin: left top;
309 | -ms-transform-origin: left top;
310 | -o-transform-origin: left top;
311 | transform-origin: left top
312 | }
313 |
314 | .swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar {
315 | -webkit-transform-origin: right top;
316 | -moz-transform-origin: right top;
317 | -ms-transform-origin: right top;
318 | -o-transform-origin: right top;
319 | transform-origin: right top
320 | }
321 |
322 | .swiper-container-horizontal>.swiper-pagination-progress {
323 | width: 100%;
324 | height: 4px;
325 | left: 0;
326 | top: 0
327 | }
328 |
329 | .swiper-container-vertical>.swiper-pagination-progress {
330 | width: 4px;
331 | height: 100%;
332 | left: 0;
333 | top: 0
334 | }
335 |
336 | .swiper-pagination-progress.swiper-pagination-white {
337 | background: rgba(255, 255, 255, .5)
338 | }
339 |
340 | .swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar {
341 | background: #fff
342 | }
343 |
344 | .swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar {
345 | background: #000
346 | }
347 |
348 | .swiper-container-3d {
349 | -webkit-perspective: 1200px;
350 | -moz-perspective: 1200px;
351 | -o-perspective: 1200px;
352 | perspective: 1200px
353 | }
354 |
355 | .swiper-container-3d .swiper-cube-shadow,
356 | .swiper-container-3d .swiper-slide,
357 | .swiper-container-3d .swiper-slide-shadow-bottom,
358 | .swiper-container-3d .swiper-slide-shadow-left,
359 | .swiper-container-3d .swiper-slide-shadow-right,
360 | .swiper-container-3d .swiper-slide-shadow-top,
361 | .swiper-container-3d .swiper-wrapper {
362 | -webkit-transform-style: preserve-3d;
363 | -moz-transform-style: preserve-3d;
364 | -ms-transform-style: preserve-3d;
365 | transform-style: preserve-3d
366 | }
367 |
368 | .swiper-container-3d .swiper-slide-shadow-bottom,
369 | .swiper-container-3d .swiper-slide-shadow-left,
370 | .swiper-container-3d .swiper-slide-shadow-right,
371 | .swiper-container-3d .swiper-slide-shadow-top {
372 | position: absolute;
373 | left: 0;
374 | top: 0;
375 | width: 100%;
376 | height: 100%;
377 | pointer-events: none;
378 | z-index: 10
379 | }
380 |
381 | .swiper-container-3d .swiper-slide-shadow-left {
382 | background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(transparent));
383 | background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, .5), transparent);
384 | background-image: -moz-linear-gradient(right, rgba(0, 0, 0, .5), transparent);
385 | background-image: -o-linear-gradient(right, rgba(0, 0, 0, .5), transparent);
386 | background-image: linear-gradient(to left, rgba(0, 0, 0, .5), transparent)
387 | }
388 |
389 | .swiper-container-3d .swiper-slide-shadow-right {
390 | background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, .5)), to(transparent));
391 | background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5), transparent);
392 | background-image: -moz-linear-gradient(left, rgba(0, 0, 0, .5), transparent);
393 | background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5), transparent);
394 | background-image: linear-gradient(to right, rgba(0, 0, 0, .5), transparent)
395 | }
396 |
397 | .swiper-container-3d .swiper-slide-shadow-top {
398 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, .5)), to(transparent));
399 | background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, .5), transparent);
400 | background-image: -moz-linear-gradient(bottom, rgba(0, 0, 0, .5), transparent);
401 | background-image: -o-linear-gradient(bottom, rgba(0, 0, 0, .5), transparent);
402 | background-image: linear-gradient(to top, rgba(0, 0, 0, .5), transparent)
403 | }
404 |
405 | .swiper-container-3d .swiper-slide-shadow-bottom {
406 | background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, .5)), to(transparent));
407 | background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, .5), transparent);
408 | background-image: -moz-linear-gradient(top, rgba(0, 0, 0, .5), transparent);
409 | background-image: -o-linear-gradient(top, rgba(0, 0, 0, .5), transparent);
410 | background-image: linear-gradient(to bottom, rgba(0, 0, 0, .5), transparent)
411 | }
412 |
413 | .swiper-container-coverflow .swiper-wrapper,
414 | .swiper-container-flip .swiper-wrapper {
415 | -ms-perspective: 1200px
416 | }
417 |
418 | .swiper-container-cube,
419 | .swiper-container-flip {
420 | overflow: visible
421 | }
422 |
423 | .swiper-container-cube .swiper-slide,
424 | .swiper-container-flip .swiper-slide {
425 | pointer-events: none;
426 | -webkit-backface-visibility: hidden;
427 | -moz-backface-visibility: hidden;
428 | -ms-backface-visibility: hidden;
429 | backface-visibility: hidden;
430 | z-index: 1
431 | }
432 |
433 | .swiper-container-cube .swiper-slide .swiper-slide,
434 | .swiper-container-flip .swiper-slide .swiper-slide {
435 | pointer-events: none
436 | }
437 |
438 | .swiper-container-cube .swiper-slide-active,
439 | .swiper-container-cube .swiper-slide-active .swiper-slide-active,
440 | .swiper-container-flip .swiper-slide-active,
441 | .swiper-container-flip .swiper-slide-active .swiper-slide-active {
442 | pointer-events: auto
443 | }
444 |
445 | .swiper-container-cube .swiper-slide-shadow-bottom,
446 | .swiper-container-cube .swiper-slide-shadow-left,
447 | .swiper-container-cube .swiper-slide-shadow-right,
448 | .swiper-container-cube .swiper-slide-shadow-top,
449 | .swiper-container-flip .swiper-slide-shadow-bottom,
450 | .swiper-container-flip .swiper-slide-shadow-left,
451 | .swiper-container-flip .swiper-slide-shadow-right,
452 | .swiper-container-flip .swiper-slide-shadow-top {
453 | z-index: 0;
454 | -webkit-backface-visibility: hidden;
455 | -moz-backface-visibility: hidden;
456 | -ms-backface-visibility: hidden;
457 | backface-visibility: hidden
458 | }
459 |
460 | .swiper-container-cube .swiper-slide {
461 | visibility: hidden;
462 | -webkit-transform-origin: 0 0;
463 | -moz-transform-origin: 0 0;
464 | -ms-transform-origin: 0 0;
465 | transform-origin: 0 0;
466 | width: 100%;
467 | height: 100%
468 | }
469 |
470 | .swiper-container-cube.swiper-container-rtl .swiper-slide {
471 | -webkit-transform-origin: 100% 0;
472 | -moz-transform-origin: 100% 0;
473 | -ms-transform-origin: 100% 0;
474 | transform-origin: 100% 0
475 | }
476 |
477 | .swiper-container-cube .swiper-slide-active,
478 | .swiper-container-cube .swiper-slide-next,
479 | .swiper-container-cube .swiper-slide-next+.swiper-slide,
480 | .swiper-container-cube .swiper-slide-prev {
481 | pointer-events: auto;
482 | visibility: visible
483 | }
484 |
485 | .swiper-container-cube .swiper-cube-shadow {
486 | position: absolute;
487 | left: 0;
488 | bottom: 0;
489 | width: 100%;
490 | height: 100%;
491 | background: #000;
492 | opacity: .6;
493 | -webkit-filter: blur(50px);
494 | filter: blur(50px);
495 | z-index: 0
496 | }
497 |
498 | .swiper-container-fade.swiper-container-free-mode .swiper-slide {
499 | -webkit-transition-timing-function: ease-out;
500 | -moz-transition-timing-function: ease-out;
501 | -ms-transition-timing-function: ease-out;
502 | -o-transition-timing-function: ease-out;
503 | transition-timing-function: ease-out
504 | }
505 |
506 | .swiper-container-fade .swiper-slide {
507 | pointer-events: none;
508 | -webkit-transition-property: opacity;
509 | -moz-transition-property: opacity;
510 | -o-transition-property: opacity;
511 | transition-property: opacity
512 | }
513 |
514 | .swiper-container-fade .swiper-slide .swiper-slide {
515 | pointer-events: none
516 | }
517 |
518 | .swiper-container-fade .swiper-slide-active,
519 | .swiper-container-fade .swiper-slide-active .swiper-slide-active {
520 | pointer-events: auto
521 | }
522 |
523 | .swiper-zoom-container {
524 | width: 100%;
525 | height: 100%;
526 | display: -webkit-box;
527 | display: -moz-box;
528 | display: -ms-flexbox;
529 | display: -webkit-flex;
530 | display: flex;
531 | -webkit-box-pack: center;
532 | -moz-box-pack: center;
533 | -ms-flex-pack: center;
534 | -webkit-justify-content: center;
535 | justify-content: center;
536 | -webkit-box-align: center;
537 | -moz-box-align: center;
538 | -ms-flex-align: center;
539 | -webkit-align-items: center;
540 | align-items: center;
541 | text-align: center
542 | }
543 |
544 | .swiper-zoom-container>canvas,
545 | .swiper-zoom-container>img,
546 | .swiper-zoom-container>svg {
547 | max-width: 100%;
548 | max-height: 100%;
549 | object-fit: contain
550 | }
551 |
552 | .swiper-scrollbar {
553 | border-radius: 10px;
554 | position: relative;
555 | -ms-touch-action: none;
556 | background: rgba(0, 0, 0, .1)
557 | }
558 |
559 | .swiper-container-horizontal>.swiper-scrollbar {
560 | position: absolute;
561 | left: 1%;
562 | bottom: 3px;
563 | z-index: 50;
564 | height: 5px;
565 | width: 98%
566 | }
567 |
568 | .swiper-container-vertical>.swiper-scrollbar {
569 | position: absolute;
570 | right: 3px;
571 | top: 1%;
572 | z-index: 50;
573 | width: 5px;
574 | height: 98%
575 | }
576 |
577 | .swiper-scrollbar-drag {
578 | height: 100%;
579 | width: 100%;
580 | position: relative;
581 | background: rgba(0, 0, 0, .5);
582 | border-radius: 10px;
583 | left: 0;
584 | top: 0
585 | }
586 |
587 | .swiper-scrollbar-cursor-drag {
588 | cursor: move
589 | }
590 |
591 | .swiper-lazy-preloader {
592 | width: 42px;
593 | height: 42px;
594 | position: absolute;
595 | left: 50%;
596 | top: 50%;
597 | margin-left: -21px;
598 | margin-top: -21px;
599 | z-index: 10;
600 | -webkit-transform-origin: 50%;
601 | -moz-transform-origin: 50%;
602 | transform-origin: 50%;
603 | -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;
604 | -moz-animation: swiper-preloader-spin 1s steps(12, end) infinite;
605 | animation: swiper-preloader-spin 1s steps(12, end) infinite
606 | }
607 |
608 | .swiper-lazy-preloader:after {
609 | display: block;
610 | content: "";
611 | width: 100%;
612 | height: 100%;
613 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
614 | background-position: 50%;
615 | -webkit-background-size: 100%;
616 | background-size: 100%;
617 | background-repeat: no-repeat
618 | }
619 |
620 | .swiper-lazy-preloader-white:after {
621 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
622 | }
623 |
624 | @-webkit-keyframes swiper-preloader-spin {
625 | 100% {
626 | -webkit-transform: rotate(360deg)
627 | }
628 | }
629 |
630 | @keyframes swiper-preloader-spin {
631 | 100% {
632 | -webkit-transform: rotate(360deg);
633 | transform: rotate(360deg)
634 | }
635 | }
636 |
637 | .m-slide {
638 | position: relative;
639 | width: 100%;
640 | padding-top: 100%;
641 | overflow: hidden
642 | }
643 |
644 | .m-slide .slide-con {
645 | position: absolute;
646 | left: 0;
647 | top: 0;
648 | width: 100%;
649 | height: 100%
650 | }
651 |
652 | .m-slide .swiper-container {
653 | width: 100%;
654 | height: 100%
655 | }
656 |
657 | .m-slide .swiper-container img {
658 | width: 100%;
659 | height: 100%;
660 | background-color: #f9f9f9
661 | }
662 |
663 | .m-slide .swiper-container-horizontal>.swiper-pagination {
664 | bottom: .4rem;
665 | width: 100%
666 | }
667 |
668 | .m-slide .swiper-container-horizontal>.swiper-pagination.detail-pagination-up {
669 | bottom: 1.36rem
670 | }
671 |
672 | .m-slide .swiper-container-horizontal>.swiper-pagination .swiper-pagination-bullet {
673 | margin: 0 .13333rem 0 0
674 | }
675 |
676 | .m-slide .swiper-pagination-bullet {
677 | width: .53333rem;
678 | height: .05333rem;
679 | display: inline-block;
680 | background: #fff;
681 | opacity: .4;
682 | border-radius: 0
683 | }
684 |
685 | .m-slide .swiper-pagination-bullet-active {
686 | opacity: 1;
687 | background: #fff;
688 | border-radius: 0
689 | }
690 |
691 | .m-slide .swiper-container-horizontal>.swiper-pagination-fraction {
692 | left: auto;
693 | right: .4rem;
694 | width: .72rem;
695 | height: .37333rem;
696 | line-height: .37333rem;
697 | border: 1px solid rgba(0, 0, 0, .15);
698 | font-size: .26667rem;
699 | text-align: center;
700 | color: #333;
701 | background-color: #fff;
702 | transition: 0s;
703 | border-radius: 4px;
704 | display: -webkit-box;
705 | display: -webkit-flex;
706 | display: -moz-flex;
707 | display: -ms-flexbox;
708 | display: flex;
709 | -webkit-box-pack: center;
710 | -ms-flex-pack: center;
711 | -webkit-justify-content: center;
712 | -moz-justify-content: center;
713 | justify-content: center;
714 | -webkit-box-align: center;
715 | -ms-flex-align: center;
716 | -webkit-align-items: center;
717 | -moz-align-items: center;
718 | align-items: center
719 | }
720 |
721 | [data-dpr="1"] .m-slide .swiper-container-horizontal>.swiper-pagination-fraction {
722 | border-radius: 2px;
723 | line-height: .42667rem
724 | }
725 |
726 | .m-slide .error {
727 | position: relative
728 | }
729 |
730 | .m-slide .error:before {
731 | content: ' ';
732 | display: block;
733 | position: absolute;
734 | z-index: 1;
735 | top: 0;
736 | left: 0;
737 | right: 0;
738 | bottom: 0;
739 | background-color: #f4f4f4;
740 | background-image: url(http://yanxuan.nosdn.127.net/f159d1b2ec1867ad1a73d5077fcca604.png);
741 | background-repeat: no-repeat;
742 | background-position: center;
743 | background-size: 2.29333rem
744 | }
745 |
746 | .m-tabBar,
747 | .m-tabs>header {
748 | display: -webkit-box;
749 | display: -webkit-flex;
750 | display: -moz-flex;
751 | display: -ms-flexbox;
752 | -webkit-flex-flow: row nowrap
753 | }
754 |
755 | .m-tabBar {
756 | display: flex;
757 | -moz-flex-flow: row nowrap;
758 | -ms-flex-flow: row nowrap;
759 | flex-flow: row nowrap;
760 | -webkit-box-align: center;
761 | -ms-flex-align: center;
762 | -webkit-align-items: center;
763 | -moz-align-items: center;
764 | align-items: center;
765 | -ms-flex-pack: distribute;
766 | -webkit-justify-content: space-around;
767 | -moz-justify-content: space-around;
768 | justify-content: space-around;
769 | position: fixed;
770 | z-index: 5;
771 | left: 0;
772 | bottom: 0;
773 | width: 100%;
774 | height: 1.30667rem;
775 | background-color: #fafafa;
776 | border-top: 1px solid #d9d9d9
777 | }
778 |
779 | .m-tabBar>.item {
780 | position: relative;
781 | text-align: center
782 | }
783 |
784 | .m-tabBar>.item .txt {
785 | display: block;
786 | margin-top: .09333rem;
787 | font-size: .32rem;
788 | color: #666;
789 | line-height: 1
790 | }
791 |
792 | .m-tabBar>.item .badge {
793 | position: absolute;
794 | top: -.01333rem;
795 | right: -.08rem
796 | }
797 |
798 | .m-tabBar>.item.active .txt {
799 | color: #b4282d
800 | }
801 |
802 | .m-badge {
803 | display: inline-block;
804 | width: .37333rem;
805 | height: .37333rem;
806 | border-radius: .18667rem;
807 | background-color: #b4282d;
808 | text-align: center;
809 | line-height: .37333rem;
810 | font-size: .24rem;
811 | color: #fff
812 | }
813 |
814 | .m-badge-1 {
815 | width: .48rem
816 | }
817 |
818 | .m-badge-2 {
819 | width: .64rem
820 | }
821 |
822 | .m-sticker,
823 | .m-sticker .img-swraper img {
824 | width: 1.06667rem;
825 | height: 1.06667rem
826 | }
827 |
828 | .m-sticker {
829 | border-radius: 100%;
830 | border: 1px solid #d9d9d9;
831 | position: absolute;
832 | background: #fff
833 | }
834 |
835 | .m-sticker .img-swraper:after {
836 | position: absolute;
837 | border-radius: 100%;
838 | color: #fff;
839 | content: '\9001';
840 | text-align: center;
841 | background-color: #f48f18;
842 | width: .48rem;
843 | height: .48rem;
844 | line-height: .48rem;
845 | font-size: .26667rem;
846 | top: -.13333rem;
847 | left: -.13333rem
848 | }
849 |
850 | .m-tabs {
851 | width: 100%
852 | }
853 |
854 | .m-tabs>header {
855 | display: flex;
856 | -moz-flex-flow: row nowrap;
857 | -ms-flex-flow: row nowrap;
858 | flex-flow: row nowrap;
859 | background-color: #fff;
860 | position: relative
861 | }
862 |
863 | .m-tabs>header:after {
864 | content: '';
865 | position: absolute;
866 | background-color: #d9d9d9;
867 | left: 0;
868 | width: 100%;
869 | height: 1px;
870 | -webkit-transform-origin: 50% 100% 0;
871 | transform-origin: 50% 100% 0;
872 | bottom: 0
873 | }
874 |
875 | [data-dpr="1"] .m-tabs>header:after {
876 | -webkit-transform: scale3d(1, .5, 1);
877 | -moz-transform: scale3d(1, .5, 1);
878 | -ms-transform: scale3d(1, .5, 1);
879 | -o-transform: scale3d(1, .5, 1);
880 | transform: scale3d(1, .5, 1)
881 | }
882 |
883 | .m-tabs>header .tab {
884 | display: -webkit-box;
885 | display: -webkit-flex;
886 | display: -moz-flex;
887 | display: -ms-flexbox;
888 | display: flex;
889 | -webkit-flex-flow: row nowrap;
890 | -moz-flex-flow: row nowrap;
891 | -ms-flex-flow: row nowrap;
892 | flex-flow: row nowrap;
893 | -webkit-box-align: center;
894 | -ms-flex-align: center;
895 | -webkit-align-items: center;
896 | -moz-align-items: center;
897 | align-items: center;
898 | -webkit-box-pack: center;
899 | -ms-flex-pack: center;
900 | -webkit-justify-content: center;
901 | -moz-justify-content: center;
902 | justify-content: center;
903 | position: relative;
904 | z-index: 1;
905 | text-align: center
906 | }
907 |
908 | .m-tabs>header .tab .txt {
909 | display: inline-block;
910 | padding: 0 .21333rem;
911 | line-height: .8rem;
912 | font-size: .37333rem;
913 | color: #333;
914 | text-align: center
915 | }
916 |
917 | .m-tabs>header .tab.active {
918 | color: #b4282d
919 | }
920 |
921 | .m-tabs>header .tab.active .txt {
922 | position: relative;
923 | color: #b4282d
924 | }
925 |
926 | .m-tabs>header .tab.active .txt:after {
927 | content: ' ';
928 | position: absolute;
929 | left: 0;
930 | bottom: 0;
931 | width: 100%;
932 | height: .05333rem;
933 | background-color: #b4282d
934 | }
935 |
936 | .m-tabs .panel {
937 | display: none
938 | }
939 |
940 | .m-tabs .panel.active {
941 | display: block
942 | }
943 |
944 | .m-tabs.scroll>header .inner,
945 | .m-tabs.scroll>header .list {
946 | display: -webkit-box;
947 | display: -webkit-flex;
948 | display: -moz-flex;
949 | display: -ms-flexbox
950 | }
951 |
952 | .m-tabs.scroll>header .inner {
953 | display: flex;
954 | -webkit-flex-flow: row nowrap;
955 | -moz-flex-flow: row nowrap;
956 | -ms-flex-flow: row nowrap;
957 | flex-flow: row nowrap
958 | }
959 |
960 | .m-tabs.scroll>header .list {
961 | display: flex;
962 | -webkit-flex-flow: row nowrap;
963 | -moz-flex-flow: row nowrap;
964 | -ms-flex-flow: row nowrap;
965 | flex-flow: row nowrap;
966 | -webkit-flex-shrink: 0;
967 | -moz-flex-shrink: 0;
968 | -ms-flex-negative: 0;
969 | flex-shrink: 0;
970 | padding: 0 .4rem;
971 | background: #fff
972 | }
973 |
974 | .m-tabs.scroll>header .tab {
975 | -webkit-flex-shrink: 0;
976 | -moz-flex-shrink: 0;
977 | -ms-flex-negative: 0;
978 | flex-shrink: 0;
979 | position: relative;
980 | margin-left: .64rem
981 | }
982 |
983 | .m-tabs.scroll>header .tab:first-of-type {
984 | margin-left: 0
985 | }
986 |
987 | .m-tabs.noScroll>header {
988 | -webkit-box-pack: justify;
989 | -ms-flex-pack: justify;
990 | -webkit-justify-content: space-between;
991 | -moz-justify-content: space-between;
992 | justify-content: space-between;
993 | padding: 0 .4rem
994 | }
995 |
996 | .m-tabs.noScroll>header .tab {
997 | -webkit-box-flex: 1;
998 | -webkit-flex-grow: 1;
999 | -moz-flex-grow: 1;
1000 | -ms-flex-positive: 1;
1001 | flex-grow: 1
1002 | }
1003 |
1004 | .m-tabs.withPanels>header .tab .txt {
1005 | padding-top: .6rem;
1006 | padding-bottom: .33333rem;
1007 | line-height: .45333rem
1008 | }
1009 |
1010 | .m-tabs.l>header {
1011 | height: 1.06667rem
1012 | }
1013 |
1014 | .m-tabs.l>header .tab .txt {
1015 | line-height: 1.06667rem
1016 | }
1017 |
1018 | .m-navForSpecificChannels {
1019 | display: -webkit-box;
1020 | display: -webkit-flex;
1021 | display: -moz-flex;
1022 | display: -ms-flexbox;
1023 | display: flex;
1024 | -webkit-flex-flow: row nowrap;
1025 | -moz-flex-flow: row nowrap;
1026 | -ms-flex-flow: row nowrap;
1027 | flex-flow: row nowrap;
1028 | -webkit-box-align: center;
1029 | -ms-flex-align: center;
1030 | -webkit-align-items: center;
1031 | -moz-align-items: center;
1032 | align-items: center;
1033 | -ms-flex-pack: distribute;
1034 | -webkit-justify-content: space-around;
1035 | -moz-justify-content: space-around;
1036 | justify-content: space-around;
1037 | height: 1.92rem;
1038 | background-color: #fff;
1039 | position: relative
1040 | }
1041 |
1042 | .m-navForSpecificChannels:after {
1043 | content: '';
1044 | position: absolute;
1045 | background-color: #d9d9d9;
1046 | left: 0;
1047 | width: 100%;
1048 | height: 1px;
1049 | -webkit-transform-origin: 50% 100% 0;
1050 | transform-origin: 50% 100% 0;
1051 | bottom: 0
1052 | }
1053 |
1054 | [data-dpr="1"] .m-navForSpecificChannels:after {
1055 | -webkit-transform: scale3d(1, .5, 1);
1056 | -moz-transform: scale3d(1, .5, 1);
1057 | -ms-transform: scale3d(1, .5, 1);
1058 | -o-transform: scale3d(1, .5, 1);
1059 | transform: scale3d(1, .5, 1)
1060 | }
1061 |
1062 | .m-navForSpecificChannels .item {
1063 | position: relative;
1064 | text-align: center
1065 | }
1066 |
1067 | .m-navForSpecificChannels .item .txt {
1068 | margin-top: .13333rem;
1069 | font-size: .32rem;
1070 | color: #333
1071 | }
1072 |
1073 | .m-navForSpecificChannels .item .badge {
1074 | position: absolute;
1075 | top: -.01333rem;
1076 | right: -.08rem
1077 | }
1078 |
1079 | .m-wapNewUserEntrance {
1080 | position: fixed;
1081 | right: 0;
1082 | bottom: 3.2rem;
1083 | display: block;
1084 | z-index: 10;
1085 | -webkit-animation: .5s moveLeft;
1086 | animation: .5s moveLeft
1087 | }
1088 |
1089 | @-webkit-keyframes moveLeft {
1090 | from {
1091 | -webkit-transform: translateX(1.33333rem);
1092 | -moz-transform: translateX(1.33333rem);
1093 | -ms-transform: translateX(1.33333rem);
1094 | -o-transform: translateX(1.33333rem);
1095 | transform: translateX(1.33333rem)
1096 | }
1097 | to {
1098 | -webkit-transform: translateX(0);
1099 | -moz-transform: translateX(0);
1100 | -ms-transform: translateX(0);
1101 | -o-transform: translateX(0);
1102 | transform: translateX(0)
1103 | }
1104 | }
1105 |
1106 | @keyframes moveLeft {
1107 | from {
1108 | -webkit-transform: translateX(1.33333rem);
1109 | -moz-transform: translateX(1.33333rem);
1110 | -ms-transform: translateX(1.33333rem);
1111 | -o-transform: translateX(1.33333rem);
1112 | transform: translateX(1.33333rem)
1113 | }
1114 | to {
1115 | -webkit-transform: translateX(0);
1116 | -moz-transform: translateX(0);
1117 | -ms-transform: translateX(0);
1118 | -o-transform: translateX(0);
1119 | transform: translateX(0)
1120 | }
1121 | }
1122 |
1123 | .m-newUserItem {
1124 | margin-top: .66667rem;
1125 | background-color: #f4f4f4;
1126 | border-radius: .05333rem;
1127 | height: 3.09333rem;
1128 | width: 100%;
1129 | display: -webkit-box;
1130 | display: -webkit-flex;
1131 | display: -moz-flex;
1132 | display: -ms-flexbox;
1133 | display: flex
1134 | }
1135 |
1136 | .m-newUserItem .img>img {
1137 | width: 3.09333rem;
1138 | height: 3.09333rem
1139 | }
1140 |
1141 | .m-newUserItem .content {
1142 | margin-left: .10667rem;
1143 | -webkit-box-flex: 1;
1144 | -webkit-flex: 1;
1145 | -moz-box-flex: 1;
1146 | -moz-flex: 1;
1147 | -ms-flex: 1;
1148 | flex: 1;
1149 | padding: .57333rem 0
1150 | }
1151 |
1152 | .m-newUserItem .content .itemName {
1153 | font-size: .37333rem;
1154 | width: 3.73333rem;
1155 | text-overflow: ellipsis;
1156 | white-space: nowrap;
1157 | overflow: hidden
1158 | }
1159 |
1160 | .m-newUserItem .content .manu {
1161 | margin-top: .2rem
1162 | }
1163 |
1164 | .m-newUserItem .content .manu .manuTag {
1165 | border: 1px solid #7f7f7f;
1166 | border-radius: .05333rem;
1167 | padding: 0 .10667rem;
1168 | height: .48rem;
1169 | line-height: .48rem
1170 | }
1171 |
1172 | .m-newUserItem .content .price {
1173 | margin-top: .26667rem;
1174 | font-size: .37333rem
1175 | }
1176 |
1177 | .m-newUserItem .content .price .retailPrice {
1178 | color: #b4282d
1179 | }
1180 |
1181 | .m-newUserItem .content .price .comparePrice {
1182 | color: #999;
1183 | display: inline-block;
1184 | margin-left: .10667rem;
1185 | text-decoration: line-through
1186 | }
1187 |
1188 | .m-newWapUserGiftModal {
1189 | position: fixed;
1190 | top: 0;
1191 | left: 0;
1192 | right: 0;
1193 | bottom: 0;
1194 | z-index: 9999
1195 | }
1196 |
1197 | .m-newWapUserGiftModal>.mask {
1198 | position: absolute;
1199 | top: 0;
1200 | left: 0;
1201 | z-index: 0;
1202 | width: 100%;
1203 | height: 100%;
1204 | background-color: rgba(0, 0, 0, .5)
1205 | }
1206 |
1207 | .m-newWapUserGiftModal .close {
1208 | position: fixed;
1209 | right: .4rem;
1210 | top: .8rem;
1211 | z-index: 2
1212 | }
1213 |
1214 | .m-newWapUserGiftModal>.wrap {
1215 | -webkit-transform: translate(-50%, -50%);
1216 | -moz-transform: translate(-50%, -50%);
1217 | -ms-transform: translate(-50%, -50%);
1218 | -o-transform: translate(-50%, -50%);
1219 | transform: translate(-50%, -50%);
1220 | position: absolute;
1221 | top: 50%;
1222 | left: 50%;
1223 | z-index: 1
1224 | }
1225 |
1226 | .m-newWapUserGiftModal .modal {
1227 | width: 8.4rem;
1228 | height: 9.22667rem;
1229 | background-color: #fff;
1230 | border-radius: .21333rem;
1231 | padding: .4rem .32rem
1232 | }
1233 |
1234 | .m-newWapUserGiftModal .modal .title {
1235 | font-size: .53333rem;
1236 | text-align: center
1237 | }
1238 |
1239 | .m-newWapUserGiftModal .modal .title .titleContent {
1240 | display: inline-block;
1241 | position: relative;
1242 | font-weight: 700
1243 | }
1244 |
1245 | .m-newWapUserGiftModal .modal .title .titleContent:after,
1246 | .m-newWapUserGiftModal .modal .title .titleContent:before {
1247 | width: .53333rem;
1248 | height: .05333rem;
1249 | background-color: #333;
1250 | position: absolute;
1251 | top: .37333rem;
1252 | content: ''
1253 | }
1254 |
1255 | .m-newWapUserGiftModal .modal .title .titleContent:before {
1256 | left: -.74667rem
1257 | }
1258 |
1259 | .m-newWapUserGiftModal .modal .title .titleContent:after {
1260 | left: 2.88rem
1261 | }
1262 |
1263 | .m-newWapUserGiftModal .modal .subTitle {
1264 | margin-top: .05333rem;
1265 | font-size: .32rem;
1266 | text-align: center
1267 | }
1268 |
1269 | .m-newWapUserGiftModal .modal .actCouponBtn {
1270 | height: 1.17333rem;
1271 | background-color: #b4282d;
1272 | color: #fff;
1273 | font-size: .37333rem;
1274 | margin-top: .53333rem;
1275 | border-radius: .05333rem;
1276 | text-align: center;
1277 | line-height: 1.17333rem
1278 | }
1279 |
1280 | .m-newWapUserGiftModal .modal .linkBtn {
1281 | height: 1.17333rem;
1282 | border: 1px solid #7F7F7F;
1283 | border-radius: .05333rem;
1284 | text-align: center;
1285 | line-height: 1.17333rem;
1286 | font-size: .37333rem;
1287 | margin-top: .32rem;
1288 | display: block;
1289 | color: #333
1290 | }
1291 |
1292 | .m-indexHd {
1293 | background-color: #fff;
1294 | position: relative
1295 | }
1296 |
1297 | .m-indexHd:after {
1298 | content: '';
1299 | position: absolute;
1300 | background-color: #d9d9d9;
1301 | left: 0;
1302 | width: 100%;
1303 | height: 1px;
1304 | -webkit-transform-origin: 50% 100% 0;
1305 | transform-origin: 50% 100% 0;
1306 | bottom: 0
1307 | }
1308 |
1309 | [data-dpr="1"] .m-indexHd:after {
1310 | -webkit-transform: scale3d(1, .5, 1);
1311 | -moz-transform: scale3d(1, .5, 1);
1312 | -ms-transform: scale3d(1, .5, 1);
1313 | -o-transform: scale3d(1, .5, 1);
1314 | transform: scale3d(1, .5, 1)
1315 | }
1316 |
1317 | .m-indexHd>.line {
1318 | display: -webkit-box;
1319 | display: -webkit-flex;
1320 | display: -moz-flex;
1321 | display: -ms-flexbox;
1322 | display: flex;
1323 | -webkit-flex-flow: row nowrap;
1324 | -moz-flex-flow: row nowrap;
1325 | -ms-flex-flow: row nowrap;
1326 | flex-flow: row nowrap;
1327 | -webkit-box-align: center;
1328 | -ms-flex-align: center;
1329 | -webkit-align-items: center;
1330 | -moz-align-items: center;
1331 | align-items: center;
1332 | padding: .21333rem .4rem
1333 | }
1334 |
1335 | .m-indexHd>.line .logo {
1336 | width: 1.84rem;
1337 | height: .53333rem;
1338 | background-image: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/indexLogo-11d65342f9.png);
1339 | display: inline-block;
1340 | margin-right: .26667rem;
1341 | background-size: cover;
1342 | background-position: center
1343 | }
1344 |
1345 | .m-indexHd>.line>.ipt {
1346 | -webkit-box-flex: 1;
1347 | -webkit-flex-grow: 1;
1348 | -moz-flex-grow: 1;
1349 | -ms-flex-positive: 1;
1350 | flex-grow: 1
1351 | }
1352 |
1353 | .m-hdForSpecificChannels {
1354 | position: fixed;
1355 | top: 0;
1356 | left: 0;
1357 | z-index: 5
1358 | }
1359 |
1360 | .m-hdForSpecificChannels header {
1361 | height: 1.2rem!important
1362 | }
1363 |
1364 | .m-hdForSpecificChannels .tab .txt {
1365 | line-height: 1.2rem!important
1366 | }
1367 |
1368 | .m-indexTopics .inner .list .item .line1 .title,
1369 | .swiper-container-no-flexbox .swiper-slide {
1370 | float: left
1371 | }
1372 |
1373 | .swiper-slide,
1374 | .swiper-wrapper {
1375 | width: 100%;
1376 | height: 100%;
1377 | position: relative
1378 | }
1379 |
1380 | .swiper-container {
1381 | margin-left: auto;
1382 | margin-right: auto;
1383 | position: relative;
1384 | overflow: hidden;
1385 | z-index: 1
1386 | }
1387 |
1388 | .swiper-container-vertical>.swiper-wrapper {
1389 | -webkit-box-orient: vertical;
1390 | -moz-box-orient: vertical;
1391 | -ms-flex-direction: column;
1392 | -webkit-flex-direction: column;
1393 | flex-direction: column
1394 | }
1395 |
1396 | .swiper-wrapper {
1397 | z-index: 1;
1398 | display: -webkit-box;
1399 | display: -moz-box;
1400 | display: -ms-flexbox;
1401 | display: -webkit-flex;
1402 | display: flex;
1403 | -webkit-transition-property: -webkit-transform;
1404 | -moz-transition-property: -moz-transform;
1405 | -o-transition-property: -o-transform;
1406 | -ms-transition-property: -ms-transform;
1407 | transition-property: -webkit-transform;
1408 | transition-property: transform;
1409 | transition-property: transform, -webkit-transform;
1410 | -webkit-box-sizing: content-box;
1411 | -moz-box-sizing: content-box;
1412 | box-sizing: content-box
1413 | }
1414 |
1415 | .swiper-container-android .swiper-slide,
1416 | .swiper-wrapper {
1417 | -webkit-transform: translate3d(0, 0, 0);
1418 | -moz-transform: translate3d(0, 0, 0);
1419 | -o-transform: translate(0, 0);
1420 | -ms-transform: translate3d(0, 0, 0);
1421 | transform: translate3d(0, 0, 0)
1422 | }
1423 |
1424 | .swiper-container-multirow>.swiper-wrapper {
1425 | -webkit-box-lines: multiple;
1426 | -moz-box-lines: multiple;
1427 | -ms-flex-wrap: wrap;
1428 | -webkit-flex-wrap: wrap;
1429 | flex-wrap: wrap
1430 | }
1431 |
1432 | .swiper-container-free-mode>.swiper-wrapper {
1433 | -webkit-transition-timing-function: ease-out;
1434 | -moz-transition-timing-function: ease-out;
1435 | -ms-transition-timing-function: ease-out;
1436 | -o-transition-timing-function: ease-out;
1437 | transition-timing-function: ease-out;
1438 | margin: 0 auto
1439 | }
1440 |
1441 | .swiper-slide {
1442 | -webkit-flex-shrink: 0;
1443 | -ms-flex: 0 0 auto;
1444 | -ms-flex-negative: 0;
1445 | flex-shrink: 0
1446 | }
1447 |
1448 | .swiper-container-autoheight,
1449 | .swiper-container-autoheight .swiper-slide {
1450 | height: auto
1451 | }
1452 |
1453 | .swiper-container-autoheight .swiper-wrapper {
1454 | -webkit-box-align: start;
1455 | -ms-flex-align: start;
1456 | -webkit-align-items: flex-start;
1457 | -ms-grid-row-align: flex-start;
1458 | align-items: flex-start;
1459 | -webkit-transition-property: -webkit-transform, height;
1460 | -moz-transition-property: -moz-transform;
1461 | -o-transition-property: -o-transform;
1462 | -ms-transition-property: -ms-transform;
1463 | transition-property: height, -webkit-transform;
1464 | transition-property: transform, height;
1465 | transition-property: transform, height, -webkit-transform
1466 | }
1467 |
1468 | .swiper-container .swiper-notification {
1469 | position: absolute;
1470 | left: 0;
1471 | top: 0;
1472 | pointer-events: none;
1473 | opacity: 0;
1474 | z-index: -1000
1475 | }
1476 |
1477 | .swiper-wp8-horizontal {
1478 | -ms-touch-action: pan-y;
1479 | touch-action: pan-y
1480 | }
1481 |
1482 | .swiper-wp8-vertical {
1483 | -ms-touch-action: pan-x;
1484 | touch-action: pan-x
1485 | }
1486 |
1487 | .swiper-button-next,
1488 | .swiper-button-prev {
1489 | position: absolute;
1490 | top: 50%;
1491 | width: 27px;
1492 | height: 44px;
1493 | margin-top: -22px;
1494 | z-index: 10;
1495 | cursor: pointer;
1496 | -moz-background-size: 27px 44px;
1497 | -webkit-background-size: 27px 44px;
1498 | background-size: 27px 44px;
1499 | background-position: center;
1500 | background-repeat: no-repeat
1501 | }
1502 |
1503 | .swiper-button-next.swiper-button-disabled,
1504 | .swiper-button-prev.swiper-button-disabled {
1505 | opacity: .35;
1506 | cursor: auto;
1507 | pointer-events: none
1508 | }
1509 |
1510 | .swiper-button-prev,
1511 | .swiper-container-rtl .swiper-button-next {
1512 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");
1513 | left: 10px;
1514 | right: auto
1515 | }
1516 |
1517 | .swiper-button-prev.swiper-button-black,
1518 | .swiper-container-rtl .swiper-button-next.swiper-button-black {
1519 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")
1520 | }
1521 |
1522 | .swiper-button-prev.swiper-button-white,
1523 | .swiper-container-rtl .swiper-button-next.swiper-button-white {
1524 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")
1525 | }
1526 |
1527 | .swiper-button-next,
1528 | .swiper-container-rtl .swiper-button-prev {
1529 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");
1530 | right: 10px;
1531 | left: auto
1532 | }
1533 |
1534 | .swiper-button-next.swiper-button-black,
1535 | .swiper-container-rtl .swiper-button-prev.swiper-button-black {
1536 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")
1537 | }
1538 |
1539 | .swiper-button-next.swiper-button-white,
1540 | .swiper-container-rtl .swiper-button-prev.swiper-button-white {
1541 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")
1542 | }
1543 |
1544 | .swiper-pagination {
1545 | position: absolute;
1546 | text-align: center;
1547 | -webkit-transition: .3s;
1548 | -moz-transition: .3s;
1549 | -o-transition: .3s;
1550 | transition: .3s;
1551 | -webkit-transform: translate3d(0, 0, 0);
1552 | -ms-transform: translate3d(0, 0, 0);
1553 | -o-transform: translate3d(0, 0, 0);
1554 | transform: translate3d(0, 0, 0);
1555 | z-index: 10
1556 | }
1557 |
1558 | .swiper-pagination.swiper-pagination-hidden {
1559 | opacity: 0
1560 | }
1561 |
1562 | .swiper-container-horizontal>.swiper-pagination-bullets,
1563 | .swiper-pagination-custom,
1564 | .swiper-pagination-fraction {
1565 | bottom: 10px;
1566 | left: 0;
1567 | width: 100%
1568 | }
1569 |
1570 | .swiper-pagination-bullet {
1571 | width: 8px;
1572 | height: 8px;
1573 | display: inline-block;
1574 | border-radius: 100%;
1575 | background: #000;
1576 | opacity: .2
1577 | }
1578 |
1579 | button.swiper-pagination-bullet {
1580 | border: none;
1581 | margin: 0;
1582 | padding: 0;
1583 | box-shadow: none;
1584 | -moz-appearance: none;
1585 | -ms-appearance: none;
1586 | -webkit-appearance: none;
1587 | appearance: none
1588 | }
1589 |
1590 | .swiper-pagination-clickable .swiper-pagination-bullet {
1591 | cursor: pointer
1592 | }
1593 |
1594 | .swiper-pagination-white .swiper-pagination-bullet {
1595 | background: #fff
1596 | }
1597 |
1598 | .swiper-pagination-bullet-active {
1599 | opacity: 1;
1600 | background: #007aff
1601 | }
1602 |
1603 | .swiper-pagination-white .swiper-pagination-bullet-active {
1604 | background: #fff
1605 | }
1606 |
1607 | .swiper-pagination-black .swiper-pagination-bullet-active {
1608 | background: #000
1609 | }
1610 |
1611 | .swiper-container-vertical>.swiper-pagination-bullets {
1612 | right: 10px;
1613 | top: 50%;
1614 | -webkit-transform: translate3d(0, -50%, 0);
1615 | -moz-transform: translate3d(0, -50%, 0);
1616 | -o-transform: translate(0, -50%);
1617 | -ms-transform: translate3d(0, -50%, 0);
1618 | transform: translate3d(0, -50%, 0)
1619 | }
1620 |
1621 | .swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet {
1622 | margin: 5px 0;
1623 | display: block
1624 | }
1625 |
1626 | .m-indexFlash,
1627 | .swiper-zoom-container {
1628 | display: -webkit-box;
1629 | display: -webkit-flex;
1630 | display: -ms-flexbox
1631 | }
1632 |
1633 | .swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet {
1634 | margin: 0 5px
1635 | }
1636 |
1637 | .swiper-pagination-progress {
1638 | background: rgba(0, 0, 0, .25);
1639 | position: absolute
1640 | }
1641 |
1642 | .swiper-pagination-progress .swiper-pagination-progressbar {
1643 | background: #007aff;
1644 | position: absolute;
1645 | left: 0;
1646 | top: 0;
1647 | width: 100%;
1648 | height: 100%;
1649 | -webkit-transform: scale(0);
1650 | -ms-transform: scale(0);
1651 | -o-transform: scale(0);
1652 | transform: scale(0);
1653 | -webkit-transform-origin: left top;
1654 | -moz-transform-origin: left top;
1655 | -ms-transform-origin: left top;
1656 | -o-transform-origin: left top;
1657 | transform-origin: left top
1658 | }
1659 |
1660 | .swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar {
1661 | -webkit-transform-origin: right top;
1662 | -moz-transform-origin: right top;
1663 | -ms-transform-origin: right top;
1664 | -o-transform-origin: right top;
1665 | transform-origin: right top
1666 | }
1667 |
1668 | .swiper-container-horizontal>.swiper-pagination-progress {
1669 | width: 100%;
1670 | height: 4px;
1671 | left: 0;
1672 | top: 0
1673 | }
1674 |
1675 | .swiper-container-vertical>.swiper-pagination-progress {
1676 | width: 4px;
1677 | height: 100%;
1678 | left: 0;
1679 | top: 0
1680 | }
1681 |
1682 | .swiper-pagination-progress.swiper-pagination-white {
1683 | background: rgba(255, 255, 255, .5)
1684 | }
1685 |
1686 | .swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar {
1687 | background: #fff
1688 | }
1689 |
1690 | .swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar {
1691 | background: #000
1692 | }
1693 |
1694 | .swiper-container-3d {
1695 | -webkit-perspective: 1200px;
1696 | -moz-perspective: 1200px;
1697 | -o-perspective: 1200px;
1698 | perspective: 1200px
1699 | }
1700 |
1701 | .swiper-container-3d .swiper-cube-shadow,
1702 | .swiper-container-3d .swiper-slide,
1703 | .swiper-container-3d .swiper-slide-shadow-bottom,
1704 | .swiper-container-3d .swiper-slide-shadow-left,
1705 | .swiper-container-3d .swiper-slide-shadow-right,
1706 | .swiper-container-3d .swiper-slide-shadow-top,
1707 | .swiper-container-3d .swiper-wrapper {
1708 | -webkit-transform-style: preserve-3d;
1709 | -moz-transform-style: preserve-3d;
1710 | -ms-transform-style: preserve-3d;
1711 | transform-style: preserve-3d
1712 | }
1713 |
1714 | .swiper-container-3d .swiper-slide-shadow-bottom,
1715 | .swiper-container-3d .swiper-slide-shadow-left,
1716 | .swiper-container-3d .swiper-slide-shadow-right,
1717 | .swiper-container-3d .swiper-slide-shadow-top {
1718 | position: absolute;
1719 | left: 0;
1720 | top: 0;
1721 | width: 100%;
1722 | height: 100%;
1723 | pointer-events: none;
1724 | z-index: 10
1725 | }
1726 |
1727 | .swiper-container-3d .swiper-slide-shadow-left {
1728 | background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(transparent));
1729 | background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, .5), transparent);
1730 | background-image: -moz-linear-gradient(right, rgba(0, 0, 0, .5), transparent);
1731 | background-image: -o-linear-gradient(right, rgba(0, 0, 0, .5), transparent);
1732 | background-image: linear-gradient(to left, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0))
1733 | }
1734 |
1735 | .swiper-container-3d .swiper-slide-shadow-right {
1736 | background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, .5)), to(transparent));
1737 | background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5), transparent);
1738 | background-image: -moz-linear-gradient(left, rgba(0, 0, 0, .5), transparent);
1739 | background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5), transparent);
1740 | background-image: linear-gradient(to right, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0))
1741 | }
1742 |
1743 | .swiper-container-3d .swiper-slide-shadow-top {
1744 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, .5)), to(transparent));
1745 | background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, .5), transparent);
1746 | background-image: -moz-linear-gradient(bottom, rgba(0, 0, 0, .5), transparent);
1747 | background-image: -o-linear-gradient(bottom, rgba(0, 0, 0, .5), transparent);
1748 | background-image: linear-gradient(to top, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0))
1749 | }
1750 |
1751 | .swiper-container-3d .swiper-slide-shadow-bottom {
1752 | background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, .5)), to(transparent));
1753 | background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, .5), transparent);
1754 | background-image: -moz-linear-gradient(top, rgba(0, 0, 0, .5), transparent);
1755 | background-image: -o-linear-gradient(top, rgba(0, 0, 0, .5), transparent);
1756 | background-image: linear-gradient(to bottom, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0))
1757 | }
1758 |
1759 | .swiper-container-coverflow .swiper-wrapper,
1760 | .swiper-container-flip .swiper-wrapper {
1761 | -ms-perspective: 1200px
1762 | }
1763 |
1764 | .swiper-container-cube,
1765 | .swiper-container-flip {
1766 | overflow: visible
1767 | }
1768 |
1769 | .swiper-container-cube .swiper-slide,
1770 | .swiper-container-flip .swiper-slide {
1771 | pointer-events: none;
1772 | -webkit-backface-visibility: hidden;
1773 | -moz-backface-visibility: hidden;
1774 | -ms-backface-visibility: hidden;
1775 | backface-visibility: hidden;
1776 | z-index: 1
1777 | }
1778 |
1779 | .swiper-container-cube .swiper-slide .swiper-slide,
1780 | .swiper-container-flip .swiper-slide .swiper-slide {
1781 | pointer-events: none
1782 | }
1783 |
1784 | .swiper-container-cube .swiper-slide-active,
1785 | .swiper-container-cube .swiper-slide-active .swiper-slide-active,
1786 | .swiper-container-flip .swiper-slide-active,
1787 | .swiper-container-flip .swiper-slide-active .swiper-slide-active {
1788 | pointer-events: auto
1789 | }
1790 |
1791 | .swiper-container-cube .swiper-slide-shadow-bottom,
1792 | .swiper-container-cube .swiper-slide-shadow-left,
1793 | .swiper-container-cube .swiper-slide-shadow-right,
1794 | .swiper-container-cube .swiper-slide-shadow-top,
1795 | .swiper-container-flip .swiper-slide-shadow-bottom,
1796 | .swiper-container-flip .swiper-slide-shadow-left,
1797 | .swiper-container-flip .swiper-slide-shadow-right,
1798 | .swiper-container-flip .swiper-slide-shadow-top {
1799 | z-index: 0;
1800 | -webkit-backface-visibility: hidden;
1801 | -moz-backface-visibility: hidden;
1802 | -ms-backface-visibility: hidden;
1803 | backface-visibility: hidden
1804 | }
1805 |
1806 | .swiper-container-cube .swiper-slide {
1807 | visibility: hidden;
1808 | -webkit-transform-origin: 0 0;
1809 | -moz-transform-origin: 0 0;
1810 | -ms-transform-origin: 0 0;
1811 | transform-origin: 0 0;
1812 | width: 100%;
1813 | height: 100%
1814 | }
1815 |
1816 | .swiper-container-cube.swiper-container-rtl .swiper-slide {
1817 | -webkit-transform-origin: 100% 0;
1818 | -moz-transform-origin: 100% 0;
1819 | -ms-transform-origin: 100% 0;
1820 | transform-origin: 100% 0
1821 | }
1822 |
1823 | .swiper-container-cube .swiper-slide-active,
1824 | .swiper-container-cube .swiper-slide-next,
1825 | .swiper-container-cube .swiper-slide-next+.swiper-slide,
1826 | .swiper-container-cube .swiper-slide-prev {
1827 | pointer-events: auto;
1828 | visibility: visible
1829 | }
1830 |
1831 | .swiper-container-cube .swiper-cube-shadow {
1832 | position: absolute;
1833 | left: 0;
1834 | bottom: 0;
1835 | width: 100%;
1836 | height: 100%;
1837 | background: #000;
1838 | opacity: .6;
1839 | -webkit-filter: blur(50px);
1840 | filter: blur(50px);
1841 | z-index: 0
1842 | }
1843 |
1844 | .swiper-container-fade.swiper-container-free-mode .swiper-slide {
1845 | -webkit-transition-timing-function: ease-out;
1846 | -moz-transition-timing-function: ease-out;
1847 | -ms-transition-timing-function: ease-out;
1848 | -o-transition-timing-function: ease-out;
1849 | transition-timing-function: ease-out
1850 | }
1851 |
1852 | .swiper-container-fade .swiper-slide {
1853 | pointer-events: none;
1854 | -webkit-transition-property: opacity;
1855 | -moz-transition-property: opacity;
1856 | -o-transition-property: opacity;
1857 | transition-property: opacity
1858 | }
1859 |
1860 | .swiper-container-fade .swiper-slide .swiper-slide {
1861 | pointer-events: none
1862 | }
1863 |
1864 | .swiper-container-fade .swiper-slide-active,
1865 | .swiper-container-fade .swiper-slide-active .swiper-slide-active {
1866 | pointer-events: auto
1867 | }
1868 |
1869 | .swiper-zoom-container {
1870 | width: 100%;
1871 | height: 100%;
1872 | display: -moz-box;
1873 | display: flex;
1874 | -webkit-box-pack: center;
1875 | -moz-box-pack: center;
1876 | -ms-flex-pack: center;
1877 | -webkit-justify-content: center;
1878 | justify-content: center;
1879 | -webkit-box-align: center;
1880 | -moz-box-align: center;
1881 | -ms-flex-align: center;
1882 | -webkit-align-items: center;
1883 | align-items: center;
1884 | text-align: center
1885 | }
1886 |
1887 | .swiper-zoom-container>canvas,
1888 | .swiper-zoom-container>img,
1889 | .swiper-zoom-container>svg {
1890 | max-width: 100%;
1891 | max-height: 100%;
1892 | object-fit: contain
1893 | }
1894 |
1895 | .swiper-scrollbar {
1896 | border-radius: 10px;
1897 | position: relative;
1898 | -ms-touch-action: none;
1899 | background: rgba(0, 0, 0, .1)
1900 | }
1901 |
1902 | .swiper-container-horizontal>.swiper-scrollbar {
1903 | position: absolute;
1904 | left: 1%;
1905 | bottom: 3px;
1906 | z-index: 50;
1907 | height: 5px;
1908 | width: 98%
1909 | }
1910 |
1911 | .swiper-container-vertical>.swiper-scrollbar {
1912 | position: absolute;
1913 | right: 3px;
1914 | top: 1%;
1915 | z-index: 50;
1916 | width: 5px;
1917 | height: 98%
1918 | }
1919 |
1920 | .swiper-scrollbar-drag {
1921 | height: 100%;
1922 | width: 100%;
1923 | position: relative;
1924 | background: rgba(0, 0, 0, .5);
1925 | border-radius: 10px;
1926 | left: 0;
1927 | top: 0
1928 | }
1929 |
1930 | .swiper-scrollbar-cursor-drag {
1931 | cursor: move
1932 | }
1933 |
1934 | .swiper-lazy-preloader {
1935 | width: 42px;
1936 | height: 42px;
1937 | position: absolute;
1938 | left: 50%;
1939 | top: 50%;
1940 | margin-left: -21px;
1941 | margin-top: -21px;
1942 | z-index: 10;
1943 | -webkit-transform-origin: 50%;
1944 | -moz-transform-origin: 50%;
1945 | transform-origin: 50%;
1946 | -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;
1947 | -moz-animation: swiper-preloader-spin 1s steps(12, end) infinite;
1948 | animation: swiper-preloader-spin 1s steps(12, end) infinite
1949 | }
1950 |
1951 | .swiper-lazy-preloader:after {
1952 | display: block;
1953 | content: "";
1954 | width: 100%;
1955 | height: 100%;
1956 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
1957 | background-position: 50%;
1958 | -webkit-background-size: 100%;
1959 | background-size: 100%;
1960 | background-repeat: no-repeat
1961 | }
1962 |
1963 | .swiper-lazy-preloader-white:after {
1964 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
1965 | }
1966 |
1967 | @-webkit-keyframes swiper-preloader-spin {
1968 | 100% {
1969 | -webkit-transform: rotate(360deg)
1970 | }
1971 | }
1972 |
1973 | @keyframes swiper-preloader-spin {
1974 | 100% {
1975 | -webkit-transform: rotate(360deg);
1976 | transform: rotate(360deg)
1977 | }
1978 | }
1979 |
1980 | .m-indexFlash {
1981 | padding: .4rem .53333rem .4rem .74667rem;
1982 | margin-bottom: .26667rem;
1983 | height: 5.06667rem;
1984 | background: #fff;
1985 | display: -moz-flex;
1986 | display: flex
1987 | }
1988 |
1989 | .m-indexFlash .left-item {
1990 | -webkit-box-flex: 1;
1991 | -webkit-flex: 1;
1992 | -moz-box-flex: 1;
1993 | -moz-flex: 1;
1994 | -ms-flex: 1;
1995 | flex: 1;
1996 | display: -webkit-box;
1997 | display: -webkit-flex;
1998 | display: -moz-flex;
1999 | display: -ms-flexbox;
2000 | display: flex;
2001 | -webkit-box-direction: normal;
2002 | -webkit-box-orient: vertical;
2003 | -webkit-flex-direction: column;
2004 | -moz-flex-direction: column;
2005 | -ms-flex-direction: column;
2006 | flex-direction: column;
2007 | padding-top: 1.06667rem
2008 | }
2009 |
2010 | .m-indexFlash .left-item .title {
2011 | font-size: .48rem;
2012 | line-height: .48rem;
2013 | margin-bottom: .32rem;
2014 | color: #333;
2015 | letter-spacing: .16rem
2016 | }
2017 |
2018 | .m-indexFlash .left-item .hours,
2019 | .m-indexFlash .left-item .mins,
2020 | .m-indexFlash .left-item .secs {
2021 | display: inline-block;
2022 | line-height: .74667rem;
2023 | text-align: center;
2024 | width: .82667rem;
2025 | height: .74667rem;
2026 | font-size: .42667rem;
2027 | color: #fff;
2028 | border-radius: .05333rem;
2029 | background: #444
2030 | }
2031 |
2032 | .m-indexFlash .left-item .colon {
2033 | color: #333;
2034 | font-size: .4rem;
2035 | width: .26667rem;
2036 | display: inline-block;
2037 | text-align: center;
2038 | font-weight: 700
2039 | }
2040 |
2041 | .m-indexFlash .right-item .price,
2042 | .m-indexFloor>.hd {
2043 | display: -webkit-box;
2044 | display: -webkit-flex;
2045 | display: -moz-flex;
2046 | display: -ms-flexbox
2047 | }
2048 |
2049 | .m-indexFlash .left-item .next-title {
2050 | margin-top: .53333rem;
2051 | color: #333;
2052 | font-size: .32rem;
2053 | line-height: .32rem;
2054 | height: .32rem
2055 | }
2056 |
2057 | .m-indexFlash .right-item {
2058 | background: #fff;
2059 | width: 4.26667rem;
2060 | height: 4.26667rem;
2061 | position: relative
2062 | }
2063 |
2064 | .m-indexFlash .right-item img {
2065 | width: 100%;
2066 | height: 100%
2067 | }
2068 |
2069 | .m-indexFlash .right-item .rmb1 {
2070 | font-size: .32rem
2071 | }
2072 |
2073 | .m-indexFlash .right-item .rmb2 {
2074 | font-size: .26667rem
2075 | }
2076 |
2077 | .m-indexFlash .right-item .price {
2078 | height: 1.28rem;
2079 | width: 1.28rem;
2080 | background: red;
2081 | position: absolute;
2082 | right: .26667rem;
2083 | bottom: .48rem;
2084 | background-color: rgba(244, 143, 24, .95);
2085 | border-radius: 100%;
2086 | color: #fff;
2087 | text-align: center;
2088 | display: flex;
2089 | -webkit-box-direction: normal;
2090 | -webkit-box-orient: vertical;
2091 | -webkit-flex-direction: column;
2092 | -moz-flex-direction: column;
2093 | -ms-flex-direction: column;
2094 | flex-direction: column;
2095 | -webkit-box-pack: center;
2096 | -ms-flex-pack: center;
2097 | -webkit-justify-content: center;
2098 | -moz-justify-content: center;
2099 | justify-content: center
2100 | }
2101 |
2102 | .m-indexFlash .right-item .price .price-origin20 .t:before,
2103 | .m-indexFlash .right-item .price .price-origin24 .t:before,
2104 | .m-indexFlash .right-item .price .price-origin28 .t:before {
2105 | content: '';
2106 | top: 0;
2107 | bottom: 0;
2108 | margin: auto;
2109 | width: 115%;
2110 | left: -.10667rem;
2111 | background: #fff
2112 | }
2113 |
2114 | .m-indexFlash .right-item .price .price-now20 {
2115 | font-size: .26667rem;
2116 | line-height: .26667rem;
2117 | height: .26667rem
2118 | }
2119 |
2120 | .m-indexFlash .right-item .price .price-now24 {
2121 | font-size: .32rem;
2122 | line-height: .32rem;
2123 | height: .32rem
2124 | }
2125 |
2126 | .m-indexFlash .right-item .price .price-now28 {
2127 | font-size: .37333rem;
2128 | line-height: .37333rem;
2129 | height: .37333rem
2130 | }
2131 |
2132 | .m-indexFlash .right-item .price .price-origin20 {
2133 | font-size: .26667rem;
2134 | line-height: .26667rem;
2135 | height: .26667rem
2136 | }
2137 |
2138 | .m-indexFlash .right-item .price .price-origin20 .t {
2139 | position: relative;
2140 | color: #fff
2141 | }
2142 |
2143 | .m-indexFlash .right-item .price .price-origin20 .t:before {
2144 | position: absolute;
2145 | height: 1px
2146 | }
2147 |
2148 | [data-dpr="1"] .m-indexFlash .right-item .price .price-origin20 .t:before {
2149 | -moz-transform: scale3d(1, .5, 1);
2150 | -webkit-transform: scale3d(1, .5, 1);
2151 | transform: scale3d(1, .5, 1)
2152 | }
2153 |
2154 | .m-indexFlash .right-item .price .price-origin24 {
2155 | font-size: .32rem;
2156 | line-height: .32rem;
2157 | height: .32rem
2158 | }
2159 |
2160 | .m-indexFlash .right-item .price .price-origin24 .t {
2161 | position: relative;
2162 | color: #fff
2163 | }
2164 |
2165 | .m-indexFlash .right-item .price .price-origin24 .t:before {
2166 | position: absolute;
2167 | height: 1px
2168 | }
2169 |
2170 | [data-dpr="1"] .m-indexFlash .right-item .price .price-origin24 .t:before {
2171 | -moz-transform: scale3d(1, .5, 1);
2172 | -webkit-transform: scale3d(1, .5, 1);
2173 | transform: scale3d(1, .5, 1)
2174 | }
2175 |
2176 | .m-indexFlash .right-item .price .price-origin28 {
2177 | font-size: .37333rem;
2178 | line-height: .37333rem;
2179 | height: .37333rem
2180 | }
2181 |
2182 | .m-indexFlash .right-item .price .price-origin28 .t {
2183 | position: relative;
2184 | color: #fff
2185 | }
2186 |
2187 | .m-indexFlash .right-item .price .price-origin28 .t:before {
2188 | position: absolute;
2189 | height: 1px
2190 | }
2191 |
2192 | .m-indexTopics .inner .list .item .error:before,
2193 | .m-indexTopics-slide .inner .list .item .error:before {
2194 | top: 0;
2195 | right: 0;
2196 | bottom: 0;
2197 | background-image: url(http://yanxuan.nosdn.127.net/f159d1b2ec1867ad1a73d5077fcca604.png);
2198 | background-repeat: no-repeat;
2199 | background-position: center;
2200 | background-size: 2.29333rem
2201 | }
2202 |
2203 | [data-dpr="1"] .m-indexFlash .right-item .price .price-origin28 .t:before {
2204 | -moz-transform: scale3d(1, .5, 1);
2205 | -webkit-transform: scale3d(1, .5, 1);
2206 | transform: scale3d(1, .5, 1)
2207 | }
2208 |
2209 | .m-indexFloor {
2210 | margin-bottom: .26667rem;
2211 | background-color: #fff
2212 | }
2213 |
2214 | .m-indexFloor .hr {
2215 | height: 1px;
2216 | background-color: #d9d9d9
2217 | }
2218 |
2219 | .m-indexFloor>.hd {
2220 | display: flex;
2221 | -webkit-flex-flow: row nowrap;
2222 | -moz-flex-flow: row nowrap;
2223 | -ms-flex-flow: row nowrap;
2224 | flex-flow: row nowrap;
2225 | -webkit-box-align: center;
2226 | -ms-flex-align: center;
2227 | -webkit-align-items: center;
2228 | -moz-align-items: center;
2229 | align-items: center;
2230 | -webkit-box-pack: center;
2231 | -ms-flex-pack: center;
2232 | -webkit-justify-content: center;
2233 | -moz-justify-content: center;
2234 | justify-content: center;
2235 | height: 1.46667rem;
2236 | font-size: .42667rem
2237 | }
2238 |
2239 | .m-indexFloor>.hd .more {
2240 | -webkit-box-align: center;
2241 | -ms-flex-align: center;
2242 | -webkit-align-items: center;
2243 | -moz-align-items: center;
2244 | align-items: center;
2245 | display: -webkit-box;
2246 | display: -webkit-flex;
2247 | display: -moz-flex;
2248 | display: -ms-flexbox;
2249 | display: flex;
2250 | -webkit-flex-flow: row nowrap;
2251 | -moz-flex-flow: row nowrap;
2252 | -ms-flex-flow: row nowrap;
2253 | flex-flow: row nowrap;
2254 | color: #333
2255 | }
2256 |
2257 | .m-indexFloor>.hd .more .icon {
2258 | margin-left: .13333rem
2259 | }
2260 |
2261 | .m-indexFloor-transparent {
2262 | background-color: transparent
2263 | }
2264 |
2265 | .m-indexManufacturersSupplying {
2266 | padding-bottom: .10667rem
2267 | }
2268 |
2269 | .m-indexManufacturersSupplying .list {
2270 | position: relative;
2271 | margin: 0 .21333rem;
2272 | height: 6.24rem;
2273 | overflow: hidden
2274 | }
2275 |
2276 | .m-indexManufacturersSupplying .list .item {
2277 | display: inline-block;
2278 | position: relative;
2279 | margin-bottom: .10667rem;
2280 | width: 4.73333rem;
2281 | height: 3.14667rem;
2282 | overflow: hidden;
2283 | background-color: #f4f4f4
2284 | }
2285 |
2286 | .m-indexManufacturersSupplying .list .item img,
2287 | .m-indexManufacturersSupplying .list .item>a {
2288 | width: 100%;
2289 | height: 100%
2290 | }
2291 |
2292 | .m-indexManufacturersSupplying .list .item .cnt {
2293 | position: absolute;
2294 | left: 0;
2295 | top: 0;
2296 | padding: .26667rem 0 0 .26667rem;
2297 | width: 100%;
2298 | z-index: 4
2299 | }
2300 |
2301 | .m-indexManufacturersSupplying .list .item .cnt .title {
2302 | text-overflow: ellipsis;
2303 | white-space: nowrap;
2304 | overflow: hidden;
2305 | color: #333;
2306 | font-size: .37333rem;
2307 | line-height: .45333rem;
2308 | margin-bottom: .08rem
2309 | }
2310 |
2311 | .m-indexManufacturersSupplying .list .item .cnt .price1 {
2312 | color: #333;
2313 | font-size: .37333rem;
2314 | line-height: .45333rem
2315 | }
2316 |
2317 | .m-indexManufacturersSupplying .list .item .cnt .price2 {
2318 | color: #333;
2319 | font-size: .32rem;
2320 | line-height: .45333rem
2321 | }
2322 |
2323 | .m-indexManufacturersSupplying .list .item .cnt .icon {
2324 | display: block;
2325 | margin-top: .13333rem
2326 | }
2327 |
2328 | .m-indexManufacturersSupplying .list .item:nth-child(1),
2329 | .m-indexManufacturersSupplying .list .item:nth-child(3) {
2330 | margin-right: .10667rem
2331 | }
2332 |
2333 | .m-indexTopics {
2334 | padding-bottom: .48rem;
2335 | overflow: hidden
2336 | }
2337 |
2338 | .m-indexTopics .inner {
2339 | overflow: visible
2340 | }
2341 |
2342 | .m-indexTopics .inner .list,
2343 | .m-indexTopics .inner .list .item {
2344 | width: 100%
2345 | }
2346 |
2347 | .m-indexTopics .inner .list .item .imgWrap {
2348 | display: block;
2349 | width: 100%;
2350 | height: 5.6rem;
2351 | margin-bottom: .30667rem;
2352 | overflow: hidden
2353 | }
2354 |
2355 | .m-indexTopics .inner .list .item .imgWrap img {
2356 | width: auto;
2357 | height: 100%;
2358 | position: relative;
2359 | left: 50%;
2360 | -moz-transform: translateX(-50%);
2361 | -ms-transform: translateX(-50%);
2362 | -webkit-transform: translateX(-50%);
2363 | transform: translateX(-50%)
2364 | }
2365 |
2366 | .m-indexTopics .inner .list .item .error {
2367 | position: relative
2368 | }
2369 |
2370 | .m-indexTopics .inner .list .item .error:before {
2371 | content: ' ';
2372 | display: block;
2373 | position: absolute;
2374 | z-index: 1;
2375 | left: 0;
2376 | background-color: #f4f4f4
2377 | }
2378 |
2379 | .m-indexTopics .inner .list .item .line1 {
2380 | overflow: visible;
2381 | margin-bottom: .16rem;
2382 | padding: 0 .4rem;
2383 | line-height: 1;
2384 | font-size: .42667rem;
2385 | zoom: 1
2386 | }
2387 |
2388 | .m-indexTopics .inner .list .item .line1:after {
2389 | display: block;
2390 | clear: both;
2391 | visibility: hidden;
2392 | height: 0;
2393 | overflow: hidden;
2394 | content: "."
2395 | }
2396 |
2397 | .m-indexTopics .inner .list .item .line1 .price {
2398 | float: right;
2399 | color: #b4282d
2400 | }
2401 |
2402 | .m-indexTopics .inner .list .item .desc {
2403 | padding: 0 .4rem;
2404 | font-size: .32rem;
2405 | line-height: 1;
2406 | color: #7F7F7F
2407 | }
2408 |
2409 | .m-indexTopics-slide {
2410 | padding: 0 .4rem .48rem;
2411 | overflow: hidden
2412 | }
2413 |
2414 | .m-indexTopics-slide .inner {
2415 | overflow: visible
2416 | }
2417 |
2418 | .m-indexTopics-slide .inner .list,
2419 | .m-indexTopics-slide .inner .list .item {
2420 | width: 7.66667rem
2421 | }
2422 |
2423 | .m-indexTopics-slide .inner .list .item .imgWrap {
2424 | display: block;
2425 | width: 7.66667rem;
2426 | height: 4.29333rem;
2427 | margin-bottom: .21333rem;
2428 | border-radius: 8px;
2429 | overflow: hidden
2430 | }
2431 |
2432 | [data-dpr="1"] .m-indexTopics-slide .inner .list .item .imgWrap {
2433 | border-radius: 4px
2434 | }
2435 |
2436 | .m-indexTopics-slide .inner .list .item .imgWrap img {
2437 | height: 100%;
2438 | width: auto;
2439 | position: relative;
2440 | left: 50%;
2441 | -moz-transform: translateX(-50%);
2442 | -ms-transform: translateX(-50%);
2443 | -webkit-transform: translateX(-50%);
2444 | transform: translateX(-50%)
2445 | }
2446 |
2447 | .m-indexTopics-slide .inner .list .item .error {
2448 | position: relative
2449 | }
2450 |
2451 | .m-indexTopics-slide .inner .list .item .error:before {
2452 | content: ' ';
2453 | display: block;
2454 | position: absolute;
2455 | z-index: 1;
2456 | left: 0;
2457 | background-color: #f4f4f4
2458 | }
2459 |
2460 | .m-indexTopics-slide .inner .list .item .line1 {
2461 | height: 41px;
2462 | margin-bottom: .02667rem;
2463 | zoom: 1
2464 | }
2465 |
2466 | .m-indexTopics-slide .inner .list .item .line1:after {
2467 | display: block;
2468 | clear: both;
2469 | visibility: hidden;
2470 | height: 0;
2471 | overflow: hidden;
2472 | content: "."
2473 | }
2474 |
2475 | .m-indexTopics-slide .inner .list .item .line1 .title {
2476 | white-space: nowrap;
2477 | overflow: hidden;
2478 | -ms-text-overflow: ellipsis;
2479 | -o-text-overflow: ellipsis;
2480 | text-overflow: ellipsis;
2481 | width: 5.46667rem;
2482 | float: left;
2483 | font-size: .37333rem
2484 | }
2485 |
2486 | .m-indexTopics-slide .inner .list .item .line1 .price {
2487 | float: right;
2488 | font-size: .37333rem;
2489 | color: #b4282d
2490 | }
2491 |
2492 | .m-indexTopics-slide .inner .list .item .desc {
2493 | white-space: nowrap;
2494 | overflow: hidden;
2495 | -ms-text-overflow: ellipsis;
2496 | -o-text-overflow: ellipsis;
2497 | text-overflow: ellipsis;
2498 | width: 7.66667rem;
2499 | font-size: .32rem;
2500 | color: #7F7F7F
2501 | }
2502 |
2503 | .m-newItems>.hd {
2504 | background: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/bitmap-d4f7b37e32.png);
2505 | background-size: 10rem 3.46667rem;
2506 | height: 3.46667rem;
2507 | margin-bottom: .42667rem;
2508 | position: relative
2509 | }
2510 |
2511 | .m-newItems>.hd>.more {
2512 | display: block;
2513 | text-align: center;
2514 | font-size: .48rem;
2515 | color: #8BA0B6
2516 | }
2517 |
2518 | .m-newItems>.hd>.more .all {
2519 | position: relative;
2520 | margin: .21333rem auto 0;
2521 | width: 3.2rem;
2522 | height: .74667rem;
2523 | font-size: .37333rem;
2524 | line-height: .74667rem;
2525 | background: #D8E5F1
2526 | }
2527 |
2528 | .m-newItems>.hd>.more .all .arrow-right {
2529 | position: absolute;
2530 | top: .22667rem;
2531 | background: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/indexNewArrow-f3b56d449b.png);
2532 | background-size: .13333rem .29333rem;
2533 | display: inline-block;
2534 | height: .29333rem;
2535 | width: .13333rem;
2536 | margin-left: .08rem
2537 | }
2538 |
2539 | .m-newItems>.hd>.more .wrap {
2540 | width: 1.70667rem;
2541 | display: inline-block;
2542 | text-align: left
2543 | }
2544 |
2545 | .m-popularItemList>.hd {
2546 | background: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/bitmap2-d626e0b52a.png);
2547 | background-size: 10rem 3.46667rem;
2548 | height: 3.46667rem;
2549 | margin-bottom: .42667rem;
2550 | position: relative
2551 | }
2552 |
2553 | .m-popularItemList>.hd>.more {
2554 | display: block;
2555 | text-align: center;
2556 | font-size: .48rem;
2557 | color: #B4A078
2558 | }
2559 |
2560 | .m-popularItemList>.hd>.more .all {
2561 | position: relative;
2562 | margin: .21333rem auto 0;
2563 | width: 3.2rem;
2564 | height: .74667rem;
2565 | font-size: .37333rem;
2566 | line-height: .74667rem;
2567 | background: #F4E9CB
2568 | }
2569 |
2570 | .m-popularItemList>.hd>.more .all .arrow-right {
2571 | position: absolute;
2572 | top: .22667rem;
2573 | background: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/indexPopularArrow-fb701819de.png);
2574 | background-size: .13333rem .29333rem;
2575 | display: inline-block;
2576 | height: .29333rem;
2577 | width: .13333rem;
2578 | margin-left: .08rem
2579 | }
2580 |
2581 | .m-popularItemList>.hd>.more .wrap {
2582 | width: 1.70667rem;
2583 | display: inline-block;
2584 | text-align: left
2585 | }
2586 |
2587 | .m-goodGrid-newItem,
2588 | .m-goodGrid-newItem .swiper-container,
2589 | .m-goodGrid-popularItem,
2590 | .m-goodGrid-popularItem .swiper-container {
2591 | height: 6.4rem
2592 | }
2593 |
2594 | .m-goodGrid-newItem .list,
2595 | .m-goodGrid-popularItem .list {
2596 | overflow: visible
2597 | }
2598 |
2599 | .m-goodGrid-newItem .list .item,
2600 | .m-goodGrid-popularItem .list .item {
2601 | padding: 0!important;
2602 | margin-left: .4rem;
2603 | width: 3.73333rem
2604 | }
2605 |
2606 | .m-goodGrid-newItem .list .item .tagWraper,
2607 | .m-goodGrid-popularItem .list .item .tagWraper {
2608 | width: 100%;
2609 | z-index: 1;
2610 | margin: 0 0 .21333rem;
2611 | height: .4rem;
2612 | overflow: hidden
2613 | }
2614 |
2615 | .m-goodGrid-newItem .list .item .status,
2616 | .m-goodGrid-popularItem .list .item .status {
2617 | height: .4rem;
2618 | padding: .06667rem .21333rem;
2619 | line-height: .26667rem;
2620 | text-align: center;
2621 | color: #fff;
2622 | font-size: .26667rem;
2623 | border-radius: .02667rem;
2624 | display: inline-block;
2625 | vertical-align: middle
2626 | }
2627 |
2628 | [data-dpr="1"] .m-goodGrid-newItem .list .item .status,
2629 | [data-dpr="1"] .m-goodGrid-popularItem .list .item .status {
2630 | border-radius: 2px;
2631 | line-height: .32rem
2632 | }
2633 |
2634 | .m-goodGrid-newItem .list .item .status.empty,
2635 | .m-goodGrid-popularItem .list .item .status.empty {
2636 | background-color: #c9c9c9
2637 | }
2638 |
2639 | .m-goodGrid-newItem .list .item .status.almostEmpty,
2640 | .m-goodGrid-popularItem .list .item .status.almostEmpty {
2641 | background-color: #b4282d
2642 | }
2643 |
2644 | .m-goodGrid-newItem .list .item .status.presale,
2645 | .m-goodGrid-popularItem .list .item .status.presale {
2646 | background-color: #f8b551
2647 | }
2648 |
2649 | .m-goodGrid-newItem .list .item .status.newItem,
2650 | .m-goodGrid-popularItem .list .item .status.newItem {
2651 | background-color: #cdb694
2652 | }
2653 |
2654 | .m-goodGrid-newItem .list .item .status.gradientPrice,
2655 | .m-goodGrid-newItem .list .item .status.presell,
2656 | .m-goodGrid-popularItem .list .item .status.gradientPrice,
2657 | .m-goodGrid-popularItem .list .item .status.presell {
2658 | background-color: #f48f18
2659 | }
2660 |
2661 | .m-goodGrid-newItem .list .item .status.anniversary,
2662 | .m-goodGrid-popularItem .list .item .status.anniversary {
2663 | background-color: #e5686d
2664 | }
2665 |
2666 | .m-goodGrid-newItem .list .item .tagWraper .status,
2667 | .m-goodGrid-popularItem .list .item .tagWraper .status {
2668 | margin-left: .16rem
2669 | }
2670 |
2671 | .m-goodGrid-newItem .list .item .manufacturerTag,
2672 | .m-goodGrid-popularItem .list .item .manufacturerTag {
2673 | position: absolute;
2674 | top: .26667rem;
2675 | left: .26667rem;
2676 | padding: 0 .2rem;
2677 | border: 1px solid #999;
2678 | font-size: .32rem;
2679 | line-height: .48rem;
2680 | color: #999;
2681 | z-index: 1;
2682 | border-radius: 4px
2683 | }
2684 |
2685 | [data-dpr="1"] .m-goodGrid-newItem .list .item .manufacturerTag,
2686 | [data-dpr="1"] .m-goodGrid-popularItem .list .item .manufacturerTag {
2687 | border: none
2688 | }
2689 |
2690 | [data-dpr="1"] .m-goodGrid-newItem .list .item .manufacturerTag:after,
2691 | [data-dpr="1"] .m-goodGrid-popularItem .list .item .manufacturerTag:after {
2692 | content: '';
2693 | position: absolute;
2694 | top: 0;
2695 | left: 0;
2696 | border: 1px solid #999;
2697 | -moz-box-sizing: border-box;
2698 | -webkit-box-sizing: border-box;
2699 | box-sizing: border-box;
2700 | width: 200%;
2701 | height: 200%;
2702 | -moz-transform: scale(.5);
2703 | -ms-transform: scale(.5);
2704 | -webkit-transform: scale(.5);
2705 | transform: scale(.5);
2706 | -moz-transform-origin: left top;
2707 | -ms-transform-origin: left top;
2708 | -webkit-transform-origin: left top;
2709 | transform-origin: left top;
2710 | border-radius: 4px
2711 | }
2712 |
2713 | .m-goodGrid-newItem .list .item .good,
2714 | .m-goodGrid-popularItem .list .item .good {
2715 | display: block
2716 | }
2717 |
2718 | .m-goodGrid-newItem .list .item .good .hd,
2719 | .m-goodGrid-popularItem .list .item .good .hd {
2720 | background-color: #f4f4f4
2721 | }
2722 |
2723 | .m-goodGrid-newItem .list .item .good .hd img,
2724 | .m-goodGrid-popularItem .list .item .good .hd img {
2725 | background-color: #f4f4f4;
2726 | top: 0;
2727 | left: 0;
2728 | width: 100%;
2729 | height: 100%
2730 | }
2731 |
2732 | .m-goodGrid-newItem .list .item .good .hd .wraper,
2733 | .m-goodGrid-popularItem .list .item .good .hd .wraper {
2734 | background-color: #f4f4f4;
2735 | border-radius: 4;
2736 | padding-bottom: 100%;
2737 | margin-bottom: .26667rem
2738 | }
2739 |
2740 | [data-dpr="1"] .m-goodGrid-newItem .list .item .good .hd .wraper,
2741 | [data-dpr="1"] .m-goodGrid-popularItem .list .item .good .hd .wraper {
2742 | border-radius: 2
2743 | }
2744 |
2745 | .m-goodGrid-newItem .list .item .good .hd .desc,
2746 | .m-goodGrid-popularItem .list .item .good .hd .desc {
2747 | display: none
2748 | }
2749 |
2750 | .m-goodGrid-newItem .list .item .good .name,
2751 | .m-goodGrid-popularItem .list .item .good .name {
2752 | margin-bottom: .13333rem;
2753 | padding: 0 .13333rem;
2754 | font-size: .37333rem;
2755 | line-height: .45333rem
2756 | }
2757 |
2758 | .m-goodGrid-newItem .list .item .good .newItemDesc,
2759 | .m-goodGrid-popularItem .list .item .good .newItemDesc {
2760 | display: block;
2761 | margin-bottom: .18667rem;
2762 | font-size: .32rem;
2763 | color: #7f7f7f;
2764 | line-height: .4rem;
2765 | white-space: nowrap;
2766 | text-overflow: ellipsis;
2767 | overflow: hidden;
2768 | padding: 0 .13333rem
2769 | }
2770 |
2771 | .m-goodGrid-newItem .list .item .good .price,
2772 | .m-goodGrid-popularItem .list .item .good .price {
2773 | padding: 0 .13333rem;
2774 | font-size: .37333rem
2775 | }
2776 |
2777 | .m-goodGrid-newItem .list .more,
2778 | .m-goodGrid-popularItem .list .more {
2779 | display: block;
2780 | border: .10667rem solid #F4F4F4;
2781 | width: 3.73333rem;
2782 | height: 3.73333rem;
2783 | margin: 0 .4rem;
2784 | line-height: 3.73333rem;
2785 | text-align: center
2786 | }
2787 |
2788 | .m-goodGrid-newItem .list .more .text,
2789 | .m-goodGrid-popularItem .list .more .text {
2790 | font-size: .37333rem;
2791 | color: #666
2792 | }
2793 |
2794 | .m-indexServicePolicy {
2795 | background: #fff
2796 | }
2797 |
2798 | .m-indexServicePolicy .g-grow {
2799 | width: 100%;
2800 | height: .96rem;
2801 | padding: 0 .4rem;
2802 | display: -webkit-box;
2803 | display: -webkit-flex;
2804 | display: -moz-flex;
2805 | display: -ms-flexbox;
2806 | display: flex;
2807 | -webkit-flex-flow: row nowrap;
2808 | -moz-flex-flow: row nowrap;
2809 | -ms-flex-flow: row nowrap;
2810 | flex-flow: row nowrap;
2811 | -webkit-box-align: center;
2812 | -ms-flex-align: center;
2813 | -webkit-align-items: center;
2814 | -moz-align-items: center;
2815 | align-items: center;
2816 | zoom: 1
2817 | }
2818 |
2819 | .m-indexServicePolicy .g-grow:after {
2820 | display: block;
2821 | clear: both;
2822 | visibility: hidden;
2823 | height: 0;
2824 | overflow: hidden;
2825 | content: "."
2826 | }
2827 |
2828 | .m-indexServicePolicy .item {
2829 | -webkit-box-flex: 1;
2830 | -webkit-flex: 1;
2831 | -moz-box-flex: 1;
2832 | -moz-flex: 1;
2833 | -ms-flex: 1;
2834 | flex: 1;
2835 | float: left
2836 | }
2837 |
2838 | .m-indexServicePolicy .item a {
2839 | display: inline-block;
2840 | vertical-align: middle;
2841 | height: .42667rem
2842 | }
2843 |
2844 | .m-indexServicePolicy .text {
2845 | font-size: .32rem;
2846 | color: #333;
2847 | margin-left: .10667rem;
2848 | line-height: .42667rem;
2849 | display: inline-block;
2850 | vertical-align: middle
2851 | }
2852 |
2853 | .slideWarp {
2854 | height: 5.33333rem;
2855 | position: relative
2856 | }
2857 |
2858 | .m-slide {
2859 | padding-top: 5.33333rem!important
2860 | }
2861 |
2862 | .hasTabBar {
2863 | padding-bottom: 1.30667rem
2864 | }
2865 |
2866 | .m-sale {
2867 | width: 10rem;
2868 | height: 4rem;
2869 | margin-bottom: .26667rem
2870 | }
2871 |
2872 | .m-sale a {
2873 | width: 100%;
2874 | height: 100%;
2875 | display: block
2876 | }
2877 |
--------------------------------------------------------------------------------
/src/components/Banner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |

10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
41 |
42 |
43 |
48 |
53 |
--------------------------------------------------------------------------------
/src/components/BottomNav.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/src/components/FloorOne.vue:
--------------------------------------------------------------------------------
1 |
2 |
61 |
62 |
--------------------------------------------------------------------------------
/src/components/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
网易严选
11 |
立即领取APP新人专享1000元礼包
12 |
13 |
14 |
打开APP
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | 搜索商品, 共10292款好物
23 |
24 |
25 |
36 |
37 |
38 |
39 |
40 |
58 |
63 |
--------------------------------------------------------------------------------
/src/entry-client.js:
--------------------------------------------------------------------------------
1 | import {
2 | createApp
3 | } from './app'
4 | import Q from 'q'
5 | import Vue from 'vue'
6 |
7 | Vue.mixin({
8 | beforeRouteUpdate(to, from, next) {
9 | const {
10 | asyncData
11 | } = this.$options
12 | if (asyncData) {
13 | asyncData({
14 | store: this.$store,
15 | route: to
16 | }).then(next).catch(next)
17 | } else {
18 | next()
19 | }
20 | }
21 | })
22 |
23 | const {
24 | app,
25 | router,
26 | store
27 | } = createApp()
28 |
29 | // 将服务端渲染时候的状态写入vuex中
30 | if (window.__INITIAL_STATE__) {
31 | store.replaceState(window.__INITIAL_STATE__)
32 | }
33 |
34 | router.onReady(() => {
35 | router.beforeResolve((to, from, next) => {
36 | const matched = router.getMatchedComponents(to)
37 | const prevMatched = router.getMatchedComponents(from)
38 | // 我们只关心之前没有渲染的组件
39 | // 所以我们对比它们,找出两个匹配列表的差异组件
40 | let diffed = false
41 | const activated = matched.filter((c, i) => {
42 | return diffed || (diffed = (prevMatched[i] !== c))
43 | })
44 | if (!activated.length) {
45 | return next()
46 | }
47 | // 这里如果有加载指示器(loading indicator),就触发
48 | Q.all(activated.map(c => {
49 | if (c.asyncData) {
50 | return c.asyncData({
51 | store,
52 | route: to
53 | })
54 | }
55 | })).then(() => {
56 | // 停止加载指示器(loading indicator)
57 | next()
58 | }).catch(next)
59 | })
60 | app.$mount('#app')
61 | })
62 |
63 | // service worker
64 | // if ('serviceWorker' in navigator) {
65 | // navigator.serviceWorker.register('/service-worker.js');
66 | // }
67 | if ('serviceWorker' in navigator) {
68 | console.log("SW present !!! ");
69 | navigator.serviceWorker.register('/service-worker.js', {
70 | //scope: '/toto/'
71 | }).then(function (registration) {
72 | console.log('Service worker registered : ', registration.scope);
73 | })
74 | .catch(function (err) {
75 | console.log("Service worker registration failed : ", err);
76 | });
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/entry-server.js:
--------------------------------------------------------------------------------
1 | import { createApp } from './app'
2 | import Q from 'q'
3 | export default context => {
4 | return new Q.Promise((resolve, reject) => {
5 | const { app, router, store } = createApp()
6 | router.push(context.url)
7 | router.onReady(() => {
8 | const matchedComponents = router.getMatchedComponents()
9 | if (!matchedComponents.length) {
10 | return reject({ code: 404 })
11 | }
12 | // 对所有匹配的路由组件调用 `asyncData()`
13 | Q.all(
14 | matchedComponents.map(Component => {
15 | if (Component.asyncData) {
16 | Component.asyncData({
17 | store,
18 | route: router.currentRoute
19 | }).then(() => {
20 | return
21 | })
22 | }
23 | })
24 | )
25 | .then(() => {
26 | // 在所有预取钩子(preFetch hook) resolve 后,
27 | // 我们的 store 现在已经填充入渲染应用程序所需的状态。
28 | // 当我们将状态附加到上下文,
29 | // 并且 `template` 选项用于 renderer 时,
30 | // 状态将自动序列化为 `window.__INITIAL_STATE__`,并注入 HTML。
31 | context.state = store.state
32 | resolve(app)
33 | })
34 | .catch(reject)
35 | }, reject)
36 | })
37 | }
38 |
--------------------------------------------------------------------------------
/src/index.template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 | {{ title }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/public/conf.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 系统 配置项
3 | */
4 | export default {
5 | HOST: "https://123.baidu.com",
6 | DEBUGMOCK: true && process.env.STATS === 'dev'
7 | }
8 |
--------------------------------------------------------------------------------
/src/public/utils/api.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import qs from 'qs'
3 | import Q from 'q'
4 | /**
5 | * 兼容 不支持promise 的低版本浏览器
6 | */
7 | require('es6-promise').polyfill();
8 | import C from '../conf'
9 |
10 | axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
11 | axios.defaults.withCredentials = true
12 |
13 | function ajax(url, type, options) {
14 |
15 | return Q.Promise((resolve, reject) => {
16 | axios({
17 | method: type,
18 | url: C.HOST + url,
19 | params: type === 'get' ? options : null,
20 | data: type !== 'get' ? qs.stringify(options) : null
21 | })
22 | .then((result) => {
23 | if (result && result.status === 401) {
24 | // location.href = '/views/401.html'
25 | }
26 | if (result && result.status === 200) {
27 | if (result.data.code === 200) {
28 | resolve(result.data.data);
29 | } else if (result.data.code === 401) {
30 | reject({
31 | nopms: true,
32 | msg: result.data.msg
33 | });
34 | } else {
35 | reject({
36 | error: true,
37 | msg: result.data.msg
38 | });
39 | }
40 | } else {
41 | reject({
42 | errno: result.errno,
43 | msg: result.msg
44 | });
45 | }
46 | })
47 | .catch(function(error) {
48 | console.log(error, url);
49 | });
50 | })
51 | }
52 |
53 | const config = {
54 | get(url, options) {
55 | return Q.Promise((resolve, reject) => {
56 | ajax(url, 'get', options)
57 | .then((data) => {
58 | resolve(data);
59 | }, (error) => {
60 | reject(error);
61 | });
62 | })
63 | },
64 |
65 | post(url, options) {
66 | return Q.Promise((resolve, reject) => {
67 | ajax(url, 'post', options)
68 | .then((data) => {
69 | resolve(data);
70 | }, (error) => {
71 | reject(error);
72 | });
73 | })
74 | },
75 |
76 | put(url, options) {
77 | return Q.Promise((resolve, reject) => {
78 | ajax(url, 'put', options)
79 | .then((data) => {
80 | resolve(data);
81 | }, (error) => {
82 | reject(error);
83 | });
84 | })
85 | },
86 |
87 | delete(url, options) {
88 | return Q.Promise((resolve, reject) => {
89 | ajax(url, 'delete', options)
90 | .then((data) => {
91 | resolve(data);
92 | }, (error) => {
93 | reject(error);
94 | });
95 | })
96 | },
97 |
98 | jsonp(url, options) {
99 | return Q.Promise((resolve, reject) => {
100 | ajax(url, 'jsonp', options)
101 | .then((data) => {
102 | resolve(data);
103 | }, (error) => {
104 | reject(error);
105 | });
106 | })
107 | }
108 | };
109 |
110 | export default config;
111 |
--------------------------------------------------------------------------------
/src/public/utils/confUtils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * [mergeMock 函数]
3 | * @param {[type]} pMock [页面开关]
4 | * @param {[type]} mMock [模块开关]
5 | * @return {[merge 后对象]}
6 | */
7 | import S from '../conf'
8 |
9 | export const mergeMock = function(pMock, mMock) {
10 | for (let item in mMock) {
11 | mMock[item].MOCK = S.DEBUGMOCK && pMock && mMock[item].MOCK;
12 | }
13 | return mMock;
14 | }
15 |
16 | /**
17 | * 初始化 mock
18 | */
19 | export const initMock = function(Mock, CONF, mockData) {
20 |
21 | return function() {
22 | const ts = ['GET', 'PUT', 'DELETE', 'POST'],
23 | m = Object.keys(mockData)[0];
24 | for (let key in CONF[m]['API']) {
25 | const t = key.split('_')[0];
26 | const type = ts.indexOf(t) !== -1 ? t : 'GET';
27 | if ('GET' === type) {
28 | const _urlString = m + '/' + (new Date().getTime()) + '/' + t + '/';
29 | CONF[m]['API'][key] = _urlString;
30 | Mock.mock(new RegExp(S.HOST + _urlString), type.toLocaleLowerCase(), mockData[m]['API'][key]);
31 | } else {
32 | Mock.mock(S.HOST + CONF[m]['API'][key], type.toLocaleLowerCase(), mockData[m]['API'][key]);
33 | }
34 | }
35 | }()
36 | }
37 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router';
3 | Vue.use(Router)
4 | export function createRouter() {
5 | return new Router({
6 | mode: 'history',
7 | routes: [{
8 | name:'Home',
9 | path: '/',
10 | component: () =>
11 | import ('../views/index/index.vue')
12 | }]
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/src/static/img/demo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wqzwh/vue-ssr/cca3e361f4921312c02fdb6ad66af1cf7c95d2c1/src/static/img/demo.jpeg
--------------------------------------------------------------------------------
/src/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wqzwh/vue-ssr/cca3e361f4921312c02fdb6ad66af1cf7c95d2c1/src/static/img/favicon.ico
--------------------------------------------------------------------------------
/src/static/img/service-demo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wqzwh/vue-ssr/cca3e361f4921312c02fdb6ad66af1cf7c95d2c1/src/static/img/service-demo.jpeg
--------------------------------------------------------------------------------
/src/static/js/flexible.js:
--------------------------------------------------------------------------------
1 | !function(e,t){function i(){var t=n.getBoundingClientRect().width;t/s>540&&(t=540*s);var i=t/10;n.style.fontSize=i+"px",d.rem=e.rem=i}var a,r=e.document,n=r.documentElement,o=r.querySelector('meta[name="viewport"]'),l=r.querySelector('meta[name="flexible"]'),s=0,m=0,d=t.flexible||(t.flexible={});if(o){console.warn("将根据已有的meta标签来设置缩放比例");var c=o.getAttribute("content").match(/initial\-scale=([\d\.]+)/);c&&(m=parseFloat(c[1]),s=parseInt(1/m))}else if(l){var p=l.getAttribute("content");if(p){var u=p.match(/initial\-dpr=([\d\.]+)/),f=p.match(/maximum\-dpr=([\d\.]+)/);u&&(s=parseFloat(u[1]),m=parseFloat((1/s).toFixed(2))),f&&(s=parseFloat(f[1]),m=parseFloat((1/s).toFixed(2)))}}if(!s&&!m){var v=(e.navigator.appVersion.match(/android/gi),e.navigator.appVersion.match(/iphone/gi)),b=e.devicePixelRatio;s=v?b>=3&&(!s||s>=3)?3:b>=2&&(!s||s>=2)?2:1:1,m=1/s}if(n.setAttribute("data-dpr",s),!o)if(o=r.createElement("meta"),o.setAttribute("name","viewport"),e.webPageScalable?o.setAttribute("content","initial-scale="+m+", user-scalable=yes"):o.setAttribute("content","initial-scale="+m+", maximum-scale="+m+", minimum-scale="+m+", user-scalable=no"),n.firstElementChild)n.firstElementChild.appendChild(o);else{var h=r.createElement("div");h.appendChild(o),r.write(h.innerHTML)}e.addEventListener("resize",function(){clearTimeout(a),a=setTimeout(i,300)},!1),e.addEventListener("pageshow",function(e){e.persisted&&(clearTimeout(a),a=setTimeout(i,300))},!1),"complete"===r.readyState?r.body.style.fontSize=12*s+"px":r.addEventListener("DOMContentLoaded",function(e){r.body.style.fontSize=12*s+"px"},!1),i(),d.dpr=e.dpr=s,d.refreshRem=i,d.rem2px=function(e){var t=parseFloat(e)*this.rem;return"string"==typeof e&&e.match(/rem$/)&&(t+="px"),t},d.px2rem=function(e){var t=parseFloat(e)/this.rem;return"string"==typeof e&&e.match(/px$/)&&(t+="rem"),t}}(window,window.lib||(window.lib={}));
--------------------------------------------------------------------------------
/src/store/actions.js:
--------------------------------------------------------------------------------
1 | const makeAction = type => {
2 | return ({ commit }, ...args) => commit(type, ...args)
3 | }
4 |
5 | // global actions
6 | export const setLginInfo = makeAction('SET_LOGIN_INFO')
7 | // 入口组件首次出发的action
8 | export const getData = makeAction('GET_DATA')
9 |
--------------------------------------------------------------------------------
/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | // store.js
2 | import Vue from 'vue'
3 | import Vuex from 'vuex'
4 | import * as actions from './actions'
5 | import getters from './getters'
6 | import modules from './modules/index'
7 | Vue.use(Vuex)
8 | export function createStore() {
9 | return new Vuex.Store({
10 | actions,
11 | getters,
12 | modules,
13 | strict: false
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/src/store/modules/global.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 | import * as types from '../mutation-types'
3 |
4 | const state = {
5 | loginfo: {},
6 | data: {}
7 | }
8 |
9 | const mutations = {
10 | [types.SET_LOGIN_INFO](state, params) {
11 | state.loginfo = _.clone(params)
12 | },
13 | [types.GET_DATA](state, params) {
14 | state.data = _.clone(params.data)
15 | }
16 | }
17 |
18 | export default {
19 | state,
20 | mutations
21 | }
22 |
--------------------------------------------------------------------------------
/src/store/modules/index.js:
--------------------------------------------------------------------------------
1 | const files = require.context('.', false, /\.js$/)
2 | const modules = {}
3 |
4 | files.keys().forEach((key) => {
5 | if (key === './index.js') return
6 | modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
7 | })
8 |
9 | export default modules
10 |
--------------------------------------------------------------------------------
/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const SET_LOGIN_INFO = 'SET_LOGIN_INFO'
2 | export const GET_DATA = 'GET_DATA'
3 |
--------------------------------------------------------------------------------
/src/views/index/conf.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 系统级配置
3 | */
4 | import {mergeMock} from '../../public/utils/confUtils'
5 | /**
6 | * 页面级 MOCK 开关
7 | */
8 | const PAGEMOCK = true;
9 | /**
10 | * 页面模块级 配置项
11 | * 注意,请求方式 默认是GET、其他特殊格式命名必须 如 PUT_STATUS '_' 链接 ,第一个字段为请求类型
12 | */
13 | const MODULECONF = {
14 | index: {
15 | NAME: '首页',
16 | MOCK: true,
17 | API: {
18 | GET: '/api/home',
19 | GETBOTTOM: '/api/home',
20 | }
21 | }
22 | };
23 |
24 | export default mergeMock(PAGEMOCK, MODULECONF);
25 |
--------------------------------------------------------------------------------
/src/views/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
63 |
68 |
--------------------------------------------------------------------------------
/src/views/index/mock.js:
--------------------------------------------------------------------------------
1 | import Mock from 'mockjs';
2 | import CONF from './conf';
3 | import { initMock } from '@/public/utils/confUtils';
4 |
5 | const mData = {
6 | index: {
7 | API: {
8 | GET: {
9 | "code": 200,
10 | "data": [
11 | {
12 | name: '推荐',
13 | type: 0
14 | },
15 | {
16 | name: '居家',
17 | type: 1
18 | },
19 | {
20 | name: '餐厨',
21 | type: 2
22 | },
23 | {
24 | name: '服装',
25 | type: 3
26 | },
27 | {
28 | name: '电器',
29 | type: 4
30 | },
31 | {
32 | name: '洗护',
33 | type: 5
34 | },
35 | {
36 | name: '杂货',
37 | type: 6
38 | }
39 | ]
40 | },
41 | GETBOTTOM: {
42 | "code": 200,
43 | "data": [
44 | {
45 | href: '/',
46 | value: '首页',
47 | type: 'index'
48 | },
49 | {
50 | href: '/',
51 | value: '识物',
52 | type: 'topic'
53 | },
54 | {
55 | href: '/',
56 | value: '分类',
57 | type: 'cate'
58 | },
59 | {
60 | href: '/',
61 | value: '购物车',
62 | type: 'cart'
63 | },
64 | {
65 | href: '/',
66 | value: '个人',
67 | type: 'ucenter'
68 | }
69 | ]
70 | }
71 | }
72 | }
73 | }
74 | /**
75 | * 接受参数,动态创建
76 | */
77 | export default initMock(Mock, CONF, mData)
78 |
--------------------------------------------------------------------------------
/src/views/index/service.js:
--------------------------------------------------------------------------------
1 | import Q from 'q';
2 | import CONF from './conf';
3 | import API from '@/public/utils/api';
4 |
5 | const M = CONF['index'];
6 |
7 | if (process.env.STATS === 'dev') M.MOCK ? require('./mock') : '';
8 |
9 | export default {
10 | get(params = {}) {
11 | return Q.Promise((resolve, reject) => {
12 | API.get(M['API']['GET'], params).then((data) => {
13 | resolve(data);
14 | });
15 | });
16 | },
17 | getBottom(params = {}) {
18 | return Q.Promise((resolve, reject) => {
19 | API.get(M['API']['GETBOTTOM'], params).then((data) => {
20 | resolve(data);
21 | });
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------