提交 f057cd79 作者: 方治民

合并分支 '3.x' 到 'main'

3.x

查看合并请求 !61
...@@ -49,12 +49,12 @@ ...@@ -49,12 +49,12 @@
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": true "source.fixAll.eslint": "explicit"
}, },
"[vue]": { "[vue]": {
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": true, "source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": true "source.fixAll.stylelint": "explicit"
} }
}, },
......
...@@ -66,93 +66,93 @@ ...@@ -66,93 +66,93 @@
} }
}, },
"dependencies": { "dependencies": {
"@dcloudio/uni-app": "3.0.0-3090620231104002", "@dcloudio/uni-app": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-app-plus": "3.0.0-3090620231104002", "@dcloudio/uni-app-plus": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-components": "3.0.0-3090620231104002", "@dcloudio/uni-components": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-h5": "3.0.0-3090620231104002", "@dcloudio/uni-h5": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-alipay": "3.0.0-3090620231104002", "@dcloudio/uni-mp-alipay": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-baidu": "3.0.0-3090620231104002", "@dcloudio/uni-mp-baidu": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-jd": "3.0.0-3090620231104002", "@dcloudio/uni-mp-jd": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-3090620231104002", "@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-lark": "3.0.0-3090620231104002", "@dcloudio/uni-mp-lark": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-qq": "3.0.0-3090620231104002", "@dcloudio/uni-mp-qq": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-toutiao": "3.0.0-3090620231104002", "@dcloudio/uni-mp-toutiao": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-mp-weixin": "3.0.0-3090620231104002", "@dcloudio/uni-mp-weixin": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-quickapp-webview": "3.0.0-3090620231104002", "@dcloudio/uni-quickapp-webview": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-ui": "^1.4.28", "@dcloudio/uni-ui": "^1.4.28",
"@faker-js/faker": "^8.2.0", "@faker-js/faker": "^8.3.1",
"@vue/runtime-core": "~3.2.47", "@vue/runtime-core": "3.3.11",
"@vueuse/core": "^10.5.0", "@vueuse/core": "^10.7.0",
"axios": "^1.6.0", "axios": "^1.6.2",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"nanoid": "^5.0.2", "nanoid": "^5.0.4",
"pinia": "~2.0.36", "pinia": "~2.0.36",
"qs": "~6.9.7", "qs": "~6.9.7",
"stompjs": "^2.3.3", "stompjs": "^2.3.3",
"urijs": "^1.19.11", "urijs": "^1.19.11",
"vue": "~3.2.47", "vue": "3.3.11",
"vue-i18n": "^9.6.5", "vue-i18n": "^9.8.0",
"vue-request": "^2.0.4", "vue-request": "^2.0.4",
"vue-types": "^5.1.1" "vue-types": "^5.1.1"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^0.43.1", "@antfu/eslint-config": "^0.43.1",
"@commitlint/cli": "^18.2.0", "@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.1.0", "@commitlint/config-conventional": "^18.4.3",
"@dcloudio/types": "^3.4.3", "@dcloudio/types": "^3.4.3",
"@dcloudio/uni-automator": "3.0.0-3090620231104002", "@dcloudio/uni-automator": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-cli-shared": "3.0.0-3090620231104002", "@dcloudio/uni-cli-shared": "3.0.0-alpha-4000020231218001",
"@dcloudio/uni-helper-json": "^1.0.13", "@dcloudio/uni-helper-json": "^1.0.13",
"@dcloudio/uni-stacktracey": "3.0.0-3090620231104002", "@dcloudio/uni-stacktracey": "3.0.0-alpha-4000020231218001",
"@dcloudio/vite-plugin-uni": "3.0.0-3090620231104002", "@dcloudio/vite-plugin-uni": "3.0.0-alpha-4000020231218001",
"@iconify/json": "^2.2.137", "@iconify/json": "^2.2.160",
"@types/crypto-js": "^4.1.3", "@types/crypto-js": "^4.2.1",
"@types/lodash-es": "^4.17.10", "@types/lodash-es": "^4.17.12",
"@types/node": "^20.8.10", "@types/node": "^20.10.5",
"@types/qs": "^6.9.9", "@types/qs": "^6.9.10",
"@types/stompjs": "^2.3.7", "@types/stompjs": "^2.3.9",
"@types/urijs": "^1.19.22", "@types/urijs": "^1.19.25",
"@typescript-eslint/eslint-plugin": "^6.9.1", "@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.9.1", "@typescript-eslint/parser": "^6.15.0",
"commitizen": "^4.3.0", "commitizen": "^4.3.0",
"conventional-changelog-cli": "^4.1.0", "conventional-changelog-cli": "^4.1.0",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^7.0.0", "cz-customizable": "^7.0.0",
"cz-git": "^1.7.1", "cz-git": "^1.8.0",
"czg": "^1.7.1", "czg": "^1.8.0",
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"eslint": "^8.53.0", "eslint": "^8.56.0",
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.0.1", "eslint-plugin-prettier": "^5.1.0",
"eslint-plugin-vue": "^9.18.1", "eslint-plugin-vue": "^9.19.2",
"husky": "^8.0.3", "husky": "^8.0.3",
"jest": "27.0.4", "jest": "27.0.4",
"jest-environment-node": "27.5.1", "jest-environment-node": "27.5.1",
"less": "^4.2.0", "less": "^4.2.0",
"lint-staged": "^14.0.1", "lint-staged": "^15.2.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"picocolors": "^1.0.0", "picocolors": "^1.0.0",
"pont-engine": "^1.5.12", "pont-engine": "^1.5.12",
"postcss": "^8.4.31", "postcss": "^8.4.32",
"postcss-html": "^1.5.0", "postcss-html": "^1.5.0",
"postcss-less": "^6.0.0", "postcss-less": "^6.0.0",
"prettier": "^3.0.3", "prettier": "^3.1.1",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"sass": "^1.69.5", "sass": "^1.69.5",
"sort-package-json": "^2.6.0", "sort-package-json": "^2.6.0",
"stylelint": "^15.11.0", "stylelint": "^16.0.2",
"stylelint-config-html": "^1.1.0", "stylelint-config-html": "^1.1.0",
"stylelint-config-recommended": "^13.0.0", "stylelint-config-recommended": "^14.0.0",
"stylelint-config-standard": "^34.0.0", "stylelint-config-standard": "^35.0.0",
"stylelint-order": "^6.0.3", "stylelint-order": "^6.0.4",
"typescript": "~5.1.6", "typescript": "~5.1.6",
"unocss": "^0.56.5", "unocss": "^0.58.0",
"unocss-preset-weapp": "^0.56.1", "unocss-preset-weapp": "^0.58.0",
"unplugin-auto-import": "^0.16.7", "unplugin-auto-import": "^0.17.2",
"unplugin-vue-components": "^0.25.2", "unplugin-vue-components": "^0.26.0",
"vite": "^4.5.0", "vite": "^4.5.1",
"vue-eslint-parser": "^9.3.2" "vue-eslint-parser": "^9.3.2"
}, },
"engines": { "engines": {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -398,6 +398,9 @@ ...@@ -398,6 +398,9 @@
/* #ifdef APP-NVUE || MP-TOUTIAO */ /* #ifdef APP-NVUE || MP-TOUTIAO */
.fui-as__safe-weex { .fui-as__safe-weex {
/* #ifdef APP-NVUE */
height: 168rpx;
/* #endif */
padding-bottom: 34px; padding-bottom: 34px;
} }
......
<template> <template>
<view class="fui-popup__animation" :class="[ani.in]" :style="'transform:' + transform + ';' + stylesObject" <view class="fui-popup__animation" :class="[ani.in]" :style="transformStyles" @tap="change" v-if="isShow"
@tap="change" v-if="isShow" ref="fui_ani"> ref="fui_ani">
<slot></slot> <slot></slot>
</view> </view>
</template> </template>
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
if (newVal) { if (newVal) {
this.open(); this.open();
} else { } else {
this.close(); this.isShow && this.close();
} }
}, },
immediate: true immediate: true
...@@ -89,6 +89,9 @@ ...@@ -89,6 +89,9 @@
transfrom += line + ':' + styles[i] + ';'; transfrom += line + ':' + styles[i] + ';';
} }
return transfrom; return transfrom;
},
transformStyles() {
return `transform:${this.transform};${this.stylesObject}`
} }
}, },
methods: { methods: {
......
...@@ -152,7 +152,6 @@ ...@@ -152,7 +152,6 @@
<style scoped> <style scoped>
.fui-badge__wrap { .fui-badge__wrap {
height: 36rpx; height: 36rpx;
padding: 0 12rpx;
color: #FFFFFF; color: #FFFFFF;
font-size: 24rpx; font-size: 24rpx;
line-height: 36rpx; line-height: 36rpx;
......
...@@ -6,13 +6,13 @@ class FillStyleLinearGradient { ...@@ -6,13 +6,13 @@ class FillStyleLinearGradient {
this._stop_count = 0; this._stop_count = 0;
this._stops = [0, 0, 0, 0, 0]; this._stops = [0, 0, 0, 0, 0];
} }
// 新特性待增加
addColorStop = function (pos, color) { addColorStop = function (pos, color) {// 2021-5-6变更
if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) { if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
this._stops[this._stop_count] = { _pos: pos, _color: color }; this._stops[this._stop_count] = { _pos: pos, _color: color };
this._stop_count++; this._stop_count++;// echo建议
} }// todo: 待修改
} }
} }
// 2021-5-6变更
export default FillStyleLinearGradient; export default FillStyleLinearGradient;
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<script> <script>
export default { export default {
name: 'fui-button', name: 'fui-button',
emits: ['click', 'getuserinfo', 'contact', 'getphonenumber', 'error', 'opensetting'], emits: ['click', 'getuserinfo', 'contact', 'getphonenumber', 'error', 'opensetting','chooseavatar','launchapp'],
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
behaviors: ['wx://form-field-button'], behaviors: ['wx://form-field-button'],
// #endif // #endif
......
...@@ -40,6 +40,10 @@ ...@@ -40,6 +40,10 @@
:style="{color:getColor(index,idx,values)}">{{getText(index,idx) || descrArr[idx]}}</text> :style="{color:getColor(index,idx,values)}">{{getText(index,idx) || descrArr[idx]}}</text>
<text class="fui-calendar__date-descr" v-if="!showLunar || language==='en'" <text class="fui-calendar__date-descr" v-if="!showLunar || language==='en'"
:style="{color:getColor(index,idx,values)}">{{getText(index,idx) || descrArr[idx]}}</text> :style="{color:getColor(index,idx,values)}">{{getText(index,idx) || descrArr[idx]}}</text>
<view class="fui-calendar__badge"
:style="{background:badgeColor || dangerColor,right:badgeRight+'rpx',top:badgeTop+'rpx'}"
v-if="badgeArr[idx]">
</view>
</view> </view>
</view> </view>
</swiper-item> </swiper-item>
...@@ -58,6 +62,10 @@ ...@@ -58,6 +62,10 @@
:style="{color:getColor(month-1,idx,values)}">{{getText(month-1,idx) || descrArr[idx]}}</text> :style="{color:getColor(month-1,idx,values)}">{{getText(month-1,idx) || descrArr[idx]}}</text>
<text class="fui-calendar__date-descr" v-if="!showLunar || language==='en'" <text class="fui-calendar__date-descr" v-if="!showLunar || language==='en'"
:style="{color:getColor(month-1,idx,values)}">{{getText(month-1,idx) || descrArr[idx]}}</text> :style="{color:getColor(month-1,idx,values)}">{{getText(month-1,idx) || descrArr[idx]}}</text>
<view class="fui-calendar__badge"
:style="{background:badgeColor || dangerColor,right:badgeRight+'rpx',top:badgeTop+'rpx'}"
v-if="badgeArr[idx]">
</view>
</view> </view>
</view> </view>
</view> </view>
...@@ -213,6 +221,21 @@ ...@@ -213,6 +221,21 @@
btnColor: { btnColor: {
type: String, type: String,
default: '#FFFFFF' default: '#FFFFFF'
},
//v2.2.0+
badgeColor: {
type: String,
default: ''
},
//v2.2.0+
badgeTop: {
type: [Number, String],
default: 16
},
//v2.2.0+
badgeRight: {
type: [Number, String],
default: 16
} }
}, },
data() { data() {
...@@ -225,6 +248,7 @@ ...@@ -225,6 +248,7 @@
daysArr: [] daysArr: []
}, },
descrArr: [], descrArr: [],
badgeArr: [],
dateWidth: '100%', dateWidth: '100%',
title: '', title: '',
year: 0, year: 0,
...@@ -243,7 +267,7 @@ ...@@ -243,7 +267,7 @@
}, },
itemWidth() { itemWidth() {
// #ifdef APP-NVUE // #ifdef APP-NVUE
return (Number(this.dateWidth.replace('px', '').replace('%','')) - 1) / 7 + 'px' return (Number(this.dateWidth.replace('px', '').replace('%', '')) - 1) / 7 + 'px'
// #endif // #endif
// #ifndef APP-NVUE // #ifndef APP-NVUE
...@@ -253,6 +277,10 @@ ...@@ -253,6 +277,10 @@
primaryColor() { primaryColor() {
const app = uni && uni.$fui && uni.$fui.color; const app = uni && uni.$fui && uni.$fui.color;
return (app && app.primary) || '#465CFF'; return (app && app.primary) || '#465CFF';
},
dangerColor() {
const app = uni && uni.$fui && uni.$fui.color;
return (app && app.danger) || '#FF2B2B';
} }
}, },
watch: { watch: {
...@@ -276,6 +304,7 @@ ...@@ -276,6 +304,7 @@
title(val) { title(val) {
if (this.year === 0) return; if (this.year === 0) return;
this.descrArr = [] this.descrArr = []
this.badgeArr = []
this.$emit('dateChange', { this.$emit('dateChange', {
year: this.year, year: this.year,
month: this.month month: this.month
...@@ -705,6 +734,18 @@ ...@@ -705,6 +734,18 @@
this.descrArr = [] this.descrArr = []
}) })
} }
},
// 传入一个返回Promise的函数,设置当前日历数据角标
//返回当前日历数据
setBadge(callback) {
const item = this.monthArr[this.month - 1]
if (item && callback && typeof callback === 'function') {
callback(this.year, this.month, item.daysArr).then(res => {
this.badgeArr = res
}).catch(err => {
this.badgeArr = []
})
}
} }
} }
} }
...@@ -902,4 +943,17 @@ ...@@ -902,4 +943,17 @@
.fui-calendar__btn-active:active { .fui-calendar__btn-active:active {
background: rgba(0, 0, 0, .2); background: rgba(0, 0, 0, .2);
} }
.fui-calendar__badge {
position: absolute;
height: 8px;
width: 8px;
/* #ifdef APP-NVUE */
border-radius: 100px;
/* #endif */
/* #ifndef APP-NVUE */
border-radius: 50%;
z-index: 3;
/* #endif */
}
</style> </style>
/* /*
===========================================
当前组件库版本号为:V2.1.0
如果与文档最新版本不一致,请更新至最新版本使用!
===========================================
*/
/*
组件属性全局配置文件。优先级:全局配置文件props < 直接设置组件props 组件属性全局配置文件。优先级:全局配置文件props < 直接设置组件props
目前支持配置的组件:fui-button、fui-icon、fui-text、fui-input、fui-form-item、fui-list-cell 目前支持配置的组件:fui-button、fui-icon、fui-text、fui-input、fui-form-item、fui-list-cell
fui-section、fui-white-space、fui-wing-blank
*/ */
// 主色(V1.9.8+),仅Nvue端以及无法使用css变量控制颜色的组件使用【保持与fui-theme中一致】 // 主色(V1.9.8+),仅Nvue端以及无法使用css变量控制颜色的组件使用【保持与fui-theme中一致】
...@@ -107,6 +115,20 @@ const fuiConfig = { ...@@ -107,6 +115,20 @@ const fuiConfig = {
descrColor: '#B2B2B2', descrColor: '#B2B2B2',
descrTop: 12 descrTop: 12
}, },
//v2.1.0+
fuiWhiteSpace: {
size: 'default',
//设置了height则size失效
height: 0,
background: 'transparent'
},
//v2.1.0+
fuiWingBlank: {
size: 'default',
//设置了gap则size失效
gap: 0,
background: 'transparent'
},
color, color,
...app ...app
} }
......
<template> <template>
<view class="fui-data__tag-wrap" :style="{marginBottom:'-'+gap+'rpx'}"> <view class="fui-data__tag-wrap" :class="[nowrap?'fui-data__tag-nowrap':'fui-data__tag-flexwrap']"
:style="{marginBottom:'-'+gap+'rpx'}">
<!-- #ifndef APP-NVUE --> <!-- #ifndef APP-NVUE -->
<view class="fui-data__tag-item" :class="{'fui-data__tag-disable':item.disable}" <view class="fui-data__tag-item" :class="{'fui-data__tag-disable':item.disable}"
:style="{width:width?width+'rpx':'auto',height:height?height+'rpx':'auto',paddingTop:padding[0] || 0,paddingRight:padding[1] || 0,paddingBottom:padding[2] || padding[0] || 0,paddingLeft:padding[3] || padding[1] || 0,borderRadius:radius+'rpx',marginRight:gap+'rpx',marginBottom:gap+'rpx',background:item.selected?activeBgColor:background,borderColor:item.selected?(borderColor || primaryColor):(defaultBorderColor || background)}" :style="{width:width?width+'rpx':'auto',height:height?height+'rpx':'auto',paddingTop:padding[0] || 0,paddingRight:padding[1] || 0,paddingBottom:padding[2] || padding[0] || 0,paddingLeft:padding[3] || padding[1] || 0,borderRadius:radius+'rpx',marginRight:gap+'rpx',marginBottom:gap+'rpx',background:item.selected?activeBgColor:background,borderColor:item.selected?(borderColor || primaryColor):(defaultBorderColor || background)}"
...@@ -142,6 +143,11 @@ ...@@ -142,6 +143,11 @@
markColor: { markColor: {
type: String, type: String,
default: '' default: ''
},
//V2.1.0+ 标签选择 是否强制一行显示,外层需要自行设置横向滚动容器
nowrap: {
type: Boolean,
default: false
} }
}, },
watch: { watch: {
...@@ -374,9 +380,16 @@ ...@@ -374,9 +380,16 @@
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
}
.fui-data__tag-flexwrap {
flex-wrap: wrap; flex-wrap: wrap;
} }
.fui-data__tag-nowrap {
flex-wrap: nowrap;
}
.fui-data__tag-item { .fui-data__tag-item {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: inline-flex; display: inline-flex;
......
...@@ -207,7 +207,7 @@ ...@@ -207,7 +207,7 @@
:mask-bottom-style="theme==='dark'?darkBottomStyle:''" :mask-style="theme==='dark'?darkStyle:''" :mask-bottom-style="theme==='dark'?darkBottomStyle:''" :mask-style="theme==='dark'?darkStyle:''"
:indicator-style="theme==='dark'?indicatorStyl:'height: 44px;border-top-width:0.5px;border-bottom-width:0.5px;'" :indicator-style="theme==='dark'?indicatorStyl:'height: 44px;border-top-width:0.5px;border-bottom-width:0.5px;'"
:indicator-class="theme==='dark'?'fui-date__picker-indicator':''" class="fui-date__picker-view" :indicator-class="theme==='dark'?'fui-date__picker-indicator':''" class="fui-date__picker-view"
:style="{height:height+'rpx'}" :key="theme+type" :value="vals" immediate-change :style="{height:height+'rpx'}" :key="theme+type" :value="vals" :immediate-change="immediate"
@change="pickerChange"> @change="pickerChange">
<picker-view-column v-if="type==1 || type==2 || type==3 || type==4 || type==5"> <picker-view-column v-if="type==1 || type==2 || type==3 || type==4 || type==5">
<text :style="contentStyl" v-for="(item,index) in years" :key="index" <text :style="contentStyl" v-for="(item,index) in years" :key="index"
...@@ -526,7 +526,12 @@ ...@@ -526,7 +526,12 @@
} }
}, },
data() { data() {
let immediate = true;
// #ifdef MP-TOUTIAO
immediate = false
// #endif
return { return {
immediate,
years: [], years: [],
months: [], months: [],
days: [], days: [],
...@@ -740,16 +745,23 @@ ...@@ -740,16 +745,23 @@
const startValues = this.getValueToDate(val); const startValues = this.getValueToDate(val);
if (this.valueEnd) { if (this.valueEnd) {
const endValues = this.getValueToDate(this.valueEnd); const endValues = this.getValueToDate(this.valueEnd);
this.values = endValues; if (endValues.join(',') !== this.values.join(',')) {
this.values = endValues;
}
this.startDate = this.getRangeInitRes(startValues); this.startDate = this.getRangeInitRes(startValues);
this.endDate = this.getRangeInitRes(endValues); this.endDate = this.getRangeInitRes(endValues);
this.isActive = 2; this.isActive = 2;
} else { } else {
this.values = startValues; if (startValues.join(',') !== this.values.join(',')) {
this.values = startValues;
}
this.startDate = this.getRangeInitRes(startValues); this.startDate = this.getRangeInitRes(startValues);
} }
} else { } else {
this.values = this.getValueToDate(val); const sVals = this.getValueToDate(val);
if (sVals.join(',') !== this.values.join(',')) {
this.values = sVals;
}
} }
}, },
toDate(date, def, isMin) { toDate(date, def, isMin) {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<text :key="theme" :style="{fontSize:`${index===3 && idx===0? spareSize:40}rpx`}" <text :key="theme" :style="{fontSize:`${index===3 && idx===0? spareSize:40}rpx`}"
class="fui-digital__keyboard-key" class="fui-digital__keyboard-key"
:class="{'fui-dk__key-dark':theme==='dark','fui-dk__key-light':theme!=='dark','fui-dk__highlight-dark':theme==='dark','fui-dk__highlight':theme==='light' && val}" :class="{'fui-dk__key-dark':theme==='dark','fui-dk__key-light':theme!=='dark','fui-dk__highlight-dark':theme==='dark','fui-dk__highlight':theme==='light' && val}"
@tap.stop="keyClick(index,idx,val)">{{val}}</text> @tap="keyClick(index,idx,val)">{{val}}</text>
</view> </view>
</view> </view>
</view> </view>
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<view class="fui-dk__grid-right"> <view class="fui-dk__grid-right">
<view :key="theme" class="fui-digital__keyboard-key" <view :key="theme" class="fui-digital__keyboard-key"
:class="{'fui-dk__key-dark':theme==='dark','fui-dk__key-light':theme!=='dark','fui-dk__highlight-dark':theme==='dark','fui-dk__highlight':theme!=='dark'}" :class="{'fui-dk__key-dark':theme==='dark','fui-dk__key-light':theme!=='dark','fui-dk__highlight-dark':theme==='dark','fui-dk__highlight':theme!=='dark'}"
@tap.stop="backspace"> @tap="backspace">
<fui-icon :name="name" :size="56" :color="theme==='dark'?'#d1d1d1':'#333'"></fui-icon> <fui-icon :name="name" :size="56" :color="theme==='dark'?'#d1d1d1':'#333'"></fui-icon>
</view> </view>
</view> </view>
......
...@@ -62,7 +62,9 @@ function touchmove(e, ins, event) { ...@@ -62,7 +62,9 @@ function touchmove(e, ins, event) {
var touch = {} var touch = {}
if (isH5 && isPC()) { if (isH5 && isPC()) {
touch = e; touch = e;
state = event.instance.getState() if (event && event.instance) {
state = event.instance.getState()
}
} else { } else {
touch = e.touches[0] || e.changedTouches[0] touch = e.touches[0] || e.changedTouches[0]
state = e.instance.getState() state = e.instance.getState()
......
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
export default { export default {
name: "fui-form", name: "fui-form",
props: { props: {
model: {
type: Object,
default () {
return {};
}
},
//表单padding值(上,右,下,左),同css顺序 //表单padding值(上,右,下,左),同css顺序
padding: { padding: {
type: Array, type: Array,
...@@ -22,7 +28,7 @@ ...@@ -22,7 +28,7 @@
return [] return []
} }
}, },
//是否显示校验错误信息 //是否显示校验错误信息,设置false时,则触发formItem校验
show: { show: {
type: Boolean, type: Boolean,
default: true default: true
...@@ -107,6 +113,16 @@ ...@@ -107,6 +113,16 @@
asteriskPosition: { asteriskPosition: {
type: String, type: String,
default: '' default: ''
},
//v2.1.0+ 1-absolute 2-relative
errorPosition: {
type: [Number, String],
default: 1
},
//v2.1.0+ left/center/right
errorAlign: {
type: String,
default: 'center'
} }
}, },
provide() { provide() {
...@@ -126,12 +142,41 @@ ...@@ -126,12 +142,41 @@
return color; return color;
} }
}, },
watch: {
/* // 备用方案,暂时未启用
model: {
handler: function(vals, oldVal) {
if (this.children && vals && !this.show) {
this.children.forEach(item => {
if (item.prop && item.prop !== true) {
item.setValue(vals[item] || '')
}
})
}
},
deep: true
},
*/
show(val) {
if (this.children && this.children.length > 0) {
this.children.forEach(item => {
item.showError = val ? false : true
})
}
}
},
data() { data() {
return { return {
errorMsg: '', errorMsg: '',
timer: null timer: null,
rules: [],
mergeRules: [],
isRealTime: false
}; };
}, },
created() {
this.children = []
},
// #ifndef VUE3 // #ifndef VUE3
beforeDestroy() { beforeDestroy() {
this.clearTimer() this.clearTimer()
...@@ -144,28 +189,142 @@ ...@@ -144,28 +189,142 @@
// #endif // #endif
methods: { methods: {
clearTimer() { clearTimer() {
this.children = null
clearTimeout(this.timer) clearTimeout(this.timer)
this.timer = null; this.timer = null;
}, },
/* getFormItemRules() {
@param model 表单数据对象 let rules = []
@param rules 表单验证规则 if (this.children && this.children.length > 0) {
@param checkAll 校验所有元素 this.children.forEach(child => {
*/ let rule = child.getRules()
rule && rules.push(rule)
})
}
return rules;
},
getMergeRules(rules) {
if (this.mergeRules.length === 0) return rules;
let formRules = [...rules]
//合并并替换当前rules数据
this.mergeRules.forEach(item => {
const index = rules.findIndex(e => e.name === item.name)
if (index === -1) {
formRules.push(item)
} else {
formRules[index] = item;
}
})
return formRules;
},
/**
* 校验方法
* @param {Object} model 表单数据对象
* @param {Array} rules 表单验证规则
* @param {Boolean} checkAll 校验所有元素,结合FormItem组件显示校验提示时必须传true
*/
validator(model, rules, checkAll = false) { validator(model, rules, checkAll = false) {
model = model || this.model
rules = rules || []
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
if (rules.length === 0) {
rules = this.getFormItemRules()
} else {
rules = this.getMergeRules(rules)
}
let res = form.validator(model, rules, checkAll); let res = form.validator(model, rules, checkAll);
if (!res.isPassed && this.show) { if (!res.isPassed) {
this.clearTimer() let errors = res.errorMsg;
if (this.show) {
this.clearTimer()
if (checkAll) {
errors = errors[0].msg
}
this.errorMsg = errors;
this.timer = setTimeout(() => {
this.errorMsg = ''
}, this.duration)
} else {
if (checkAll && this.children && this.children.length > 0) {
//formItem 显示提示
this.children.forEach(item => {
const index = errors.findIndex(err => err.name === item.prop)
if (item.prop && item.prop !== true && ~index) {
item.errorMsg = errors[index].msg
item.itemValue = this.model[item.prop]
}
})
}
}
}
resolve(res)
} catch (e) {
reject({
isPassed: false,
errorMsg: '校验出错,请检查传入的数据格式是否有误!'
})
}
})
},
/**
* 验证具体的某个字段
* @param {Array<string> | String} props 字段key
* @param {Object} model 表单数据对象,传null则使用属性中model值
* @param {Array} rules 表单验证规则,当传null 或空数组时使用FormItem组件内rules
*/
validateField(props, model, rules) {
if (!rules || rules.length === 0) {
rules = this.getFormItemRules()
} else {
rules = this.getMergeRules(rules)
}
const isString = typeof props === 'string';
const formRules = rules.filter(item => props === item.name || (!isString && props
.indexOf(item.name) !== -1));
model = model || this.model
return this.validator(model, formRules, true)
},
//v2.1.0+ 通知formItem组件重置props参数
resetFormItemParam() {
if (this.children && this.children.length > 0) {
this.children.forEach(item => {
item.initParam(true)
})
}
},
//v2.1.0+ 通知formItem组件开启实时校验
switchRealTimeValidator(isOpen, rules = []) {
this.isRealTime = isOpen;
if (isOpen) {
if (!rules || rules.length === 0) {
rules = this.getFormItemRules()
} else {
rules = this.getMergeRules(rules)
}
this.rules = rules || []
}
if (this.children && this.children.length > 0) {
this.children.forEach(item => {
item.switchRealTimeValidator(isOpen)
})
}
},
//内部方法,提供给FormItem组件使用
realTimeValidator(prop, model, rules) {
return new Promise((resolve, reject) => {
try {
let res = form.validator(model || this.model, rules || this.rules, true);
if (!res.isPassed) {
//formItem 显示提示
let errors = res.errorMsg; let errors = res.errorMsg;
if (checkAll) { const index = errors.findIndex(err => err.name === prop)
errors = errors[0].msg if (~index) {
res.errorMsg = errors[index].msg
} else {
res.isPassed = true
res.errorMsg = ''
} }
this.errorMsg = errors;
this.timer = setTimeout(() => {
this.errorMsg = ''
}, this.duration)
} }
resolve(res) resolve(res)
} catch (e) { } catch (e) {
...@@ -175,6 +334,43 @@ ...@@ -175,6 +334,43 @@
}) })
} }
}) })
},
clearValidate(props = []) {
let arr = props;
arr = !arr ? [] : arr
if (typeof props === 'string') {
arr = [props]
}
if (this.children && this.children.length > 0) {
//清除指定字段的表单验证信息
if (arr && arr.length > 0) {
this.children.forEach(item => {
if (item.prop && ~arr.indexOf(item.prop)) {
item.errorMsg = ''
}
})
} else {
//清除所有字段的表单验证信息
this.children.forEach(item => {
item.errorMsg = ''
})
}
}
},
// 移除表单项
uninstall(instance) {
if (this.children && this.children.length > 0) {
const index = this.children.findIndex(item => item === instance)
if (index !== -1) {
this.children.splice(index, 1)
}
const rules = instance.getRules() || {}
const prop = instance.prop || rules.name || ''
const idx = this.mergeRules.findIndex(ru => ru.name === prop)
if (idx !== -1) {
this.mergeRules.splice(idx, 1)
}
}
} }
} }
} }
......
...@@ -3,11 +3,12 @@ const BindingX = uni.requireNativePlugin('bindingx'); ...@@ -3,11 +3,12 @@ const BindingX = uni.requireNativePlugin('bindingx');
export default { export default {
methods: { methods: {
getEl(el) { getEl(el) {
return this.$refs[el].ref; return this.$refs[el] ? this.$refs[el].ref : null;
}, },
nvueScrollHandler(e) { nvueScrollHandler(e) {
const anchor = this.getEl('fui_scroller_view') const anchor = this.getEl('fui_scroller_view')
const element = this.getEl('fui_hor_indicator') const element = this.getEl('fui_hor_indicator')
if (!anchor || !element) return;
const scrollLeft = e.contentOffset.x const scrollLeft = e.contentOffset.x
const contentWidth = e.contentSize.width const contentWidth = e.contentSize.width
if (this.scroll && element) { if (this.scroll && element) {
......
...@@ -258,7 +258,9 @@ ...@@ -258,7 +258,9 @@
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
/* #ifndef APP-NVUE */
transition: all 0.1s linear;
/* #endif */
} }
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
......
<template> <template>
<!-- #ifndef APP-NVUE --> <!-- #ifndef APP-NVUE -->
<text :style="{ color:getColor, fontSize: getSize, fontWeight: fontWeight}" class="fui-icon" <text :style="{ color:getColor, fontSize: getSize, fontWeight: fontWeight}" class="fui-icon"
:class="[!getColor && !primary?'fui-icon__color':'',primary && (!color || color===true)?'fui-icon__active-color':'',disabled?'fui-icon__not-allowed':'',customPrefix,customPrefix?name:'']" :class="[!getColor && !primary?'fui-icon__color':'',primary && (!color || color===true)?'fui-icon__active-color':'',disabled?'fui-icon__not-allowed':'',customPrefix && customPrefix!==true?customPrefix:'',customPrefix && customPrefix!==true?name:'']"
@click="handleClick">{{ icons[name] || '' }}</text> @click="handleClick">{{ icons[name] || '' }}</text>
<!-- #endif --> <!-- #endif -->
<!-- #ifdef APP-NVUE --> <!-- #ifdef APP-NVUE -->
<text <text
:style="{ color: primary && (!color || color===true)?primaryColor:getColor, fontSize: getSize,lineHeight:getSize, fontWeight: fontWeight}" :style="{ color: primary && (!color || color===true)?primaryColor:getColor, fontSize: getSize,lineHeight:getSize, fontWeight: fontWeight}"
class="fui-icon" :class="[customPrefix]" @click="handleClick">{{ customPrefix?name:icons[name] }}</text> class="fui-icon" :class="[customPrefix && customPrefix!==true?customPrefix:'']"
@click="handleClick">{{ customPrefix && customPrefix!==true?name:icons[name] }}</text>
<!-- #endif --> <!-- #endif -->
</template> </template>
...@@ -84,8 +85,10 @@ ...@@ -84,8 +85,10 @@
}, },
getColor() { getColor() {
const app = uni && uni.$fui && uni.$fui.fuiIcon; const app = uni && uni.$fui && uni.$fui.fuiIcon;
let color = this.color || (app && app.color) let color = this.color;
if (!color || (color && color === true)) {
color = (app && app.color)
}
// #ifdef APP-NVUE // #ifdef APP-NVUE
if (!color || color === true) { if (!color || color === true) {
color = '#333333' color = '#333333'
......
<template> <template>
<view class="fui-index__list" ref="fui_index_list" id="fui_index_list"> <view class="fui-index__list" ref="fui_index_list" id="fui_index_list">
<!-- #ifdef APP-NVUE --> <!-- #ifdef APP-NVUE -->
<list class="fui-index__list-sv" scrollable="true" show-scrollbar="false"> <list class="fui-index__list-sv" :scrollable="true" :show-scrollbar="false" :loadmoreoffset="10"
@loadmore="scrolltolower">
<cell> <cell>
<slot></slot> <slot></slot>
</cell> </cell>
...@@ -27,7 +28,8 @@ ...@@ -27,7 +28,8 @@
<!-- #endif --> <!-- #endif -->
<!-- #endif --> <!-- #endif -->
<!-- #ifndef APP-NVUE --> <!-- #ifndef APP-NVUE -->
<scroll-view class="fui-index__list-sv" scroll-y :scroll-into-view="scrollViewId"> <scroll-view class="fui-index__list-sv" scroll-y :scroll-into-view="scrollViewId"
@scrolltolower="scrolltolower">
<slot></slot> <slot></slot>
<view :id="'fui_il_letter_'+idx" v-for="(list, idx) in lists" :key="list.key"> <view :id="'fui_il_letter_'+idx" v-for="(list, idx) in lists" :key="list.key">
<view class="fui-index__list-letter" :class="{'fui-il__key-bg':!background}" <view class="fui-index__list-letter" :class="{'fui-il__key-bg':!background}"
...@@ -146,7 +148,7 @@ ...@@ -146,7 +148,7 @@
// #endif // #endif
export default { export default {
name: 'fui-index-list', name: 'fui-index-list',
emits: ['click', 'init'], emits: ['click', 'init', 'scrolltolower'],
components: { components: {
fIndexListItem fIndexListItem
}, },
...@@ -283,6 +285,10 @@ ...@@ -283,6 +285,10 @@
}) })
}, },
methods: { methods: {
//滚动到底部,会触发 scrolltolower 事件
scrolltolower() {
this.$emit('scrolltolower', {})
},
getIndex(y) { getIndex(y) {
let index = -1; let index = -1;
// #ifdef H5 // #ifdef H5
......
...@@ -21,18 +21,34 @@ ...@@ -21,18 +21,34 @@
<text :style="{fontSize:getLabelSize,color:labelColor}">{{label}}</text> <text :style="{fontSize:getLabelSize,color:labelColor}">{{label}}</text>
</view> </view>
<slot name="left"></slot> <slot name="left"></slot>
<!-- #ifndef APP-NVUE -->
<input class="fui-input__self"
:class="{'fui-input__text-right':textRight,'fui-input__disabled-styl':disabled && disabledStyle,'fui-input__disabled':disabled}"
:style="{fontSize:getSize,color:color,textAlign:textRight?'right':textAlign}"
placeholder-class="fui-input__placeholder" :type="type" :name="name" :value="val"
:placeholder="val?'':placeholder" :password="password || type === 'password' || null"
:placeholder-style="placeholderStyl" :disabled="disabled || readonly" :cursor-spacing="cursorSpacing"
:maxlength="maxlength" :focus="focused" :confirm-type="confirmType" :confirm-hold="confirmHold"
:cursor="cursor" :selection-start="selectionStart" :selection-end="selectionEnd"
:adjust-position="adjustPosition" :hold-keyboard="holdKeyboard" :auto-blur="autoBlur" :enableNative="false"
:always-embed="alwaysEmbed" @focus="onFocus" @blur="onBlur" @input="onInput" @confirm="onConfirm"
@keyboardheightchange="onKeyboardheightchange" />
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<view class="fui-input__self-wrap"> <view class="fui-input__self-wrap">
<input class="fui-input__self" :class="{'fui-input__text-right':textRight}" <input ref="fuiInput" class="fui-input__self" :class="{'fui-input__text-right':textRight}"
:style="{fontSize:getSize,color:color}" placeholder-class="fui-input__placeholder" :type="type" :name="name" :style="{fontSize:getSize,color:color,textAlign:textRight?'right':textAlign}"
:value="val" :placeholder="placeholder" :password="password || type === 'password' || undefined" placeholder-class="fui-input__placeholder" :type="type" :name="name" :value="val"
:placeholder="placeholder" :password="password || type === 'password'"
:placeholder-style="placeholderStyl" :disabled="disabled || readonly" :cursor-spacing="cursorSpacing" :placeholder-style="placeholderStyl" :disabled="disabled || readonly" :cursor-spacing="cursorSpacing"
:maxlength="maxlength" :focus="focused" :confirm-type="confirmType" :confirm-hold="confirmHold" :maxlength="maxlength" :focus="focused" :confirm-type="confirmType" :confirm-hold="confirmHold"
:cursor="cursor" :selection-start="selectionStart" :selection-end="selectionEnd" :cursor="cursor" :selection-start="selectionStart" :selection-end="selectionEnd"
:adjust-position="adjustPosition" :hold-keyboard="holdKeyboard" :auto-blur="autoBlur" :enableNative="false" :adjust-position="adjustPosition" :hold-keyboard="holdKeyboard" :auto-blur="autoBlur"
:always-embed="alwaysEmbed" @focus="onFocus" @blur="onBlur" @input="onInput" @confirm="onConfirm" :enableNative="false" :always-embed="alwaysEmbed" @focus="onFocus" @blur="onBlur" @input="onInput"
@keyboardheightchange="onKeyboardheightchange" /> @confirm="onConfirm" @keyboardheightchange="onKeyboardheightchange" />
<view class="fui-input__cover" v-if="disabled || readonly" @tap="fieldClick"></view> <view class="fui-input__cover" v-if="disabled || readonly" @tap="fieldClickAndroid"></view>
</view> </view>
<!-- #endif -->
<view class="fui-input__clear-wrap" :style="{background:clearColor}" v-if="clearable && val != ''" <view class="fui-input__clear-wrap" :style="{background:clearColor}" v-if="clearable && val != ''"
@tap.stop="onClear"> @tap.stop="onClear">
<view class="fui-input__clear"> <view class="fui-input__clear">
...@@ -156,6 +172,11 @@ ...@@ -156,6 +172,11 @@
type: Boolean, type: Boolean,
default: false default: false
}, },
//V2.1.0+
disabledStyle: {
type: Boolean,
default: false
},
readonly: { readonly: {
type: Boolean, type: Boolean,
default: false default: false
...@@ -272,10 +293,16 @@ ...@@ -272,10 +293,16 @@
type: Boolean, type: Boolean,
default: true default: true
}, },
//即将废弃,请使用textAlign属性
textRight: { textRight: {
type: Boolean, type: Boolean,
default: false default: false
}, },
//V2.2.0+ 可选值:left/center/right
textAlign: {
type: String,
default: 'left'
},
padding: { padding: {
type: Array, type: Array,
default () { default () {
...@@ -329,9 +356,25 @@ ...@@ -329,9 +356,25 @@
watch: { watch: {
focus(val) { focus(val) {
this.$nextTick(() => { this.$nextTick(() => {
this.focused = val setTimeout(() => {
this.focused = val
}, 20)
})
},
// #ifdef APP-NVUE
focused(val) {
if (!this.$refs.fuiInput) return;
this.$nextTick(() => {
setTimeout(() => {
if (val) {
this.$refs.fuiInput.focus()
} else {
this.$refs.fuiInput.blur()
}
}, 50)
}) })
}, },
// #endif
placeholderStyle() { placeholderStyle() {
this.fieldPlaceholderStyle() this.fieldPlaceholderStyle()
}, },
...@@ -345,32 +388,26 @@ ...@@ -345,32 +388,26 @@
} }
}, },
created() { created() {
// #ifndef VUE3 this.fieldPlaceholderStyle()
this.val = this.value setTimeout(() => {
// #endif // #ifndef VUE3
// #ifdef VUE3
if (this.value && !this.modelValue) {
this.val = this.value this.val = this.value
} else { // #endif
this.val = this.modelValue
}
// #endif
this.fieldPlaceholderStyle() // #ifdef VUE3
if (this.value && !this.modelValue) {
this.val = this.value
} else {
this.val = this.modelValue
}
// #endif
}, 50)
}, },
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
// #ifdef MP-TOUTIAO
setTimeout(() => { setTimeout(() => {
this.focused = this.focus this.focused = this.focus
}, 300) }, 300)
// #endif
// #ifndef MP-TOUTIAO
setTimeout(() => {
this.focused = this.focus
}, 120)
// #endif
}) })
}, },
methods: { methods: {
...@@ -404,7 +441,7 @@ ...@@ -404,7 +441,7 @@
} }
this.$nextTick(() => { this.$nextTick(() => {
//当输入框为空时,输入框显示不赋值为0 //当输入框为空时,输入框显示不赋值为0
event.detail.value !== '' && (this.val = value); event.detail.value !== '' && (this.val = String(value));
}) })
//如果为空时返回0 ,当双向绑定会将输入框赋值0 //如果为空时返回0 ,当双向绑定会将输入框赋值0
const inputValue = event.detail.value !== '' ? value : '' const inputValue = event.detail.value !== '' ? value : ''
...@@ -556,12 +593,14 @@ ...@@ -556,12 +593,14 @@
/* #endif */ /* #endif */
} }
.fui-input__self-wrap{ /* #ifdef APP-NVUE */
.fui-input__self-wrap {
flex: 1; flex: 1;
flex-direction: row; flex-direction: row;
position: relative; position: relative;
} }
.fui-input__cover{
.fui-input__cover {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
...@@ -569,6 +608,8 @@ ...@@ -569,6 +608,8 @@
bottom: 0; bottom: 0;
} }
/* #endif */
.fui-input__self { .fui-input__self {
flex: 1; flex: 1;
padding-right: 12rpx; padding-right: 12rpx;
...@@ -660,6 +701,10 @@ ...@@ -660,6 +701,10 @@
/* #endif */ /* #endif */
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
.fui-input__disabled {
pointer-events: none;
}
.fui-input__border { .fui-input__border {
position: absolute; position: absolute;
height: 200%; height: 200%;
...@@ -683,7 +728,19 @@ ...@@ -683,7 +728,19 @@
/* #endif */ /* #endif */
.fui-input__text-left {
text-align: left;
}
.fui-input__text-right { .fui-input__text-right {
text-align: right; text-align: right;
} }
.fui-input__text-center {
text-align: center;
}
.fui-input__disabled-styl {
opacity: .6;
}
</style> </style>
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
local: isLocalFile, local: isLocalFile,
show: isLocalFile, show: isLocalFile,
visible: false, visible: false,
isMounted: false,
elId: `fui_lazy_${Math.ceil(Math.random() * 10e5).toString(36)}` elId: `fui_lazy_${Math.ceil(Math.random() * 10e5).toString(36)}`
}; };
}, },
......
...@@ -65,8 +65,8 @@ ...@@ -65,8 +65,8 @@
} }
}, },
mounted() { mounted() {
this.init(this.options)
setTimeout(() => { setTimeout(() => {
this.init(this.options)
this.isInit = true; this.isInit = true;
}, 200) }, 200)
} }
...@@ -153,10 +153,10 @@ ...@@ -153,10 +153,10 @@
mounted() { mounted() {
this.actionVal = this.getAction(this.action) this.actionVal = this.getAction(this.action)
// #ifdef MP // #ifdef MP
this.$nextTick(()=>{ this.$nextTick(() => {
setTimeout(()=> { setTimeout(() => {
this.initMp() this.initMp()
}, 10); }, 50);
}) })
// #endif // #endif
}, },
......
...@@ -87,7 +87,9 @@ function touchmove(e, ins, event) { ...@@ -87,7 +87,9 @@ function touchmove(e, ins, event) {
var touch = {} var touch = {}
if (isH5 && isPC()) { if (isH5 && isPC()) {
touch = e; touch = e;
state = event.instance.getState() if (event && event.instance) {
state = event.instance.getState()
}
} else { } else {
touch = e.touches[0] || e.changedTouches[0] touch = e.touches[0] || e.changedTouches[0]
state = e.instance.getState() state = e.instance.getState()
......
...@@ -171,7 +171,6 @@ ...@@ -171,7 +171,6 @@
} }
.fui-nav__header { .fui-nav__header {
flex: 1;
height: 44px; height: 44px;
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
width: 100%; width: 100%;
......
...@@ -9,12 +9,14 @@ ...@@ -9,12 +9,14 @@
:class="{'fui-picker__header-dark':theme==='dark','fui-picker__radius':radius}" :style="headerStyl"> :class="{'fui-picker__header-dark':theme==='dark','fui-picker__radius':radius}" :style="headerStyl">
<text class="fui-picker__btn-cancel" <text class="fui-picker__btn-cancel"
:class="[theme==='dark'?'fui-pk__cancel-color_dark':'fui-pk__cancel-color']" :style="cancelStyl" :class="[theme==='dark'?'fui-pk__cancel-color_dark':'fui-pk__cancel-color']" :style="cancelStyl"
@tap.stop="btnCancel">取消</text> @tap.stop="btnCancel">{{cancelText}}</text>
<text class="fui-picker__title" <slot>
:class="[theme==='dark'?'fui-pk__title-color_dark':'fui-pk__title-color']" <text class="fui-picker__title"
:style="titleStyl">{{title}}</text> :class="[theme==='dark'?'fui-pk__title-color_dark':'fui-pk__title-color']"
:style="titleStyl">{{title}}</text>
</slot>
<text class="fui-picker__btn-sure fui-pk__sure-color" :style="confrimStyl" <text class="fui-picker__btn-sure fui-pk__sure-color" :style="confrimStyl"
@tap.stop="btnConfirm">确定</text> @tap.stop="btnConfirm">{{confirmText}}</text>
</view> </view>
<view @touchstart.stop="pickerstart"> <view @touchstart.stop="pickerstart">
<!--支付宝小程序不支持动态切换 picker-view-column ... 设置高度也不行--> <!--支付宝小程序不支持动态切换 picker-view-column ... 设置高度也不行-->
...@@ -96,7 +98,7 @@ ...@@ -96,7 +98,7 @@
:mask-bottom-style="theme==='dark'?darkBottomStyle:''" :mask-style="theme==='dark'?darkStyle:''" :mask-bottom-style="theme==='dark'?darkBottomStyle:''" :mask-style="theme==='dark'?darkStyle:''"
:indicator-style="theme==='dark'?indicatorStyl:'height: 44px;border-top-width:0.5px;border-bottom-width:0.5px;'" :indicator-style="theme==='dark'?indicatorStyl:'height: 44px;border-top-width:0.5px;border-bottom-width:0.5px;'"
:indicator-class="theme==='dark'?'fui-picker__indicator':''" class="fui-picker__view" :indicator-class="theme==='dark'?'fui-picker__indicator':''" class="fui-picker__view"
:style="{height:height+'rpx'}" :key="theme+layer" :value="vals" immediate-change :style="{height:height+'rpx'}" :key="theme+layer" :value="vals" :immediate-change="immediate"
@change="pickerChange"> @change="pickerChange">
<picker-view-column> <picker-view-column>
<text :style="contentStyl" class="fui-picker__text" <text :style="contentStyl" class="fui-picker__text"
...@@ -343,7 +345,13 @@ ...@@ -343,7 +345,13 @@
} }
}, },
data() { data() {
//抖音小程序此属性有问题,设置为true,change事件可能不触发
let immediate = true;
// #ifdef MP-TOUTIAO
immediate = false
// #endif
return { return {
immediate,
firstArr: [], firstArr: [],
secondArr: [], secondArr: [],
thirdArr: [], thirdArr: [],
...@@ -476,7 +484,13 @@ ...@@ -476,7 +484,13 @@
}, },
initData() { initData() {
let data = this.options; let data = this.options;
if (!data || data.length === 0) return; if (!data || data.length === 0) {
this.firstArr = [];
this.secondArr = [];
this.thirdArr = [];
this.fourthArr = [];
return;
}
if (this.layer == 1 && !Array.isArray(data[0])) { if (this.layer == 1 && !Array.isArray(data[0])) {
this.firstArr = data this.firstArr = data
} else { } else {
...@@ -574,6 +588,7 @@ ...@@ -574,6 +588,7 @@
vals.push(this.fourthArr.indexOf(values[i])) vals.push(this.fourthArr.indexOf(values[i]))
} }
} }
if (this.vals.join('') === vals.join('')) return;
this.vals = [] this.vals = []
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* 生成海报 * 生成海报
* nvue端专用,需真机运行查看效果,其他端请使用fui-poster组件 * nvue端专用,需真机运行查看效果,其他端请使用fui-poster组件
* poster - v1.0.0 (2021/7/19, 16:52:14 PM) * poster - v1.0.0 (2021/7/19, 16:52:14 PM)
* updated V2.2.0+ 2023/11/07
* *
* 官网地址:https://firstui.cn/ * 官网地址:https://firstui.cn/
* 文档地址:https://doc.firstui.cn/ * 文档地址:https://doc.firstui.cn/
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
enable, enable,
WeexBridge WeexBridge
} from './gcanvas/index.js'; } from './gcanvas/index.js';
import fuiQr from './fui-qr/index.js'
export default { export default {
name: "fui-poster-weex", name: "fui-poster-weex",
emits: ['ready'], emits: ['ready'],
...@@ -59,7 +61,7 @@ ...@@ -59,7 +61,7 @@
this.h = this._toPx(this.height) this.h = this._toPx(this.height)
}, },
mounted() { mounted() {
this.$nextTick(()=>{ this.$nextTick(() => {
let ganvas = this.$refs[this.canvasId]; let ganvas = this.$refs[this.canvasId];
/*通过元素引用获取canvas对象*/ /*通过元素引用获取canvas对象*/
let canvasObj = enable(ganvas, { let canvasObj = enable(ganvas, {
...@@ -74,7 +76,7 @@ ...@@ -74,7 +76,7 @@
}, },
methods: { methods: {
_toPx(rpx) { _toPx(rpx) {
// * Number(this.pixelRatio) // * Number(this.pixelRatio)
return uni.upx2px(Number(rpx)) return uni.upx2px(Number(rpx))
}, },
_getTextWidth(context, text, fontSize) { _getTextWidth(context, text, fontSize) {
...@@ -344,6 +346,38 @@ ...@@ -344,6 +346,38 @@
context.closePath(); context.closePath();
context.restore(); context.restore();
}, },
_drawQrcode(context, params) {
let {
x,
y,
width,
height,
value,
foreground = "#181818",
background = "#ffffff"
} = params;
x = poster._toPx(x)
y = poster._toPx(y)
width = poster._toPx(width)
height = poster._toPx(height)
const qrcode = fuiQr(this.utf16to8(value), {
typeNumber: -1,
errorCorrectLevel: 2,
})
const cells = qrcode.modules
const tileW = width / cells.length
const tileH = height / cells.length
cells.forEach((row, rdx) => {
row.forEach((cell, cdx) => {
context.setFillStyle(cell ? foreground : background)
const w = (Math.ceil((cdx + 1) * tileW) - Math.floor(cdx * tileW))
const h = (Math.ceil((rdx + 1) * tileH) - Math.floor(rdx * tileH))
context.fillRect(Math.round(cdx * tileW) + x, Math.round(rdx * tileH) + y, w, h)
})
})
context.restore();
},
//ios用户拒绝相册访问 ,引导用户到设置页面,开启相册访问权限 //ios用户拒绝相册访问 ,引导用户到设置页面,开启相册访问权限
//-1=未请求 1 = 已允许,0 = 拒绝|受限 //-1=未请求 1 = 已允许,0 = 拒绝|受限
_judgeIosPermissionPhotoLibrary() { _judgeIosPermissionPhotoLibrary() {
...@@ -465,7 +499,7 @@ ...@@ -465,7 +499,7 @@
} }
} }
}, },
_getPosterData(texts, blocks, lines, imgs) { _getPosterData(texts, blocks, lines, imgs, qrcode) {
let queue = [].concat(texts.map((item) => { let queue = [].concat(texts.map((item) => {
item.type = 'text'; item.type = 'text';
item.zIndex = item.zIndex || 0; item.zIndex = item.zIndex || 0;
...@@ -478,6 +512,10 @@ ...@@ -478,6 +512,10 @@
item.type = 'line'; item.type = 'line';
item.zIndex = item.zIndex || 0; item.zIndex = item.zIndex || 0;
return item; return item;
})).concat(qrcode.map((item) => {
item.type = 'qrcode';
item.zIndex = item.zIndex || 0;
return item;
})).concat(imgs.map((item) => { })).concat(imgs.map((item) => {
item.type = 'image'; item.type = 'image';
item.zIndex = item.zIndex || 0; item.zIndex = item.zIndex || 0;
...@@ -534,6 +572,8 @@ ...@@ -534,6 +572,8 @@
this._drawBlock(context, params) this._drawBlock(context, params)
} else if (params.type === 'line') { } else if (params.type === 'line') {
this._drawLine(context, params) this._drawLine(context, params)
} else if (params.type === 'qrcode') {
this._drawQrcode(context, params)
} }
}); });
const sys = uni.getSystemInfoSync(); const sys = uni.getSystemInfoSync();
...@@ -566,7 +606,7 @@ ...@@ -566,7 +606,7 @@
//生成海报 //生成海报
generatePoster(params, callback) { generatePoster(params, callback) {
let { let {
texts = [], imgs = [], blocks = [], lines = [] texts = [], imgs = [], blocks = [], lines = [], qrcode = []
} = params; } = params;
//需要看平台支持情况,如果对应平台不支持将会绘制失败 //需要看平台支持情况,如果对应平台不支持将会绘制失败
//图片处理 type:1-无需处理(base64或者网络路径,需在平台支持下),2-网络图片,下载 3-base64转本地图片 //图片处理 type:1-无需处理(base64或者网络路径,需在平台支持下),2-网络图片,下载 3-base64转本地图片
...@@ -591,7 +631,7 @@ ...@@ -591,7 +631,7 @@
let item = imgs[idxArr[idx]] let item = imgs[idxArr[idx]]
item.imgResource = imgRes item.imgResource = imgRes
}) })
const queue = this._getPosterData(texts, blocks, lines, imgs); const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
this._generatePoster(this.width, this.height, queue, callback) this._generatePoster(this.width, this.height, queue, callback)
}).catch(err => { }).catch(err => {
...@@ -602,11 +642,11 @@ ...@@ -602,11 +642,11 @@
}) })
}) })
} else { } else {
const queue = this._getPosterData(texts, blocks, lines, imgs); const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
this._generatePoster(this.width, this.height, queue, callback) this._generatePoster(this.width, this.height, queue, callback)
} }
} else { } else {
const queue = this._getPosterData(texts, blocks, lines, imgs); const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
this._generatePoster(this.width, this.height, queue, callback) this._generatePoster(this.width, this.height, queue, callback)
} }
}, },
...@@ -633,6 +673,27 @@ ...@@ -633,6 +673,27 @@
}) })
} }
}) })
},
utf16to8(str) {
const len = str.length
let out = ''
for (let i = 0; i < len; i++) {
const c = str.charCodeAt(i)
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i)
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
}
}
return out
} }
} }
} }
......
import QRCode from './lib/QRCode.js'
import ErrorCorrectLevel from './lib/ErrorCorrectLevel.js'
var qrcode = function(data, opt) {
opt = opt || {};
var qr = new QRCode(opt.typeNumber || -1,
opt.errorCorrectLevel || ErrorCorrectLevel.H);
qr.addData(data);
qr.make();
return qr;
};
qrcode.ErrorCorrectLevel = ErrorCorrectLevel;
export default qrcode;
import mode from './mode.js'
function QR8bitByte(data) {
this.mode = mode.MODE_8BIT_BYTE;
this.data = data;
}
QR8bitByte.prototype = {
getLength : function(buffer) {
return this.data.length;
},
write : function(buffer) {
for (var i = 0; i < this.data.length; i++) {
// not JIS ...
buffer.put(this.data.charCodeAt(i), 8);
}
}
};
export default QR8bitByte;
function QRBitBuffer() {
this.buffer = new Array();
this.length = 0;
}
QRBitBuffer.prototype = {
get : function(index) {
var bufIndex = Math.floor(index / 8);
return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
},
put : function(num, length) {
for (var i = 0; i < length; i++) {
this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
}
},
getLengthInBits : function() {
return this.length;
},
putBit : function(bit) {
var bufIndex = Math.floor(this.length / 8);
if (this.buffer.length <= bufIndex) {
this.buffer.push(0);
}
if (bit) {
this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) );
}
this.length++;
}
};
export default QRBitBuffer;
Copyright (c) 2009 Kazuhiko Arase <kazuhiko.arase@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import math from './math.js'
function QRPolynomial(num, shift) {
if (num.length == undefined) {
throw new Error(num.length + "/" + shift);
}
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset++;
}
this.num = new Array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i++) {
this.num[i] = num[i + offset];
}
}
QRPolynomial.prototype = {
get : function(index) {
return this.num[index];
},
getLength : function() {
return this.num.length;
},
multiply : function(e) {
var num = new Array(this.getLength() + e.getLength() - 1);
for (var i = 0; i < this.getLength(); i++) {
for (var j = 0; j < e.getLength(); j++) {
num[i + j] ^= math.gexp(math.glog(this.get(i) ) + math.glog(e.get(j) ) );
}
}
return new QRPolynomial(num, 0);
},
mod : function(e) {
if (this.getLength() - e.getLength() < 0) {
return this;
}
var ratio = math.glog(this.get(0) ) - math.glog(e.get(0) );
var num = new Array(this.getLength() );
for (var i = 0; i < this.getLength(); i++) {
num[i] = this.get(i);
}
for (var i = 0; i < e.getLength(); i++) {
num[i] ^= math.gexp(math.glog(e.get(i) ) + ratio);
}
// recursive call
return new QRPolynomial(num, 0).mod(e);
}
};
export default QRPolynomial;
import BitByte from './8BitByte.js'
import RSBlock from './RSBlock.js'
import BitBuffer from './BitBuffer.js'
import util from './util.js'
import Polynomial from './Polynomial.js'
function QRCode(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
// for client side minification
var proto = QRCode.prototype;
proto.addData = function(data) {
var newData = new BitByte(data);
this.dataList.push(newData);
this.dataCache = null;
};
proto.isDark = function(row, col) {
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
throw new Error(row + "," + col);
}
return this.modules[row][col];
};
proto.getModuleCount = function() {
return this.moduleCount;
};
proto.make = function() {
// Calculate automatically typeNumber if provided is < 1
if (this.typeNumber < 1 ){
var typeNumber = 1;
for (typeNumber = 1; typeNumber < 40; typeNumber++) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
var buffer = new BitBuffer();
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
for (var i = 0; i < this.dataList.length; i++) {
var data = this.dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
if (buffer.getLengthInBits() <= totalDataCount * 8)
break;
}
this.typeNumber = typeNumber;
}
this.makeImpl(false, this.getBestMaskPattern() );
};
proto.makeImpl = function(test, maskPattern) {
this.moduleCount = this.typeNumber * 4 + 17;
this.modules = new Array(this.moduleCount);
for (var row = 0; row < this.moduleCount; row++) {
this.modules[row] = new Array(this.moduleCount);
for (var col = 0; col < this.moduleCount; col++) {
this.modules[row][col] = null;//(col + row) % 3;
}
}
this.setupPositionProbePattern(0, 0);
this.setupPositionProbePattern(this.moduleCount - 7, 0);
this.setupPositionProbePattern(0, this.moduleCount - 7);
this.setupPositionAdjustPattern();
this.setupTimingPattern();
this.setupTypeInfo(test, maskPattern);
if (this.typeNumber >= 7) {
this.setupTypeNumber(test);
}
if (this.dataCache == null) {
this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
}
this.mapData(this.dataCache, maskPattern);
};
proto.setupPositionProbePattern = function(row, col) {
for (var r = -1; r <= 7; r++) {
if (row + r <= -1 || this.moduleCount <= row + r) continue;
for (var c = -1; c <= 7; c++) {
if (col + c <= -1 || this.moduleCount <= col + c) continue;
if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
|| (0 <= c && c <= 6 && (r == 0 || r == 6) )
|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
};
proto.getBestMaskPattern = function() {
var minLostPoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i++) {
this.makeImpl(true, i);
var lostPoint = util.getLostPoint(this);
if (i == 0 || minLostPoint > lostPoint) {
minLostPoint = lostPoint;
pattern = i;
}
}
return pattern;
};
proto.createMovieClip = function(target_mc, instance_name, depth) {
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
var cs = 1;
this.make();
for (var row = 0; row < this.modules.length; row++) {
var y = row * cs;
for (var col = 0; col < this.modules[row].length; col++) {
var x = col * cs;
var dark = this.modules[row][col];
if (dark) {
qr_mc.beginFill(0, 100);
qr_mc.moveTo(x, y);
qr_mc.lineTo(x + cs, y);
qr_mc.lineTo(x + cs, y + cs);
qr_mc.lineTo(x, y + cs);
qr_mc.endFill();
}
}
}
return qr_mc;
};
proto.setupTimingPattern = function() {
for (var r = 8; r < this.moduleCount - 8; r++) {
if (this.modules[r][6] != null) {
continue;
}
this.modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < this.moduleCount - 8; c++) {
if (this.modules[6][c] != null) {
continue;
}
this.modules[6][c] = (c % 2 == 0);
}
};
proto.setupPositionAdjustPattern = function() {
var pos = util.getPatternPosition(this.typeNumber);
for (var i = 0; i < pos.length; i++) {
for (var j = 0; j < pos.length; j++) {
var row = pos[i];
var col = pos[j];
if (this.modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r++) {
for (var c = -2; c <= 2; c++) {
if (r == -2 || r == 2 || c == -2 || c == 2
|| (r == 0 && c == 0) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
}
}
};
proto.setupTypeNumber = function(test) {
var bits = util.getBCHTypeNumber(this.typeNumber);
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
}
};
proto.setupTypeInfo = function(test, maskPattern) {
var data = (this.errorCorrectLevel << 3) | maskPattern;
var bits = util.getBCHTypeInfo(data);
// vertical
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 6) {
this.modules[i][8] = mod;
} else if (i < 8) {
this.modules[i + 1][8] = mod;
} else {
this.modules[this.moduleCount - 15 + i][8] = mod;
}
}
// horizontal
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 8) {
this.modules[8][this.moduleCount - i - 1] = mod;
} else if (i < 9) {
this.modules[8][15 - i - 1 + 1] = mod;
} else {
this.modules[8][15 - i - 1] = mod;
}
}
// fixed module
this.modules[this.moduleCount - 8][8] = (!test);
};
proto.mapData = function(data, maskPattern) {
var inc = -1;
var row = this.moduleCount - 1;
var bitIndex = 7;
var byteIndex = 0;
for (var col = this.moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col--;
while (true) {
for (var c = 0; c < 2; c++) {
if (this.modules[row][col - c] == null) {
var dark = false;
if (byteIndex < data.length) {
dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
}
var mask = util.getMask(maskPattern, row, col - c);
if (mask) {
dark = !dark;
}
this.modules[row][col - c] = dark;
bitIndex--;
if (bitIndex == -1) {
byteIndex++;
bitIndex = 7;
}
}
}
row += inc;
if (row < 0 || this.moduleCount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
};
QRCode.PAD0 = 0xEC;
QRCode.PAD1 = 0x11;
QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
var buffer = new BitBuffer();
for (var i = 0; i < dataList.length; i++) {
var data = dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
// calc num max data.
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error("code length overflow. ("
+ buffer.getLengthInBits()
+ ">"
+ totalDataCount * 8
+ ")");
}
// end code
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
buffer.put(0, 4);
}
// padding
while (buffer.getLengthInBits() % 8 != 0) {
buffer.putBit(false);
}
// padding
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD0, 8);
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD1, 8);
}
return QRCode.createBytes(buffer, rsBlocks);
};
QRCode.createBytes = function(buffer, rsBlocks) {
var offset = 0;
var maxDcCount = 0;
var maxEcCount = 0;
var dcdata = new Array(rsBlocks.length);
var ecdata = new Array(rsBlocks.length);
for (var r = 0; r < rsBlocks.length; r++) {
var dcCount = rsBlocks[r].dataCount;
var ecCount = rsBlocks[r].totalCount - dcCount;
maxDcCount = Math.max(maxDcCount, dcCount);
maxEcCount = Math.max(maxEcCount, ecCount);
dcdata[r] = new Array(dcCount);
for (var i = 0; i < dcdata[r].length; i++) {
dcdata[r][i] = 0xff & buffer.buffer[i + offset];
}
offset += dcCount;
var rsPoly = util.getErrorCorrectPolynomial(ecCount);
var rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);
var modPoly = rawPoly.mod(rsPoly);
ecdata[r] = new Array(rsPoly.getLength() - 1);
for (var i = 0; i < ecdata[r].length; i++) {
var modIndex = i + modPoly.getLength() - ecdata[r].length;
ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;
}
}
var totalCodeCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalCodeCount += rsBlocks[i].totalCount;
}
var data = new Array(totalCodeCount);
var index = 0;
for (var i = 0; i < maxDcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < dcdata[r].length) {
data[index++] = dcdata[r][i];
}
}
}
for (var i = 0; i < maxEcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < ecdata[r].length) {
data[index++] = ecdata[r][i];
}
}
}
return data;
};
export default QRCode;
// ErrorCorrectLevel
import ECL from './ErrorCorrectLevel.js'
function QRRSBlock(totalCount, dataCount) {
this.totalCount = totalCount;
this.dataCount = dataCount;
}
QRRSBlock.RS_BLOCK_TABLE = [
// L
// M
// Q
// H
// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
// 11
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
// 12
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
// 13
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
// 14
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
// 15
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12],
// 16
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
// 17
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
// 18
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
// 19
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
// 20
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
// 21
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
// 22
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
// 23
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
// 24
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
// 25
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
// 26
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
// 27
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
// 28
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
// 29
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
// 30
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
// 31
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
// 32
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
// 33
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
// 34
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
// 35
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
// 36
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
// 37
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
// 38
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
// 39
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
// 40
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]
];
QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
if (rsBlock == undefined) {
throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
}
var length = rsBlock.length / 3;
var list = new Array();
for (var i = 0; i < length; i++) {
var count = rsBlock[i * 3 + 0];
var totalCount = rsBlock[i * 3 + 1];
var dataCount = rsBlock[i * 3 + 2];
for (var j = 0; j < count; j++) {
list.push(new QRRSBlock(totalCount, dataCount) );
}
}
return list;
}
QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
switch(errorCorrectLevel) {
case ECL.L :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
case ECL.M :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
case ECL.Q :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
case ECL.H :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
default :
return undefined;
}
}
export default QRRSBlock;
var QRMath = {
glog : function(n) {
if (n < 1) {
throw new Error("glog(" + n + ")");
}
return QRMath.LOG_TABLE[n];
},
gexp : function(n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return QRMath.EXP_TABLE[n];
},
EXP_TABLE : new Array(256),
LOG_TABLE : new Array(256)
};
for (var i = 0; i < 8; i++) {
QRMath.EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i++) {
QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4]
^ QRMath.EXP_TABLE[i - 5]
^ QRMath.EXP_TABLE[i - 6]
^ QRMath.EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i++) {
QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i;
}
export default QRMath;
export default {
MODE_NUMBER : 1 << 0,
MODE_ALPHA_NUM : 1 << 1,
MODE_8BIT_BYTE : 1 << 2,
MODE_KANJI : 1 << 3
};
import Mode from './mode.js'
import Polynomial from './Polynomial.js'
import math from './math.js'
var QRMaskPattern = {
PATTERN000 : 0,
PATTERN001 : 1,
PATTERN010 : 2,
PATTERN011 : 3,
PATTERN100 : 4,
PATTERN101 : 5,
PATTERN110 : 6,
PATTERN111 : 7
};
var QRUtil = {
PATTERN_POSITION_TABLE : [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
],
G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
getBCHTypeInfo : function(data) {
var d = data << 10;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) );
}
return ( (data << 10) | d) ^ QRUtil.G15_MASK;
},
getBCHTypeNumber : function(data) {
var d = data << 12;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) );
}
return (data << 12) | d;
},
getBCHDigit : function(data) {
var digit = 0;
while (data != 0) {
digit++;
data >>>= 1;
}
return digit;
},
getPatternPosition : function(typeNumber) {
return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
},
getMask : function(maskPattern, i, j) {
switch (maskPattern) {
case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;
case QRMaskPattern.PATTERN001 : return i % 2 == 0;
case QRMaskPattern.PATTERN010 : return j % 3 == 0;
case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;
case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;
case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;
case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;
case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;
default :
throw new Error("bad maskPattern:" + maskPattern);
}
},
getErrorCorrectPolynomial : function(errorCorrectLength) {
var a = new Polynomial([1], 0);
for (var i = 0; i < errorCorrectLength; i++) {
a = a.multiply(new Polynomial([1, math.gexp(i)], 0) );
}
return a;
},
getLengthInBits : function(mode, type) {
if (1 <= type && type < 10) {
// 1 - 9
switch(mode) {
case Mode.MODE_NUMBER : return 10;
case Mode.MODE_ALPHA_NUM : return 9;
case Mode.MODE_8BIT_BYTE : return 8;
case Mode.MODE_KANJI : return 8;
default :
throw new Error("mode:" + mode);
}
} else if (type < 27) {
// 10 - 26
switch(mode) {
case Mode.MODE_NUMBER : return 12;
case Mode.MODE_ALPHA_NUM : return 11;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 10;
default :
throw new Error("mode:" + mode);
}
} else if (type < 41) {
// 27 - 40
switch(mode) {
case Mode.MODE_NUMBER : return 14;
case Mode.MODE_ALPHA_NUM : return 13;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 12;
default :
throw new Error("mode:" + mode);
}
} else {
throw new Error("type:" + type);
}
},
getLostPoint : function(qrCode) {
var moduleCount = qrCode.getModuleCount();
var lostPoint = 0;
// LEVEL1
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount; col++) {
var sameCount = 0;
var dark = qrCode.isDark(row, col);
for (var r = -1; r <= 1; r++) {
if (row + r < 0 || moduleCount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c++) {
if (col + c < 0 || moduleCount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrCode.isDark(row + r, col + c) ) {
sameCount++;
}
}
}
if (sameCount > 5) {
lostPoint += (3 + sameCount - 5);
}
}
}
// LEVEL2
for (var row = 0; row < moduleCount - 1; row++) {
for (var col = 0; col < moduleCount - 1; col++) {
var count = 0;
if (qrCode.isDark(row, col ) ) count++;
if (qrCode.isDark(row + 1, col ) ) count++;
if (qrCode.isDark(row, col + 1) ) count++;
if (qrCode.isDark(row + 1, col + 1) ) count++;
if (count == 0 || count == 4) {
lostPoint += 3;
}
}
}
// LEVEL3
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount - 6; col++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row, col + 1)
&& qrCode.isDark(row, col + 2)
&& qrCode.isDark(row, col + 3)
&& qrCode.isDark(row, col + 4)
&& !qrCode.isDark(row, col + 5)
&& qrCode.isDark(row, col + 6) ) {
lostPoint += 40;
}
}
}
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount - 6; row++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row + 1, col)
&& qrCode.isDark(row + 2, col)
&& qrCode.isDark(row + 3, col)
&& qrCode.isDark(row + 4, col)
&& !qrCode.isDark(row + 5, col)
&& qrCode.isDark(row + 6, col) ) {
lostPoint += 40;
}
}
}
// LEVEL4
var darkCount = 0;
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount; row++) {
if (qrCode.isDark(row, col) ) {
darkCount++;
}
}
}
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
lostPoint += ratio * 10;
return lostPoint;
}
};
export default QRUtil;
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
_toPx(rpx) { _toPx(rpx) {
return uni.upx2px(Number(rpx) * Number(this.pixelRatio)) return uni.upx2px(Number(rpx) * Number(this.pixelRatio))
}, },
_getPosterData(texts, blocks, lines, imgs) { _getPosterData(texts, blocks, lines, imgs, qrcode) {
let queue = [].concat(texts.map((item) => { let queue = [].concat(texts.map((item) => {
item.type = 'text'; item.type = 'text';
item.zIndex = item.zIndex || 0; item.zIndex = item.zIndex || 0;
...@@ -93,6 +93,10 @@ ...@@ -93,6 +93,10 @@
item.type = 'line'; item.type = 'line';
item.zIndex = item.zIndex || 0; item.zIndex = item.zIndex || 0;
return item; return item;
})).concat(qrcode.map((item) => {
item.type = 'qrcode';
item.zIndex = item.zIndex || 0;
return item;
})).concat(imgs.map((item) => { })).concat(imgs.map((item) => {
item.type = 'image'; item.type = 'image';
item.zIndex = item.zIndex || 0; item.zIndex = item.zIndex || 0;
...@@ -105,7 +109,7 @@ ...@@ -105,7 +109,7 @@
//生成海报 //生成海报
generatePoster(params, callback) { generatePoster(params, callback) {
let { let {
texts = [], imgs = [], blocks = [], lines = [] texts = [], imgs = [], blocks = [], lines = [], qrcode = []
} = params; } = params;
//需要看平台支持情况,如果对应平台不支持将会绘制失败 //需要看平台支持情况,如果对应平台不支持将会绘制失败
//图片处理 type:1-无需处理(base64、本地路径、网络路径等,需在平台支持下),2-网络图片,下载 3-base64转本地图片(只支持App,微信小程序,H5) //图片处理 type:1-无需处理(base64、本地路径、网络路径等,需在平台支持下),2-网络图片,下载 3-base64转本地图片(只支持App,微信小程序,H5)
...@@ -131,7 +135,7 @@ ...@@ -131,7 +135,7 @@
item.imgResource = imgRes item.imgResource = imgRes
// console.log(imgRes) // console.log(imgRes)
}) })
const queue = this._getPosterData(texts, blocks, lines, imgs); const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
poster.generatePoster(this.width, this.height, queue, callback) poster.generatePoster(this.width, this.height, queue, callback)
}).catch(err => { }).catch(err => {
...@@ -142,11 +146,11 @@ ...@@ -142,11 +146,11 @@
}) })
}) })
} else { } else {
const queue = this._getPosterData(texts, blocks, lines, imgs); const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
poster.generatePoster(this.width, this.height, queue, callback) poster.generatePoster(this.width, this.height, queue, callback)
} }
} else { } else {
const queue = this._getPosterData(texts, blocks, lines, imgs); const queue = this._getPosterData(texts, blocks, lines, imgs, qrcode);
poster.generatePoster(this.width, this.height, queue, callback) poster.generatePoster(this.width, this.height, queue, callback)
} }
}, },
......
import QRCode from './lib/QRCode.js'
import ErrorCorrectLevel from './lib/ErrorCorrectLevel.js'
var qrcode = function(data, opt) {
opt = opt || {};
var qr = new QRCode(opt.typeNumber || -1,
opt.errorCorrectLevel || ErrorCorrectLevel.H);
qr.addData(data);
qr.make();
return qr;
};
qrcode.ErrorCorrectLevel = ErrorCorrectLevel;
export default qrcode;
import mode from './mode.js'
function QR8bitByte(data) {
this.mode = mode.MODE_8BIT_BYTE;
this.data = data;
}
QR8bitByte.prototype = {
getLength : function(buffer) {
return this.data.length;
},
write : function(buffer) {
for (var i = 0; i < this.data.length; i++) {
// not JIS ...
buffer.put(this.data.charCodeAt(i), 8);
}
}
};
export default QR8bitByte;
function QRBitBuffer() {
this.buffer = new Array();
this.length = 0;
}
QRBitBuffer.prototype = {
get : function(index) {
var bufIndex = Math.floor(index / 8);
return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
},
put : function(num, length) {
for (var i = 0; i < length; i++) {
this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
}
},
getLengthInBits : function() {
return this.length;
},
putBit : function(bit) {
var bufIndex = Math.floor(this.length / 8);
if (this.buffer.length <= bufIndex) {
this.buffer.push(0);
}
if (bit) {
this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) );
}
this.length++;
}
};
export default QRBitBuffer;
Copyright (c) 2009 Kazuhiko Arase <kazuhiko.arase@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import math from './math.js'
function QRPolynomial(num, shift) {
if (num.length == undefined) {
throw new Error(num.length + "/" + shift);
}
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset++;
}
this.num = new Array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i++) {
this.num[i] = num[i + offset];
}
}
QRPolynomial.prototype = {
get : function(index) {
return this.num[index];
},
getLength : function() {
return this.num.length;
},
multiply : function(e) {
var num = new Array(this.getLength() + e.getLength() - 1);
for (var i = 0; i < this.getLength(); i++) {
for (var j = 0; j < e.getLength(); j++) {
num[i + j] ^= math.gexp(math.glog(this.get(i) ) + math.glog(e.get(j) ) );
}
}
return new QRPolynomial(num, 0);
},
mod : function(e) {
if (this.getLength() - e.getLength() < 0) {
return this;
}
var ratio = math.glog(this.get(0) ) - math.glog(e.get(0) );
var num = new Array(this.getLength() );
for (var i = 0; i < this.getLength(); i++) {
num[i] = this.get(i);
}
for (var i = 0; i < e.getLength(); i++) {
num[i] ^= math.gexp(math.glog(e.get(i) ) + ratio);
}
// recursive call
return new QRPolynomial(num, 0).mod(e);
}
};
export default QRPolynomial;
import BitByte from './8BitByte.js'
import RSBlock from './RSBlock.js'
import BitBuffer from './BitBuffer.js'
import util from './util.js'
import Polynomial from './Polynomial.js'
function QRCode(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
// for client side minification
var proto = QRCode.prototype;
proto.addData = function(data) {
var newData = new BitByte(data);
this.dataList.push(newData);
this.dataCache = null;
};
proto.isDark = function(row, col) {
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
throw new Error(row + "," + col);
}
return this.modules[row][col];
};
proto.getModuleCount = function() {
return this.moduleCount;
};
proto.make = function() {
// Calculate automatically typeNumber if provided is < 1
if (this.typeNumber < 1 ){
var typeNumber = 1;
for (typeNumber = 1; typeNumber < 40; typeNumber++) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
var buffer = new BitBuffer();
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
for (var i = 0; i < this.dataList.length; i++) {
var data = this.dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
if (buffer.getLengthInBits() <= totalDataCount * 8)
break;
}
this.typeNumber = typeNumber;
}
this.makeImpl(false, this.getBestMaskPattern() );
};
proto.makeImpl = function(test, maskPattern) {
this.moduleCount = this.typeNumber * 4 + 17;
this.modules = new Array(this.moduleCount);
for (var row = 0; row < this.moduleCount; row++) {
this.modules[row] = new Array(this.moduleCount);
for (var col = 0; col < this.moduleCount; col++) {
this.modules[row][col] = null;//(col + row) % 3;
}
}
this.setupPositionProbePattern(0, 0);
this.setupPositionProbePattern(this.moduleCount - 7, 0);
this.setupPositionProbePattern(0, this.moduleCount - 7);
this.setupPositionAdjustPattern();
this.setupTimingPattern();
this.setupTypeInfo(test, maskPattern);
if (this.typeNumber >= 7) {
this.setupTypeNumber(test);
}
if (this.dataCache == null) {
this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
}
this.mapData(this.dataCache, maskPattern);
};
proto.setupPositionProbePattern = function(row, col) {
for (var r = -1; r <= 7; r++) {
if (row + r <= -1 || this.moduleCount <= row + r) continue;
for (var c = -1; c <= 7; c++) {
if (col + c <= -1 || this.moduleCount <= col + c) continue;
if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
|| (0 <= c && c <= 6 && (r == 0 || r == 6) )
|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
};
proto.getBestMaskPattern = function() {
var minLostPoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i++) {
this.makeImpl(true, i);
var lostPoint = util.getLostPoint(this);
if (i == 0 || minLostPoint > lostPoint) {
minLostPoint = lostPoint;
pattern = i;
}
}
return pattern;
};
proto.createMovieClip = function(target_mc, instance_name, depth) {
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
var cs = 1;
this.make();
for (var row = 0; row < this.modules.length; row++) {
var y = row * cs;
for (var col = 0; col < this.modules[row].length; col++) {
var x = col * cs;
var dark = this.modules[row][col];
if (dark) {
qr_mc.beginFill(0, 100);
qr_mc.moveTo(x, y);
qr_mc.lineTo(x + cs, y);
qr_mc.lineTo(x + cs, y + cs);
qr_mc.lineTo(x, y + cs);
qr_mc.endFill();
}
}
}
return qr_mc;
};
proto.setupTimingPattern = function() {
for (var r = 8; r < this.moduleCount - 8; r++) {
if (this.modules[r][6] != null) {
continue;
}
this.modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < this.moduleCount - 8; c++) {
if (this.modules[6][c] != null) {
continue;
}
this.modules[6][c] = (c % 2 == 0);
}
};
proto.setupPositionAdjustPattern = function() {
var pos = util.getPatternPosition(this.typeNumber);
for (var i = 0; i < pos.length; i++) {
for (var j = 0; j < pos.length; j++) {
var row = pos[i];
var col = pos[j];
if (this.modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r++) {
for (var c = -2; c <= 2; c++) {
if (r == -2 || r == 2 || c == -2 || c == 2
|| (r == 0 && c == 0) ) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
}
}
};
proto.setupTypeNumber = function(test) {
var bits = util.getBCHTypeNumber(this.typeNumber);
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
}
};
proto.setupTypeInfo = function(test, maskPattern) {
var data = (this.errorCorrectLevel << 3) | maskPattern;
var bits = util.getBCHTypeInfo(data);
// vertical
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 6) {
this.modules[i][8] = mod;
} else if (i < 8) {
this.modules[i + 1][8] = mod;
} else {
this.modules[this.moduleCount - 15 + i][8] = mod;
}
}
// horizontal
for (var i = 0; i < 15; i++) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 8) {
this.modules[8][this.moduleCount - i - 1] = mod;
} else if (i < 9) {
this.modules[8][15 - i - 1 + 1] = mod;
} else {
this.modules[8][15 - i - 1] = mod;
}
}
// fixed module
this.modules[this.moduleCount - 8][8] = (!test);
};
proto.mapData = function(data, maskPattern) {
var inc = -1;
var row = this.moduleCount - 1;
var bitIndex = 7;
var byteIndex = 0;
for (var col = this.moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col--;
while (true) {
for (var c = 0; c < 2; c++) {
if (this.modules[row][col - c] == null) {
var dark = false;
if (byteIndex < data.length) {
dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
}
var mask = util.getMask(maskPattern, row, col - c);
if (mask) {
dark = !dark;
}
this.modules[row][col - c] = dark;
bitIndex--;
if (bitIndex == -1) {
byteIndex++;
bitIndex = 7;
}
}
}
row += inc;
if (row < 0 || this.moduleCount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
};
QRCode.PAD0 = 0xEC;
QRCode.PAD1 = 0x11;
QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
var buffer = new BitBuffer();
for (var i = 0; i < dataList.length; i++) {
var data = dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
// calc num max data.
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error("code length overflow. ("
+ buffer.getLengthInBits()
+ ">"
+ totalDataCount * 8
+ ")");
}
// end code
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
buffer.put(0, 4);
}
// padding
while (buffer.getLengthInBits() % 8 != 0) {
buffer.putBit(false);
}
// padding
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD0, 8);
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD1, 8);
}
return QRCode.createBytes(buffer, rsBlocks);
};
QRCode.createBytes = function(buffer, rsBlocks) {
var offset = 0;
var maxDcCount = 0;
var maxEcCount = 0;
var dcdata = new Array(rsBlocks.length);
var ecdata = new Array(rsBlocks.length);
for (var r = 0; r < rsBlocks.length; r++) {
var dcCount = rsBlocks[r].dataCount;
var ecCount = rsBlocks[r].totalCount - dcCount;
maxDcCount = Math.max(maxDcCount, dcCount);
maxEcCount = Math.max(maxEcCount, ecCount);
dcdata[r] = new Array(dcCount);
for (var i = 0; i < dcdata[r].length; i++) {
dcdata[r][i] = 0xff & buffer.buffer[i + offset];
}
offset += dcCount;
var rsPoly = util.getErrorCorrectPolynomial(ecCount);
var rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);
var modPoly = rawPoly.mod(rsPoly);
ecdata[r] = new Array(rsPoly.getLength() - 1);
for (var i = 0; i < ecdata[r].length; i++) {
var modIndex = i + modPoly.getLength() - ecdata[r].length;
ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;
}
}
var totalCodeCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalCodeCount += rsBlocks[i].totalCount;
}
var data = new Array(totalCodeCount);
var index = 0;
for (var i = 0; i < maxDcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < dcdata[r].length) {
data[index++] = dcdata[r][i];
}
}
}
for (var i = 0; i < maxEcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < ecdata[r].length) {
data[index++] = ecdata[r][i];
}
}
}
return data;
};
export default QRCode;
// ErrorCorrectLevel
import ECL from './ErrorCorrectLevel.js'
function QRRSBlock(totalCount, dataCount) {
this.totalCount = totalCount;
this.dataCount = dataCount;
}
QRRSBlock.RS_BLOCK_TABLE = [
// L
// M
// Q
// H
// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
// 11
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
// 12
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
// 13
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
// 14
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
// 15
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12],
// 16
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
// 17
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
// 18
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
// 19
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
// 20
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
// 21
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
// 22
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
// 23
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
// 24
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
// 25
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
// 26
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
// 27
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
// 28
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
// 29
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
// 30
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
// 31
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
// 32
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
// 33
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
// 34
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
// 35
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
// 36
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
// 37
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
// 38
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
// 39
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
// 40
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]
];
QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
if (rsBlock == undefined) {
throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
}
var length = rsBlock.length / 3;
var list = new Array();
for (var i = 0; i < length; i++) {
var count = rsBlock[i * 3 + 0];
var totalCount = rsBlock[i * 3 + 1];
var dataCount = rsBlock[i * 3 + 2];
for (var j = 0; j < count; j++) {
list.push(new QRRSBlock(totalCount, dataCount) );
}
}
return list;
}
QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
switch(errorCorrectLevel) {
case ECL.L :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
case ECL.M :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
case ECL.Q :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
case ECL.H :
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
default :
return undefined;
}
}
export default QRRSBlock;
var QRMath = {
glog : function(n) {
if (n < 1) {
throw new Error("glog(" + n + ")");
}
return QRMath.LOG_TABLE[n];
},
gexp : function(n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return QRMath.EXP_TABLE[n];
},
EXP_TABLE : new Array(256),
LOG_TABLE : new Array(256)
};
for (var i = 0; i < 8; i++) {
QRMath.EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i++) {
QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4]
^ QRMath.EXP_TABLE[i - 5]
^ QRMath.EXP_TABLE[i - 6]
^ QRMath.EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i++) {
QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i;
}
export default QRMath;
export default {
MODE_NUMBER : 1 << 0,
MODE_ALPHA_NUM : 1 << 1,
MODE_8BIT_BYTE : 1 << 2,
MODE_KANJI : 1 << 3
};
import Mode from './mode.js'
import Polynomial from './Polynomial.js'
import math from './math.js'
var QRMaskPattern = {
PATTERN000 : 0,
PATTERN001 : 1,
PATTERN010 : 2,
PATTERN011 : 3,
PATTERN100 : 4,
PATTERN101 : 5,
PATTERN110 : 6,
PATTERN111 : 7
};
var QRUtil = {
PATTERN_POSITION_TABLE : [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
],
G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
getBCHTypeInfo : function(data) {
var d = data << 10;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) );
}
return ( (data << 10) | d) ^ QRUtil.G15_MASK;
},
getBCHTypeNumber : function(data) {
var d = data << 12;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) );
}
return (data << 12) | d;
},
getBCHDigit : function(data) {
var digit = 0;
while (data != 0) {
digit++;
data >>>= 1;
}
return digit;
},
getPatternPosition : function(typeNumber) {
return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
},
getMask : function(maskPattern, i, j) {
switch (maskPattern) {
case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;
case QRMaskPattern.PATTERN001 : return i % 2 == 0;
case QRMaskPattern.PATTERN010 : return j % 3 == 0;
case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;
case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;
case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;
case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;
case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;
default :
throw new Error("bad maskPattern:" + maskPattern);
}
},
getErrorCorrectPolynomial : function(errorCorrectLength) {
var a = new Polynomial([1], 0);
for (var i = 0; i < errorCorrectLength; i++) {
a = a.multiply(new Polynomial([1, math.gexp(i)], 0) );
}
return a;
},
getLengthInBits : function(mode, type) {
if (1 <= type && type < 10) {
// 1 - 9
switch(mode) {
case Mode.MODE_NUMBER : return 10;
case Mode.MODE_ALPHA_NUM : return 9;
case Mode.MODE_8BIT_BYTE : return 8;
case Mode.MODE_KANJI : return 8;
default :
throw new Error("mode:" + mode);
}
} else if (type < 27) {
// 10 - 26
switch(mode) {
case Mode.MODE_NUMBER : return 12;
case Mode.MODE_ALPHA_NUM : return 11;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 10;
default :
throw new Error("mode:" + mode);
}
} else if (type < 41) {
// 27 - 40
switch(mode) {
case Mode.MODE_NUMBER : return 14;
case Mode.MODE_ALPHA_NUM : return 13;
case Mode.MODE_8BIT_BYTE : return 16;
case Mode.MODE_KANJI : return 12;
default :
throw new Error("mode:" + mode);
}
} else {
throw new Error("type:" + type);
}
},
getLostPoint : function(qrCode) {
var moduleCount = qrCode.getModuleCount();
var lostPoint = 0;
// LEVEL1
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount; col++) {
var sameCount = 0;
var dark = qrCode.isDark(row, col);
for (var r = -1; r <= 1; r++) {
if (row + r < 0 || moduleCount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c++) {
if (col + c < 0 || moduleCount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrCode.isDark(row + r, col + c) ) {
sameCount++;
}
}
}
if (sameCount > 5) {
lostPoint += (3 + sameCount - 5);
}
}
}
// LEVEL2
for (var row = 0; row < moduleCount - 1; row++) {
for (var col = 0; col < moduleCount - 1; col++) {
var count = 0;
if (qrCode.isDark(row, col ) ) count++;
if (qrCode.isDark(row + 1, col ) ) count++;
if (qrCode.isDark(row, col + 1) ) count++;
if (qrCode.isDark(row + 1, col + 1) ) count++;
if (count == 0 || count == 4) {
lostPoint += 3;
}
}
}
// LEVEL3
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount - 6; col++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row, col + 1)
&& qrCode.isDark(row, col + 2)
&& qrCode.isDark(row, col + 3)
&& qrCode.isDark(row, col + 4)
&& !qrCode.isDark(row, col + 5)
&& qrCode.isDark(row, col + 6) ) {
lostPoint += 40;
}
}
}
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount - 6; row++) {
if (qrCode.isDark(row, col)
&& !qrCode.isDark(row + 1, col)
&& qrCode.isDark(row + 2, col)
&& qrCode.isDark(row + 3, col)
&& qrCode.isDark(row + 4, col)
&& !qrCode.isDark(row + 5, col)
&& qrCode.isDark(row + 6, col) ) {
lostPoint += 40;
}
}
}
// LEVEL4
var darkCount = 0;
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount; row++) {
if (qrCode.isDark(row, col) ) {
darkCount++;
}
}
}
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
lostPoint += ratio * 10;
return lostPoint;
}
};
export default QRUtil;
/*! /*!
* 生成海报 * 生成海报
* poster - v1.8.0 (2023/02/02, 16:52:14 PM) * poster - v1.8.0 (2023/02/02, 16:52:14 PM)
* updated V2.2.0+ 2023/11/07
* *
* *
* 官网地址:https://firstui.cn/ * 官网地址:https://firstui.cn/
* 文档地址:https://doc.firstui.cn/ * 文档地址:https://doc.firstui.cn/
*/ */
import fuiQr from './fui-qr/index.js'
const poster = { const poster = {
_pixelRatio: 2, _pixelRatio: 2,
_ctx: null, _ctx: null,
...@@ -320,6 +322,38 @@ const poster = { ...@@ -320,6 +322,38 @@ const poster = {
context.closePath(); context.closePath();
context.restore(); context.restore();
}, },
_drawQrcode(context, params) {
let {
x,
y,
width,
height,
value,
foreground = "#181818",
background = "#ffffff"
} = params;
x = poster._toPx(x)
y = poster._toPx(y)
width = poster._toPx(width)
height = poster._toPx(height)
const qrcode = fuiQr(poster.utf16to8(value), {
typeNumber: -1,
errorCorrectLevel: 2,
})
const cells = qrcode.modules
const tileW = width / cells.length
const tileH = height / cells.length
cells.forEach((row, rdx) => {
row.forEach((cell, cdx) => {
context.setFillStyle(cell ? foreground : background)
const w = (Math.ceil((cdx + 1) * tileW) - Math.floor(cdx * tileW))
const h = (Math.ceil((rdx + 1) * tileH) - Math.floor(rdx * tileH))
context.fillRect(Math.round(cdx * tileW) + x, Math.round(rdx * tileH) + y, w, h)
})
})
context.restore();
},
//ios用户拒绝相册访问 ,引导用户到设置页面,开启相册访问权限 //ios用户拒绝相册访问 ,引导用户到设置页面,开启相册访问权限
//-1=未请求 1 = 已允许,0 = 拒绝|受限 //-1=未请求 1 = 已允许,0 = 拒绝|受限
_judgeIosPermissionPhotoLibrary() { _judgeIosPermissionPhotoLibrary() {
...@@ -559,6 +593,8 @@ const poster = { ...@@ -559,6 +593,8 @@ const poster = {
poster._drawBlock(context, params) poster._drawBlock(context, params)
} else if (params.type === 'line') { } else if (params.type === 'line') {
poster._drawLine(context, params) poster._drawLine(context, params)
} else if (params.type === 'qrcode') {
poster._drawQrcode(context, params)
} }
}); });
const platform = uni.getSystemInfoSync().platform; const platform = uni.getSystemInfoSync().platform;
...@@ -631,6 +667,27 @@ const poster = { ...@@ -631,6 +667,27 @@ const poster = {
urls: [file] urls: [file]
}); });
// #endif // #endif
},
utf16to8(str) {
const len = str.length
let out = ''
for (let i = 0; i < len; i++) {
const c = str.charCodeAt(i)
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i)
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
}
}
return out
} }
} }
......
...@@ -36,11 +36,11 @@ ...@@ -36,11 +36,11 @@
<view class="fui-preview__ft" :style="{'border-top-color':borderColor}" <view class="fui-preview__ft" :style="{'border-top-color':borderColor}"
v-if="pvd[buttons] && pvd[buttons].length>0"> v-if="pvd[buttons] && pvd[buttons].length>0">
<view :style="{'border-right-color':idx!==pvd[buttons].length-1?borderColor : 'transparent'}" <view :style="{'border-right-color':idx!==pvd[buttons].length-1?borderColor : 'transparent'}"
:class="[highlight?'fui-preview__hover-weex':'',idx!==pvd[buttons].length-1?'fui-preview__btn-def':'fui-preview__btn']" :class="[highlight && !btn[disabled]?'fui-preview__hover-weex':'',idx!==pvd[buttons].length-1?'fui-preview__btn-def':'fui-preview__btn']"
:hover-class="highlight?'fui-preview_hover':''" :hover-stay-time="150" v-for="(btn,idx) in pvd[buttons]" :hover-class="highlight && !btn[disabled]?'fui-preview_hover':''" :hover-stay-time="150"
:key="idx" @tap="handleClick(idx)"> v-for="(btn,idx) in pvd[buttons]" :key="idx" @tap="handleClick(idx)">
<text :style="{fontSize:btnSize+'rpx',color:btn[color] || '#465CFF'}" <text :style="{fontSize:btnSize+'rpx',color:btn[color] || '#465CFF'}"
:class="{'fui-preview__link':!btn[color]}">{{btn[text]}}</text> :class="{'fui-preview__link':!btn[color],'fui-preview__button-disable':btn[disabled]}">{{btn[text]}}</text>
</view> </view>
</view> </view>
</view> </view>
...@@ -217,7 +217,8 @@ ...@@ -217,7 +217,8 @@
valueColor: 'valueColor', valueColor: 'valueColor',
buttons: 'buttons', buttons: 'buttons',
text: 'text', text: 'text',
color: 'color' color: 'color',
disabled: 'disabled'
}; };
}, },
methods: { methods: {
...@@ -231,6 +232,7 @@ ...@@ -231,6 +232,7 @@
this.buttons = this.fields.buttons || 'buttons'; this.buttons = this.fields.buttons || 'buttons';
this.text = this.fields.text || 'text'; this.text = this.fields.text || 'text';
this.color = this.fields.color || 'color'; this.color = this.fields.color || 'color';
this.disabled = this.fields.disabled || 'disabled';
} }
}, },
initData(val) { initData(val) {
...@@ -242,6 +244,7 @@ ...@@ -242,6 +244,7 @@
}, },
handleClick(idx) { handleClick(idx) {
let params = this.pvd[this.buttons][idx] || {} let params = this.pvd[this.buttons][idx] || {}
if (params.disabled) return;
this.$emit('click', { this.$emit('click', {
index: idx, index: idx,
...params ...params
...@@ -546,6 +549,12 @@ ...@@ -546,6 +549,12 @@
.fui-preview__hover-weex:active { .fui-preview__hover-weex:active {
background-color: rgba(0, 0, 0, 0.2) !important; background-color: rgba(0, 0, 0, 0.2) !important;
} }
/* #endif */ /* #endif */
.fui-preview__button-disable {
opacity: .5;
/* #ifdef H5 */
cursor: not-allowed;
/* #endif */
}
</style> </style>
...@@ -46,10 +46,10 @@ const base = { ...@@ -46,10 +46,10 @@ const base = {
let options = { let options = {
...config ...config
}; };
['host', 'timeout', 'prevent', 'keys', 'brief', 'cancelToken', 'showLoading', 'loadingText', 'errorMsg', const keys = ['host', 'timeout', 'prevent', 'keys', 'brief', 'cancelToken', 'showLoading', 'loadingText',
'arrayFormat' 'errorMsg', 'arrayFormat'
] ];
.forEach(item => { keys.forEach(item => {
delete options[item]; delete options[item];
}) })
return options; return options;
......
...@@ -23,9 +23,11 @@ function bool(str) { ...@@ -23,9 +23,11 @@ function bool(str) {
function touchstart(e, ins) { function touchstart(e, ins) {
var state = e.instance.getState() var state = e.instance.getState()
var touch = e.touches[0] || e.changedTouches[0] var touch = {}
if (isH5 && isPC()) { if (isH5 && isPC()) {
touch = e; touch = e;
} else {
touch = e.touches[0] || e.changedTouches[0]
} }
var dataset = e.instance.getDataset() var dataset = e.instance.getDataset()
state.startX = touch.pageX state.startX = touch.pageX
......
...@@ -18,7 +18,7 @@ export default { ...@@ -18,7 +18,7 @@ export default {
}, },
methods: { methods: {
styleChange(left, deg) { styleChange(left, deg) {
if (left == 0 && deg == 0) { if (left == 0 && deg == 0) {// 功能需要优化
this.resetAni = true this.resetAni = true
} else { } else {
this.resetAni = false this.resetAni = false
...@@ -48,14 +48,14 @@ export default { ...@@ -48,14 +48,14 @@ export default {
let left = this.sliderWidth - this.sliderHeight; let left = this.sliderWidth - this.sliderHeight;
let deg = 360 / left * this.lastLeft let deg = 360 / left * this.lastLeft
this.verify({ this.verify({
angle: deg angle: deg// 2021-5-6变更
}) })
} }// todo: 待修改
} }
} }// 新特性待增加
// #endif // #endif
// #ifdef APP-PLUS|| MP-WEIXIN || H5 // #ifdef APP-PLUS|| MP-WEIXIN || H5
export default {} export default {}// 2021-5-6变更
// #endif // #endif
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
</view> </view>
<input ref="searchBarRef" class="fui-search__bar-input" :class="{'fui-sb__input-color':!color}" <input ref="searchBarRef" class="fui-search__bar-input" :class="{'fui-sb__input-color':!color}"
:style="{color:color,height: height+'rpx'}" placeholder-class="fui-search__bar-pl" :style="{color:color,height: height+'rpx'}" placeholder-class="fui-search__bar-pl"
:placeholder="placeholder" :value="val" :focus="isFocus" :disabled="disabled" confirm-type="search" :placeholder="plholder" :value="val" :focus="isFocus" :disabled="disabled" confirm-type="search"
@blur="inputBlur" @focus="inputFocus" @input="inputChange" @confirm="search" /> @blur="inputBlur" @focus="inputFocus" @input="inputChange" @confirm="search" />
<view class="fui-sbi__clear-wrap" v-if="val.length > 0 && !disabled" @tap.stop="clearInput"> <view class="fui-sbi__clear-wrap" v-if="val.length > 0 && !disabled" @tap.stop="clearInput">
<view class="fui-sbi__clear"> <view class="fui-sbi__clear">
...@@ -137,10 +137,25 @@ ...@@ -137,10 +137,25 @@
showLabel: { showLabel: {
type: Boolean, type: Boolean,
default: true default: true
},
//v2.1.0
fixed: {
type: Boolean,
default: false
} }
}, },
created() { created() {
this.val = this.value; this.val = this.value;
// #ifndef MP-WEIXIN
this.plholder = this.placeholder;
// #endif
// #ifdef MP-WEIXIN
if(!this.showLabel || !this.fixed || this.focus || this.val.length > 0){
this.plholder = this.placeholder;
}
// #endif
if (this.focus || this.val.length > 0) { if (this.focus || this.val.length > 0) {
this.isSearch = true; this.isSearch = true;
} }
...@@ -177,6 +192,17 @@ ...@@ -177,6 +192,17 @@
if (this.focus || this.val.length > 0) { if (this.focus || this.val.length > 0) {
this.isSearch = true; this.isSearch = true;
} }
},
placeholder(val) {
// #ifndef MP-WEIXIN
this.plholder = this.placeholder;
// #endif
// #ifdef MP-WEIXIN
if(!this.showLabel || !this.fixed){
this.plholder = this.placeholder;
}
// #endif
} }
}, },
computed: { computed: {
...@@ -195,8 +221,8 @@ ...@@ -195,8 +221,8 @@
return { return {
isSearch: false, isSearch: false,
isFocus: false, isFocus: false,
val: '' val: '',
plholder: ''
}; };
}, },
methods: { methods: {
...@@ -224,6 +250,11 @@ ...@@ -224,6 +250,11 @@
inputBlur(e) { inputBlur(e) {
this.isFocus = false; this.isFocus = false;
if (!this.cancel && !this.val) { if (!this.cancel && !this.val) {
// #ifdef MP-WEIXIN
if(this.fixed && this.showLabel){
this.plholder = '';
}
// #endif
this.isSearch = false; this.isSearch = false;
} }
this.$emit('blur', e); this.$emit('blur', e);
...@@ -231,6 +262,11 @@ ...@@ -231,6 +262,11 @@
onShowInput() { onShowInput() {
if (!this.disabled && this.showInput) { if (!this.disabled && this.showInput) {
this.isSearch = true; this.isSearch = true;
// #ifdef MP-WEIXIN
if(this.fixed && this.showLabel){
this.plholder = this.placeholder;
}
// #endif
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
this.isFocus = true; this.isFocus = true;
...@@ -240,6 +276,11 @@ ...@@ -240,6 +276,11 @@
this.$emit('click', {}); this.$emit('click', {});
}, },
hideInput() { hideInput() {
// #ifdef MP-WEIXIN
if(this.fixed && this.showLabel){
this.plholder = '';
}
// #endif
this.isSearch = false; this.isSearch = false;
this.isFocus = false; this.isFocus = false;
uni.hideKeyboard() uni.hideKeyboard()
......
...@@ -420,7 +420,7 @@ ...@@ -420,7 +420,7 @@
let items = [] let items = []
this.itemList.forEach((item, idx) => { this.itemList.forEach((item, idx) => {
if (item.checked) { if (item.checked) {
items.push(this.options[idx]) items.push(item)
} }
}) })
this.$emit('confirm', { this.$emit('confirm', {
......
...@@ -579,6 +579,9 @@ ...@@ -579,6 +579,9 @@
/* #ifdef APP-NVUE || MP-TOUTIAO */ /* #ifdef APP-NVUE || MP-TOUTIAO */
.fui-ss__safe-weex { .fui-ss__safe-weex {
/* #ifdef APP-NVUE */
height: 164rpx;
/* #endif */
padding-bottom: 34px; padding-bottom: 34px;
} }
......
...@@ -239,17 +239,11 @@ ...@@ -239,17 +239,11 @@
this.getVals(val, true) this.getVals(val, true)
}, },
mounted() { mounted() {
// #ifndef MP-TOUTIAO this.$nextTick(()=>{
setTimeout(() => { setTimeout(() => {
this.initFocus(this.isFocus) this.initFocus(this.isFocus)
}, 200) }, 300)
// #endif })
// #ifdef MP-TOUTIAO
setTimeout(() => {
this.initFocus(this.isFocus)
}, 300)
// #endif
}, },
//nvue暂不支持vue3,所以不需要做兼容,此处以防后续兼容 //nvue暂不支持vue3,所以不需要做兼容,此处以防后续兼容
// #ifdef APP-NVUE // #ifdef APP-NVUE
...@@ -499,7 +493,7 @@ ...@@ -499,7 +493,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
opacity: 0; opacity: 0;
/* #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO */ /* #ifdef MP-BAIDU || MP-TOUTIAO */
font-size: 0; font-size: 0;
/* #endif */ /* #endif */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<view class="fui-skeleton__wrap" :style="{background:background,height:height+'px'}" ref="fui_skeleton"> <view class="fui-skeleton__wrap" :style="{background:background,height:height+'px'}" ref="fui_skeleton">
<view class="fui-skeleton__item" <view class="fui-skeleton__item"
:class="{'fui-skeleton__dark':theme==='dark','fui-skeleton__dark-ani':active && theme==='dark','fui-skeleton__light-ani':active && theme!=='dark'}" :class="{'fui-skeleton__dark':theme==='dark','fui-skeleton__dark-ani':active && theme==='dark','fui-skeleton__light-ani':active && theme!=='dark'}"
:style="{width: item.width+'px', height:item.height+'px', left: item.left+'px', top: item.top+'px',borderRadius:item.type==='round'?(isNvue?item.width/2+'px':'50%'):'6rpx'}" :style="{width: item.width+'px', height:item.height+'px', left: item.left+'px', top: (item.top-top)+'px',borderRadius:item.type==='round'?(isNvue?item.width/2+'px':'50%'):'6rpx'}"
v-for="(item,index) in elList" :key="index"> v-for="(item,index) in elList" :key="index">
</view> </view>
</view> </view>
...@@ -50,6 +50,16 @@ ...@@ -50,6 +50,16 @@
theme: { theme: {
type: String, type: String,
default: 'light' default: 'light'
},
//v2.1.0+ 组件初始化完成后是否立即显示骨架【仅在页面使用及component为false时有效】
immediate: {
type: Boolean,
default: true
},
//v2.1.0+ 是否在自定义组件内使用,需要调用方法显示骨架
component: {
type: Boolean,
default: false
} }
}, },
data() { data() {
...@@ -62,7 +72,8 @@ ...@@ -62,7 +72,8 @@
stop: false, stop: false,
//round、rect //round、rect
elList: [], elList: [],
height: 0 height: 0,
top: 0
}; };
}, },
created() { created() {
...@@ -73,25 +84,12 @@ ...@@ -73,25 +84,12 @@
} }
}, },
mounted() { mounted() {
// #ifndef APP-NVUE
this.$nextTick(() => { this.$nextTick(() => {
this.nodesRef(this.outerClass).then((res) => { if (this.immediate && !this.component) {
if (res && res[0]) { //页面使用无需传
this.height = res[0].height this.shown()
}
});
if (!this.preloadList || this.preloadList.length === 0) {
this.selectorQuery()
} }
}) })
// #endif
// #ifdef APP-NVUE
this.$nextTick(() => {
setTimeout(() => {
this._animation(false)
}, 50)
})
// #endif
}, },
// #ifdef APP-NVUE // #ifdef APP-NVUE
// #ifndef VUE3 // #ifndef VUE3
...@@ -106,6 +104,24 @@ ...@@ -106,6 +104,24 @@
// #endif // #endif
// #endif // #endif
methods: { methods: {
shown(instance) {
// #ifndef APP-NVUE
this.nodesRef(this.outerClass, instance).then((res) => {
if (res && res[0]) {
this.height = res[0].height
this.top = this.component ? res[0].top : 0
}
});
if (!this.preloadList || this.preloadList.length === 0) {
this.selectorQuery(instance)
}
// #endif
// #ifdef APP-NVUE
setTimeout(() => {
this._animation(false)
}, 50)
// #endif
},
// #ifdef APP-NVUE // #ifdef APP-NVUE
_animation(type) { _animation(type) {
if (!this.$refs['fui_skeleton'] || this.stop || !this.active) return; if (!this.$refs['fui_skeleton'] || this.stop || !this.active) return;
...@@ -127,11 +143,11 @@ ...@@ -127,11 +143,11 @@
// #endif // #endif
// #ifndef APP-NVUE // #ifndef APP-NVUE
//nvue端暂不支持动态获取节点信息 //nvue端暂不支持动态获取节点信息
async selectorQuery() { async selectorQuery(instance) {
let selector = this.selector || [] let selector = this.selector || []
let nodes = [] let nodes = []
for (let item of selector) { for (let item of selector) {
await this.nodesRef(item).then((res) => { await this.nodesRef(item, instance).then((res) => {
res.map(d => { res.map(d => {
d.type = item.indexOf('round') === -1 ? 'rect' : 'round'; d.type = item.indexOf('round') === -1 ? 'rect' : 'round';
}) })
...@@ -143,17 +159,32 @@ ...@@ -143,17 +159,32 @@
nodes: nodes nodes: nodes
}) })
}, },
async nodesRef(name) { async nodesRef(name, instance) {
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
uni.createSelectorQuery() if (this.component) {
.selectAll(`.${name}`) uni.createSelectorQuery()
.boundingClientRect((res) => { // #ifndef MP-ALIPAY
if (res) { .in(instance)
resolve(res); // #endif
} else { .selectAll(`.${name}`)
reject(res) .boundingClientRect((res) => {
} if (res) {
}).exec(); resolve(res);
} else {
reject(res)
}
}).exec();
} else {
uni.createSelectorQuery()
.selectAll(`.${name}`)
.boundingClientRect((res) => {
if (res) {
resolve(res);
} else {
reject(res)
}
}).exec();
}
}) })
} }
// #endif // #endif
......
...@@ -25,9 +25,11 @@ function bool(str) { ...@@ -25,9 +25,11 @@ function bool(str) {
function touchstart(e, ins) { function touchstart(e, ins) {
var state = e.instance.getState() var state = e.instance.getState()
var touch = e.touches[0] || e.changedTouches[0] var touch = {}
if (isH5 && isPC()) { if (isH5 && isPC()) {
touch = e; touch = e;
} else {
touch = e.touches[0] || e.changedTouches[0]
} }
var dataset = e.instance.getDataset() var dataset = e.instance.getDataset()
state.startX = touch.pageX state.startX = touch.pageX
......
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
:class="[direction==='row'?'fui-steps__flex-row':'fui-steps__flex-col',direction==='row'?'':'fui-steps__node-weex']" :class="[direction==='row'?'fui-steps__flex-row':'fui-steps__flex-col',direction==='row'?'':'fui-steps__node-weex']"
:style="getStyles"> :style="getStyles">
<view class="fui-steps__line" <view class="fui-steps__line"
:class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index<=current && index!==0 && !getActiveColor?'fui-steps__background':'']" :class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index<=current && index!==0 && !getColor(index,current,true)?'fui-steps__background':'']"
:style="{background:index===0?'transparent':(index<=current?getActiveColor:nodeColor)}" :style="{background:index===0?'transparent':(index<=current?getColor(index,current,true):nodeColor)}"
v-if="direction==='row'"></view> v-if="direction==='row'"></view>
<view class="fui-steps__node"> <view class="fui-steps__node" :class="{'fui-steps__node-size':direction!='row' || (direction==='row' && !lineThrough)}">
<text class="fui-steps__node-text" <text class="fui-steps__node-text"
:class="{'fui-steps__background':index<=current && !getActiveColor,'fui-steps__border':index<=current && !getActiveColor}" :class="{'fui-steps__background':index<=current && !getActiveColor,'fui-steps__border':index<=current && !getActiveColor}"
v-if="item.text && !(isMark && index==current)" v-if="item.text && !(isMark && index==current)"
...@@ -36,13 +36,13 @@ ...@@ -36,13 +36,13 @@
:style="{borderRadius:radius || 0}"></image> :style="{borderRadius:radius || 0}"></image>
</view> </view>
<view class="fui-steps__line" <view class="fui-steps__line"
:class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index!==items.length-1 && !getActiveColor && (index<current || (index==current && isWait && direction==='row' && !processColor))?'fui-steps__background':'']" :class="['fui-steps__line-'+direction+(lineBold?'_bold':''),index!==items.length-1 && !getColor(index,current,true,true) && (index<current || (index==current && isWait && direction==='row' && !processColor))?'fui-steps__background':'']"
:style="{background:index===items.length-1?'transparent':((index<current) || (index==current && isWait && direction==='row')?getColor(index,current):nodeColor)}"> :style="{background:index===items.length-1?'transparent':((index<current) || (index==current && isWait && direction==='row')?getColor(index,current,true,true):nodeColor)}">
</view> </view>
</view> </view>
<view class="fui-steps__content" <view class="fui-steps__content"
:class="[direction==='row'?'fui-steps__content-row':'fui-steps__content-col']" :class="[direction==='row'?'fui-steps__content-row':'fui-steps__content-col']"
:style="{paddingBottom:index===items.length-1 || direction==='row'? '0rpx':'64rpx',paddingLeft:direction==='row'?'20rpx':(isNvue?`${height+24}rpx`:'24rpx')}"> :style="{paddingBottom:index===items.length-1 || direction==='row'? '0rpx':(itemGap+'rpx'),paddingLeft:direction==='row'?'20rpx':(isNvue?`${height+24}rpx`:'24rpx')}">
<text class="fui-steps__title" <text class="fui-steps__title"
:class="{'fui-steps__text-row':direction==='row','fui-steps__color':(index<current && !getActiveColor) || (index===current && !processColor && !getActiveColor)}" :class="{'fui-steps__text-row':direction==='row','fui-steps__color':(index<current && !getActiveColor) || (index===current && !processColor && !getActiveColor)}"
v-if="item.title" v-if="item.title"
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
type: String, type: String,
default: '' default: ''
}, },
//V1.9.8+ 设置当前步骤的状态 wait / error / success //V1.9.8+ 设置当前步骤的状态 wait / fail / success
processStatus: { processStatus: {
type: String, type: String,
default: '' default: ''
...@@ -145,6 +145,16 @@ ...@@ -145,6 +145,16 @@
lineBold: { lineBold: {
type: Boolean, type: Boolean,
default: false default: false
},
//V2.1.0+ item项之间间隔,仅纵向有效
itemGap: {
type: [Number, String],
default: 64
},
//V2.1.0+ 当默认节点为小圆点时线条是否贯穿,仅横向有效
lineThrough: {
type: Boolean,
default: false
} }
}, },
computed: { computed: {
...@@ -176,9 +186,9 @@ ...@@ -176,9 +186,9 @@
} }
}, },
methods: { methods: {
getColor(index, current) { getColor(index, current, isLine, isRight) {
let color = this.getActiveColor let color = this.getActiveColor
if (index === current) { if (index === current || (index === current - 1 && !this.isWait && isLine && isRight)) {
color = this.processColor || color color = this.processColor || color
} }
return color; return color;
...@@ -310,6 +320,11 @@ ...@@ -310,6 +320,11 @@
justify-content: center; justify-content: center;
} }
.fui-steps__node-size {
width: 44rpx;
height: 44rpx;
}
.fui-steps__node-text { .fui-steps__node-text {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
......
...@@ -29,7 +29,7 @@ export default { ...@@ -29,7 +29,7 @@ export default {
} }
}, },
mounted() { mounted() {
this.$nextTick(()=>{ this.$nextTick(() => {
this.box = this.getEl(this.$refs['fui_swipea_wrap']) this.box = this.getEl(this.$refs['fui_swipea_wrap'])
this.selector = this.getEl(this.$refs['fui_swipea_content']); this.selector = this.getEl(this.$refs['fui_swipea_content']);
this.rightButton = this.getEl(this.$refs['fui_swipea_buttons']); this.rightButton = this.getEl(this.$refs['fui_swipea_buttons']);
...@@ -90,7 +90,7 @@ export default { ...@@ -90,7 +90,7 @@ export default {
}); });
}, },
touchend(e) { touchend(e) {
if (this.isopen && !this.isclick) { if (this.isopen && !this.isclick && this.clickClose) {
this.open(false) this.open(false)
} }
}, },
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
<!-- #ifdef APP-VUE || MP-WEIXIN || H5 --> <!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
<view class="fui-swipe__action-wrap" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}"> <view class="fui-swipe__action-wrap" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}">
<view class="fui-swipe__action-inner" :show="isShow" :change:show="handler.showChange" :threshold="thresholdVal" <view class="fui-swipe__action-inner" :show="isShow" :change:show="handler.showChange" :threshold="thresholdVal"
:change:threshold="handler.thresholdChange" :disabled="isDisabled" :change:disabled="handler.disabledChange" :change:threshold="handler.thresholdChange" :clickclose="clickClose"
@touchstart="handler.touchstart" @touchmove="handler.touchmove" @touchend="handler.touchend" :change:clickclose="handler.clickCloseChange" :disabled="isDisabled"
@mousedown="handler.mousedown" @mousemove="handler.mousemove" @mouseup="handler.mouseup" :change:disabled="handler.disabledChange" @touchstart="handler.touchstart" @touchmove="handler.touchmove"
@mouseleave="handler.mouseleave"> @touchend="handler.touchend" @mousedown="handler.mousedown" @mousemove="handler.mousemove"
@mouseup="handler.mouseup" @mouseleave="handler.mouseleave">
<view class="fui-swipe__action-left"> <view class="fui-swipe__action-left">
<slot></slot> <slot></slot>
</view> </view>
...@@ -110,6 +111,11 @@ ...@@ -110,6 +111,11 @@
type: Boolean, type: Boolean,
default: true default: true
}, },
//v2.1.0+ 点击当前菜单是否立即关闭菜单
clickClose: {
type: Boolean,
default: true
},
//1.9.9+ //1.9.9+
marginTop: { marginTop: {
type: [Number, String], type: [Number, String],
......
...@@ -150,7 +150,7 @@ function moveDirection(left, ins, ownerInstance) { ...@@ -150,7 +150,7 @@ function moveDirection(left, ins, ownerInstance) {
var position = state.position var position = state.position
var open = state.open || 'none' var open = state.open || 'none'
var rightWidth = state.rightWidth var rightWidth = state.rightWidth
if (state.deltaX === 0) { if (state.deltaX === 0 && state.clickclose) {
openState('none', ins, ownerInstance) openState('none', ins, ownerInstance)
return return
} }
...@@ -228,6 +228,15 @@ function thresholdChange(newVal, oldVal, ownerInstance, ins) { ...@@ -228,6 +228,15 @@ function thresholdChange(newVal, oldVal, ownerInstance, ins) {
st.threshold = newVal || 30 st.threshold = newVal || 30
} }
function clickCloseChange(newVal, oldVal, ownerInstance, ins) {
var st = ins.getState()
if (newVal || newVal === null || newVal === undefined) {
st.clickclose = true
} else {
st.clickclose = false
}
}
module.exports = { module.exports = {
touchstart: touchstart, touchstart: touchstart,
...@@ -239,5 +248,6 @@ module.exports = { ...@@ -239,5 +248,6 @@ module.exports = {
mouseleave: mouseleave, mouseleave: mouseleave,
disabledChange: disabledChange, disabledChange: disabledChange,
thresholdChange: thresholdChange, thresholdChange: thresholdChange,
showChange: showChange showChange: showChange,
clickCloseChange:clickCloseChange
} }
...@@ -103,7 +103,7 @@ export default { ...@@ -103,7 +103,7 @@ export default {
const open = this.open || false const open = this.open || false
const leftWidth = this.leftWidth const leftWidth = this.leftWidth
const rightWidth = this.rightWidth const rightWidth = this.rightWidth
if (this.deltaX === 0) { if (this.deltaX === 0 && this.clickClose) {
this.openState(false) this.openState(false)
return return
} }
......
...@@ -9,7 +9,7 @@ export default { ...@@ -9,7 +9,7 @@ export default {
}, },
watch: { watch: {
show(newVal) { show(newVal) {
this.isShow = this.show this.isShow = this.show ? 'right' : 'none'
}, },
disabled(val) { disabled(val) {
this.isDisabled = this.disabled this.isDisabled = this.disabled
...@@ -27,7 +27,7 @@ export default { ...@@ -27,7 +27,7 @@ export default {
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
this.isShow = this.show this.isShow = this.show ? 'right' : 'none'
this.isDisabled = this.disabled this.isDisabled = this.disabled
this.thresholdVal = Number(this.threshold) this.thresholdVal = Number(this.threshold)
}, 10) }, 10)
...@@ -39,8 +39,9 @@ export default { ...@@ -39,8 +39,9 @@ export default {
this.group && this.group.closeAuto(this) this.group && this.group.closeAuto(this)
}, },
change(e) { change(e) {
const isOpen = e.open === 'right'
this.$emit('change', { this.$emit('change', {
isOpen: e.open === 'right', isOpen: isOpen,
param: this.param param: this.param
}) })
if (this.isShow !== e.open) { if (this.isShow !== e.open) {
......
...@@ -6,14 +6,19 @@ ...@@ -6,14 +6,19 @@
<view class="fui-tabbar__item" v-for="(item,index) in tabs" :key="index" @tap="itemClick(index)"> <view class="fui-tabbar__item" v-for="(item,index) in tabs" :key="index" @tap="itemClick(index)">
<view class="fui-tabbar__icon-wrap" <view class="fui-tabbar__icon-wrap"
:style="{width:(isNvue && item.midButton && item.width?item.width:56)+'rpx',height:(isNvue && item.midButton && item.height?item.height:56)+'rpx'}" :style="{width:(isNvue && item.midButton && item.width?item.width:56)+'rpx',height:(isNvue && item.midButton && item.height?item.height:56)+'rpx'}"
v-if="item.iconPath"> v-if="item.iconPath || item.iconName">
<image class="fui-tabbar__icon" :src="current==index?item.selectedIconPath:item.iconPath" <image class="fui-tabbar__icon" :src="current==index?item.selectedIconPath:item.iconPath"
v-if="!item.midButton"></image> v-if="!item.midButton && item.iconPath"></image>
<!-- #ifdef APP-NVUE --> <!-- #ifdef APP-NVUE -->
<image v-if="item.midButton" class="fui-tabbar__icon" :src="item.iconPath" <image v-if="item.midButton" class="fui-tabbar__icon" :src="item.iconPath"
:style="{width:(item.width || 56)+'rpx',height:(item.height || 56)+'rpx'}"> :style="{width:(item.width || 56)+'rpx',height:(item.height || 56)+'rpx'}">
</image> </image>
<!-- #endif --> <!-- #endif -->
<fui-icon v-if="item.iconName && !item.iconPath && !item.midButton"
:name="current==index?item.selectedIconName:item.iconName" :size="item.iconSize || iconSize"
:unit="item.iconUnit || iconUnit"
:color="current==index?(item.selectedColor || getSelectedColor):(item.color || color)"
:customPrefix="item.customPrefix || ''"></fui-icon>
<text <text
:class="[item.dot?'fui-tabbar__dot':'fui-tabbar__badge',badgeBackground?'':'fui-tabbar__badge-color']" :class="[item.dot?'fui-tabbar__dot':'fui-tabbar__badge',badgeBackground?'':'fui-tabbar__badge-color']"
:style="{background:getBadgeBgColor,color:badgeColor,width:getWidth(item.badge,item.dot)}" :style="{background:getBadgeBgColor,color:badgeColor,width:getWidth(item.badge,item.dot)}"
...@@ -39,9 +44,13 @@ ...@@ -39,9 +44,13 @@
</template> </template>
<script> <script>
// import fuiIcon from "@/components/firstui/fui-icon/fui-icon.vue"
export default { export default {
name: 'fui-tabbar', name: 'fui-tabbar',
emits: ['init', 'click'], emits: ['init', 'click'],
// components: {
// fuiIcon
// },
props: { props: {
tabBar: { tabBar: {
type: Array, type: Array,
...@@ -62,6 +71,16 @@ ...@@ -62,6 +71,16 @@
type: [Number, String], type: [Number, String],
default: 400 default: 400
}, },
//V2.2.0+ 字体图标字体大小 rpx
iconSize: {
type: [Number, String],
default: 56
},
//V2.2.0+ 字体图标字体大小 rpx
iconUnit: {
type: String,
default: 'rpx'
},
//字体颜色 //字体颜色
color: { color: {
type: String, type: String,
...@@ -124,12 +143,10 @@ ...@@ -124,12 +143,10 @@
computed: { computed: {
getSelectedColor() { getSelectedColor() {
let color = this.selectedColor let color = this.selectedColor
// #ifdef APP-NVUE
if (!color || color === true) { if (!color || color === true) {
const app = uni && uni.$fui && uni.$fui.color; const app = uni && uni.$fui && uni.$fui.color;
color = (app && app.primary) || '#465CFF'; color = (app && app.primary) || '#465CFF';
} }
// #endif
return color return color
}, },
getBadgeBgColor() { getBadgeBgColor() {
...@@ -370,12 +387,14 @@ ...@@ -370,12 +387,14 @@
background-color: transparent; background-color: transparent;
} }
/* #ifndef APP-NVUE */ /* #ifdef APP-NVUE || MP-TOUTIAO */
.fui-tabbar__safe-weex { .fui-tabbar__safe-weex {
padding-bottom: 34px; padding-bottom: 34px;
} }
/* #endif */
/* #ifndef APP-NVUE */
.fui-tabbar__selected-color { .fui-tabbar__selected-color {
color: var(--fui-color-primary, #465CFF) !important; color: var(--fui-color-primary, #465CFF) !important;
} }
......
<template> <template>
<view class="fui-table__wrap" :style="{height:height>0 || height!=0?height+'rpx':'auto',width:width+'px'}"> <view class="fui-table__wrap" :style="{height:height>0 || height!=0?height+'rpx':'auto',width:width+'px'}">
<!-- #ifdef MP-BAIDU --> <!-- #ifdef MP-BAIDU -->
<scroll-view :show-scrollbar="false" scroll-x <scroll-view :show-scrollbar="false" :scroll-x="true"
:style="{width:width+'px',height:height>0 || height!=0?height+'rpx':'auto'}" class="fui-table__scroll-view" :style="{width:width+'px',height:height>0 || height!=0?height+'rpx':'auto'}" class="fui-table__scroll-view"
:class="{'fui-table__flex-row':!height || height==0}"> :class="{'fui-table__flex-row':!height || height==0}">
<!-- #endif --> <!-- #endif -->
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
v-for="(item,index) in hData" :key="index" @tap.stop="tableSort(index,false)"> v-for="(item,index) in hData" :key="index" @tap.stop="tableSort(index,false)">
<view class="fui-table__checkbox" <view class="fui-table__checkbox"
:class="{'fui-table__checkbox-color':(!checkboxColor || checkboxColor===true) && chkAll}" :class="{'fui-table__checkbox-color':(!checkboxColor || checkboxColor===true) && chkAll}"
:style="{background:chkAll ?getCheckboxColor:'transparent',borderColor:chkAll ?getCheckboxColor:checkboxBorderColor}" :style="{background:chkAll?getCheckboxColor:'transparent',borderColor:chkAll ?getCheckboxColor:checkboxBorderColor}"
v-if="item.type==='selection'" @tap.stop="selectionAll"> v-if="item.type==='selection'" @tap.stop="selectionAll">
<view class="fui-table__checkmark" <view class="fui-table__checkmark"
:style="{borderBottomColor:checkmarkColor,borderRightColor:checkmarkColor}"></view> :style="{borderBottomColor:checkmarkColor,borderRightColor:checkmarkColor}"></view>
...@@ -77,6 +77,11 @@ ...@@ -77,6 +77,11 @@
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
<view class="fui-table--empty" :style="{width:width+'px'}"
:class="{'fui-table__empty-ab':totalW>width && (height>0 && height!=0)}"
v-if="itemList.length===0 && emptyText!==true && emptyText!==''">
<text class="fui-table__empty-text" :style="{fontSize:emptySize+'rpx',color:emptyColor}">{{emptyText}}</text>
</view>
</view> </view>
</template> </template>
...@@ -216,6 +221,19 @@ ...@@ -216,6 +221,19 @@
checkmarkColor: { checkmarkColor: {
type: String, type: String,
default: '#fff' default: '#fff'
},
//V2.1.0+
emptyText: {
type: String,
default: '暂无数据'
},
emptySize: {
type: [String, Number],
default: 24
},
emptyColor: {
type: String,
default: '#B2B2B2'
} }
}, },
watch: { watch: {
...@@ -327,7 +345,9 @@ ...@@ -327,7 +345,9 @@
this.hData = vals; this.hData = vals;
}, },
handleData(vals) { handleData(vals) {
if (!vals || vals.length === 0) return; if (!vals) {
vals = []
}
let table = JSON.parse(JSON.stringify(vals)) let table = JSON.parse(JSON.stringify(vals))
table.map(item => { table.map(item => {
item.is_disabled = item.is_disabled || false; item.is_disabled = item.is_disabled || false;
...@@ -543,7 +563,7 @@ ...@@ -543,7 +563,7 @@
setSort(prop, sortOrder = 'ascending') { setSort(prop, sortOrder = 'ascending') {
const index = this.hData.findIndex(item => item.prop === prop) const index = this.hData.findIndex(item => item.prop === prop)
if (index !== -1) { if (index !== -1) {
this.tableSort(index,sortOrder) this.tableSort(index, sortOrder)
} }
} }
} }
...@@ -591,6 +611,37 @@ ...@@ -591,6 +611,37 @@
flex-direction: row; flex-direction: row;
} }
.fui-table--empty {
/* #ifndef APP-NVUE */
width: 100%;
display: flex;
box-sizing: border-box;
/* #endif */
flex-direction: row;
justify-content: center;
}
.fui-table__empty-ab {
position: absolute;
left: 0;
top: 96rpx;
/* #ifndef APP-NVUE */
z-index: 2;
/* #endif */
}
.fui-table__empty-text {
/* #ifndef APP-NVUE */
width: 100%;
/* #endif */
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
font-weight: 400;
text-align: center;
padding: 48rpx 0;
}
.fui-table--td { .fui-table--td {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
......
...@@ -194,7 +194,9 @@ ...@@ -194,7 +194,9 @@
}) })
if (this.call) { if (this.call) {
uni.makePhoneCall({ uni.makePhoneCall({
phoneNumber: this.text phoneNumber: this.text,
success: function() {},
fail: function() {}
}) })
} }
} }
...@@ -239,9 +241,10 @@ ...@@ -239,9 +241,10 @@
/* #endif */ /* #endif */
/* #ifdef APP-NVUE */ /* #ifdef APP-NVUE */
.fui-text__nvue{ .fui-text__nvue {
flex: 1; flex: 1;
} }
/* #endif */ /* #endif */
.fui-text__center { .fui-text__center {
......
...@@ -27,9 +27,10 @@ ...@@ -27,9 +27,10 @@
</view> </view>
<slot name="left"></slot> <slot name="left"></slot>
<view class="fui-textarea__flex-1"> <view class="fui-textarea__flex-1">
<textarea ref="fuiTextarea" class="fui-textarea__self" :class="{'fui-text__right':textRight}" <textarea ref="fuiTextarea" class="fui-textarea__self"
:class="{'fui-text__right':textRight,'fui-textarea__disabled-styl':disabled && disabledStyle}"
:style="{height:height,minHeight:minHeight,fontSize:size+'rpx',color:color}" :style="{height:height,minHeight:minHeight,fontSize:size+'rpx',color:color}"
placeholder-class="fui-textarea-placeholder" :name="name" :value="val" :placeholder="placeholder" placeholder-class="fui-textarea-placeholder" :name="name" :value="val" :placeholder="val?'':placeholder"
:placeholderStyle="placeholderStyl" :disabled="disabled" :cursor-spacing="cursorSpacing" :placeholderStyle="placeholderStyl" :disabled="disabled" :cursor-spacing="cursorSpacing"
:maxlength="maxlength" :focus="focused" :auto-height="autoHeight" :fixed="fixed" :maxlength="maxlength" :focus="focused" :auto-height="autoHeight" :fixed="fixed"
:show-confirm-bar="showConfirmBar" :cursor="cursor" :selection-start="selectionStart" :show-confirm-bar="showConfirmBar" :cursor="cursor" :selection-start="selectionStart"
...@@ -142,6 +143,11 @@ ...@@ -142,6 +143,11 @@
type: Boolean, type: Boolean,
default: false default: false
}, },
//V2.1.0+
disabledStyle: {
type: Boolean,
default: false
},
maxlength: { maxlength: {
type: [Number, String], type: [Number, String],
default: 140 default: 140
...@@ -353,19 +359,21 @@ ...@@ -353,19 +359,21 @@
} }
}, },
created() { created() {
// #ifndef VUE3
this.val = this.getVal(this.value)
// #endif
// #ifdef VUE3
if (this.value && !this.modelValue) {
this.val = this.getVal(this.value)
} else {
this.val = this.getVal(this.modelValue)
}
// #endif
this.count = this.getCount(String(this.val).length)
this.fieldPlaceholderStyle() this.fieldPlaceholderStyle()
setTimeout(() => {
// #ifndef VUE3
this.val = this.getVal(this.value)
// #endif
// #ifdef VUE3
if (this.value && !this.modelValue) {
this.val = this.getVal(this.value)
} else {
this.val = this.getVal(this.modelValue)
}
// #endif
this.count = this.getCount(String(this.val).length)
}, 50)
}, },
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
...@@ -630,4 +638,8 @@ ...@@ -630,4 +638,8 @@
.fui-text__right { .fui-text__right {
text-align: right; text-align: right;
} }
.fui-textarea__disabled-styl {
opacity: .6;
}
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论