Repository: MrKaKaluote/vue-mobile
Branch: master
Commit: dfeb7079ffcb
Files: 49
Total size: 50.9 KB
Directory structure:
gitextract_uvzfa1d0/
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build/
│ ├── build.js
│ ├── check-versions.js
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ └── webpack.prod.conf.js
├── config/
│ ├── dev.env.js
│ ├── dev.mock.env.js
│ ├── dev.proxy.js
│ ├── dev.test.env.js
│ ├── dev.test.proxy.js
│ ├── index.js
│ ├── prod.env.js
│ └── prod.test.env.js
├── index.html
├── package.json
├── src/
│ ├── App.vue
│ ├── api/
│ │ └── home-api.js
│ ├── apiconfig/
│ │ └── index.js
│ ├── components/
│ │ ├── common-header.vue
│ │ └── cus-input.vue
│ ├── main.js
│ ├── mock/
│ │ ├── index.js
│ │ └── user.js
│ ├── pages/
│ │ ├── detail.vue
│ │ ├── index/
│ │ │ ├── day.vue
│ │ │ ├── footprints.vue
│ │ │ ├── home.vue
│ │ │ └── story.vue
│ │ └── index.vue
│ ├── router/
│ │ └── index.js
│ ├── store/
│ │ ├── index.js
│ │ ├── modules/
│ │ │ └── home.js
│ │ └── mutation-type.js
│ └── styles/
│ ├── base.less
│ ├── index.less
│ ├── mixin.less
│ ├── reset.less
│ └── variable.less
└── static/
├── .gitkeep
└── js/
└── flexible.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
================================================
FILE: .editorconfig
================================================
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
================================================
FILE: .eslintignore
================================================
/build/
/config/
/dist/
/*.js
================================================
FILE: .eslintrc.js
================================================
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: true,
},
extends: [
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
'plugin:vue/essential',
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
'standard'
],
// required to lint *.vue files
plugins: [
'vue'
],
// add your custom rules here
rules: {
// allow async-await
'generator-star-spacing': 'off',
// 强制在 function的左括号之前使用一致的空格
'space-before-function-paren': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}
================================================
FILE: .gitignore
================================================
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
================================================
FILE: .postcssrc.js
================================================
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}
================================================
FILE: README.md
================================================
# myproject
> A Vue.js project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev or npm run dev:test
# use mock data
npm run dev:mock
# build for production with minification
npm run build or npm run build:test
# build for production and view the bundle analyzer report
npm run build --report
```
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
================================================
FILE: build/build.js
================================================
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
================================================
FILE: build/check-versions.js
================================================
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
================================================
FILE: build/utils.js
================================================
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
================================================
FILE: build/vue-loader.conf.js
================================================
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
================================================
FILE: build/webpack.base.conf.js
================================================
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
externals:{ // 使用CDN数据
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex':'Vuex',
'mint-ui': 'MINT'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
'config': resolve('src/apiconfig'),
'api': resolve('src/api'),
'styles': resolve('src/styles'),
'common': resolve('src/components'),
}
},
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
================================================
FILE: build/webpack.dev.conf.js
================================================
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
================================================
FILE: build/webpack.prod.conf.js
================================================
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = config.build.env
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
================================================
FILE: config/dev.env.js
================================================
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_URL: '""',
MOCK: false
})
================================================
FILE: config/dev.mock.env.js
================================================
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_URL: '""',
MOCK: true
})
================================================
FILE: config/dev.proxy.js
================================================
module.exports = {
'/root/': {
target: 'http://114.55.72.164:8091/',
changeOrigin: true
}
}
================================================
FILE: config/dev.test.env.js
================================================
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_URL: '""',
MOCK: false
})
================================================
FILE: config/dev.test.proxy.js
================================================
module.exports = {
'/root/': {
target: 'http://114.55.72.164:8091/',
changeOrigin: true
}
}
================================================
FILE: config/index.js
================================================
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
let serverObj = {
dev: {
// Paths
env: require('./dev.env'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8088, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: true,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: true,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
/**
* 依据命令执行不同的代理文件
* 全局变量在package.json里配置
*/
if (process.env.NODE_ENV === 'development') {
if (process.env.DEV_ENV === 'local') {
serverObj.dev.env = require('./dev.env')
serverObj.dev.proxyTable = require('./dev.proxy')
} else if (process.env.DEV_ENV === 'test') {
serverObj.dev.env = require('./dev.test.env')
serverObj.dev.proxyTable = require('./dev.test.proxy')
} else {
serverObj.dev.env = require('./dev.mock.env')
serverObj.dev.proxyTable = require('./dev.proxy')
}
}
if (process.env.NODE_ENV === 'production') {
serverObj.build.env = (process.env.DEV_ENV === 'test' ? require('./prod.test.env') : require('./prod.env'))
}
module.exports = serverObj
================================================
FILE: config/prod.env.js
================================================
'use strict'
module.exports = {
NODE_ENV: '"production"',
BASE_URL: '""',
MOCK: false
}
================================================
FILE: config/prod.test.env.js
================================================
'use strict'
module.exports = {
NODE_ENV: '"production"',
BASE_URL: '""',
MOCK: false
}
================================================
FILE: index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>myproject</title>
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/mint-ui/2.2.13/index.js"></script>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
================================================
FILE: package.json
================================================
{
"name": "myproject",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "MrKaKaluote <gaosongai@foxmail.com>",
"private": true,
"scripts": {
"dev": "cross-env DEV_ENV=local NODE_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"dev:test": "cross-env DEV_ENV=test NODE_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"dev:mock": "cross-env DEV_ENV=mock NODE_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",
"build": "cross-env DEV_ENV=prod NODE_ENV=production node build/build.js",
"build:test": "cross-env DEV_ENV=test NODE_ENV=production node build/build.js"
},
"dependencies": {
"axios": "^0.18.0",
"cross-env": "^5.2.0",
"fastclick": "^1.0.6",
"js-cookie": "^2.2.0",
"less": "^3.7.1",
"less-loader": "^4.1.0",
"mint-ui": "^2.2.13",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.0.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"less": "^3.7.1",
"less-loader": "^4.1.0",
"mockjs": "^1.0.1-beta3",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
================================================
FILE: src/App.vue
================================================
<template>
<div id="app">
<transition :name="transitionName">
<router-view class="Router"></router-view>
</transition>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
transitionName: ''
}
},
watch: {
$route() {
if (this.$router.isleft) {
this.transitionName = 'slideleft'
}
if (this.$router.isright) {
this.transitionName = 'slideright'
}
}
}
}
</script>
<style lang="less">
@import "~styles/variable.less";
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color:rgba(0,0,0,0);
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
.Router {
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
background-color: @body-bg-color;;
transition: all .5s ease;
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
}
.slideleft-enter,
.slideright-leave-active {
opacity: 1;
transform: translate3d(90% 0, 0);
-webkit-transform: translate3d(90%, 0, 0);
-moz-transform: translate3d(90%, 0, 0);
}
.slideleft-leave-active,
.slideright-enter {
opacity: 1;
transform: translate3d(-90% 0, 0);
-webkit-transform: translate3d(-90%, 0, 0);
-moz-transform: translate3d(-90%, 0, 0);
}
</style>
================================================
FILE: src/api/home-api.js
================================================
/**
* 引入fetch、baseUrl
* @param params
* @returns {*}
*/
import {fetch, baseUrl} from 'config/index'
// 登录接口
export function loginUserNo(params) {
return fetch(`${baseUrl}/root/login/checkMemberLogin`, params)
}
================================================
FILE: src/apiconfig/index.js
================================================
/* eslint-disable */
import axios from 'axios'
/**
* 定义请求常量
* TIME_OUT、ERR_OK
*/
export const TIME_OUT = 1000; // 请求超时时间
export const ERR_OK = true; // 请求成功返回状态,字段和后台统一
export const baseUrl = process.env.BASE_URL // 引入全局url,定义在全局变量process.env中
// 请求超时时间
axios.defaults.timeout = TIME_OUT
// 封装请求拦截
axios.interceptors.request.use(
config => {
let token = localStorage.getItem('token') // 获取token
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
config.headers['Authorization'] = ''
if(token != null){ // 如果token不为null,否则传token给后台
config.headers['Authorization'] = token
}
return config
},
error => {
return Promise.reject(error)
}
)
// 封装响应拦截,判断token是否过期
axios.interceptors.response.use(
response => {
let {data} = response
if (data.message === 'token failure!') { // 如果后台返回的错误标识为token过期,则重新登录
localStorage.removeItem('token') // token过期,移除token
// 进行重新登录操作
} else {
return Promise.resolve(response)
}
},
error => {
return Promise.reject(error)
}
)
// 封装post请求
export function fetch(requestUrl, params = '') {
return axios({
url: requestUrl,
method: 'post',
data: {
'body': params
}
})
}
================================================
FILE: src/components/common-header.vue
================================================
<template>
<div class="header-box">
<div class="left-icon">
<span v-if="showback" @click="back" class="icon-back"></span>
</div>
<div class="header-tittle">
<span v-if="showinput">
<cus-input></cus-input>
</span>
<span v-if="!showinput">{{tittle}}</span>
</div>
<div class="right-icon">
<span v-if="showmore" class="icon"></span>
</div>
</div>
</template>
<script>
import cusInput from 'common/cus-input'
export default {
data() {
return {}
},
props: {
showright: {
type: Boolean,
default: false
},
showleft: {
type: Boolean,
default: false
},
showinput: {
type: Boolean,
default: false
},
tittle: {
type: String,
default: '标题'
},
showback: {
type: Boolean,
default: true
},
showmore: {
type: Boolean,
default: false
}
},
methods: {
back() {
this.$router.goBack()
}
},
components: {
cusInput
}
}
</script>
<style lang="less" scoped>
@import "~styles/index.less";
@import "~styles/variable.less";
.header-box{
// position: fixed;
// top: 0;
// left: 0;
width: 100%;
.h(100);
.lh(100);
background-color: @base-color;
color: @base-header-color;
.fs(@base-header-size);
display: flex;
z-index: 1;
.left-icon{
position: relative;
flex: 1;
.icon-back{
position: absolute;
display: inline-block;
.w(50);
.h(50);
.left(25);
.top(25);
background-image: url("../assets/imgs/w-back.svg");
background-size: cover;
}
}
.header-tittle{
flex: 3;
}
.right-icon{
position: relative;
flex: 1;
.icon{
position: absolute;
display: inline-block;
.w(50);
.h(50);
.right(25);
.top(25);
background-image: url("../assets/imgs/more.svg");
background-size: cover;
}
}
}
</style>
================================================
FILE: src/components/cus-input.vue
================================================
<template>
<div class="input-box">
<span class="icon"></span>
<input type="text" class="search" placeholder="找人 找故事">
</div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
@import "~styles/index.less";
@import "~styles/variable.less";
.input-box{
position: relative;
.icon{
position: absolute;
display: inline-block;
.w(45);
.h(45);
top: 50%;
.mt(-18);
.left(-20);
background-image: url("../assets/imgs/search.svg");
background-size: cover;
}
.search{
.b-radius(8);
.h(50);
.lh(50);
width: 100%;
outline: none;
.pl(50);
.pt(5);
.pt(5);
.ml(-25);
.fs(26);
}
}
</style>
================================================
FILE: src/main.js
================================================
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
/*eslint-disable*/
import Vue from 'vue'
import App from './App'
import Vuex from 'vuex'
import store from './store'
import router from './router'
import Mint from 'mint-ui'
import 'mint-ui/lib/style.css'
import FastClick from 'fastclick'
import '../static/js/flexible.js'
if (process.env.MOCK) { // 判断是否为mock模式
require('./mock/index.js')
}
/**
*监听浏览器点击返回前进操作动画
*浏览器端使用需要注意路由path的创建,二级应该在一级的基础上添加
*如一级/Home,则二级为/Home/Detail,依次往后加,如果是app的话可忽略以下代码
*/
let init = 0
window.addEventListener('popstate', function(e) {
init++
if (init < 2) {
router.beforeEach((to, from, next) => {
let arr1 = to.path.split('/')
let arr2 = from.path.split('/')
if (arr1.length === 2) {
if (arr1[1].length === 0) {
arr1.splice(1, 1)
}
}
if (arr2.length === 2) {
if (arr2[1].length === 0) {
arr2.splice(1, 1)
}
}
if (arr1.length < arr2.length) {
router.togoback()
} else {
router.togoin()
}
next()
})
}
}, false)
// app 修改状态栏颜色
// document.addEventListener('plusready', function () {
// let System = window.plus.os.name
// if (System === 'iOS') {
// window.plus.navigator.setStatusBarBackground('#d81e06')
// }
// })
Vue.use(Mint)
Vue.use(Vuex)
Vue.config.productionTip = false
FastClick.attach(document.body)
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
================================================
FILE: src/mock/index.js
================================================
/*
* @Description: 引入mock.js及配置文件
* @Author: MrGao
* @LastEditors: gaosong
* @Date: 2019-03-12 10:35:08
* @LastEditTime: 2019-03-12 15:57:56
*/
import Mock from 'mockjs'
import User from './user'
// 此处会劫持/root/login/checkMemberLogin接口,并返回数据
Mock.mock('/root/login/checkMemberLogin', 'post', () => {
// 返回模拟数据
return User.userInfo
})
================================================
FILE: src/mock/user.js
================================================
/*
* @Description: 返回数据模板
* @Author: gaosong
* @LastEditors: gaosong
* @Date: 2019-03-12 10:35:23
* @LastEditTime: 2019-03-12 15:56:32
*/
let userInfo = {
code: 200,
id: '123456',
msg: 'success',
name: 'gs',
tel: '12306'
}
let user = {
userInfo
}
export default user
================================================
FILE: src/pages/detail.vue
================================================
<template>
<div class="content-box">
<common-header :tittle="tittle" :showmore="true"></common-header>
<div class="page-content">
<h1>{{data}}</h1>
<h1>{{newdata}}</h1>
</div>
</div>
</template>
<script>
import commonHeader from 'common/common-header'
export default {
data() {
return {
tittle: '详情',
data: 0
}
},
components: {
commonHeader
},
computed: {
newdata: function() {
return this.data + 1
}
},
methods: {
tohome() {
this.$router.goBack()
},
add() {
this.data++
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
@import "~styles/index.less";
@import "~styles/variable.less";
</style>
================================================
FILE: src/pages/index/day.vue
================================================
<template>
<div class="content-box">
<common-header :tittle="tittle" :showback="false"></common-header>
<div class="page-content">
<mt-button @click="todetail">user</mt-button>
</div>
</div>
</template>
<script>
import {mapMutations, mapGetters, mapState} from 'vuex'
import commonHeader from 'common/common-header'
export default {
data () {
return {
tittle: '激情燃烧的岁月',
num: 0
}
},
created() {},
methods: {
...mapMutations({
setNum: 'SET_NUM'
}),
todetail() {
this.$router.togo('/Home/Detail')
}
},
components: {
commonHeader
},
computed: {
...mapGetters([
'number'
]),
...mapState({
number: state => state.home.number
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
@import "~styles/index.less";
@import "~styles/variable.less";
.page-content{
.mb(98);
}
</style>
================================================
FILE: src/pages/index/footprints.vue
================================================
<template>
<div class="content-box">
<common-header :tittle="tittle" :showback="false"></common-header>
<div class="page-content">
<mt-button @click="todetail">footprints</mt-button>
</div>
</div>
</template>
<script>
import {mapMutations, mapGetters, mapState} from 'vuex'
import commonHeader from 'common/common-header'
export default {
data () {
return {
tittle: '我的足迹',
num: 0
}
},
created() {},
methods: {
...mapMutations({
setNum: 'SET_NUM'
}),
todetail() {
this.$router.togo('/Home/Detail')
}
},
components: {
commonHeader
},
computed: {
...mapGetters([
'number'
]),
...mapState({
number: state => state.home.number
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
@import "~styles/index.less";
@import "~styles/variable.less";
.page-content{
.mb(98);
}
</style>
================================================
FILE: src/pages/index/home.vue
================================================
<template>
<div class="content-box">
<common-header :showinput="true" :showback="false"></common-header>
<div class="page-content">
<mt-button @click="todetail">home</mt-button>
</div>
</div>
</template>
<script>
import {mapMutations, mapGetters, mapState} from 'vuex'
import commonHeader from 'common/common-header'
// import * as homeApi from 'api/home-api'
// import { ERR_OK } from 'config/index'
export default {
data () {
return {
num: 0
}
},
created() {},
methods: {
...mapMutations({
setNum: 'SET_NUM'
}),
todetail() {
this.$router.togo('/Home/Detail')
}
// login() {
// let params = {
// password: 'gs123456',
// storeNo: '',
// userName: '17326015487'
// }
// homeApi.loginUserNo(params).then((res) => {
// let {data} = res
// if (data.success === ERR_OK) {
// alert(data.value.token)
// } else {
// }
// }).catch(() => {
// })
// }
},
components: {
commonHeader
},
computed: {
...mapGetters([
'number'
]),
...mapState({
number: state => state.home.number
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
@import "~styles/index.less";
@import "~styles/variable.less";
.page-content{
.mb(98);
}
</style>
================================================
FILE: src/pages/index/story.vue
================================================
<template>
<div class="content-box">
<common-header :tittle="tittle" :showback="false"></common-header>
<div class="page-content">
<mt-button @click="todetail">story</mt-button>
</div>
</div>
</template>
<script>
import {mapMutations, mapGetters, mapState} from 'vuex'
import commonHeader from 'common/common-header'
export default {
data () {
return {
tittle: '我的故事',
num: 0
}
},
created() {},
methods: {
...mapMutations({
setNum: 'SET_NUM'
}),
todetail() {
this.$router.togo('/Home/Detail')
}
},
components: {
commonHeader
},
computed: {
...mapGetters([
'number'
]),
...mapState({
number: state => state.home.number
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
@import "~styles/index.less";
@import "~styles/variable.less";
.page-content{
.mb(98);
}
</style>
================================================
FILE: src/pages/index.vue
================================================
<template>
<div class="page">
<keep-alive>
<router-view></router-view>
</keep-alive>
<div class="nav-footer">
<footer>
<router-link v-for='(item, index) in navList' :to='item.path' :key='index'
v-bind:class="{'active':activeRoute == item.path}">
<div :class="'tab-'+index"></div>
<p v-text="item.name"></p>
</router-link>
</footer>
</div>
</div>
</template>
<script>
export default {
data () {
return {
navList: [
{
'path': '/home',
'name': '推荐'
},
{
'path': '/story',
'name': '故事'
},
{
'path': '/footprints',
'name': '足迹'
},
{
'path': '/day',
'name': '纪念日'
}
]
}
},
computed: {
activeRoute () {
return this.$route.path
}
},
methods: {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
@import "~styles/index.less";
@import "~styles/variable.less";
.nav-footer {
position: fixed;
left: 0px;
bottom: 0px;
width: 100%;
.h(98);
background: @tab-general-bg-color;
display: block;
footer {
font-size: 0;
border-top: 1px solid #E7E7E7;
border-bottom: 1px solid #F8F8F8;
.pt(10);
line-height: 1.2;
width: 100%;
.h(98);
display: flex;
a {
text-decoration: none;
color: @base-font-color;
-webkit-box-flex: 1;
-moz-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
text-align: center;
box-sizing: border-box;
display: block;
.fs(22);
.tab-0, .tab-1, .tab-2, .tab-3 {
display: inline-block;
.h(42);
.w(42);
background-size: cover;
}
.tab-0 {
background-image: url("../assets/imgs/index-noselect.svg");
}
.tab-1 {
background-image: url("../assets/imgs/note-noselect.svg");
}
.tab-2 {
background-image: url("../assets/imgs/print-noselect.svg");
}
.tab-3 {
background-image: url("../assets/imgs/dy-noselect.svg");
}
&:hover {
text-decoration: none;
}
&.router-link-active.active {
.tab-0 {
background-image: url("../assets/imgs/index-select.svg");
}
.tab-1 {
background-image: url("../assets/imgs/note-select.svg");
}
.tab-2 {
background-image: url("../assets/imgs/print-select.svg");
}
.tab-3 {
background-image: url("../assets/imgs/dy-select.svg");
}
}
}
p {
margin: 0;
}
}
}
</style>
================================================
FILE: src/router/index.js
================================================
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
// 需要左方向动画的路由用this.$router.to('****')
Router.prototype.togo = function (path) {
this.isleft = true
this.isright = false
this.push(path)
}
// 需要右方向动画的路由用this.$router.goRight('****')
Router.prototype.goRight = function (path) {
this.isright = true
this.isleft = false
this.push(path)
}
// 需要返回按钮动画的路由用this.$router.goBack(),返回上一个路由
Router.prototype.goBack = function () {
this.isright = true
this.isleft = false
this.go(-1)
}
// 点击浏览器返回按钮执行,此时不需要路由回退
Router.prototype.togoback = function () {
this.isright = true
this.isleft = false
}
// 点击浏览器前进按钮执行
Router.prototype.togoin = function () {
this.isright = false
this.isleft = true
}
export default new Router({
routes: [
{
path: '/',
name: 'index',
component: (resolve) => require(['@/pages/index'], resolve),
redirect: '/home',
children: [
{
path: '/home',
name: 'home',
component: (resolve) => require(['@/pages/index/home'], resolve)
},
{
path: '/story',
name: 'story',
component: (resolve) => require(['@/pages/index/story'], resolve)
},
{
path: '/footprints',
name: 'footprints',
component: (resolve) => require(['@/pages/index/footprints'], resolve)
},
{
path: '/day',
name: 'day',
component: (resolve) => require(['@/pages/index/day'], resolve)
}
]
},
{
path: '/Home/Detail',
name: 'Detail',
component: (resolve) => require(['@/pages/detail'], resolve)
}
]
})
================================================
FILE: src/store/index.js
================================================
import Vue from 'vue'
import Vuex from 'vuex'
import home from './modules/home'
import createLogger from 'vuex/dist/logger'
Vue.use(Vuex)
const debug = true
/* eslint-disable */
export default new Vuex.Store({
modules: {
home
},
plugins: debug ? [createLogger()] : [] // 是否开启vuex的debug模式
})
================================================
FILE: src/store/modules/home.js
================================================
/**
* home.js
* 用于home模块的状态管理
*/
/* eslint-disable */
import * as types from '../mutation-type' // 引入定义的方法
const home = {
state: {
number: 1
},
mutations: {
[types.SET_NUM](state, num) { // 修改state 可通过mapMutations调用
state.number = num
}
},
actions: {},
getters: { // 定义getters,可以通过mapGetters拓展函数调用
number: state => {
return state.number
}
}
}
export default home // 输出home模块
================================================
FILE: src/store/mutation-type.js
================================================
// global
export const SET_NUM = 'SET_NUM'
================================================
FILE: src/styles/base.less
================================================
@import "variable";
body, html {
line-height: 1;
font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', arial, sans-serif, 'Droid Sans Fallback';
user-select: none;
-webkit-tap-highlight-color: transparent;
background-color: @body-bg-color;
}
.content-box{
display:-webkit-box;
display:-webkit-flex;
display:-ms-flexbox;
display:flex;
-webkit-box-orient:vertical;
-webkit-flex-direction:column;
-ms-flex-direction:column;
flex-direction:column;
width:100%;
height:100%;
}
.page-content{
-webkit-box-flex:1;
-webkit-flex:1;
-ms-flex:1;
flex:1;
width:100%;
overflow:auto;/* winphone8和android4+ */
-webkit-overflow-scrolling: touch; /* ios5+ */
overflow-y: scroll;
}
================================================
FILE: src/styles/index.less
================================================
@import "./reset.less";
@import "./mixin.less";
@import "./base.less";
================================================
FILE: src/styles/mixin.less
================================================
@baseFontSize: 75;
.px2rem(@name, @px) {
@name: @px / @baseFontSize * 1rem;
}
.flex(@a, @b, @c) {
flex: @a @b @c/@baseFontSize*1rem;
}
.b-radius(@px) {
border-radius: @px / @baseFontSize * 1rem;
}
.b-radius(@px) {
border-radius: @px / @baseFontSize * 1rem;
}
.h(@px) {
height: @px / @baseFontSize * 1rem;
}
.minh(@px) {
min-height: @px / @baseFontSize * 1rem;
}
.maxh(@px) {
max-height: @px / @baseFontSize * 1rem;
}
.w(@px) {
width: @px / @baseFontSize * 1rem;
}
.mt(@px) {
margin-top: @px / @baseFontSize * 1rem;
}
.mb(@px) {
margin-bottom: @px / @baseFontSize * 1rem;
}
.ml(@px) {
margin-left: @px / @baseFontSize * 1rem;
}
.mr(@px) {
margin-right: @px / @baseFontSize * 1rem;
}
.pt(@px) {
padding-top: @px / @baseFontSize * 1rem;
}
.pb(@px) {
padding-bottom: @px / @baseFontSize * 1rem;
}
.pl(@px) {
padding-left: @px / @baseFontSize * 1rem;
}
.pr(@px) {
padding-right: @px / @baseFontSize * 1rem;
}
.padding(@tbpx,@lrpx) {
padding: @tbpx / @baseFontSize * 1rem @lrpx / @baseFontSize * 1rem;
}
.padding(@top,@left,@bottom,@right) {
.pt(@top);
.pl(@left);
.pb(@bottom);
.pr(@right);
}
.padding-rl(@rightpx,@leftpx) {
padding: 0rem @rightpx/@baseFontSize*1rem 0rem @leftpx/@baseFontSize*1rem;
}
.margin(@tbpx,@lrpx) {
margin: @tbpx / @baseFontSize * 1rem @lrpx / @baseFontSize * 1rem;
}
.margin(@top,@left,@bottom,@right) {
.mt(@top);
.ml(@left);
.mb(@bottom);
.mr(@right);
}
.border-1px(@color) {
position: relative;
&:after {
display: block;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
border-top: 1px solid @color;
content: ' ';
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2) {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
@media (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5) {
-webkit-transform: scaleY(0.7);
transform: scaleY(0.7);
}
}
}
.border-right-1px(@px,@color) {
position: relative;
&:after {
display: block;
position: absolute;
right: 1/@baseFontSize*1rem;;
bottom: 0;
width: @px/@baseFontSize*1rem;
top: 0;
background-color: @color;
content: ' ';
}
}
.border-left-1px(@px,@color) {
position: relative;
&:after {
display: block;
position: absolute;
left: 1/@baseFontSize*1rem;;
bottom: 0;
width: @px/@baseFontSize*1rem;
top: 0;
background-color: @color;
content: ' ';
}
}
.border-before-1px(@color) {
position: relative;
&:before {
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
border-top: 1/@baseFontSize*1rem solid @color;
content: ' '
}
}
.border-npx(@color,@height) {
position: relative;
&:after {
display: block;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
border-top: @height/@baseFontSize*1rem solid @color;
content: ' '
}
}
.border-none() {
&:after {
display: none;
}
}
.border-solid (@bw,@color) {
border: @bw/@baseFontSize*1rem solid @color;
}
.lh(@px) {
line-height: @px / @baseFontSize * 1rem;
}
.fs(@px) {
font-size: @px / @baseFontSize * 1rem;
}
.ellipsis2() {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
/*! autoprefixer: off */
-webkit-box-orient: vertical;
/* autoprefixer: on */
-webkit-line-clamp: 2;
}
.top(@px) {
top: @px / @baseFontSize * 1rem;
}
.left(@px) {
left: @px / @baseFontSize * 1rem;
}
.bottom(@px) {
bottom: @px / @baseFontSize * 1rem;
}
.right(@px) {
right: @px / @baseFontSize * 1rem;
}
.vertical(@px) {
vertical-align: @px / @baseFontSize * 1rem;
}
.ellipsis() {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
word-wrap: break-word;
}
.mh(@px) {
min-height: @px / @baseFontSize * 1rem;
}
.wordspacing(@px) {
word-spacing: @px / @baseFontSize * 1rem;
}
================================================
FILE: src/styles/reset.less
================================================
/**
* Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
* http://cssreset.com
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header,
menu, nav, output, ruby, section, summary,
time, mark, audio, video, input {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font-weight: normal;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, menu, nav, section {
display: block;
}
//body {
// line-height: 1;
//}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* custom */
a {
color: #7e8c8d;
-webkit-backface-visibility: hidden;
text-decoration: none;
outline: none;
}
li {
list-style: none;
}
body {
-webkit-text-size-adjust: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
================================================
FILE: src/styles/variable.less
================================================
// 项目主题颜色和主题字体大小、颜色
@base-color:#d81e06;
@base-font-color:#121007;
@base-header-color:#ffffff;
@base-header-size: 36;
@body-bg-color: #EDEFF2;
@tab-general-bg-color: rgba(255,255,255,0.95);
================================================
FILE: static/.gitkeep
================================================
================================================
FILE: static/js/flexible.js
================================================
/* eslint-disable */!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("将根据已有的meta标签来设置缩放比例");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
gitextract_uvzfa1d0/
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build/
│ ├── build.js
│ ├── check-versions.js
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ └── webpack.prod.conf.js
├── config/
│ ├── dev.env.js
│ ├── dev.mock.env.js
│ ├── dev.proxy.js
│ ├── dev.test.env.js
│ ├── dev.test.proxy.js
│ ├── index.js
│ ├── prod.env.js
│ └── prod.test.env.js
├── index.html
├── package.json
├── src/
│ ├── App.vue
│ ├── api/
│ │ └── home-api.js
│ ├── apiconfig/
│ │ └── index.js
│ ├── components/
│ │ ├── common-header.vue
│ │ └── cus-input.vue
│ ├── main.js
│ ├── mock/
│ │ ├── index.js
│ │ └── user.js
│ ├── pages/
│ │ ├── detail.vue
│ │ ├── index/
│ │ │ ├── day.vue
│ │ │ ├── footprints.vue
│ │ │ ├── home.vue
│ │ │ └── story.vue
│ │ └── index.vue
│ ├── router/
│ │ └── index.js
│ ├── store/
│ │ ├── index.js
│ │ ├── modules/
│ │ │ └── home.js
│ │ └── mutation-type.js
│ └── styles/
│ ├── base.less
│ ├── index.less
│ ├── mixin.less
│ ├── reset.less
│ └── variable.less
└── static/
├── .gitkeep
└── js/
└── flexible.js
Condensed preview — 49 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (57K chars).
[
{
"path": ".babelrc",
"chars": 230,
"preview": "{\n \"presets\": [\n [\"env\", {\n \"modules\": false,\n \"targets\": {\n \"browsers\": [\"> 1%\", \"last 2 versions\"..."
},
{
"path": ".editorconfig",
"chars": 147,
"preview": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_..."
},
{
"path": ".eslintignore",
"chars": 30,
"preview": "/build/\n/config/\n/dist/\n/*.js\n"
},
{
"path": ".eslintrc.js",
"chars": 862,
"preview": "// https://eslint.org/docs/user-guide/configuring\n\nmodule.exports = {\n root: true,\n parserOptions: {\n parser: 'babe..."
},
{
"path": ".gitignore",
"chars": 154,
"preview": ".DS_Store\nnode_modules/\n/dist/\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Editor directories and files\n.idea\n.vsc..."
},
{
"path": ".postcssrc.js",
"chars": 246,
"preview": "// https://github.com/michael-ciniawsky/postcss-load-config\n\nmodule.exports = {\n \"plugins\": {\n \"postcss-import\": {},..."
},
{
"path": "README.md",
"chars": 542,
"preview": "# myproject\n\n> A Vue.js project\n\n## Build Setup\n\n``` bash\n# install dependencies\nnpm install\n\n# serve with hot reload at..."
},
{
"path": "build/build.js",
"chars": 1198,
"preview": "'use strict'\nrequire('./check-versions')()\n\nprocess.env.NODE_ENV = 'production'\n\nconst ora = require('ora')\nconst rm = r..."
},
{
"path": "build/check-versions.js",
"chars": 1290,
"preview": "'use strict'\nconst chalk = require('chalk')\nconst semver = require('semver')\nconst packageConfig = require('../package.j..."
},
{
"path": "build/utils.js",
"chars": 2587,
"preview": "'use strict'\nconst path = require('path')\nconst config = require('../config')\nconst ExtractTextPlugin = require('extract..."
},
{
"path": "build/vue-loader.conf.js",
"chars": 553,
"preview": "'use strict'\nconst utils = require('./utils')\nconst config = require('../config')\nconst isProduction = process.env.NODE_..."
},
{
"path": "build/webpack.base.conf.js",
"chars": 2766,
"preview": "'use strict'\nconst path = require('path')\nconst utils = require('./utils')\nconst config = require('../config')\nconst vue..."
},
{
"path": "build/webpack.dev.conf.js",
"chars": 2990,
"preview": "'use strict'\nconst utils = require('./utils')\nconst webpack = require('webpack')\nconst config = require('../config')\ncon..."
},
{
"path": "build/webpack.prod.conf.js",
"chars": 5042,
"preview": "'use strict'\nconst path = require('path')\nconst utils = require('./utils')\nconst webpack = require('webpack')\nconst conf..."
},
{
"path": "config/dev.env.js",
"chars": 189,
"preview": "'use strict'\nconst merge = require('webpack-merge')\nconst prodEnv = require('./prod.env')\n\nmodule.exports = merge(prodEn..."
},
{
"path": "config/dev.mock.env.js",
"chars": 188,
"preview": "'use strict'\nconst merge = require('webpack-merge')\nconst prodEnv = require('./prod.env')\n\nmodule.exports = merge(prodEn..."
},
{
"path": "config/dev.proxy.js",
"chars": 97,
"preview": "module.exports = {\n\t'/root/': {\n\t\ttarget: 'http://114.55.72.164:8091/',\n\t\tchangeOrigin: true\n\t}\n}"
},
{
"path": "config/dev.test.env.js",
"chars": 189,
"preview": "'use strict'\nconst merge = require('webpack-merge')\nconst prodEnv = require('./prod.env')\n\nmodule.exports = merge(prodEn..."
},
{
"path": "config/dev.test.proxy.js",
"chars": 103,
"preview": "module.exports = {\n '/root/': {\n target: 'http://114.55.72.164:8091/',\n changeOrigin: true\n }\n}"
},
{
"path": "config/index.js",
"chars": 3019,
"preview": "'use strict'\n// Template version: 1.3.1\n// see http://vuejs-templates.github.io/webpack for documentation.\n\nconst path =..."
},
{
"path": "config/prod.env.js",
"chars": 94,
"preview": "'use strict'\nmodule.exports = {\n NODE_ENV: '\"production\"',\n BASE_URL: '\"\"',\n MOCK: false\n}\n"
},
{
"path": "config/prod.test.env.js",
"chars": 94,
"preview": "'use strict'\nmodule.exports = {\n NODE_ENV: '\"production\"',\n BASE_URL: '\"\"',\n MOCK: false\n}\n"
},
{
"path": "index.html",
"chars": 599,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initia..."
},
{
"path": "package.json",
"chars": 2904,
"preview": "{\n \"name\": \"myproject\",\n \"version\": \"1.0.0\",\n \"description\": \"A Vue.js project\",\n \"author\": \"MrKaKaluote <gaosongai@..."
},
{
"path": "src/App.vue",
"chars": 1363,
"preview": "<template>\n <div id=\"app\">\n <transition :name=\"transitionName\">\n <router-view class=\"Router\"></router-view>..."
},
{
"path": "src/api/home-api.js",
"chars": 217,
"preview": "/**\n * 引入fetch、baseUrl\n * @param params\n * @returns {*}\n */\nimport {fetch, baseUrl} from 'config/index'\n// 登录接口\nexport f..."
},
{
"path": "src/apiconfig/index.js",
"chars": 1249,
"preview": "/* eslint-disable */\nimport axios from 'axios'\n\n/**\n* 定义请求常量\n* TIME_OUT、ERR_OK\n*/\nexport const TIME_OUT = 1000; // 请求..."
},
{
"path": "src/components/common-header.vue",
"chars": 1972,
"preview": "<template>\n <div class=\"header-box\">\n <div class=\"left-icon\">\n <span v-if=\"showback\" @click=\"back\" class=..."
},
{
"path": "src/components/cus-input.vue",
"chars": 697,
"preview": "<template>\n <div class=\"input-box\">\n <span class=\"icon\"></span>\n <input type=\"text\" class=\"search\" placeholder=\"找..."
},
{
"path": "src/main.js",
"chars": 1574,
"preview": "// The Vue build version to load with the `import` command\n// (runtime-only or standalone) has been set in webpack.base...."
},
{
"path": "src/mock/index.js",
"chars": 344,
"preview": "/*\n * @Description: 引入mock.js及配置文件\n * @Author: MrGao\n * @LastEditors: gaosong\n * @Date: 2019-03-12 10:35:08\n * @LastEdit..."
},
{
"path": "src/mock/user.js",
"chars": 288,
"preview": "/*\n * @Description: 返回数据模板\n * @Author: gaosong\n * @LastEditors: gaosong\n * @Date: 2019-03-12 10:35:23\n * @LastEditTime:..."
},
{
"path": "src/pages/detail.vue",
"chars": 766,
"preview": "<template>\n <div class=\"content-box\">\n <common-header :tittle=\"tittle\" :showmore=\"true\"></common-header>\n <div cl..."
},
{
"path": "src/pages/index/day.vue",
"chars": 954,
"preview": "<template>\n <div class=\"content-box\">\n <common-header :tittle=\"tittle\" :showback=\"false\"></common-header>\n <div c..."
},
{
"path": "src/pages/index/footprints.vue",
"chars": 957,
"preview": "<template>\n <div class=\"content-box\">\n <common-header :tittle=\"tittle\" :showback=\"false\"></common-header>\n <div c..."
},
{
"path": "src/pages/index/home.vue",
"chars": 1398,
"preview": "<template>\n <div class=\"content-box\">\n <common-header :showinput=\"true\" :showback=\"false\"></common-header>\n <div..."
},
{
"path": "src/pages/index/story.vue",
"chars": 956,
"preview": "<template>\n <div class=\"content-box\">\n <common-header :tittle=\"tittle\" :showback=\"false\"></common-header>\n <div..."
},
{
"path": "src/pages/index.vue",
"chars": 2858,
"preview": "<template>\n <div class=\"page\">\n <keep-alive>\n <router-view></router-view>\n </keep-alive>\n <div class=\"nav..."
},
{
"path": "src/router/index.js",
"chars": 1667,
"preview": "import Vue from 'vue'\nimport Router from 'vue-router'\nVue.use(Router)\n// 需要左方向动画的路由用this.$router.to('****')\nRouter.proto..."
},
{
"path": "src/store/index.js",
"chars": 304,
"preview": "import Vue from 'vue'\nimport Vuex from 'vuex'\nimport home from './modules/home'\nimport createLogger from 'vuex/dist/logg..."
},
{
"path": "src/store/modules/home.js",
"chars": 441,
"preview": "/**\n * home.js\n * 用于home模块的状态管理\n */\n/* eslint-disable */\nimport * as types from '../mutation-type' // 引入定义的方法\nconst hom..."
},
{
"path": "src/store/mutation-type.js",
"chars": 43,
"preview": "// global\nexport const SET_NUM = 'SET_NUM'\n"
},
{
"path": "src/styles/base.less",
"chars": 721,
"preview": "@import \"variable\";\n\nbody, html {\n line-height: 1;\n font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light',..."
},
{
"path": "src/styles/index.less",
"chars": 71,
"preview": "@import \"./reset.less\";\n@import \"./mixin.less\";\n@import \"./base.less\";\n"
},
{
"path": "src/styles/mixin.less",
"chars": 3899,
"preview": "@baseFontSize: 75;\n.px2rem(@name, @px) {\n @name: @px / @baseFontSize * 1rem;\n}\n\n.flex(@a, @b, @c) {\n flex: @a @b @c/@b..."
},
{
"path": "src/styles/reset.less",
"chars": 1304,
"preview": "/**\n * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)\n * http://cssreset.com\n */\nhtml, body, di..."
},
{
"path": "src/styles/variable.less",
"chars": 189,
"preview": "// 项目主题颜色和主题字体大小、颜色\n@base-color:#d81e06;\n@base-font-color:#121007;\n@base-header-color:#ffffff;\n@base-header-size: 36;\n@b..."
},
{
"path": "static/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "static/js/flexible.js",
"chars": 1814,
"preview": "/* eslint-disable */!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.st..."
}
]
About this extraction
This page contains the full source code of the MrKaKaluote/vue-mobile GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 49 files (50.9 KB), approximately 15.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.