Commit 0790f132 authored by Nature's avatar Nature

Initial commit

parents
build/
config/
static/
{{#if test}}
test/
{{/if}}
dist/
src/assets/
src/libs/
!src/data/config/
# MacOS file
.DS_Store
# Project directories and files
node_modules/
dist/
## npm-shrinkwrap.json
## package-lock.json
## yarn.lock
npm-debug.log*
yarn-debug.log*
yarn-error.log*
{{#if test}}
test/unit/coverage/
test/e2e/reports/
selenium-debug.log
{{/if}}
# Editor directories and files
.idea/
.vscode/
*.suo
*.ntvs*
*.njsproj
*.sln
# Others
.project
*.zip
# hippius-vue-init
[查看文档](http://hmap.hand-china.com/hippius-docs/init)
```bash
# 注意将vue cli更新到最新版本,低版本可能报错
vue init https://rdc.hand-china.com/gitlab:hmap-cloud-develop/hippius-vue-init <project_name> -c
```
\ No newline at end of file
// https://vuepress.vuejs.org/zh/config
const themeConfig = require('./theme-config')
module.exports = {
base: '/hippius-docs/init/',
title: 'Hippius Init',
description: 'Hippius docs',
themeConfig,
}
$accentColor = #1F8CEB
\ No newline at end of file
// https://vuepress.vuejs.org/zh/default-theme-config
module.exports = {
nav: [{ text: '首页', link: '/' }],
sidebar: [
{
title: '初始化',
collapsable: false,
children: ['/'],
},
{
title: '开发指南',
collapsable: false,
children: ['eslint-guide', 'stylus-guide', 'http-guide', 'router-guide', 'store-guide', 'i18n-guide', 'git-commit-validate-guide'],
},
{
title: '高级配置',
collapsable: false,
children: ['env-config-guide','flexible-guide'],
},
{
title: '海马汇开发',
collapsable: false,
children: ['hmap-guide', 'hmap-deploy', 'hand-maintain'],
},
{
title: '加入我们',
collapsable: false,
children: ['join'],
},
],
}
# hippius-vue-init
## 项目初始化
```bash
# 注意将vue cli更新到最新版本,低版本可能报错
# <project_name> 替换成 项目名称
vue init https://rdc.hand-china.com/gitlab:hmap-cloud-develop/hippius-vue-init <project_name> -c
```
### 构建命令
```bash
# install dependencies
yarn
# 安装 chromedriver 可能会报错,源镜像被墙了,换成淘宝镜像
# yarn config set chromedriver_cdnurl https://npm.taobao.org/mirrors/chromedriver
# 开发环境:使用 src/data/dev.env.js 配置,with hot reload
yarn start | yarn run dev
# 构建测试环境包:使用 src/data/alpha.env.js 配置,会自动引入vConsole调试工具。输出到 /dist
yarn run build:alpha
# 构建生产环境包:使用 src/data/prod.env.js 配置。输出到 /dist
yarn run build
# build for production and view the bundle analyzer report
yarn run build --report
# run unit tests:使用 src/data/test.env.js 配置
yarn run unit
# run e2e tests
yarn run e2e
# run all tests
yarn test
```
## 目录结构
* api 目录 (存放与接口调用相关资源)
* assets 目录 (存放项目需要引用的资源)
* fonts 目录 (字体资源)
* images 目录 (图片资源)
* stylus 目录 (全局通用的 stylus 样式资源)
* components 目录 (存放项目中的 vue 组件)
* data 目录 (存放项目中需要用到的配置数据)
* i18n 目录 (存放国际化处理的数据文件)
* libs 目录 (存放一些无法通过 npm 安装的第三方库)
* router 目录 (存放 vue-router 相关配置)
* routes.js 文件 (存放 vue-router 的所有 route 配置)
* store 目录 (存放 vuex.store 相关配置)
* modules 目录 (按模块分隔 store 配置,如果是所有模块的通用配置可以直接写在 store/index.js 文件中)
* utils 目录 (存放全局共享的工具函数)
* http 目录 (存放对 axios 的一些加工处理)
* directives.js 文件 (存放全局的 vue directive)
* filters.js 文件 (存放全局的 vue filter)
* views 目录 (存放项目的所有页面展示组件)
* App.vue 文件 (主组件文件)
* main.js 文件 (入口文件)
## 全局对象
* $config (包含项目的通用配置数据,数据配置文件为 src/data/config/\*.env.js)
## 常见问题
### Failed to download ... 'git clone' failed with status 128
查看下vue-cli的版本是不是太低了:`vue --version`
推荐使用vue-cli 2.9.x 或 3.x.x
- 安装2.9.x:`npm install -g vue-cli``yarn global add vue-cli`
- 安装3.x.x:`npm install -g @vue/cli``yarn global add @vue/cli`
注意:vue-cli版本过低时可能会有个提示安装:`yarn global add @vue/cli-init`,这个命令貌似是有问题的,不要加上`-init`
### 长时间处于 download template 状态
估计是网络问题,切换下网络试试。
### babel-polyfill
babel-polyfill 在 webpack 构建过程中已注入,无需在 main.js 中重复引入!
### 项目中使用vux注意事项
安装完vux、vux-loader、less-loader之后
修改webpack.base.conf.js文件
```js
const vuxLoader = require('vux-loader')
// 将原来moudle.exports出来的对象用const webpackConfig接收
// 然后添加以下代码
module.exports = vuxLoader.merge(webpackConfig, {
plugins: [
{
name: 'vux-ui',
},
],
})
```
# 新环境数据配置指南
项目中用到的环境数据配置存放在 `data/config` 目录下,不同环境数据单独存放在一个文件中
如果要添加一个新的环境,如 UAT 环境,需要做两步操作:
* 在 package.json 文件中的 scripts 字段中添加一行脚本,推荐在打包脚本前添加 `build:` 前缀,以 UAT 环境为例,参考 dev 和 build,只需要修改 CONFIG_ENV 为对应环境即可
* UAT 开发:`"uat": "cross-env CONFIG_ENV=uat webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",`
* UAT 打包:`"build:uat": "cross-env CONFIG_ENV=uat node build/build.js",`
*`src/data/config` 目录中添加一个环境数据配置文件 `*.env.js`(\* = CONFIG_ENV,如:uat.env.js)
**注意:CONFIG_ENV 是用来指定当前脚本执行时使用哪个环境的配置数据的,所以其值必须要和自己新建的环境数据配置文件名 `uat.env.js` 中的 uat 匹配,否则将会找不到对应环境的配置数据**
_除非需要修改 webpack 配置,否则不需要添加对应环境的 webpack 配置文件_
# eslint 指南
## 风格指南
🔥 [vue 风格指南](https://cn.vuejs.org/v2/style-guide/) <br>
[eslint-standard 风格指南](https://github.com/standard/standard/blob/master/docs/README-zhcn.md)
## 配置 eslint fix
### 使用 VSCode(推荐):
1. 安装 eslint 插件:ESLint
2. 左下角设置 -> 设置 -> 用户设置中添加如下配置
```json
"eslint.autoFixOnSave": true,
"eslint.validate": [
{ "language": "javascript", "autoFix": true },
{ "language": "javascriptreact", "autoFix": true },
{ "language": "html", "autoFix": true },
{ "language": "vue", "autoFix": true }
],
```
3. 效果:编辑文件保存时会自动 fix 代码格式。
### 使用 Atom:
1. 找到 settings -> install 安装 package: 'linter-eslint'
2. 找到 settings -> package -> linter-eslint:settings 勾选 'fix errors on save' 和 'Lint HTML Files'
3. 效果:保存文件的时候会自动 fix 当前文件的代码格式
### 使用 WebStorm:(待补充)
### 使用命令行:
1. cmd/powershell/终端 进入工程目录,运行 node_modules/.bin/eslint --fix <path/fileName>
### 使用 webpack 配置(可能会有副作用)
1. /build/webpack.base.conf.js 中 找到 createLintingRule 中 option 中将 fix 改为 true
```js
const createLintingRule = () => ({
...,
options: {
...,
fix: true, // default: false. might cause webpack to enter an infinite build loop if some issues cannot be fixed properly.
},
});
```
2. 效果:webpack 编译的时候会 fix 所有文件的代码格式
## 常见问题
> 引入的全局变量提示未定义?在 ./eslintrc.js 中 ‘globals’ 中添加你的全局变量:
```js
"globals": {
navigator: false, // false 为只读(不能被复写),true 为该变量可被重写
}
```
> 如何在文件或行中部分禁用 eslint?
在.js 中:
```js
// eslint-disable-line // 当前行禁用
// eslint-disable-next-line // 下一行禁用
/* eslint-disable */ // 该行以下全部禁用
/* eslint-enable */ // 该行以下全部启用
```
在.vue template 中:
```html
<!-- eslint-disable-line -->
<!-- eslint-disable-next-line -->
<!-- eslint-disable -->
<!-- eslint-enable -->
```
## flexible 相关配置
该项目使用的是 ydui 的 flexible 方案,因为相比阿里的 flexible 方案,这套方案用起来方便的多,当前项目设置的根字体大小为 50px,如果根据实际情况确定需要修改该字体大小,修改 config/index.js 文件中 base 对象的 remUnit 即可,目前而言,绝大多数的情况下应该不需要修改。
如果有些 px 不想转换成 rem,如 1px,2px 转换之后可能由于数值太小在有些手机上不能正常显示了,可以使用`/*no*/`
* 如何修改 remUnit:
* 打开 chrome 浏览器,在手机模拟模式上切换到对应的设计稿尺寸,查看此时 html 标签上的 font-size 值,使用该值,也就是说,除非 UI 设计稿尺寸调整,否则不需要修改 remUnit。
# git 校验说明
**注意:git 的校验是通过 husky 插件来实现的,husky 插件现在有一个 bug,需要在 git init 之后再安装 husky 才能起效,所以如果你 commit 的时候发现 husky 没工作,需要重新安装下 husky:`yarn upgrade husky` 或 `yarn add husky@next --dev`**
## eslint
该项目默认启用 eslint 进行 js 代码语法检查,检查不通过时将出现以下现象:
- 开发环境代码运行报错
- git commit 无法提交成功
当你执行 git commit 时,会在代码提交之前先执行 eslint 校验暂存区中的 js 或 vue 文件,如果 eslint 语法检查不通过,将会阻止本次提交。
如果想定制 eslint 校验规则,修改 .eslintrc.js 文件,在其中的 rules 对象中添加想用的规则。
如果你的项目不想使用 eslint,将 `config/index.js` 文件中的 `dev.useEslint` 设置为 false 即可 (推荐启用 eslint)
## commit message
同 eslint 校验,提交信息也需要校验通过才能提交成功,即 `git commit -m 'xxx'` 中 xxx 必须符合提交规范。
我们采用当下流行最广的 angular 团队的规范,结构为:`<type>(<scope>): <subject>`,具体规范要求查看下面链接
- [Commit message 和 Change log 编写指南](http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html)
### 使所有项目成为 Commitizen-friendly
通常我们使用 git commit 来提交代码,如果你想使用 git cz 来代替 git commit,使提交代码时出现提交选项,可以做如下配置:
[Commitizen cz-cli - Github](https://github.com/commitizen/cz-cli)
- 全局安装 commitizen:`npm install -g commitizen`
- commitizen 提供了 git cz 命令来替代 git commit,此时 git cz 等价于 git commit
- 全局安装 commitizen 适配器:`npm install -g cz-conventional-changelog`
- 该适配器用来修改 git cz 的行为,使用这个之后 git cz 的行为和 git commit 不一样了,执行 git cz 时会出现 commit message 选项,且错误提示信息也发生改变
- 执行 CLI 在主目录中添加.czrc 配置文件:`echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc`
- 这个配置文件用来指定 commitizen 适配器路径,否则 cz-conventional-changelog 无法生效
此时在我们的任意 git 项目中都已经可以使用 commitizen 了,使用 git cz 来替代 git commit 即可,git commit 中的所有可选参数都包含在 git cz 中。
# 汉得内部子应用维护
## vue 子应用(2017-2018 初)
### 开始
[git 仓库地址](https://code.choerodon.com.cn/mobile-center-hmap/vue.git)`https://code.choerodon.com.cn/mobile-center-hmap/vue.git`
找到相应负责人申请该仓库的开发者权限。
切换到 `develop` 分支。
### 构建命令
```bash
# 开发环境运行,使用 src/config/config.json 配置
yarn dev
# 测试环境包,使用 src/config/config-test.json 配置。输出到 /dist
yarn build # 部分子应用可能为 yarn build-test ,具体需查看 package.json
# 生产环境包,使用 src/config/config-prod.json 配置。输出到 /prod
yarn build-prod
```
### 目录结构
⚠️ 主目录下每一个文件夹都是一个单独的子应用。
* common (前期部分子应用可能依赖于该文件夹)
* emp-statement (发了吗:嘉航)
* group-active (群活动)
* group-bannerMessage (banner消息:凯华)
* group-corpMessage (企业频道消息:凯华)
* group-notice (群通知)
* group-questionnaire (群问卷:嘉航)
* group-vote (群投票)
* my-footprint (我的足迹)
* my-footprint-h5 (我的足迹分享页)
* vue-bus (班车信息:凯华)
* vue-contract-manage (CRM合同管理)
* vue-house (房屋转租)
* vue-house-share (房屋转租分享页)
* vue-suggest (我要吐槽)
### 常见问题
⚠️ 需要注意有些子应用为离线子应用。判断应用类型可以查看 后台管理页面 -> 子应用管理 -> 应用详情。
> 地图开发指南
[百度地图示例](http://lbsyun.baidu.com/jsdemo.htm)
[百度地图 API](http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html)
> my-footprint(我的足迹)在开发环境中无法定位成功?
开发环境为 IP 定位,可能需要科学上网。测试/生产环境使用的是 GPS 定位,不存在此问题。
> my-footprint(我的足迹)与 my-footprint-h5(我的足迹活动页)如何通信?
my-footprint-h5 是一个单独部署的页面,通过 iframe 的方式嵌入 my-footprint 中。其中使用 postMessage 进行通信。
当 my-footprint-h5 被分享出去时,实际上是在页面链接后拼接上一个 `userId`,通过获取该字段,拿到用户的相关信息。
## ionic 子应用(2017 年前)
### 开始
[git 仓库地址](https://rdc.hand-china.com/gitlab/hmap-cloud-develop/hmap-subApp.git): `https://rdc.hand-china.com/gitlab/hmap-cloud-develop/hmap-subApp.git`
找到相应负责人申请该仓库的开发者权限。
因为历史遗留原因,所有 ionic 应用都在一个工程中,通过手动更改 app.js、gulpfile.js 等文件以达到打出不同子应用的包的目的。
**打不同包时需要修改的文件有:**
1. app/app.js
2. app/theme/app.core.scss
3. gulpfile.js(可能需要)
因为该方式过于鬼畜,所以后续的部分子应用已单独到一个 git 分支中,这样直接切换分支就行。建议后续维护的过程中,将子应用都划分到不同 git 分支。
因为历史遗留原因,**ionic 子应用无法在开发环境直接运行**,需打包到手机上才能看到效果。当然你也可以自由发挥,通过其它操作运行在开发环境。
### 构建命令
```bash
# 打包
# 不同的子应用打包命令不同,具体请查看 gulpfile.js 最底部。运行指定的 gulp task 即可
```
# 子应用部署指南
## 打包
```bash
# 测试版海马汇(测试环境)打包,输出到 /dist
yarn build:alpha
# 正式版海马汇(正式环境)打包,输出到 /dist
yarn build
```
⚠️ 不同的包与环境不能弄错,否则会造成无法登录等后果。
## 部署
### 测试环境
#### 第一步:找到相应负责人 黄昊(8467) 申请[测试环境中台](http://wechat.hand-china.com/hippius-admin)登录权限。
测试环境中台地址:`http://wechat.hand-china.com/hippius-admin`
#### 第二步:下载测试版海马汇
中台找到 应用管理 -> 应用版本管理,点击进入相应的平台。
![步骤1](img/download-1.png)
找到版本设置下的最新版本的 下载地址,复制该地址,在手机上打开下载安装。
![步骤2](img/download-2.png)
#### 第三步:中台找到 应用管理 -> 子应用管理。根据需求新建应用或编辑现有应用。
新建子应用流程:
1. 新建应用
![步骤1](img/hmap-1.png)
2. 选择`应用类型`,如果是全屏应用,需选择 `隐藏导航`
![步骤2](img/hmap-2.png)
3. 点进去你刚刚新建的应用,找到版本新建
![步骤3](img/hmap-3.png)
4. 新建版本
**在线子应用**需将打包后的 dist 文件夹重命名成子应用的名称,如 `testName` ,然后发给相应负责人上传到测试环境服务器(建议使用图形化工具操作,如 `Transmit``FileZilla`)。
代码资源为 `http://wechat.hand-china.com/hmapshowcase/oauth/authorize?&client_id=a765ff3f-8d33-49b4-a9c9-48e991544242&response_type=code&redirect_uri=http://wechat.hand-china.com/testName/index.html`
需将代码资源路径最后的 `testName` 改为你上面重命名的名称。(根据上传路径的不同,代码资源最后的 `redirect_uri` 也需相应变化)
⚠️ _一般情况下代码资源的前面部分都是固定的,只有最后的 `redirect_uri` 需要更改。如果在外交付的产品 `client_id` 有变化,则 `client_id` 也需要更改,具体参考[后端文档](https://hmap.hand-china.com/hippius-api/10013.html)_
![步骤4](img/hmap-4.png)
**离线子应用**先将 dist 文件夹压缩成 zip 包并点击 `上传包`
资源目录为 `dist/index.html`
若包文件夹名称非 `dist`,则资源目录路径也需要更改成相同名称。
⚠️ _压缩 zip 包时尽量使用操作系统自带的压缩工具,曾经有 windows 上用第三方工具压缩后打开白屏的案例。_
![步骤5](img/hmap-5.png)
5. 海马汇应用 tab 页下拉刷新,应用版本即会更新。(特殊情况可能需要杀掉进程重启海马汇或退出登录重新进入)
### 正式环境
跟测试环境部署流程相同,url 地址变更为正式环境地址。需发给有相应权限的负责人操作。
## 调试
### 方式一:vconsole 调试
通过 `yarn build:alpha` 打出的包,vconsole 会自动引入。
![调试方式1](img/hmap-test-1.png)
### 方式二:真机调试(必须是有打开调试模式的测试安装包)
**安卓**通过数据线连上电脑,chrome 中地址栏输入 `chrome://inspect/` 找到页面调试。
**iOS**需要原生帮助在你的 xcode 上跑测试版海马汇,然后打开 safari(需勾选 偏好设置 -> 高级 -> 在菜单栏中显示开发菜单),找到开发菜单中的页面调试。
![调试方式2](img/hmap-test-2.png)
### 方式三:vorlon 远程调试
[vorlon 官网](http://www.vorlonjs.com/)
# 子应用开发指南
## 开发流程
1. 在入口文件 src/main.js 中引入 hmap 环境(若项目生成的时候选择了 HMAP ,则该步骤已默认引入)
```js
// src/main.js
import '@/platform/hmap/env'
```
⚠️ 默认为 在线子应用 的环境。若为 本地子应用,可修改 `src/platform/hmap/env.js` 注释掉在线子应用部分,打开离线子应用的注释,同时删除 `static/` 下的 `cordova` 文件夹。
2. 在你需要的时机使用 hmap 登录
```js
// 在 app.vue 中
import hmapLogin from '@/platform/hmap/login'
export default {
/* ... */
async mounted() {
// Tips:hmapLogin 会自动判断环境以采用相应的登录方式,所以构建的包需放在相应的环境才能正确登录
// yarn dev 为模拟登录。yarn build:alpha 测试版海马汇环境。yarn build 正式版海马汇环境。
/**
* hmapLogin 登录总成
* @param {String} [type] 应用类型:可选:'online''local' 默认:'online'
* @param {Boolean} [needInfo] 是否需要获取用户详细信息 默认: true
* @return {Object.Promise} 返回一个promise。若登录成功PromiseValue为数据对象/登录失败PromiseValue 为 false
*/
const res = await hmapLogin()
// 使用promise写法:
hmapLogin().then(res => {})
},
/* ... */
}
```
## 参考资料
[海马汇项目实施文档](http://eco.hand-china.com/doc/hmap-cloud/latest/part5/chapter1.html)
# http 使用指南
## 说明
http 为基于 axios 二次封装,使用方式保持与 axios 一致。
[axios 官方教程](https://github.com/axios/axios)
## 使用指南
1. 在 src/api 文件夹下定义你的业务相关接口函数并导出
```js
// api/home.js中
import http from '@/utils/http'
// 注意:http 中会自动给 url 前拼接环境定义的 baseUrl。定义的 url 中无需包含 baseUrl
// 如需修改环境配置参数(如:baseUrl),可在 src/data/config 下修改
// http 中默认会携带 localStorage.token(若采用hmap login方法,localStorage.token 会在登录成功后写入),无需手动设置
// 仅仅放心的去使用它 :)
export function getSomething() {
const url = '/fetch'
return http.get(url)
}
export function postSomething(data) {
const url = '/fetch2'
return http.post(url, data)
}
```
2. 在你的 src/views/ 页面中导入你需要用到的接口函数,使用它
```js
// views/home.vue中
import { getSomething, postSomething } from 'api/home'
export default {
/* ... */
methods: {
async handle() {
// 使用 async/await 写法时方法前要加 async
// 使用 async/await 写法(推荐)
try {
const data = {} // post参数
const res = await postSomething(data) // res即为response.data
} catch (e) {
// 处理error
}
// 使用 promise 写法
getSomething()
.then(res => {
// 注意:res即为response.data,不需要进行response.data.success === true的判断
// 若项目接口无 response.data.success 字段,修改 src/utils/http/interceptors.js 第13行
})
.catch(err => {
// 所有error情况统一在此处理,包括返回状态码为200,和 response.data.success 为 false 的情况。http 内部默认会对一些错误码做提示(alert)处理
})
},
},
/* ... */
}
```
## 不统一处理接口返回的 success 字段
如果项目接口规范不到位,或者因为一些原因无法做到所有接口返回中都有 success 字段,那么可能无法对 success 字段做统一处理,需要修改下 src/utils/http/interceptors.js 文件:
```js
// 请求返回之后的预处理函数:若返回状态码为200,但实际请求未完成,将异常处理统一到错误处理
const responseAfter = response => response.data.success ? response.data : Promise.reject(response)
// 若项目接口无 response.data.success 状态字段,注释上一行,使用下行
// const responseAfter = response => response
```
改为
```js
// 请求返回之后的预处理函数:若返回状态码为200,但实际请求未完成,将异常处理统一到错误处理
// const responseAfter = response => response.data.success ? response.data : Promise.reject(response)
// 若项目接口无 response.data.success 状态字段,注释上一行,使用下行
const responseAfter = response => response
```
然后自行对每个接口单独做处理。
# i18n 极简使用指南
* [vue-i18n - github](https://github.com/kazupon/vue-i18n)
* [vuex-i18n - github](https://github.com/dkfbasel/vuex-i18n)
*i18n 配置文件在 i18n 目录中*
vue 有两个支持 i18n 的插件,vuex-i18n 使用起来舒服一些,但需要依赖 vuex,所以如果使用 cli 生成项目时,选择使用 vuex,项目中会默认配置 vuex-i18n 作为多语言插件,否则使用 vue-i18n,以下是两个插件最基本的用法,更加详细用法请自行查阅文档
**vue-i18n**
```js
// 以下三种用法都可以,但作为对象名时不能添加空格
// 如下:'project name'可以,'message key.projectName'不行
{{ $t('projectName') }}
{{ $t('message.projectName') }}
{{ $t('message-key.projectName') }}
// 切换语言
this.$i18n.locale = 'en'; // 默认是中文,zh
```
**vuex-i18n**
```js
// 以下四种用法都可以
// 数据存在store中,所有的对象子属性都会被转成store.state中的字符串键来存储,用.连接
{{ $t('projectName') }}
{{ $t('message.projectName') }}
{{ $t('message-key.projectName') }}
{{ $t('message key.projectName') }}
// 切换语言
this.$i18n.set('en'); // 默认是中文,zh
```
## 项目后期追加 i18n 配置
如果早期项目没考虑要做国际化,因此项目创建时没加入 i18n 配置,而后期需要追加国际化,此时需要做如下几步:
1. 使用初始化项目命令重新创建一个和当前项目配置相同的空项目,并选择使用 i18n
2. 将新创建项目的 src/i18n 目录拷贝到当前项目的 src 目录下
3. 将新创建项目中 src/main.js 文件中和 i18n 相关的内容,拷贝到当前项目的 src/main.js 文件中
4. 根据项目的需求安装对应的 i18n 插件,vue-i18n 或 vuex-i18n
# hippius-init 开发指南
## 快速参与
[git 仓库地址](https://rdc.hand-china.com/gitlab/hmap-cloud-develop/hippius-vue-init.git): `https://rdc.hand-china.com/gitlab/hmap-cloud-develop/hippius-vue-init.git`
方式一:
1. 找到相应负责人申请该仓库的开发者权限。
2. 修改后提交一个 pr,等待核心开发者 merge。
方式二:
1. fork 该项目。
2. 修改后提交一个 pr,等待核心开发者 merge。
## 目录结构
* docs (文档目录)
* template (模版目录)
## 模版开发
因为脚手架为一个模版,无法直接运行。
需先初始化一个完整工程,在该工程上修改并查看效果。
最后再将修改转移到模版上。
模版语法参考 [vue-template-webpack](https://github.com/vuejs-templates/webpack)
## 文档开发
```bash
# 全局安装 vuepress(注意:node 8+)
npm i -g vuepress
# 在项目目录下运行
vuepress dev docs
```
[vuepress 官方教程](https://vuepress.vuejs.org/zh/guide/)
## 文档部署
```bash
# 文档打包
vuepress build docs
```
`docs/.vuepress/dist/` 文件夹下的内容部署到服务器 static 静态文件夹下的路径 `/hippius-docs/init/`
# route 对象添加指南
* [vue-router 官方文档](https://router.vuejs.org/zh-cn/)
router 的所有配置存放在 router 目录下面,router 的配置按模块分块如果需要添加一个模块的 router 配置,只需要执行以下步骤:
1.`router/modules` 目录下添加一个 js 文件,文件名以 camel 形式命名
2. 在添加的 js 文件中添加对应模块的 route 配置,形如:
```js
import Home from '@/views/Home'
const routes = [
{
path: '/Home',
name: 'Home',
component: Home,
},
]
export default routes
```
3. 将新添加的配置文件在 `router/routes.js` 文件中引入,形如:
```js
import home from './modules/home'
export default [
...home,
{
path: '*',
redirect: '/home',
},
]
```
# vuex store 使用指南
* [vuex 官方网址](https://vuex.vuejs.org/zh-cn/)
store 配置是按模块区分的,所以添加配置时同一个模块的 store 放在一个文件中添加新的
store 配置很简单,步骤如下:
1.`store/modules` 目录下添加模块对应的 store 文件,内容格式如下:
```js
const state = {
increment: 0,
}
const getters = {}
Object.keys(state).forEach(prop => {
getters[prop] = state => state[prop]
})
const mutations = {}
Object.keys(state).forEach(prop => {
const setProp = `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`
mutations[setProp] = (state, payload) => {
state[prop] = payload
}
})
// actions不做统一处理,因为大多数情况下,并不需要使用异步设置值
// 若需要使用actions,注意:mutation_type的命名规则为set开头加上state对象属性的camel形式
// const actions = {
// async setIncrement({ commit }, value) {
// commit('setIncrement', await value);
// },
// };
const actions = {}
export default {
state,
getters,
mutations,
actions,
}
```
要添加缓存数据时,只需要在 state 对象中添加属性即可,getters 和 mutations 对象通常不需要修改
由于根据以往项目经验,很少会用到异步修改值的功能,所以 actions 没做统一处理,若需要自行拓展,按以上注释掉的部分修改即可
2.`store/index.js` 文件中引入添加的 store 文件,并在 modules 字段中注入,如下:
```js
import helloWorld from './modules/helloWorld'
export default new Vuex.Store({
modules: {
helloWorld,
},
state: {},
getters: {},
mutations: {},
actions: {},
})
```
如果有些 store 属性是全局的,不属于某个模块,可以直接在 `store/index.js` 如上几个空对象中添加
## 组件中使用 store 属性
所有的 state 中的属性都会在 getters 中生成同名的属性,以及在 mutations 中生成以 `set + 首字母大写的 state 属性` 的属性,所以用法如下:
```js
import {
mapGetters,
mapMutations,
// mapActions,
} from 'vuex'
export default {
computed: {
...mapGetters(['increment']),
},
methods: {
...mapMutations(['setIncrement']),
// ...mapActions(['setIncrement']),
click() {
this.setIncrement(this.increment + 1)
},
},
}
```
# stylus 指南
## 语法
[stylus 官网](http://stylus-lang.com/)
### 风格
> ⚠️ 因为 stylus 语法过于灵活,缺乏约束,部门将统一采用下列的风格约束。
1. 保留大括号、冒号、分号的语法(类似于 scss)。
2. 变量定义统一 $ 开头。
3. 函数/mixin 调用保留小括号,参数使用逗号隔开。
### 基础指引
```stylus
// 定义变量
$baseColor = #1F8CEB;
// 定义mixin,并给定参数默认值
do-something($color = $baseColor) {
border: 1px solid $color;
}
// 使用定义的变量和mixin
.example {
color: $baseColor;
do-something();
}
```
## 模版已带的样式
### 1px 边框
使用方式一:公共样式类
```html
<div class="border-top-line"></div>
<div class="border-bottom-line"></div>
<div class="border-left-line"></div>
<div class="border-right-line"></div>
```
使用方式二:mixin 方法
```stylus
// 引入公共变量和公共mixin
@import '../../assets/stylus/import.styl';
// 使用
.example {
// 单边边框
border-line(bottom);
border-line(top);
border-line(left);
border-line(right);
// 改变颜色
border-line(bottom, #000);
// 四周边框
border-radius-line();
// 改变颜色
border-radius-line(#000);
// 加上圆角
border-radius-line(#000, 20px);
}
```
## 常见问题
> 为什么是 stylus 而不是 sass/scss ?
1. 为了规避 node-sass 因为一些原因可能导致的安装失败和编译时间过长的问题。
2. stylus 的语法更接近 js,更强大,更友好。
> 特殊情况下,如何规避工程默认的 px 自动转换成 rem?
在该行样式的后面加上 `/*no*/` ,则该行的 `px` 单位不会被转换为 `rem`
```stylus
border: 1px solid #000; /*no*/
```
const path = require('path')
const fs = require('fs')
/**
* Sorts dependencies in package.json alphabetically.
* They are unsorted because they were grouped for the handlebars helpers
* @param {object} data Data from questionnaire
*/
function sortDependencies(data) {
// Code from https://github.com/vuejs-templates/webpack/blob/develop/utils/index.js
const packageJsonFile = path.join(data.inPlace ? '' : data.destDirName, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonFile))
packageJson.devDependencies = sortObject(packageJson.devDependencies)
packageJson.dependencies = sortObject(packageJson.dependencies)
fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2) + '\n')
}
function sortObject(object) {
// Based on https://github.com/yarnpkg/yarn/blob/v1.3.2/src/config.js#L79-L85
const sortedObject = {}
Object.keys(object)
.sort()
.forEach(item => {
sortedObject[item] = object[item]
})
return sortedObject
}
module.exports = {
helpers: {},
prompts: {
name: {
type: 'string',
required: true,
message: 'Project name',
},
description: {
type: 'string',
required: false,
message: 'Project description',
default: 'A Vue.js project',
},
author: {
type: 'string',
message: 'Author',
},
bp:{
type: 'confirm',
message: 'install partner modules in App?',
},
project:{
type: 'confirm',
message: 'install project modules in App?',
},
contract:{
type: 'confirm',
message: 'install contract modules in App?',
},
wfl:{
type: 'confirm',
message: 'install workflow modules in App?',
},
calculate:{
type: 'confirm',
message: 'install calculate modules in App?',
},
riskstrom:{
type: 'confirm',
message: 'install riskstrom modules in App?',
},
robot:{
type: 'confirm',
message: 'install robot modules in App?',
},
esign:{
type: 'confirm',
message: 'install esign modules in App?',
},
report:{
type: 'confirm',
message: 'install report modules in App?',
},
qixin:{
type: 'confirm',
message: 'install QiXinBao modules in App?',
},
ocr:{
type: 'confirm',
message: 'install ocr modules in App?',
},
},
filters: {
'src/pages/applications/partnerManager/**/*': 'bp',
'scr/pages/applications/workflow/**/*' :'wfl',
'src/pages/applications/financCalculate/**/*': 'calculate',
'src/pages/applications/projectManager/**/*': 'project',
'src/pages/applications/contractSign/**/*': 'contract',
'src/pages/applications/contractMainten/**/*': 'contract',
'src/pages/applications/riskStorm/**/*': 'riskstrom',
'src/pages/applications/robot/**/*': 'robot',
'src/pages/applications/esign/**/*': 'esign',
'src/pages/applications/reports/**/*': 'report',
'src/pages/applications/qiXinBao/**/*': 'qixin',
'src/pages/applications/ocrIdentify/**/*': 'ocr'
},
complete(data, { chalk }) {
sortDependencies(data)
},
}
{
"presets": [
["env", {
"modules": false
}],
"stage-2"
],
"plugins": ["transform-runtime"]
}
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
build/
config/
static/
test/
dist/
src/assets/
src/libs/
!src/data/config/
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
// 指定环境
env: {
browser: true,
node: true,
jest: true,
es6: true,
},
// 全局变量
"globals": {
navigator: false,
cordova: false,
HandBridge: false,
process: true,
$config: true,
JMessagePlugin:true,
vum:true,
hlsPopup:true,
hlsHttp:true,
hlsUtil:true,
wx:true
},
// 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.
extends: ['plugin:vue/recommended', 'standard'],
// required to lint *.vue files
plugins: ['vue', 'import'],
// check if imports actually resolve
settings: {
'import/resolver': {
webpack: {
config: 'build/webpack.base.conf.js'
}
}
},
// add your custom rules here
// "off" 或 0 - 关闭规则
// "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
// "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
rules: {
// 以下为自定义的 javascript 规则:
// 箭头函数当只有一个参数时允许省略圆括号
'arrow-parens': 0,
// 允许生成器
'generator-star-spacing': 0,
// 对象和数组结尾强制分号
"comma-dangle": [2, {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "ignore",
}],
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
"no-array-constructor": 0,
"no-irregular-whitespace": 0,
"no-new-wrappers": 0,
"no-alert": 0,
"no-eq-null": 2,
// 以下为自定义的 plugin-vue 规则:
// 单行中允许多个属性
"vue/max-attributes-per-line": ['error', {
"singleline": 4,
"multiline": {
"max": 4,
"allowFirstLine": false
}
}],
// 关闭属性名必须是 '-' 连接
"vue/attribute-hyphenation": 0,
"vue/require-v-for-key": 0,
// 以下为自定义的 plugin-import 规则:
// https://github.com/benmosher/eslint-plugin-import
// don't require .vue extension when importing
'import/extensions': ['error', 'always', {
js: 'never',
vue: 'never'
}],
// allow optionalDependencies
'import/no-extraneous-dependencies': ['error', {
optionalDependencies: ['test/unit/index.js']
}],
// 关闭必须默认输出
'import/prefer-default-export': ['off'],
}
}
.DS_Store
node_modules/
platforms/
www/
.idea/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*~
*.sw[mnpcod]
*.log
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
Thumbs.db
UserInterfaceState.xcuserstate
# OS X
.DS_Store
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
// to edit target browsers: use "browserslist" field in package.json
"postcss-import": {},
"autoprefixer": {}
}
}
*.min.css
iconfont.css
// https://stylelint.io/user-guide/configuration
module.exports = {
defaultSeverity: 'warning',
extends: 'stylelint-config-standard',
rules: {
'rule-empty-line-before': null,
'selector-list-comma-newline-after': 'always-multi-line',
},
};
# hls-car-vue
> A Vue.js project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# 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).
### 文件命名规范
1. 文件夹全部采用驼峰命名法,即首字母小写后面每个单词首字母大写
2. 文件名全部使用小写字母,单词与单词之间采用**-**连接,如 **user-info.vue,user-info-detail.vue**,
3. 路由的注册 `import` 语句后的单词采用 Pascal命名法,所有单词的首字母大写,其余字母小写,单词与单词之间不使用任何符号风格。如
```javascript
import HomeManager from '@/pages/homeManager/home-manager'
import LoadMore from '@/pages/loadMore/load-more'
import UserInfo from '@/pages/userInfo/user-info'
import UserInfoDetail from '@/pages/userInfo/user-info-detail'
```
4. 实际路由注册需安照如下写法,`path``/tab/文件名`,`/tab`是否保留视实际情况而定。`component`后接的单词需和`import`的单词保持一致,`name`后接的单词也需和`import`的单词保持一致
```javascript
{path: "/tab/home-manager", component: HomeManager, name: 'HomeManager', meta: {keepAlive: true}},
{path: '/tab/load-more', component: LoadMore, name: 'LoadMore', meta: {keepAlive: true}},
{path: '/tab/user-info', component: UserInfo, name: 'UserInfo', meta: {keepAlive: true}},
```
# keyStore签名信息
keystore文件 hlscar.keystore
别名 HLSkey
密码 com.hls.easy.car
# 签名
jarsigner -verbose -keystore hls.keystore -signedjar 车租易.apk hls.apk HLSkey
# 打包冲突解决
各项目如果安装了 com.hls.plugins.barcode 扫码插件与cordova-plugin-open-camera 媒体插件
两个插件之间存在一些冲突 请注释掉媒体插件 plugin.xml 第83行 <uses-feature android:name="android.hardware.camera" />
'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, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
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'
))
})
})
'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)
}
}
require('./check-versions')()
var config = require('../config')
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable
var app = express()
var compiler = webpack(webpackConfig)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(options.filter || context, options))
})
// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())
// serve webpack bundle output
app.use(devMiddleware)
// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)
// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
var uri = 'http://localhost:' + port
var _resolve
var readyPromise = new Promise(resolve => {
_resolve = resolve
})
console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
console.log('> Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
_resolve()
})
var server = app.listen(port)
module.exports = {
ready: readyPromise,
close: () => {
server.close()
}
}
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const pkg = 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 px2remLoader = {
loader: 'px2rem-loader',
options: {
remUnit: options.remUnit,
},
};
var 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,px2remLoader] : [cssLoader]
let loaders = options.useFlexible ? [cssLoader, px2remLoader]: [cssLoader]
loaders = options.usePostCSS ? [...loaders, postcssLoader] : loaders
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',
publicPath:'../../'
})
} 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 = function () {
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: pkg.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'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({
useFlexible: config.base.useFlexible,
remUnit: config.base.remUnit,
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: 'src',
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const vuxLoader = require('vux-loader')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
let webpackConfig = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
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'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'),resolve('node_modules/hls-easy-ui/packages')]
},
{
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]')
}
}
]
}
}
module.exports = vuxLoader.merge(webpackConfig, {
plugins: [
'vux-ui',
'progress-bar',
{
name: 'duplicate-style',
options: {
cssProcessorOptions : {
safe: true,
zindex: false,
autoprefixer: {
add: true,
browsers: [
'iOS >= 7',
'Android >= 4.1'
]
}
}
}
},
{name: 'less-theme', path: 'src/styles/variables.less'}
]
})
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
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: true,
hot: true,
compress: true,
host: process.env.HOST || config.dev.host,
port: process.env.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': require('../config/dev.env'),
$config: require('../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
}),
]
})
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://${config.dev.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
'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')
//console.log(config)
const env = require(`../config/${config.ENV}.env`)
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: false
})
},
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,
$config: env,
}),
// UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_debugger: !env.debug,
drop_console: !env.debug
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// set the following option to `true` if you want to extract CSS from
// codesplit chunks into this main css file as well.
// This will result in *all* of your app's CSS being loaded upfront.
allChunks: false,
}),
// 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 vender 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: function (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.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.hls.easy.car" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>车租易 ToC</name>
<description>
测试环境版
</description>
<author email="jingchao.wu@hand-china.com" href="http://example.com.com/">
chris
</author>
<content src="index.html"/>
<access origin="*"/>
<access origin="mailto:*" launch-external="yes"/>
<access origin="tel:*" launch-external="yes"/>
<allow-intent href="mailto:*"/>
<allow-intent href="tel:*"/>
<allow-navigation href="mailto:*"/>
<allow-navigation href="tel:*"/>
<allow-navigation href="http://wechat.hand-china.com/*" />
<allow-navigation href="https://www.pgyer.com/*"/>
<access launch-external="yes" origin="tel:*"/>
<access launch-external="yes" origin="sms:*"/>
<preference name="ScrollEnabled" value="false" />
<preference name="android-minSdkVersion" value="19" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="false" />
<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="3000" />
<preference name="android-windowSoftInputMode" value="adjustPan|stateAlwaysHidden"/>
<preference name="KeyboardDisplayRequiresUserAction" value="false"/>
<feature name="StatusBar">
<param name="ios-package" onload="true" value="CDVStatusBar"/>
</feature>
<platform name="android">
<allow-intent href="market:*" />
<hook src="hooks/copy-build-extras-gradle.js" type="before_build"/>
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
<icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
<icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
<icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
<icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
<icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
<splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
<splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
<splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
<splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
<splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
<splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
<splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
<splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
<splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
<splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
<splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
<splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
<preference name="webviewbounce" value="false"/>
<preference name="UIWebViewBounce" value="false"/>
<icon src="resources/ios/icon/icon-small@3x.png"/>
<preference name="xwalkVersion" value="19+"/>
<preference name="xwalkCommandLine" value="--disable-pull-to-refresh-effect"/>
<preference name="xwalkMode" value="embedded"/>
<preference name="xwalkMultipleApk" value="true"/>
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<icon height="57" src="resources/ios/icon/icon.png" width="57" />
<icon height="114" src="resources/ios/icon/icon@2x.png" width="114" />
<icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
<icon height="80" src="resources/ios/icon/icon-40@2x.png" width="80" />
<icon height="120" src="resources/ios/icon/icon-40@3x.png" width="120" />
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
<icon height="100" src="resources/ios/icon/icon-50@2x.png" width="100" />
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
<icon height="120" src="resources/ios/icon/icon-60@2x.png" width="120" />
<icon height="180" src="resources/ios/icon/icon-60@3x.png" width="180" />
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
<icon height="144" src="resources/ios/icon/icon-72@2x.png" width="144" />
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
<icon height="152" src="resources/ios/icon/icon-76@2x.png" width="152" />
<icon height="167" src="resources/ios/icon/icon-83.5@2x.png" width="167" />
<icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-small@2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-small@3x.png" width="87" />
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
<splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
<splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
<splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
<splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
<splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
<splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
<splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
<splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
<splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
<splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
<splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
<splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
</platform>
<plugin name="cordova-plugin-whitelist" spec="1.3.3" />
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-device" spec="2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
<plugin name="ionic-plugin-keyboard" spec="^2.2.1" />
</widget>
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: true,
isMobilePlatform: false,
appCode:'"HLS_APP"',
clearTable: true,
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"',
wxCode:"'hlsWx'",
uploadSysName:"'HLS_APP'",
uploadApiName:"'attachment_upload'"
});
'use strict'
// Template version: 1.2.4
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
const CONFIG_ENV = process.env.CONFIG_ENV
module.exports = {
ENV:CONFIG_ENV,
base: {
// Use Flexible?
useFlexible: true,
remUnit: 50, // 启用flexible时的根字体大小(px)
// Use PostCSS?
usePostCSS: false,
},
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
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: '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,
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false,
ENV:CONFIG_ENV
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../www/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../www'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// 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,
ENV:CONFIG_ENV
}
}
'use strict'
module.exports = {
NODE_ENV: '"production"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: false,
isMobilePlatform: false,
appCode:'"HLS_APP"',
clearTable: true,
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"',
wxCode:"'hlsWx'",
uploadSysName:"'HLS_APP'",
uploadApiName:"'attachment_upload'"
}
'use strict'
module.exports = {
NODE_ENV: '"production"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: true,
isMobilePlatform: false,
appCode:'"HLS_APP"',
clearTable: true,
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"',
wxCode:"'hlsWx'",
uploadSysName:"'HLS_APP'",
uploadApiName:"'attachment_upload'"
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, width=device-width, viewport-fit=cover">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="email=no">
<!-- safari私有meta标签 允许全屏模式浏览 指定safari顶部状态栏样式(黑色) -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<!-- <script type="text/javascript" src="../../cordova.js"></script>-->
<script src="./static/signature-pad-min.js"></script>
<!-- <script src="./static/jquery-2-1-1.js"></script>-->
<script src="./static/jquery-touch-punch-min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/f2/3.3.5/f2-all.min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/lodash-4.17.4.min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
<script src="https://gw.alipayobjects.com/os/rmsportal/NjNldKHIVQRozfbAOJUW.js"></script>
<title>车租易</title>
</head>
<body>
<div id="app-box"></div>
<!-- built files will be auto injected -->
</body>
</html>
{
"name": "{{ name }}",
"version": "1.0.0",
"description": "{{ description }}",
"author": "{{ author }}",
"private": true,
"scripts": {
"dev": "cross-env CONFIG_ENV=dev webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build:uat": "cross-env CONFIG_ENV=uat node build/build.js",
"build": "cross-env CONFIG_ENV=prod node build/build.js",
"clean": "rimraf www/*"
},
"dependencies": {
"autosize": "^3.0.20",
"better-scroll": "^1.10.3",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vux": "^2.9.2",
"hls-easy-ui": "https://hel.hand-china.com/easyUI/hls-easy-ui.git"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-loader": "^7.1.1",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^2.0.1",
"connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^5.2.0",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-import-resolver-webpack": "^0.8.3",
"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.5.0",
"eventsource-polyfill": "^0.9.6",
"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": "^2.7.1",
"less-loader": "^2.2.3",
"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",
"prelude-ls": "^1.1.2",
"px2rem-loader": "^0.1.9",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"stylelint": "^8.0.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-webpack-plugin": "^0.10.4",
"style-loader": "^0.21.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"url-loader": "^0.5.8",
"vconsole": "^3.2.0",
"vue-infinite-scroll": "^2.0.2",
"vue-loader": "^13.3.0",
"vue-loading-template": "^1.3.0",
"vue-slim-better-scroll": "^1.4.1",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"vux-loader": "^1.2.9",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-middleware": "^1.10.0",
"webpack-dev-server": "^2.9.1",
"webpack-hot-middleware": "^2.16.1",
"webpack-merge": "^4.1.0",
"yaml-loader": "^0.4.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"iOS >= 7",
"Android >= 4.1"
]
}
<template>
<div id="app">
<transition :name="transitionName">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
</transition>
<transition :name="transitionName">
<router-view v-if="!$route.meta.keepAlive"/>
</transition>
</div>
</template>
<script>
export default {
data () {
return {
pathList: [],
transitionName: 'slide-left',
}
},
watch: { // 监听路由变化
$route (to, from) {
// debugger;
if (this.pathList.includes(to.path)) {
const index = (this.pathList.findIndex(() => {
return from.path
}))
this.pathList.splice(index, 1)
this.$router.isBack = true
} else {
this.pathList.push(to.path)
this.$router.isBack = false
}
if (to.path === '/home') {
this.$router.isBack = true
this.pathList = []
}
this.transitionName = 'router-slide-right'
/*let isBack = this.$router.isBack
if (isBack) {
this.transitionName = 'router-slide-right'
} else {
this.transitionName = 'router-slide-left'
}*/
this.$router.isBack = false
},
},
mounted () {
// this.getAccessToken()
},
methods: {
getAccessToken () {
let vm = this
let url = process.env.loginPath + 'appadmin'
let param = {}
vm.hlsHttp.post(url, param).then(function (res) {
window.localStorage.setItem('access_token', res.access_token)
})
},
onSwipeLeft () {
this.$router.go(-1)
},
},
}
</script>
<style lang="less">
@import "styles/variables";
@import "styles/platform-wx";
html, body, #app {
height: 100%;
width: 100%;
overflow-x: hidden;
}
//overflow: auto;
//-webkit-overflow-scrolling: touch;
//overflow-scrolling: touch;
</style>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment