Commit bd130f02 authored by nature's avatar nature

使用vw替换rem

parent 62636c4b
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
// to edit target browsers: use "browserslist" field in package.json
"postcss-import": {},
"autoprefixer": {}
}
plugins: {
'autoprefixer': {
browsers: ['Android >= 4.0', 'iOS >= 7'],
},
//'postcss-aspect-ratio-mini': {},
'postcss-px-to-viewport': {
viewportWidth: 375,
// 视窗的宽度,对应的是我们设计稿的宽度,一般是750
// viewportHeight: 750,
// 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
unitPrecision: 3,
// 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
viewportUnit: 'vw',
// 指定需要转换成的视窗单位,建议使用vw
selectorBlackList: [
'.ignore',
'.hairlines',
],
// 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
minPixelValue: 1,
// 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
mediaQuery: true, // 允许在媒体查询中转换`px`
},
'cssnano': {
autoprefixer: false,
'postcss-zindex': false,
},
},
}
......@@ -19,7 +19,7 @@ const webpackConfig = merge(baseWebpackConfig, {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: false
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
......
......@@ -10,10 +10,10 @@ module.exports = {
ENV:CONFIG_ENV,
base: {
// Use Flexible?
useFlexible: true,
useFlexible: false,
remUnit: 50, // 启用flexible时的根字体大小(px)
// Use PostCSS?
usePostCSS: false,
usePostCSS: true,
},
dev: {
......
......@@ -57,6 +57,7 @@
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-px-to-viewport": "^1.1.1",
"prelude-ls": "^1.1.2",
"px2rem-loader": "^0.1.9",
"rimraf": "^2.6.0",
......
......@@ -50,7 +50,7 @@ export default {
<style lang="less">
@import "styles/variables";
@import "~hls-easy-ui/packages/common/styles/publicStyle";
html, body, #app {
height: 100%;
width: 100%;
......
......@@ -4,20 +4,9 @@ import Vue from 'vue'
// import FastClick from 'fastclick'
import App from './App'
import router from './router/index'
import flexible from './common/ydui.flexible'
// import flexible from './common/ydui.flexible'
import {componentInstall, appStyle} from 'hls-easy-ui'
/**
* 指令
*/
import directives from './scripts/directives'
import filter from './scripts/filter'
/**
* 弹框组件
*/
import hlsPopup from './scripts/hlsPopup'
import {componentInstall, hlsPopup, directives, filter} from 'hls-easy-ui'
/**
* http
......@@ -42,8 +31,6 @@ Vue.use(filter)
*/
Vue.use(componentInstall)
Vue.use(appStyle)
Vue.use(flexible)
Vue.prototype.hlsPopup = window.hlsPopup = hlsPopup
Vue.prototype.$devicePixelRatio = 2
......@@ -70,23 +57,6 @@ let routeGo = function (index) {
}
Vue.prototype.$routeGo = routeGo
/*let hlsExit = function () {
if (vum.Platform.isIOS()) {
cordova.exec(null, null, 'BridgePlugin', 'closeWebView', [])
} else {
var dict = {
'className': 'WebBridge',
'function': 'close',
'successCallBack': 'sCallBack',
'failureCallBack': 'eCallBack',
}
HandBridge.postMessage(JSON.stringify(dict))
}
}
Vue.prototype.$hlsExit = hlsExit*/
// FastClick.attach(document.body)
Vue.config.productionTip = true
/* eslint-disable no-new */
......
<template>
<h-view id="home" class="public-style" title="车租易" >
<h-view class="home public-style" title="车租易" >
<h-header>
<div slot="left" class="h-header-btn" @click="$hlsExit()">
<div slot="left" class="h-header-btn">
<i class="ion-ios-arrow-back"/>
</div>
<div slot="center">车租易</div>
......@@ -11,7 +11,7 @@
<tab-item>Vue</tab-item>
</s-tab>
<h-content>
<div class="icon">
<div class="logo">
<img src="@/assets/image/icon.png">
</div>
<h3>Welcome to Your Vue.js App</h3>
......@@ -20,34 +20,33 @@
</h-view>
</template>
<script>
export default {
data () {
return {
fileList: [],
}
},
activated: function () {
},
updated: function () {
export default {
data () {
return {
fileList: [],
}
},
activated: function () {
},
methods: {
tabClick (index) {
console.log(index)
},
},
}
</script>
<style lang="less" scoped type="text/less">
updated: function () {
#home {
},
methods: {
tabClick (index) {
console.log(index)
},
},
}
</script>
<style lang="less" type="text/less">
.home {
.content{
display: flex;
align-items: center;
flex-direction: column;
font-size: 24px;
.icon{
.logo{
margin-top: 60px;
margin-bottom: 20px;
width: 100px;
......@@ -62,7 +61,7 @@ export default {
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios {
#home{
.home{
}
}
}
......@@ -71,7 +70,7 @@ export default {
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios {
.platform-ios {
#home{
.home{
}
}
}
......
This diff is collapsed.
export default{
createElement: function (marker, tag) {
let el = document.createElement(tag || 'div')
el.setAttribute(marker, '')
document.body.appendChild(el)
},
removeElement: function (marker) {
let el = document.querySelector(marker) || document.querySelector(`[${marker}]`)
if (el) { document.body.removeChild(el) }
},
timeout: function (duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration)
})
},
}
export default (Vue) => {
Vue.filter('currency', function (val) {
if (!val) return '0.00'
var intPart = parseInt(Number(val)) // 获取整数部分
var intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
var floatPart = '.00' // 预定义小数部分
var value2Array = (val + '').split('.')
// =2表示数据有小数位
if (value2Array.length === 2) {
floatPart = value2Array[1].toString() // 拿到小数部分
if (floatPart.length === 1) { // 补0,实际上用不着
return intPartFormat + '.' + floatPart + '0'
} else {
return intPartFormat + '.' + floatPart
}
} else {
return intPartFormat + floatPart
}
})
Vue.filter('uncurrency', function (val) {
if (!val) return null
return Number((val).replace(/,/gi, ''))
})
Vue.filter('datetime', timestamp => {
function format (number) {
return number.toString().padStart(2, '0')
}
const date = new Date(Number.parseInt(timestamp, 10))
const YYYY = date.getFullYear()
const MM = date.getMonth() + 1
const DD = date.getDate()
const hh = date.getHours()
const mm = date.getMinutes()
const ss = date.getSeconds()
return `${YYYY}-${format(MM)}-${format(DD)} ${format(hh)}:${format(mm)}:${format(ss)}`
})
}
// 引入axios
import axios from 'axios'
import hlsPopup from './hlsPopup'
import {hlsPopup} from 'hls-easy-ui'
import router from '../router/index'
let promiseArr = {}
let cancel = {}
......
import Vue from 'vue'
import {ToastPlugin, AlertPlugin, ConfirmPlugin, LoadingPlugin, DatetimePlugin} from 'vux'
import {ActionSheetPlugin, ShowPicturePlugin, SelectPlugin, NotifyPlugin, NumberKeyboardPlugin} from 'hls-easy-ui'
Vue.use(ToastPlugin)
Vue.use(AlertPlugin)
Vue.use(ConfirmPlugin)
Vue.use(LoadingPlugin)
Vue.use(DatetimePlugin)
Vue.use(ActionSheetPlugin)
Vue.use(ShowPicturePlugin)
Vue.use(SelectPlugin)
Vue.use(NumberKeyboardPlugin)
Vue.use(NotifyPlugin)
export default {
isLoading: false,
SHOW_TIMES: 2000,
IS_SHOW_MASK: true,
/**
* 锁屏函数 超过10s后自动解屏用于防止屏幕锁死
* 自动截屏成弹出错误提示框
* @param content 锁屏内容
*/
showLoading: function (content) {
let vm = this
Vue.$vux.loading.show({
text: content || 'Loading',
})
this.isLoading = true
// 10s后自动解屏用于防止屏幕锁死
setTimeout(() => {
if (vm.isLoading) {
Vue.$vux.loading.hide()
vm.isLoading = false
// 弹出操作失败
/* Vue.$vux.toast.show({
text: '操作失败',
type: 'warn',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'middle',
}) */
}
}, 40000)
},
/**
* 隐藏
*/
hideLoading: function () {
Vue.$vux.loading.hide()
this.isLoading = false
},
/**
* 长时间顶部提示toast
* @param content
*/
showLongTop: function (content) {
let vm = this
let text = content || '操作失败'
Vue.$vux.toast.show({
text: text,
type: 'text',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'top',
})
},
/**
* 长时间中部提示toast
* @param content
*/
showLongCenter: function (content) {
let vm = this
let text = content || '操作失败'
Vue.$vux.toast.show({
text: text,
type: 'text',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'middle',
})
},
/**
* 长时间中部提示toast
* @param content
*/
showLongBottom: function (content) {
let vm = this
let text = content || '操作失败'
Vue.$vux.toast.show({
text: text,
time: vm.SHOW_TIMES,
type: 'text',
isShowMask: vm.IS_SHOW_MASK,
position: 'bottom',
})
},
/**
* 成功提示框
* @param content
*/
showSuccess: function (content) {
let vm = this
Vue.$vux.toast.show({
text: content || '操作成功',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
type: 'success',
position: 'middle',
})
},
/**
* 成功提示框
* @param content
*/
showError: function (content) {
let vm = this
Vue.$vux.toast.show({
text: content || '操作失败',
type: 'warn',
isShowMask: vm.IS_SHOW_MASK,
time: vm.SHOW_TIMES,
position: 'middle',
})
},
/**
* 弹出是否确认的窗口
* @param confirmObject.title 标题
* @param confirmObject.content 内容
* @param confirmObject.onConfirm 确定函数
*/
showConfirm: function (confirmObject) {
let def = {
title: confirmObject.title || '提示',
content: confirmObject.content || '',
confirmText: '确定',
cancelText: '取消',
onConfirm: () => {
confirmObject.onConfirm(1)
},
onCancel: () => {
confirmObject.onConfirm(0)
},
}
Vue.$vux.confirm.show(def)
},
/*
* 弹出确认的窗口
* @param confirmObject.title 标题
* @param confirmObject.content 内容
* @param confirmObject.onConfirm 确定函数
*
*/
showPopup: function (confirmObject) {
let def = {
title: confirmObject.title || '提示',
content: confirmObject.content || '',
confirmText: '确定',
showCancelButton: false,
onConfirm: () => {
confirmObject.onConfirm()
},
}
Vue.$vux.confirm.show(def)
},
/**
* @param actionObject.titleText 弹出框的标题可空
* @param actionObject.callback 点击按钮的回调函数 回传buttonArray数组下标
* @param actionObject.buttonArray 按钮数组支持[string,string],[object,object],
* 当为后一种是 object为{text:'拍照',type:'primary'},type支持 primary,warn,disabled
*
* {
* titleText: '照片',
* buttonArray: [{text:'拍照',type:'warn'}, {text:'从相册取',type:'primary'}],
* callback: (index) => {
* alert(index);
* }
* }
*
* {
* buttonArray: ['拍照','从相册取'],
* callback: (index) => {
* alert(index);
* }
* }
*
*/
showActionSheet: function (actionObject) {
if (typeof actionObject === 'object') {
let buttons = []
for (let i = 0; i < actionObject.buttonArray.length; i++) {
if (typeof actionObject.buttonArray[i] === 'object') {
buttons.push({
text: actionObject.buttonArray[i].text,
type: actionObject.buttonArray[i].type,
callback: actionObject.callback,
})
} else {
buttons.push({
text: actionObject.buttonArray[i],
callback: actionObject.callback,
})
}
}
ActionSheetPlugin.show({
title: actionObject.titleText || '',
buttons: buttons,
})
}
},
/**
* 时间选择函数
* @param timeObject.nowDate 当前展示的时间 可不填
* @param timeObject.format 时间格式支持不支持秒
* @param timeObject.callback 点击确定的回调函数
*
*/
showTime: function (timeObject) {
let date = new Date().format('yyyy-MM-dd')
let format = 'YYYY-MM-DD'
if (timeObject.nowDate) {
date = timeObject.nowDate
}
if (timeObject.format) {
format = timeObject.format
}
Vue.$vux.datetime.show({
cancelText: '取消',
confirmText: '确定',
minYear: '1900',
maxYear: '2200',
format: format,
value: date,
onConfirm (val) {
timeObject.callback(val)
},
})
},
/**
* 图片放大预览
* @param imgObject.imgUrl
*/
showBigPicture: function (imgObject) {
if (typeof imgObject === 'object') {
ShowPicturePlugin.show({
imgUrl: imgObject.imgUrl,
width: imgObject.width,
imgList: imgObject.imgList,
startPosition: imgObject.startPosition,
})
}
},
/**
* 下拉框 支持级联操作 需指定 parent 属性
* @param selectOption.list Array [{"code": "NP","code_name": "个人"}]
* @param selectOption.code String "bp_type"
* @param selectOption.object Object 当前数据对象
* @param selectOption.returnItem function 回调函数返回index与object
* var bp_class_list = [
* {
* "code": "NP",
* "code_name": "个人"
* },{
* "code": "NP1",
* "code_name": "个人1"
* }];
* hlsPopup.selectList({
* list: bp_class_list,
* code: 'bp_type',
* object: {},
* returnItem: function (index, obj) {
* console.log(obj)
* }
* })
*
*/
selectList: function (selectOption) {
if (typeof selectOption === 'object') {
let list = []
let length = selectOption.list.length
vum.forEach(selectOption.list, function (date, index, array) {
list.push({
value: date.code,
name: date.code_name,
parent: date.parent,
})
if (index === (length - 1)) {
SelectPlugin.show({
list: list,
callBack: selectOption.returnItem,
code: selectOption.code,
object: selectOption.object,
})
}
})
}
},
/**
* 弹出数字键盘
* @param keyboardObject.title 键盘的title
* @param keyboardObject.closeButtonText 键盘的关闭按钮文字
* @param keyboardObject.keyDown 普通按键按下去事件
* @param keyboardObject.keyDelete 删除按键按下去事件
*/
showNumberKeyborad: function (keyboardObject) {
if (typeof keyboardObject === 'object') {
NumberKeyboardPlugin.show({
title: keyboardObject.title,
closeButtonText: keyboardObject.closeButtonText,
extraKey: keyboardObject.extraKey || '.',
keyDown: function (text) {
keyboardObject.keyDown(text)
},
keyDelete: function () {
keyboardObject.keyDelete()
// console.log('delete')
},
})
}
},
/**
* 弹出Notify
* @param notifyObject.content 内容
* @param notifyObject.position 位置
* @param notifyObject.time 显示时长
* @param notifyObject.type 类型 success warning default
*/
showNotify: function (notifyObject) {
if (typeof notifyObject === 'object') {
NotifyPlugin.show({
show: true,
content: notifyObject.content,
position: notifyObject.position || 'top',
time: notifyObject.time || 3000,
type: notifyObject.type || 'default',
})
}
},
}
/**
* hmap子应用登录逻辑
* @author momoko 2018/05/08
*/
import axios from 'axios'
import { getUrlParam } from './utils'
// 模拟登录
export function analogLogin () {
return new Promise((resolve, reject) => {
const url = `${$config.hmapUrl}/oauth/token?client_id=18f58010-2831-11e8-b467-0ed5f89f718b&client_secret=2fe58f36-2831-11e8-b467-0ed5f89f718b&grant_type=password&username=%2B8618325379820&password=jingchaowu520&authType=TEL`
axios.post(url).then(res => {
window.localStorage.setItem('token', res.access_token)
resolve({
token: res.access_token,
tokenType: res.token_type,
expires: res.expires_in,
userId: res.userId,
organizationId: res.organizationId,
})
})
})
}
// 授权码登录
export async function authorizedLogin () {
return new Promise((resolve, reject) => {
const code = getUrlParam('code')
const url = `${$config.hmapUrl}/oauth/token?client_id=18f58010-2831-11e8-b467-0ed5f89f718b&client_secret=2fe58f36-2831-11e8-b467-0ed5f89f718b&grant_type=authorization_code&code=${encodeURIComponent(code)}`
axios.post(url).then(res => {
window.localStorage.setItem('token', res.access_token)
resolve({
token: res.access_token,
tokenType: res.token_type,
expires: res.expires_in,
userId: res.userId,
organizationId: res.organizationId,
account: res.account,
mobile: res.phoneNumber,
})
})
})
}
// 桥登录
export function bridgeLogin () {
return new Promise((resolve, reject) => {
// 登录成功回调
window.bridgeLoginSuccess = function (str) {
const res = JSON.parse(str)
window.localStorage.setItem('token', res.token)
const data = {
token: res.token,
tokenType: res.tokenType,
expires: res.expiresIn,
userId: res.userId,
organizationId: res.organizationId,
account: res.account,
mobile: res.phoneNumber,
}
resolve(data)
}
// 登录失败回调
window.bridgeLoginFailure = function (res) {
console.error(res)
reject(res)
}
const dict = {
'className': 'BaseBridge',
'function': 'getBaseInfo',
'successCallBack': 'bridgeLoginSuccess',
'failureCallBack': 'bridgeLoginFailure',
}
HandBridge.postMessage(JSON.stringify(dict))
})
}
// 获取用户详细信息
export function getUserInfo (userId) {
const url = `${$config.hmapUrl}/i/api/staff/customDetail`
const data = {
userId,
}
const options = {
headers: {
Authorization: `Bearer ${window.localStorage.token}`,
},
}
return new Promise((resolve, reject) => {
axios.post(url, data, options).then(res => {
resolve({
account: res.accountNumber,
mobile: res.mobile,
userId: res.userId,
organizationId: res.organizationId,
email: res.email,
})
})
})
}
/**
* 获取中台的token
* @returns {Promise<*>}
*/
export async function getSupportToken () {
const url = `${$config.loginPath}appadmin`
const res = await axios.post(url)
return res
}
/**
* 获取业务系统个人信息
* @returns {Promise<*>}
*/
export async function getLeasingUserInfo (account, mobile) {
window.localStorage.setItem('account', account)
const url = `${$config.basePath}hmap_app_login`
const data = {
'user_name': account,
'mobile': mobile,
}
const options = {
headers: {
Authorization: `Bearer ${window.localStorage.access_token}`,
},
}
return new Promise((resolve, reject) => {
axios.post(url, data, options).then(res => {
// console.log('leasingInfo:' + JSON.stringify(res))
if (res.result === 'S') {
resolve(res.user_info[0])
}
})
})
}
/**
* 登录总成
* @param {String} [type] 可选:'online''local'
* @param {Boolean} [needInfo] 是否需要获取用户详细信息
* @return {Object.Promise} 若登录成功PromiseValue为数据对象/登录失败PromiseValue 为 false
*/
export async function login (type = 'online', needInfo = true) { // 登录
const env = process.env.CONFIG_ENV // 环境
try {
let result = {}
let tokenInfo = {}
tokenInfo = await getSupportToken()
window.localStorage.setItem('access_token', tokenInfo.access_token)
if (env === 'prod' || env === 'uat') { // 真机
if (type === 'online') result = await authorizedLogin() // 在线子应用
if (type === 'local') result = await bridgeLogin() // 本地子应用
window.localStorage.setItem('mobile', result.mobile)
result.userInfo = await getLeasingUserInfo(result.account, result.mobile)
} else {
result = await analogLogin()
result.hmapUserInfo = await getUserInfo(result.userId)
window.localStorage.setItem('mobile', result.hmapUserInfo.mobile)
result.userInfo = await getLeasingUserInfo(result.hmapUserInfo.account, result.hmapUserInfo.mobile)
}
window.localStorage.setItem('user_id', result.userInfo.user_id)
return result
} catch (e) {
// console.error(e)
return false
}
}
/**
* 海马汇业务系统集成登录
* @param type
* @param needInfo
* @returns {Promise<any>}
*/
export default function hmapLogin (type = 'local', needInfo = true) {
const env = process.env.CONFIG_ENV // 环境
return new Promise((resolve, reject) => {
try {
let result = {}
if (env === 'prod' || env === 'uat') { // 真机
if (type === 'online') {
authorizedLogin().then(res => {
result = res
window.localStorage.setItem('mobile', res.mobile)
})
}// 在线子应用
if (type === 'local') {
result = bridgeLogin().then(res => {
result = res
window.localStorage.setItem('mobile', res.mobile)
})
}
getSupportToken().then(res => {
window.localStorage.setItem('access_token', res.access_token)
getLeasingUserInfo(result.account, result.mobile).then(res => {
result.userInfo = res
window.localStorage.setItem('user_id', res.user_id)
resolve(result)
})
})
} else {
analogLogin().then(res => {
result = res
getUserInfo(res.userId).then(info => {
result.hmapUserInfo = info
window.localStorage.setItem('mobile', info.mobile)
getSupportToken().then(support => {
window.localStorage.setItem('access_token', support.access_token)
getLeasingUserInfo(info.account, info.mobile).then(res => {
result.userInfo = res
window.localStorage.setItem('user_id', res.user_id)
resolve(result)
})
})
})
})
}
} catch (e) {
reject(e)
}
})
}
/**
* 一些帮助函数
* @author momoko
*/
/**
* 取URL上的参数
* @param {String} param 参数名
* @return {String}
*/
export function getUrlParam (param) {
const result = window.location.href.match(new RegExp('(\\?|&)' + param + '(\\[\\])?=([^&#]*)'))
return result ? result[3] : undefined
}
/**
* 动态插入 script to html
* @param url
* @param callback
*/
export function createScript (url, callback) {
const oScript = document.createElement('script')
oScript.type = 'text/javascript'
oScript.async = true
oScript.src = url
/**
* IE6/7/8 -- onreadystatechange
* IE9/10 -- onreadystatechange, onload
* Firefox/Chrome/Opera -- onload
*/
const isIE = !-[1,] // eslint-disable-line
if (isIE) {
// 判断IE8及以下浏览器
oScript.onreadystatechange = function () {
if (this.readyState === 'loaded' || this.readyState === 'complete') {
callback && callback()
}
}
} else {
// IE9及以上浏览器,Firefox,Chrome,Opera
oScript.onload = function () {
callback && callback()
}
}
document.body.appendChild(oScript)
}
/**
* 判断平台
* @return {String} 平台
*/
export function detectOS () {
const ua = navigator.userAgent.toLowerCase()
if (/MicroMessenger/i.test(ua)) {
return 'weixin'
} else if (/iPhone|iPad|iPod|iOS/i.test(ua)) {
return 'ios'
} else if (/Android/i.test(ua)) {
return 'android'
} else {
return 'other'
}
}
......@@ -75,7 +75,7 @@ To get started:
${yellow(
`${data.inPlace ? '' : `cd ${data.destDirName}\n `}${installMsg(
data
)}${lintMsg(data)}npm run dev`
)}${lintMsg(data)}yarn start`
)}
Documentation can be found at https://vuejs-templates.github.io/webpack
......
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