├── .babelrc
├── .editorconfig
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
├── build.js
├── check-versions.js
├── dev-client.js
├── dev-server.js
├── utils.js
├── vue-loader.conf.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
└── webpack.prod.conf.js
├── config
├── dev.env.js
├── index.js
└── prod.env.js
├── img
├── 1.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
└── 5.jpg
├── index.html
├── mock
├── data
│ ├── cityhomehot.js
│ ├── comment.js
│ ├── details.js
│ ├── homehot.js
│ ├── homehot2.js
│ ├── order.js
│ └── searchdata.js
├── index.js
└── router.js
├── package.json
├── package.swan.json
├── project.config.json
├── project.swan.json
├── src
├── App.vue
├── app.json
├── components
│ ├── HomeHotView.vue
│ ├── ShopListView.vue
│ ├── card.vue
│ ├── headnav.vue
│ └── myswiper.vue
├── config
│ └── index.js
├── main.js
├── pages
│ ├── counter
│ │ ├── index.vue
│ │ ├── main.js
│ │ └── store.js
│ ├── details
│ │ ├── index.vue
│ │ ├── main.js
│ │ └── main.json
│ ├── index
│ │ ├── index.vue
│ │ ├── main.js
│ │ ├── main.json
│ │ └── subpage
│ │ │ └── homehot.vue
│ ├── logs
│ │ ├── index.vue
│ │ ├── main.js
│ │ └── main.json
│ ├── mine
│ │ ├── index.vue
│ │ ├── main.js
│ │ └── main.json
│ ├── search
│ │ ├── index.vue
│ │ ├── main.js
│ │ └── main.json
│ ├── service
│ │ ├── index.vue
│ │ ├── main.js
│ │ └── main.json
│ └── shop
│ │ ├── index.vue
│ │ ├── main.js
│ │ ├── main.json
│ │ └── subpage
│ │ └── shoplist.vue
├── store
│ └── index.js
└── utils
│ └── index.js
└── static
├── .gitkeep
├── images
├── banner1.png
├── banner2.png
├── banner3.png
├── banner4.png
├── banner5.png
├── banner6.png
├── car.png
├── deploymentunit.png
├── search.png
└── user.png
└── tabs
├── home.png
├── home_select.png
├── reconciliation.png
├── reconciliation_select.png
├── shop.png
├── shop_select.png
├── team.png
└── team_select.png
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-runtime"],
12 | "env": {
13 | "test": {
14 | "presets": ["env", "stage-2"],
15 | "plugins": ["istanbul"]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.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
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | *.suo
11 | *.ntvs*
12 | *.njsproj
13 | *.sln
14 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-mpvue-wxss": {}
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # livable
2 |
3 | > A Mpvue project
4 |
5 | ## 技术点
6 | 1. 底部导航(tabBar)
7 | 2. swiper
8 | 3. 位置获取
9 | 4. 腾讯地图lbs
10 | 5. 搜索功能
11 | 6. 页面跳转
12 | 7. mock处理数据
13 | 8. 上拉加载
14 | 9. tab切换
15 | 10. 个人信息获取
16 | 11. Vuex共享城市信息
17 |
18 | ## 存在问题
19 | 1. swiper无法显示导航点
20 |
21 |
22 | ## Build Setup
23 |
24 | ``` bash
25 | # 初始化项目
26 | vue init mpvue/mpvue-quickstart myproject
27 | cd myproject
28 |
29 | # 安装依赖
30 | yarn
31 |
32 | # 开发时构建
33 | npm dev
34 | cd mock
35 | node index.js
36 |
37 | # 打包构建
38 | npm build
39 |
40 | # 指定平台的开发时构建(微信、百度、头条、支付宝)
41 | npm dev:wx
42 | npm dev:swan
43 | npm dev:tt
44 | npm dev:my
45 |
46 | # 指定平台的打包构建
47 | npm build:wx
48 | npm build:swan
49 | npm build:tt
50 | npm build:my
51 |
52 | # 生成 bundle 分析报告
53 | npm run build --report
54 | ```
55 |
56 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | process.env.NODE_ENV = 'production'
4 | process.env.PLATFORM = process.argv[process.argv.length - 1] || 'wx'
5 |
6 | var ora = require('ora')
7 | var rm = require('rimraf')
8 | var path = require('path')
9 | var chalk = require('chalk')
10 | var webpack = require('webpack')
11 | var config = require('../config')
12 | var webpackConfig = require('./webpack.prod.conf')
13 | var utils = require('./utils')
14 |
15 | var spinner = ora('building for production...')
16 | spinner.start()
17 |
18 | rm(path.join(config.build.assetsRoot, '*'), err => {
19 | if (err) throw err
20 | webpack(webpackConfig, function (err, stats) {
21 | spinner.stop()
22 | if (err) throw err
23 | if (process.env.PLATFORM === 'swan') {
24 | utils.writeFrameworkinfo()
25 | }
26 | process.stdout.write(stats.toString({
27 | colors: true,
28 | modules: false,
29 | children: false,
30 | chunks: false,
31 | chunkModules: false
32 | }) + '\n\n')
33 |
34 | if (stats.hasErrors()) {
35 | console.log(chalk.red(' Build failed with errors.\n'))
36 | process.exit(1)
37 | }
38 |
39 | console.log(chalk.cyan(' Build complete.\n'))
40 | console.log(chalk.yellow(
41 | ' Tip: built files are meant to be served over an HTTP server.\n' +
42 | ' Opening index.html over file:// won\'t work.\n'
43 | ))
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | var chalk = require('chalk')
2 | var semver = require('semver')
3 | var packageConfig = require('../package.json')
4 | var shell = require('shelljs')
5 | function exec (cmd) {
6 | return require('child_process').execSync(cmd).toString().trim()
7 | }
8 |
9 | var versionRequirements = [
10 | {
11 | name: 'node',
12 | currentVersion: semver.clean(process.version),
13 | versionRequirement: packageConfig.engines.node
14 | }
15 | ]
16 |
17 | if (shell.which('npm')) {
18 | versionRequirements.push({
19 | name: 'npm',
20 | currentVersion: exec('npm --version'),
21 | versionRequirement: packageConfig.engines.npm
22 | })
23 | }
24 |
25 | module.exports = function () {
26 | var warnings = []
27 | for (var i = 0; i < versionRequirements.length; i++) {
28 | var mod = versionRequirements[i]
29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
30 | warnings.push(mod.name + ': ' +
31 | chalk.red(mod.currentVersion) + ' should be ' +
32 | chalk.green(mod.versionRequirement)
33 | )
34 | }
35 | }
36 |
37 | if (warnings.length) {
38 | console.log('')
39 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
40 | console.log()
41 | for (var i = 0; i < warnings.length; i++) {
42 | var warning = warnings[i]
43 | console.log(' ' + warning)
44 | }
45 | console.log()
46 | process.exit(1)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('eventsource-polyfill')
3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4 |
5 | hotClient.subscribe(function (event) {
6 | if (event.action === 'reload') {
7 | window.location.reload()
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/build/dev-server.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | process.env.PLATFORM = process.argv[process.argv.length - 1] || 'wx'
4 | var config = require('../config')
5 | if (!process.env.NODE_ENV) {
6 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
7 | }
8 |
9 | // var opn = require('opn')
10 | var path = require('path')
11 | var express = require('express')
12 | var webpack = require('webpack')
13 | var proxyMiddleware = require('http-proxy-middleware')
14 | var portfinder = require('portfinder')
15 | var webpackConfig = require('./webpack.dev.conf')
16 | var utils = require('./utils')
17 |
18 | // default port where dev server listens for incoming traffic
19 | var port = process.env.PORT || config.dev.port
20 | // automatically open browser, if not set will be false
21 | var autoOpenBrowser = !!config.dev.autoOpenBrowser
22 | // Define HTTP proxies to your custom API backend
23 | // https://github.com/chimurai/http-proxy-middleware
24 | var proxyTable = config.dev.proxyTable
25 |
26 | var app = express()
27 | var compiler = webpack(webpackConfig)
28 | if (process.env.PLATFORM === 'swan') {
29 | utils.writeFrameworkinfo()
30 | }
31 |
32 | // var devMiddleware = require('webpack-dev-middleware')(compiler, {
33 | // publicPath: webpackConfig.output.publicPath,
34 | // quiet: true
35 | // })
36 |
37 | // var hotMiddleware = require('webpack-hot-middleware')(compiler, {
38 | // log: false,
39 | // heartbeat: 2000
40 | // })
41 | // force page reload when html-webpack-plugin template changes
42 | // compiler.plugin('compilation', function (compilation) {
43 | // compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
44 | // hotMiddleware.publish({ action: 'reload' })
45 | // cb()
46 | // })
47 | // })
48 |
49 | // proxy api requests
50 | Object.keys(proxyTable).forEach(function (context) {
51 | var options = proxyTable[context]
52 | if (typeof options === 'string') {
53 | options = { target: options }
54 | }
55 | app.use(proxyMiddleware(options.filter || context, options))
56 | })
57 |
58 | // handle fallback for HTML5 history API
59 | app.use(require('connect-history-api-fallback')())
60 |
61 | // serve webpack bundle output
62 | // app.use(devMiddleware)
63 |
64 | // enable hot-reload and state-preserving
65 | // compilation error display
66 | // app.use(hotMiddleware)
67 |
68 | // serve pure static assets
69 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
70 | app.use(staticPath, express.static('./static'))
71 |
72 | // var uri = 'http://localhost:' + port
73 |
74 | var _resolve
75 | var readyPromise = new Promise(resolve => {
76 | _resolve = resolve
77 | })
78 |
79 | // console.log('> Starting dev server...')
80 | // devMiddleware.waitUntilValid(() => {
81 | // console.log('> Listening at ' + uri + '\n')
82 | // // when env is testing, don't need open it
83 | // if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
84 | // opn(uri)
85 | // }
86 | // _resolve()
87 | // })
88 |
89 | module.exports = new Promise((resolve, reject) => {
90 | portfinder.basePort = port
91 | portfinder.getPortPromise()
92 | .then(newPort => {
93 | if (port !== newPort) {
94 | console.log(`${port}端口被占用,开启新端口${newPort}`)
95 | }
96 | var server = app.listen(newPort, 'localhost')
97 | // for 小程序的文件保存机制
98 | require('webpack-dev-middleware-hard-disk')(compiler, {
99 | publicPath: webpackConfig.output.publicPath,
100 | quiet: true
101 | })
102 | resolve({
103 | ready: readyPromise,
104 | close: () => {
105 | server.close()
106 | }
107 | })
108 | }).catch(error => {
109 | console.log('没有找到空闲端口,请打开任务管理器杀死进程端口再试', error)
110 | })
111 | })
112 |
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var fs = require('fs')
3 | var config = require('../config')
4 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | var mpvueInfo = require('../node_modules/mpvue/package.json')
6 | var packageInfo = require('../package.json')
7 | var mkdirp = require('mkdirp')
8 |
9 | exports.assetsPath = function (_path) {
10 | var assetsSubDirectory = process.env.NODE_ENV === 'production'
11 | ? config.build.assetsSubDirectory
12 | : config.dev.assetsSubDirectory
13 | return path.posix.join(assetsSubDirectory, _path)
14 | }
15 |
16 | exports.cssLoaders = function (options) {
17 | options = options || {}
18 |
19 | var cssLoader = {
20 | loader: 'css-loader',
21 | options: {
22 | minimize: process.env.NODE_ENV === 'production',
23 | sourceMap: options.sourceMap
24 | }
25 | }
26 |
27 | var postcssLoader = {
28 | loader: 'postcss-loader',
29 | options: {
30 | sourceMap: true
31 | }
32 | }
33 |
34 | var px2rpxLoader = {
35 | loader: 'px2rpx-loader',
36 | options: {
37 | baseDpr: 1,
38 | rpxUnit: 0.5
39 | }
40 | }
41 |
42 | // generate loader string to be used with extract text plugin
43 | function generateLoaders (loader, loaderOptions) {
44 | var loaders = [cssLoader, px2rpxLoader, postcssLoader]
45 | if (loader) {
46 | loaders.push({
47 | loader: loader + '-loader',
48 | options: Object.assign({}, loaderOptions, {
49 | sourceMap: options.sourceMap
50 | })
51 | })
52 | }
53 |
54 | // Extract CSS when that option is specified
55 | // (which is the case during production build)
56 | if (options.extract) {
57 | return ExtractTextPlugin.extract({
58 | use: loaders,
59 | fallback: 'vue-style-loader'
60 | })
61 | } else {
62 | return ['vue-style-loader'].concat(loaders)
63 | }
64 | }
65 |
66 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
67 | return {
68 | css: generateLoaders(),
69 | wxss: generateLoaders(),
70 | postcss: generateLoaders(),
71 | less: generateLoaders('less'),
72 | sass: generateLoaders('sass', { indentedSyntax: true }),
73 | scss: generateLoaders('sass'),
74 | stylus: generateLoaders('stylus'),
75 | styl: generateLoaders('stylus')
76 | }
77 | }
78 |
79 | // Generate loaders for standalone style files (outside of .vue)
80 | exports.styleLoaders = function (options) {
81 | var output = []
82 | var loaders = exports.cssLoaders(options)
83 | for (var extension in loaders) {
84 | var loader = loaders[extension]
85 | output.push({
86 | test: new RegExp('\\.' + extension + '$'),
87 | use: loader
88 | })
89 | }
90 | return output
91 | }
92 |
93 | const writeFile = async (filePath, content) => {
94 | let dir = path.dirname(filePath)
95 | let exist = fs.existsSync(dir)
96 | if (!exist) {
97 | await mkdirp(dir)
98 | }
99 | await fs.writeFileSync(filePath, content, 'utf8')
100 | }
101 |
102 | exports.writeFrameworkinfo = function () {
103 | var buildInfo = {
104 | 'toolName': mpvueInfo.name,
105 | 'toolFrameWorkVersion': mpvueInfo.version,
106 | 'toolCliVersion': packageInfo.mpvueTemplateProjectVersion || '',
107 | 'createTime': Date.now()
108 | }
109 |
110 | var content = JSON.stringify(buildInfo)
111 | var fileName = '.frameworkinfo'
112 | var rootDir = path.resolve(__dirname, `../${fileName}`)
113 | var distDir = path.resolve(config.build.assetsRoot, `./${fileName}`)
114 |
115 | writeFile(rootDir, content)
116 | writeFile(distDir, content)
117 | }
118 |
--------------------------------------------------------------------------------
/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var config = require('../config')
3 | // var isProduction = process.env.NODE_ENV === 'production'
4 | // for mp
5 | var isProduction = true
6 |
7 | module.exports = {
8 | loaders: utils.cssLoaders({
9 | sourceMap: isProduction
10 | ? config.build.productionSourceMap
11 | : config.dev.cssSourceMap,
12 | extract: isProduction
13 | }),
14 | transformToRequire: {
15 | video: 'src',
16 | source: 'src',
17 | img: 'src',
18 | image: 'xlink:href'
19 | },
20 | fileExt: config.build.fileExt
21 | }
22 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var fs = require('fs')
3 | var utils = require('./utils')
4 | var config = require('../config')
5 | var webpack = require('webpack')
6 | var merge = require('webpack-merge')
7 | var vueLoaderConfig = require('./vue-loader.conf')
8 | var MpvuePlugin = require('webpack-mpvue-asset-plugin')
9 | var glob = require('glob')
10 | var CopyWebpackPlugin = require('copy-webpack-plugin')
11 | var relative = require('relative')
12 |
13 | function resolve (dir) {
14 | return path.join(__dirname, '..', dir)
15 | }
16 |
17 | function getEntry (rootSrc) {
18 | var map = {};
19 | glob.sync(rootSrc + '/pages/**/main.js')
20 | .forEach(file => {
21 | var key = relative(rootSrc, file).replace('.js', '');
22 | map[key] = file;
23 | })
24 | return map;
25 | }
26 |
27 | const appEntry = { app: resolve('./src/main.js') }
28 | const pagesEntry = getEntry(resolve('./src'), 'pages/**/main.js')
29 | const entry = Object.assign({}, appEntry, pagesEntry)
30 |
31 | let baseWebpackConfig = {
32 | // 如果要自定义生成的 dist 目录里面的文件路径,
33 | // 可以将 entry 写成 {'toPath': 'fromPath'} 的形式,
34 | // toPath 为相对于 dist 的路径, 例:index/demo,则生成的文件地址为 dist/index/demo.js
35 | entry,
36 | target: require('mpvue-webpack-target'),
37 | output: {
38 | path: config.build.assetsRoot,
39 | jsonpFunction: 'webpackJsonpMpvue',
40 | filename: '[name].js',
41 | publicPath: process.env.NODE_ENV === 'production'
42 | ? config.build.assetsPublicPath
43 | : config.dev.assetsPublicPath
44 | },
45 | resolve: {
46 | extensions: ['.js', '.vue', '.json'],
47 | alias: {
48 | 'vue': 'mpvue',
49 | '@': resolve('src')
50 | },
51 | symlinks: false,
52 | aliasFields: ['mpvue', 'weapp', 'browser'],
53 | mainFields: ['browser', 'module', 'main']
54 | },
55 | module: {
56 | rules: [
57 | {
58 | test: /\.vue$/,
59 | loader: 'mpvue-loader',
60 | options: vueLoaderConfig
61 | },
62 | {
63 | test: /\.js$/,
64 | include: [resolve('src'), resolve('test')],
65 | use: [
66 | 'babel-loader',
67 | {
68 | loader: 'mpvue-loader',
69 | options: Object.assign({checkMPEntry: true}, vueLoaderConfig)
70 | },
71 | ]
72 | },
73 | {
74 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
75 | loader: 'url-loader',
76 | options: {
77 | limit: 10000,
78 | name: utils.assetsPath('img/[name].[ext]')
79 | }
80 | },
81 | {
82 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
83 | loader: 'url-loader',
84 | options: {
85 | limit: 10000,
86 | name: utils.assetsPath('media/[name].[ext]')
87 | }
88 | },
89 | {
90 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
91 | loader: 'url-loader',
92 | options: {
93 | limit: 10000,
94 | name: utils.assetsPath('fonts/[name].[ext]')
95 | }
96 | }
97 | ]
98 | },
99 | plugins: [
100 | // api 统一桥协议方案
101 | new webpack.DefinePlugin({
102 | 'mpvue': 'global.mpvue',
103 | 'mpvuePlatform': 'global.mpvuePlatform'
104 | }),
105 | new MpvuePlugin(),
106 | new CopyWebpackPlugin([{
107 | from: '**/*.json',
108 | to: ''
109 | }], {
110 | context: 'src/'
111 | }),
112 | new CopyWebpackPlugin([
113 | {
114 | from: path.resolve(__dirname, '../static'),
115 | to: path.resolve(config.build.assetsRoot, './static'),
116 | ignore: ['.*']
117 | }
118 | ])
119 | ]
120 | }
121 |
122 | // 针对百度小程序,由于不支持通过 miniprogramRoot 进行自定义构建完的文件的根路径
123 | // 所以需要将项目根路径下面的 project.swan.json 拷贝到构建目录
124 | // 然后百度开发者工具将 dist/swan 作为项目根目录打
125 | const projectConfigMap = {
126 | tt: '../project.config.json',
127 | swan: '../project.swan.json'
128 | }
129 |
130 | const PLATFORM = process.env.PLATFORM
131 | if (/^(swan)|(tt)$/.test(PLATFORM)) {
132 | baseWebpackConfig = merge(baseWebpackConfig, {
133 | plugins: [
134 | new CopyWebpackPlugin([{
135 | from: path.resolve(__dirname, projectConfigMap[PLATFORM]),
136 | to: path.resolve(config.build.assetsRoot)
137 | }])
138 | ]
139 | })
140 | }
141 |
142 | module.exports = baseWebpackConfig
143 |
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var webpack = require('webpack')
3 | var config = require('../config')
4 | var merge = require('webpack-merge')
5 | var baseWebpackConfig = require('./webpack.base.conf')
6 | // var HtmlWebpackPlugin = require('html-webpack-plugin')
7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
8 | var MpvueVendorPlugin = require('webpack-mpvue-vendor-plugin')
9 |
10 | // copy from ./webpack.prod.conf.js
11 | var path = require('path')
12 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
13 | var CopyWebpackPlugin = require('copy-webpack-plugin')
14 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
15 |
16 | // add hot-reload related code to entry chunks
17 | // Object.keys(baseWebpackConfig.entry).forEach(function (name) {
18 | // baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
19 | // })
20 |
21 | module.exports = merge(baseWebpackConfig, {
22 | module: {
23 | rules: utils.styleLoaders({
24 | sourceMap: config.dev.cssSourceMap,
25 | extract: true
26 | })
27 | },
28 | // cheap-module-eval-source-map is faster for development
29 | // devtool: '#cheap-module-eval-source-map',
30 | // devtool: '#source-map',
31 | output: {
32 | path: config.build.assetsRoot,
33 | // filename: utils.assetsPath('[name].[chunkhash].js'),
34 | // chunkFilename: utils.assetsPath('[id].[chunkhash].js')
35 | filename: utils.assetsPath('[name].js'),
36 | chunkFilename: utils.assetsPath('[id].js')
37 | },
38 | plugins: [
39 | new webpack.DefinePlugin({
40 | 'process.env': config.dev.env
41 | }),
42 |
43 | // copy from ./webpack.prod.conf.js
44 | // extract css into its own file
45 | new ExtractTextPlugin({
46 | // filename: utils.assetsPath('[name].[contenthash].css')
47 | filename: utils.assetsPath(`[name].${config.dev.fileExt.style}`)
48 | }),
49 | // Compress extracted CSS. We are using this plugin so that possible
50 | // duplicated CSS from different components can be deduped.
51 | new OptimizeCSSPlugin({
52 | cssProcessorOptions: {
53 | safe: true
54 | }
55 | }),
56 | new webpack.optimize.CommonsChunkPlugin({
57 | name: 'common/vendor',
58 | minChunks: function (module, count) {
59 | // any required modules inside node_modules are extracted to vendor
60 | return (
61 | module.resource &&
62 | /\.js$/.test(module.resource) &&
63 | module.resource.indexOf('node_modules') >= 0
64 | ) || count > 1
65 | }
66 | }),
67 | new webpack.optimize.CommonsChunkPlugin({
68 | name: 'common/manifest',
69 | chunks: ['common/vendor']
70 | }),
71 | new MpvueVendorPlugin({
72 | platform: process.env.PLATFORM
73 | }),
74 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
75 | // new webpack.HotModuleReplacementPlugin(),
76 | new webpack.NoEmitOnErrorsPlugin(),
77 | // https://github.com/ampedandwired/html-webpack-plugin
78 | // new HtmlWebpackPlugin({
79 | // filename: 'index.html',
80 | // template: 'index.html',
81 | // inject: true
82 | // }),
83 | new FriendlyErrorsPlugin()
84 | ]
85 | })
86 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var webpack = require('webpack')
4 | var config = require('../config')
5 | var merge = require('webpack-merge')
6 | var baseWebpackConfig = require('./webpack.base.conf')
7 | var UglifyJsPlugin = require('uglifyjs-webpack-plugin')
8 | var CopyWebpackPlugin = require('copy-webpack-plugin')
9 | // var HtmlWebpackPlugin = require('html-webpack-plugin')
10 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
11 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12 | var MpvueVendorPlugin = require('webpack-mpvue-vendor-plugin')
13 | var env = config.build.env
14 |
15 | var webpackConfig = merge(baseWebpackConfig, {
16 | module: {
17 | rules: utils.styleLoaders({
18 | sourceMap: config.build.productionSourceMap,
19 | extract: true
20 | })
21 | },
22 | devtool: config.build.productionSourceMap ? '#source-map' : false,
23 | output: {
24 | path: config.build.assetsRoot,
25 | // filename: utils.assetsPath('[name].[chunkhash].js'),
26 | // chunkFilename: utils.assetsPath('[id].[chunkhash].js')
27 | filename: utils.assetsPath('[name].js'),
28 | chunkFilename: utils.assetsPath('[id].js')
29 | },
30 | plugins: [
31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
32 | new webpack.DefinePlugin({
33 | 'process.env': env
34 | }),
35 | // extract css into its own file
36 | new ExtractTextPlugin({
37 | // filename: utils.assetsPath('[name].[contenthash].css')
38 | filename: utils.assetsPath(`[name].${config.build.fileExt.style}`)
39 | }),
40 | // Compress extracted CSS. We are using this plugin so that possible
41 | // duplicated CSS from different components can be deduped.
42 | new OptimizeCSSPlugin({
43 | cssProcessorOptions: {
44 | safe: true
45 | }
46 | }),
47 | // generate dist index.html with correct asset hash for caching.
48 | // you can customize output by editing /index.html
49 | // see https://github.com/ampedandwired/html-webpack-plugin
50 | // new HtmlWebpackPlugin({
51 | // filename: config.build.index,
52 | // template: 'index.html',
53 | // inject: true,
54 | // minify: {
55 | // removeComments: true,
56 | // collapseWhitespace: true,
57 | // removeAttributeQuotes: true
58 | // // more options:
59 | // // https://github.com/kangax/html-minifier#options-quick-reference
60 | // },
61 | // // necessary to consistently work with multiple chunks via CommonsChunkPlugin
62 | // chunksSortMode: 'dependency'
63 | // }),
64 | // keep module.id stable when vender modules does not change
65 | new webpack.HashedModuleIdsPlugin(),
66 | // split vendor js into its own file
67 | new webpack.optimize.CommonsChunkPlugin({
68 | name: 'common/vendor',
69 | minChunks: function (module, count) {
70 | // any required modules inside node_modules are extracted to vendor
71 | return (
72 | module.resource &&
73 | /\.js$/.test(module.resource) &&
74 | module.resource.indexOf('node_modules') >= 0
75 | ) || count > 1
76 | }
77 | }),
78 | // extract webpack runtime and module manifest to its own file in order to
79 | // prevent vendor hash from being updated whenever app bundle is updated
80 | new webpack.optimize.CommonsChunkPlugin({
81 | name: 'common/manifest',
82 | chunks: ['common/vendor']
83 | }),
84 | new MpvueVendorPlugin({
85 | platform: process.env.PLATFORM
86 | })
87 | ]
88 | })
89 |
90 | // if (config.build.productionGzip) {
91 | // var CompressionWebpackPlugin = require('compression-webpack-plugin')
92 |
93 | // webpackConfig.plugins.push(
94 | // new CompressionWebpackPlugin({
95 | // asset: '[path].gz[query]',
96 | // algorithm: 'gzip',
97 | // test: new RegExp(
98 | // '\\.(' +
99 | // config.build.productionGzipExtensions.join('|') +
100 | // ')$'
101 | // ),
102 | // threshold: 10240,
103 | // minRatio: 0.8
104 | // })
105 | // )
106 | // }
107 |
108 | if (config.build.bundleAnalyzerReport) {
109 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
110 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
111 | }
112 |
113 | var useUglifyJs = process.env.PLATFORM !== 'swan'
114 | if (useUglifyJs) {
115 | webpackConfig.plugins.push(new UglifyJsPlugin({
116 | sourceMap: true
117 | }))
118 | }
119 |
120 | module.exports = webpackConfig
121 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var prodEnv = require('./prod.env')
3 |
4 | module.exports = merge(prodEnv, {
5 | NODE_ENV: '"development"'
6 | })
7 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | // see http://vuejs-templates.github.io/webpack for documentation.
2 | var path = require('path')
3 | var fileExtConfig = {
4 | swan: {
5 | template: 'swan',
6 | script: 'js',
7 | style: 'css',
8 | platform: 'swan'
9 | },
10 | tt: {
11 | template: 'ttml',
12 | script: 'js',
13 | style: 'ttss',
14 | platform: 'tt'
15 | },
16 | wx: {
17 | template: 'wxml',
18 | script: 'js',
19 | style: 'wxss',
20 | platform: 'wx'
21 | },
22 | my: {
23 | template: 'axml',
24 | script: 'js',
25 | style: 'acss',
26 | platform: 'my'
27 | }
28 | }
29 | var fileExt = fileExtConfig[process.env.PLATFORM]
30 |
31 | module.exports = {
32 | build: {
33 | env: require('./prod.env'),
34 | index: path.resolve(__dirname, `../dist/${fileExt.platform}/index.html`),
35 | assetsRoot: path.resolve(__dirname, `../dist/${fileExt.platform}`),
36 | assetsSubDirectory: '',
37 | assetsPublicPath: '/',
38 | productionSourceMap: false,
39 | // Gzip off by default as many popular static hosts such as
40 | // Surge or Netlify already gzip all static assets for you.
41 | // Before setting to `true`, make sure to:
42 | // npm install --save-dev compression-webpack-plugin
43 | productionGzip: false,
44 | productionGzipExtensions: ['js', 'css'],
45 | // Run the build command with an extra argument to
46 | // View the bundle analyzer report after build finishes:
47 | // `npm run build --report`
48 | // Set to `true` or `false` to always turn it on or off
49 | bundleAnalyzerReport: process.env.npm_config_report,
50 | fileExt: fileExt
51 | },
52 | dev: {
53 | env: require('./dev.env'),
54 | port: 8080,
55 | // 在小程序开发者工具中不需要自动打开浏览器
56 | autoOpenBrowser: false,
57 | assetsSubDirectory: '',
58 | assetsPublicPath: '/',
59 | proxyTable: {},
60 | // CSS Sourcemaps off by default because relative paths are "buggy"
61 | // with this option, according to the CSS-Loader README
62 | // (https://github.com/webpack/css-loader#sourcemaps)
63 | // In our experience, they generally work as expected,
64 | // just be aware of this issue when enabling this option.
65 | cssSourceMap: false,
66 | fileExt: fileExt
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | NODE_ENV: '"production"'
3 | }
4 |
--------------------------------------------------------------------------------
/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/img/1.jpg
--------------------------------------------------------------------------------
/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/img/2.jpg
--------------------------------------------------------------------------------
/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/img/3.jpg
--------------------------------------------------------------------------------
/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/img/4.jpg
--------------------------------------------------------------------------------
/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/img/5.jpg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | livable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/mock/data/cityhomehot.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | id: Math.random().toString().slice(2),
4 | title:"上海储物柜",
5 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_chuwugui.png",
6 | link:"http://www.wwtliu.com/blog"
7 | },
8 | {
9 | id: Math.random().toString().slice(2),
10 | title:"上海照明灯1",
11 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_zhaoming.png",
12 | link:"http://www.wwtliu.com/blog"
13 | },
14 | {
15 | id: Math.random().toString().slice(2),
16 | title:"上海抱枕",
17 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_baozhen.png",
18 | link:"http://www.wwtliu.com/blog"
19 | },
20 | {
21 | id: Math.random().toString().slice(2),
22 | title:"上海镜子",
23 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_jingzi.png",
24 | link:"http://www.wwtliu.com/blog"
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/mock/data/comment.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | hasMore: true,
3 | data: [
4 | {
5 | username: '133****3355',
6 | comment: '房子不错,价钱好,服务也好',
7 | star: 5
8 | },
9 | {
10 | username: '137****3235',
11 | comment: '这房子完全没办法住了,价钱高的离谱,服务差的要命。重点是甲醛超标,必须给个差评',
12 | star: 1
13 | },
14 | {
15 | username: '185****2425',
16 | comment: '我对门是自如房子,他们实在是过分了。装修完毕之后楼道的垃圾也不收拾,找自如管家,竟然说是装修师傅的事情,他们管不了',
17 | star: 2
18 | },
19 | {
20 | username: '157****5549',
21 | comment: '我租的比较早,价钱上还算合理。是涨价之前租的。总体还是满意的。',
22 | star: 5
23 | },
24 | {
25 | username: '139****9999',
26 | comment: '太有钱了,任性,不做评价',
27 | star: 5
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/mock/data/details.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | imgs: [
3 | "http://www.wwtliu.com/sxtstu/livable/details/1.jpg",
4 | "http://www.wwtliu.com/sxtstu/livable/details/2.jpg",
5 | "http://www.wwtliu.com/sxtstu/livable/details/3.jpg",
6 | "http://www.wwtliu.com/sxtstu/livable/details/4.jpg",
7 | "http://www.wwtliu.com/sxtstu/livable/details/5.jpg",
8 | "http://www.wwtliu.com/sxtstu/livable/details/6.jpg",
9 | "http://www.wwtliu.com/sxtstu/livable/details/7.jpg",
10 | "http://www.wwtliu.com/sxtstu/livable/details/8.jpg",
11 | "http://www.wwtliu.com/sxtstu/livable/details/9.jpg",
12 | "http://www.wwtliu.com/sxtstu/livable/details/10.jpg",
13 | "http://www.wwtliu.com/sxtstu/livable/details/11.jpg",
14 | "http://www.wwtliu.com/sxtstu/livable/details/12.jpg",
15 | "http://www.wwtliu.com/sxtstu/livable/details/13.jpg"
16 | ],
17 | title: "豪宅 · 使馆壹号院4居室-南
",
18 | price: "130000",
19 | rentType: "整租",
20 | houseType: "273.97 ㎡",
21 | info: {
22 | years: "2002年",
23 | type: "4室1厅",
24 | level: "17/19层",
25 | style: "精装性",
26 | orientation: "朝南"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/mock/data/homehot.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | id: Math.random().toString().slice(2),
4 | title:"储物柜",
5 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_chuwugui.png",
6 | link:"http://www.wwtliu.com/blog"
7 | },
8 | {
9 | id: Math.random().toString().slice(2),
10 | title:"照明灯",
11 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_zhaoming.png",
12 | link:"http://www.wwtliu.com/blog"
13 | },
14 | {
15 | id: Math.random().toString().slice(2),
16 | title:"抱枕",
17 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_baozhen.png",
18 | link:"http://www.wwtliu.com/blog"
19 | },
20 | {
21 | id: Math.random().toString().slice(2),
22 | title:"镜子",
23 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_jingzi.png",
24 | link:"http://www.wwtliu.com/blog"
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/mock/data/homehot2.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | id: Math.random().toString().slice(2),
4 | title:"落地灯",
5 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_luodideng.png",
6 | link:"http://www.wwtliu.com/blog"
7 | },
8 | {
9 | id: Math.random().toString().slice(2),
10 | title:"置物架",
11 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_zhiwujia.png",
12 | link:"http://www.wwtliu.com/blog"
13 | },
14 | {
15 | id: Math.random().toString().slice(2),
16 | title:"矮脚灯",
17 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_aijiaodeng.png",
18 | link:"http://www.wwtliu.com/blog"
19 | },
20 | {
21 | id: Math.random().toString().slice(2),
22 | title:"毛巾",
23 | img:"http://www.wwtliu.com/sxtstu/livable/homehot/img_maojin.png",
24 | link:"http://www.wwtliu.com/blog"
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/mock/data/order.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | id: Math.random().toString().slice(2),
4 | title:"东城区 安外大街3号院",
5 | houseType:"1室1厅1卫 - 48m²",
6 | price:"4800",
7 | rentType:"整租",
8 | commentState:0,
9 | img:"http://www.wwtliu.com/sxtstu/livable/shop/z1.jpg"
10 | },
11 | {
12 | id: Math.random().toString().slice(2),
13 | title:"整租 · 义宾北区2居室-南北",
14 | houseType:"2室1厅1卫 - 78m²",
15 | price:"7200",
16 | rentType:"整租",
17 | commentState:0,
18 | img:"http://www.wwtliu.com/sxtstu/livable/shop/z5.jpg"
19 | },
20 | {
21 | id: Math.random().toString().slice(2),
22 | title:"整租 · 杨庄北区2居室-南北",
23 | houseType:"1室1厅1卫 - 48m²",
24 | price:"4300",
25 | rentType:"整租",
26 | commentState:2,
27 | img:"http://www.wwtliu.com/sxtstu/livable/shop/z6.jpg"
28 | }
29 | ]
30 |
--------------------------------------------------------------------------------
/mock/data/searchdata.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | hasMore: true,
3 | data: [
4 | {
5 | id: Math.random().toString().slice(2),
6 | title: "豪宅 · 使馆壹号院4居室-南",
7 | houseType: "17/19层| 4室1厅 - 273.97 ㎡",
8 | price: "130000",
9 | rentType: "整租",
10 | img: "http://www.wwtliu.com/sxtstu/livable/search/1.jpg"
11 | },
12 | {
13 | id: Math.random().toString().slice(2),
14 | title: "豪宅 · 金茂府东区3居室-南北",
15 | houseType: "201.27 ㎡| 15/24层| 3室1厅",
16 | price: "40000",
17 | rentType: "整租",
18 | img: "http://www.wwtliu.com/sxtstu/livable/search/2.JPG"
19 | },
20 | {
21 | id: Math.random().toString().slice(2),
22 | title: "豪宅 · 使馆壹号院2居室-南",
23 | houseType: "204 ㎡| 2/19层| 2室1厅",
24 | price: "42000",
25 | rentType: "整租",
26 | img: "http://www.wwtliu.com/sxtstu/livable/search/3.jpg"
27 | },
28 | {
29 | id: Math.random().toString().slice(2),
30 | title: "豪宅 · 使馆壹号院3居室-南",
31 | houseType: "237 ㎡| 13/19层| 3室1厅",
32 | price: "80000",
33 | rentType: "整租",
34 | img: "http://www.wwtliu.com/sxtstu/livable/search/4.JPG"
35 | },
36 | {
37 | id: Math.random().toString().slice(2),
38 | title: "豪宅 · 棕榈泉国际公寓2居室-南北",
39 | houseType: "176.52 ㎡| 2/30层| 2室1厅",
40 | price: "33000",
41 | rentType: "整租",
42 | img: "http://www.wwtliu.com/sxtstu/livable/search/5.jpg"
43 | },
44 | {
45 | id: Math.random().toString().slice(2),
46 | title: "豪宅 · 华悦国际公寓6居室-南",
47 | houseType: "235.76 ㎡| 7/24层| 3室2厅",
48 | price: "50000",
49 | rentType: "整租",
50 | img: "http://www.wwtliu.com/sxtstu/livable/search/6.jpg"
51 | }
52 | ]
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/mock/index.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const app = express();
3 | const router = require("./router")
4 | // 引入中间件 body-parser
5 | var bodyParser = require("body-parser");
6 |
7 | // 配置中间件
8 | app.use(bodyParser.urlencoded({
9 | extended: true
10 | }));
11 |
12 | app.use("/",router);
13 |
14 | app.listen(3300,function(){
15 | console.log("3300");
16 | })
--------------------------------------------------------------------------------
/mock/router.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const request = require('request');
3 | const router = express.Router();
4 | const homeHot = require("./data/homehot")
5 | const homeHot2 = require("./data/homehot2")
6 | const cityHomeHot = require("./data/cityhomehot")
7 | const searchData = require('./data/searchdata')
8 | const detailsData = require("./data/details");
9 | const commentData = require("./data/comment")
10 | const orderData = require("./data/order");
11 | const url = require("url");
12 |
13 |
14 | // homehot
15 | router.get("/api/homehot",function(req,res){
16 | const city = url.parse(req.url,true).query.city;
17 | console.log(city);
18 | if(city === "上海"){
19 | res.send(cityHomeHot)
20 | }else{
21 | res.send(homeHot)
22 | }
23 | })
24 |
25 | router.get("/api/homehot2",function(req,res){
26 | res.send(homeHot2)
27 | })
28 |
29 | // 搜索接口
30 | router.get("/api/search",function(req,res){
31 | // 搜索内容
32 | const searchContent = url.parse(req.url,true).query.content;
33 | const city = url.parse(req.url,true).query.city;
34 | console.log(searchContent);
35 | console.log(city);
36 | res.send(searchData)
37 | })
38 |
39 |
40 | // 详情
41 | router.get('/api/details',function(req,res){
42 | // id
43 | const id = url.parse(req.url,true).query.id;
44 | console.log(id);
45 | res.send(detailsData);
46 | })
47 |
48 | // 评价
49 | router.get("/api/comment",function(req,res){
50 | const id = url.parse(req.url,true).query.id;
51 | const page = url.parse(req.url,true).query.page;
52 | console.log(id);
53 | console.log(page);
54 | res.send(commentData);
55 | })
56 |
57 | // 订单
58 | router.get("/api/order",function(req,res){
59 | const username = url.parse(req.url,true).query.username;
60 | console.log(username);
61 | res.send(orderData)
62 | })
63 |
64 | // 接受评价数据
65 | router.post("/api/comment",function(req,res){
66 | const commentContent = req.body.content;
67 | console.log(commentContent);
68 | res.send({
69 | msg:"评价成功"
70 | })
71 | })
72 |
73 |
74 | // 城市信息
75 | router.get('/lbs/location', function (req, res, next) {
76 | let lat = req.query.latitude
77 | let lng = req.query.longitude
78 |
79 | request.get({
80 | uri: 'https://apis.map.qq.com/ws/geocoder/v1/',
81 | json: true,
82 | qs: {
83 | location: `${lat},${lng}`,
84 | key: '24EBZ-QOT3V-RN3P2-ULHSA-D6KIH-FEFB4'
85 | }
86 | }, (err, response, data) => {
87 | if (response.statusCode === 200) {
88 | res.send(data)
89 | } else {
90 | res.send({
91 | msg:"获取失败"
92 | })
93 | }
94 | })
95 | })
96 |
97 | module.exports = router;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "livable",
3 | "version": "1.0.0",
4 | "mpvueTemplateProjectVersion": "0.1.0",
5 | "description": "A Mpvue project",
6 | "author": "iwen",
7 | "private": true,
8 | "scripts": {
9 | "dev:wx": "node build/dev-server.js wx",
10 | "start:wx": "npm run dev:wx",
11 | "build:wx": "node build/build.js wx",
12 | "dev:swan": "node build/dev-server.js swan",
13 | "start:swan": "npm run dev:swan",
14 | "build:swan": "node build/build.js swan",
15 | "dev:tt": "node build/dev-server.js tt",
16 | "start:tt": "npm run dev:tt",
17 | "build:tt": "node build/build.js tt",
18 | "dev:my": "node build/dev-server.js my",
19 | "start:my": "npm run dev:my",
20 | "build:my": "node build/build.js my",
21 | "dev": "node build/dev-server.js wx",
22 | "start": "npm run dev",
23 | "build": "node build/build.js wx"
24 | },
25 | "dependencies": {
26 | "mpvue": "^2.0.0",
27 | "vuex": "^3.0.1"
28 | },
29 | "devDependencies": {
30 | "babel-core": "^6.22.1",
31 | "babel-loader": "^7.1.1",
32 | "babel-plugin-transform-runtime": "^6.22.0",
33 | "babel-preset-env": "^1.3.2",
34 | "babel-preset-stage-2": "^6.22.0",
35 | "babel-register": "^6.22.0",
36 | "chalk": "^2.4.0",
37 | "connect-history-api-fallback": "^1.3.0",
38 | "copy-webpack-plugin": "^4.5.1",
39 | "css-loader": "^0.28.11",
40 | "cssnano": "^3.10.0",
41 | "eventsource-polyfill": "^0.9.6",
42 | "express": "^4.16.4",
43 | "extract-text-webpack-plugin": "^3.0.2",
44 | "file-loader": "^1.1.11",
45 | "friendly-errors-webpack-plugin": "^1.7.0",
46 | "glob": "^7.1.2",
47 | "html-webpack-plugin": "^3.2.0",
48 | "http-proxy-middleware": "^0.18.0",
49 | "mkdirp": "^0.5.1",
50 | "mpvue-loader": "^2.0.0",
51 | "mpvue-template-compiler": "^2.0.0",
52 | "mpvue-webpack-target": "^1.0.3",
53 | "optimize-css-assets-webpack-plugin": "^3.2.0",
54 | "ora": "^2.0.0",
55 | "portfinder": "^1.0.13",
56 | "postcss-loader": "^2.1.4",
57 | "postcss-mpvue-wxss": "^1.0.0",
58 | "prettier": "~1.12.1",
59 | "px2rpx-loader": "^0.1.10",
60 | "relative": "^3.0.2",
61 | "request": "^2.88.0",
62 | "rimraf": "^2.6.0",
63 | "semver": "^5.3.0",
64 | "shelljs": "^0.8.1",
65 | "uglifyjs-webpack-plugin": "^1.2.5",
66 | "url-loader": "^1.0.1",
67 | "vue-style-loader": "^4.1.0",
68 | "webpack": "^3.11.0",
69 | "webpack-bundle-analyzer": "^2.2.1",
70 | "webpack-dev-middleware-hard-disk": "^1.12.0",
71 | "webpack-merge": "^4.1.0",
72 | "webpack-mpvue-asset-plugin": "^2.0.0",
73 | "webpack-mpvue-vendor-plugin": "^2.0.0"
74 | },
75 | "engines": {
76 | "node": ">= 4.0.0",
77 | "npm": ">= 3.0.0"
78 | },
79 | "browserslist": [
80 | "> 1%",
81 | "last 2 versions",
82 | "not ie <= 8"
83 | ]
84 | }
85 |
--------------------------------------------------------------------------------
/package.swan.json:
--------------------------------------------------------------------------------
1 | {
2 | "appid": "touristappid",
3 | "setting": {
4 | "urlCheck": false
5 | },
6 | "condition": {
7 | "swan": {
8 | "current": -1,
9 | "list": []
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "setting": {
4 | "urlCheck": true,
5 | "es6": false,
6 | "postcss": true,
7 | "minified": true,
8 | "newFeature": true
9 | },
10 | "miniprogramRoot": "dist/wx/",
11 | "compileType": "miniprogram",
12 | "appid": "wxa7b5034536eb7fb7",
13 | "projectname": "livable",
14 | "condition": {
15 | "search": {
16 | "current": -1,
17 | "list": []
18 | },
19 | "conversation": {
20 | "current": -1,
21 | "list": []
22 | },
23 | "game": {
24 | "currentL": -1,
25 | "list": []
26 | },
27 | "miniprogram": {
28 | "current": -1,
29 | "list": []
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/project.swan.json:
--------------------------------------------------------------------------------
1 | {
2 | "appid": "testappid",
3 | "setting": {
4 | "urlCheck": false
5 | },
6 | "condition": {
7 | "swan": {
8 | "current": -1,
9 | "list": []
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
32 |
33 |
36 |
--------------------------------------------------------------------------------
/src/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/index/main",
4 | "pages/logs/main",
5 | "pages/counter/main",
6 | "pages/shop/main",
7 | "pages/service/main",
8 | "pages/mine/main",
9 | "pages/search/main",
10 | "pages/details/main"
11 | ],
12 | "permission": {
13 | "scope.userLocation": {
14 | "desc": "你的位置信息将用于小程序位置接口的效果展示"
15 | }
16 | },
17 | "window": {
18 | "backgroundTextStyle": "light",
19 | "navigationBarBackgroundColor": "#fff",
20 | "navigationBarTitleText": "WeChat",
21 | "navigationBarTextStyle": "black"
22 | },
23 | "tabBar": {
24 | "color": "#999",
25 | "backgroundColor": "#fafafa",
26 | "selectedColor": "#333",
27 | "borderStyle": "white",
28 | "list": [
29 | {
30 | "text": "首页",
31 | "pagePath": "pages/index/main",
32 | "iconPath": "static/tabs/home.png",
33 | "selectedIconPath": "static/tabs/home_select.png"
34 | },
35 | {
36 | "text": "商城",
37 | "pagePath": "pages/shop/main",
38 | "iconPath": "static/tabs/shop.png",
39 | "selectedIconPath": "static/tabs/shop_select.png"
40 | },
41 | {
42 | "text": "生活服务",
43 | "pagePath": "pages/service/main",
44 | "iconPath": "static/tabs/reconciliation.png",
45 | "selectedIconPath": "static/tabs/reconciliation_select.png"
46 | },
47 | {
48 | "text": "我的",
49 | "pagePath": "pages/mine/main",
50 | "iconPath": "static/tabs/team.png",
51 | "selectedIconPath": "static/tabs/team_select.png"
52 | }
53 | ],
54 | "items": [
55 | {
56 | "name": "首页",
57 | "pagePath": "pages/index/main",
58 | "icon": "static/tabs/home.png",
59 | "activeIcon": "static/tabs/home-active.png"
60 | },
61 | {
62 | "name": "订单",
63 | "pagePath": "pages/logs/main",
64 | "icon": "static/tabs/orders.png",
65 | "activeIcon": "static/tabs/orders-active.png"
66 | }
67 | ],
68 | "position": "bottom"
69 | }
70 | }
--------------------------------------------------------------------------------
/src/components/HomeHotView.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
38 |
--------------------------------------------------------------------------------
/src/components/ShopListView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
![]()
8 |
9 |
10 |
{{ item.title }}
11 |
{{ item.houseType }}
12 |
价格:{{ item.price }}元/月
13 |
{{ item.rentType }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
38 |
--------------------------------------------------------------------------------
/src/components/card.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
20 |
--------------------------------------------------------------------------------
/src/components/headnav.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
75 |
--------------------------------------------------------------------------------
/src/components/myswiper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
34 |
--------------------------------------------------------------------------------
/src/config/index.js:
--------------------------------------------------------------------------------
1 | const G_URL = "http://localhost:3300"
2 |
3 | export default {
4 | G_URL
5 | }
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 |
4 | import Config from './config/index'; //全局变量
5 | Vue.prototype.Config = Config; //绑定到vue原型上
6 |
7 | Vue.config.productionTip = false
8 | App.mpType = 'app'
9 |
10 | const app = new Vue(App)
11 | app.$mount()
12 |
--------------------------------------------------------------------------------
/src/pages/counter/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Vuex counter:{{ count }}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
31 |
32 |
45 |
--------------------------------------------------------------------------------
/src/pages/counter/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | const app = new Vue(App)
5 | app.$mount()
6 |
--------------------------------------------------------------------------------
/src/pages/counter/store.js:
--------------------------------------------------------------------------------
1 | // https://vuex.vuejs.org/zh-cn/intro.html
2 | // make sure to call Vue.use(Vuex) if using a module system
3 | import Vue from 'vue'
4 | import Vuex from 'vuex'
5 |
6 | Vue.use(Vuex)
7 |
8 | const store = new Vuex.Store({
9 | state: {
10 | count: 0
11 | },
12 | mutations: {
13 | increment: (state) => {
14 | const obj = state
15 | obj.count += 1
16 | },
17 | decrement: (state) => {
18 | const obj = state
19 | obj.count -= 1
20 | }
21 | }
22 | })
23 |
24 | export default store
25 |
--------------------------------------------------------------------------------
/src/pages/details/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 商品详情
7 | 商品评价
8 |
9 |
10 |
11 |
12 |
13 | 房屋大小:{{ goodsDetails.houseType }}
14 | 房租:{{ goodsDetails.price }}
15 | 租售方式:{{ goodsDetails.rentType }}
16 |
17 |
18 |
19 |
20 | 商品评价
21 |
22 |
23 |
24 |
25 |
26 |
76 |
--------------------------------------------------------------------------------
/src/pages/details/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | const app = new Vue(App)
5 | app.$mount()
6 |
--------------------------------------------------------------------------------
/src/pages/details/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "详情页",
3 | "navigationBarTextStyle":"white",
4 | "navigationBarBackgroundColor":"#ff5555"
5 | }
6 |
--------------------------------------------------------------------------------
/src/pages/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
37 |
38 |
42 |
--------------------------------------------------------------------------------
/src/pages/index/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | // add this to handle exception
5 | Vue.config.errorHandler = function (err) {
6 | if (console && console.error) {
7 | console.error(err)
8 | }
9 | }
10 |
11 | const app = new Vue(App)
12 | app.$mount()
13 |
--------------------------------------------------------------------------------
/src/pages/index/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "宜居生活",
3 | "navigationBarTextStyle":"white",
4 | "navigationBarBackgroundColor":"#ff5555"
5 | }
6 |
--------------------------------------------------------------------------------
/src/pages/index/subpage/homehot.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
47 |
--------------------------------------------------------------------------------
/src/pages/logs/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
50 |
51 |
62 |
--------------------------------------------------------------------------------
/src/pages/logs/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | const app = new Vue(App)
5 | app.$mount()
6 |
--------------------------------------------------------------------------------
/src/pages/logs/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "查看启动日志"
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/mine/index.vue:
--------------------------------------------------------------------------------
1 | import card from '@/components/card';
2 |
3 |
4 |
5 |
6 |
7 |
![]()
8 |
{{ userInfo.nickName }}
9 |
10 |
11 |
12 |
67 |
--------------------------------------------------------------------------------
/src/pages/mine/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | const app = new Vue(App)
5 | app.$mount()
6 |
--------------------------------------------------------------------------------
/src/pages/mine/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "我的"
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/search/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
66 |
--------------------------------------------------------------------------------
/src/pages/search/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | const app = new Vue(App)
5 | app.$mount()
6 |
--------------------------------------------------------------------------------
/src/pages/search/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "搜索"
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/service/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 生活服务
4 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/src/pages/service/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | const app = new Vue(App)
5 | app.$mount()
6 |
--------------------------------------------------------------------------------
/src/pages/service/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "生活服务"
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/shop/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
31 |
--------------------------------------------------------------------------------
/src/pages/shop/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './index'
3 |
4 | const app = new Vue(App)
5 | app.$mount()
6 |
--------------------------------------------------------------------------------
/src/pages/shop/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "商城",
3 | "navigationBarTextStyle":"white",
4 | "navigationBarBackgroundColor":"#ff5555"
5 | }
6 |
--------------------------------------------------------------------------------
/src/pages/shop/subpage/shoplist.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | // https://vuex.vuejs.org/zh-cn/intro.html
2 | // make sure to call Vue.use(Vuex) if using a module system
3 | import Vue from 'vue'
4 | import Vuex from 'vuex'
5 |
6 | Vue.use(Vuex)
7 |
8 | const store = new Vuex.Store({
9 | state: {
10 | cityName:"上海"
11 | },
12 | mutations: {
13 | setName: (state,data) => {
14 | state.cityName = data;
15 | },
16 | updateName: (state,data) => {
17 | state.cityName = data;
18 | }
19 | }
20 | })
21 |
22 | export default store
23 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | function formatNumber (n) {
2 | const str = n.toString()
3 | return str[1] ? str : `0${str}`
4 | }
5 |
6 | export function formatTime (date) {
7 | const year = date.getFullYear()
8 | const month = date.getMonth() + 1
9 | const day = date.getDate()
10 |
11 | const hour = date.getHours()
12 | const minute = date.getMinutes()
13 | const second = date.getSeconds()
14 |
15 | const t1 = [year, month, day].map(formatNumber).join('/')
16 | const t2 = [hour, minute, second].map(formatNumber).join(':')
17 |
18 | return `${t1} ${t2}`
19 | }
20 |
21 | export default {
22 | formatNumber,
23 | formatTime
24 | }
25 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/.gitkeep
--------------------------------------------------------------------------------
/static/images/banner1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/banner1.png
--------------------------------------------------------------------------------
/static/images/banner2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/banner2.png
--------------------------------------------------------------------------------
/static/images/banner3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/banner3.png
--------------------------------------------------------------------------------
/static/images/banner4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/banner4.png
--------------------------------------------------------------------------------
/static/images/banner5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/banner5.png
--------------------------------------------------------------------------------
/static/images/banner6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/banner6.png
--------------------------------------------------------------------------------
/static/images/car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/car.png
--------------------------------------------------------------------------------
/static/images/deploymentunit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/deploymentunit.png
--------------------------------------------------------------------------------
/static/images/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/search.png
--------------------------------------------------------------------------------
/static/images/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/images/user.png
--------------------------------------------------------------------------------
/static/tabs/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/home.png
--------------------------------------------------------------------------------
/static/tabs/home_select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/home_select.png
--------------------------------------------------------------------------------
/static/tabs/reconciliation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/reconciliation.png
--------------------------------------------------------------------------------
/static/tabs/reconciliation_select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/reconciliation_select.png
--------------------------------------------------------------------------------
/static/tabs/shop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/shop.png
--------------------------------------------------------------------------------
/static/tabs/shop_select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/shop_select.png
--------------------------------------------------------------------------------
/static/tabs/team.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/team.png
--------------------------------------------------------------------------------
/static/tabs/team_select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nickiwen/mpvue/2b53680e19b3b276fc00b9cb2452beb781e6a46d/static/tabs/team_select.png
--------------------------------------------------------------------------------