commit
710d92e9c4
@ -0,0 +1,2 @@
|
||||
/unpackage/
|
||||
/.idea/
|
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (c) 2019 <a href="http://www.jeecg.com">Jeecg Boot</a> All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
@ -0,0 +1,44 @@
|
||||
import { http, getAction, postAction } from '@/common/service/service.js'
|
||||
import configService from '@/common/service/config.service.js';
|
||||
import stationApis from './modules/station.js'
|
||||
|
||||
|
||||
const apiService = {
|
||||
...stationApis,
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
login(params) {
|
||||
return http.post('/sys/mLogin',params)
|
||||
},
|
||||
/**
|
||||
* 手机号码登录
|
||||
*/
|
||||
phoneNoLogin(params) {
|
||||
return http.post('/sys/phoneLogin',params);
|
||||
},
|
||||
/**
|
||||
* 退出
|
||||
*/
|
||||
logout(params) {
|
||||
return http.post('/sys/logout',params);
|
||||
},
|
||||
/**
|
||||
* 获取文件访问路径
|
||||
* @param avatar
|
||||
* @param subStr
|
||||
* @returns {*}
|
||||
*/
|
||||
getFileAccessHttpUrl(avatar,subStr){
|
||||
if(!subStr) subStr = 'http'
|
||||
if(avatar && avatar.startsWith(subStr)){
|
||||
return avatar;
|
||||
}else{
|
||||
return configService.staticDomainURL + "/" + avatar;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default apiService;
|
@ -0,0 +1,28 @@
|
||||
import { http, getAction, postAction } from '@/common/service/service.js'
|
||||
|
||||
const getStationList = params => getAction('/station/powerStationInfo/list', params)
|
||||
const getBigScreenPowerInverterInfo = params => getAction('/station/inverterInfo/matrixViewFocus', params)
|
||||
const getBigScreenPowerInverterInfo2 = params => getAction('/sys/xinFeiA7MatrixView', params)
|
||||
const getBigScreenPowerInverterInfoMatrixView = params => getAction('/station/inverterInfo/matrixView', params)
|
||||
const getBigScreenPowerPinLianSubarrayView= params => getAction('/sys/pinLianSubarrayView', params)
|
||||
const getBigScreenPowerInverterAGC= params => postAction('/station/inverterInfo/inverterAGC', params)
|
||||
const getBigScreenPowerInverterMqttBySn= params => getAction('/station/inverterMqtt/queryBySn', params)
|
||||
export {
|
||||
getStationList,
|
||||
getBigScreenPowerInverterInfo,
|
||||
getBigScreenPowerInverterInfo2,
|
||||
getBigScreenPowerInverterInfoMatrixView,
|
||||
getBigScreenPowerPinLianSubarrayView,
|
||||
getBigScreenPowerInverterAGC,
|
||||
getBigScreenPowerInverterMqttBySn
|
||||
}
|
||||
export default {
|
||||
getStationList,
|
||||
getBigScreenPowerInverterInfo,
|
||||
getBigScreenPowerInverterInfo2,
|
||||
getBigScreenPowerInverterInfoMatrixView,
|
||||
getBigScreenPowerPinLianSubarrayView,
|
||||
getBigScreenPowerInverterAGC,
|
||||
getBigScreenPowerInverterMqttBySn
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
'use strict'
|
||||
|
||||
import isAbsoluteURL from '../helpers/isAbsoluteURL'
|
||||
import combineURLs from '../helpers/combineURLs'
|
||||
|
||||
/**
|
||||
* Creates a new URL by combining the baseURL with the requestedURL,
|
||||
* only when the requestedURL is not already an absolute URL.
|
||||
* If the requestURL is absolute, this function returns the requestedURL untouched.
|
||||
*
|
||||
* @param {string} baseURL The base URL
|
||||
* @param {string} requestedURL Absolute or relative URL to combine
|
||||
* @returns {string} The combined full path
|
||||
*/
|
||||
export default function buildFullPath(baseURL, requestedURL) {
|
||||
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
||||
return combineURLs(baseURL, requestedURL)
|
||||
}
|
||||
return requestedURL
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
'use strict'
|
||||
|
||||
import * as utils from './../utils'
|
||||
|
||||
function encode(val) {
|
||||
return encodeURIComponent(val).
|
||||
replace(/%40/gi, '@').
|
||||
replace(/%3A/gi, ':').
|
||||
replace(/%24/g, '$').
|
||||
replace(/%2C/gi, ',').
|
||||
replace(/%20/g, '+').
|
||||
replace(/%5B/gi, '[').
|
||||
replace(/%5D/gi, ']')
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a URL by appending params to the end
|
||||
*
|
||||
* @param {string} url The base of the url (e.g., http://www.google.com)
|
||||
* @param {object} [params] The params to be appended
|
||||
* @returns {string} The formatted url
|
||||
*/
|
||||
export default function buildURL(url, params) {
|
||||
/*eslint no-param-reassign:0*/
|
||||
if (!params) {
|
||||
return url
|
||||
}
|
||||
|
||||
var serializedParams
|
||||
if (utils.isURLSearchParams(params)) {
|
||||
serializedParams = params.toString()
|
||||
} else {
|
||||
var parts = []
|
||||
|
||||
utils.forEach(params, function serialize(val, key) {
|
||||
if (val === null || typeof val === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
if (utils.isArray(val)) {
|
||||
key = key + '[]'
|
||||
} else {
|
||||
val = [val]
|
||||
}
|
||||
|
||||
utils.forEach(val, function parseValue(v) {
|
||||
if (utils.isDate(v)) {
|
||||
v = v.toISOString()
|
||||
} else if (utils.isObject(v)) {
|
||||
v = JSON.stringify(v)
|
||||
}
|
||||
parts.push(encode(key) + '=' + encode(v))
|
||||
})
|
||||
})
|
||||
|
||||
serializedParams = parts.join('&')
|
||||
}
|
||||
|
||||
if (serializedParams) {
|
||||
var hashmarkIndex = url.indexOf('#')
|
||||
if (hashmarkIndex !== -1) {
|
||||
url = url.slice(0, hashmarkIndex)
|
||||
}
|
||||
|
||||
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Creates a new URL by combining the specified URLs
|
||||
*
|
||||
* @param {string} baseURL The base URL
|
||||
* @param {string} relativeURL The relative URL
|
||||
* @returns {string} The combined URL
|
||||
*/
|
||||
export default function combineURLs(baseURL, relativeURL) {
|
||||
return relativeURL
|
||||
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
||||
: baseURL
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Determines whether the specified URL is absolute
|
||||
*
|
||||
* @param {string} url The URL to test
|
||||
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
||||
*/
|
||||
export default function isAbsoluteURL(url) {
|
||||
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
||||
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
||||
// by any combination of letters, digits, plus, period, or hyphen.
|
||||
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
import Request from './core/Request'
|
||||
export default Request
|
@ -0,0 +1,95 @@
|
||||
'use strict'
|
||||
|
||||
// utils is a library of generic helper functions non-specific to axios
|
||||
|
||||
var toString = Object.prototype.toString
|
||||
|
||||
/**
|
||||
* Determine if a value is an Array
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is an Array, otherwise false
|
||||
*/
|
||||
export function isArray (val) {
|
||||
return toString.call(val) === '[object Array]'
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a value is an Object
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is an Object, otherwise false
|
||||
*/
|
||||
export function isObject (val) {
|
||||
return val !== null && typeof val === 'object'
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a value is a Date
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is a Date, otherwise false
|
||||
*/
|
||||
export function isDate (val) {
|
||||
return toString.call(val) === '[object Date]'
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a value is a URLSearchParams object
|
||||
*
|
||||
* @param {Object} val The value to test
|
||||
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
||||
*/
|
||||
export function isURLSearchParams (val) {
|
||||
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over an Array or an Object invoking a function for each item.
|
||||
*
|
||||
* If `obj` is an Array callback will be called passing
|
||||
* the value, index, and complete array for each item.
|
||||
*
|
||||
* If 'obj' is an Object callback will be called passing
|
||||
* the value, key, and complete object for each property.
|
||||
*
|
||||
* @param {Object|Array} obj The object to iterate
|
||||
* @param {Function} fn The callback to invoke for each item
|
||||
*/
|
||||
export function forEach (obj, fn) {
|
||||
// Don't bother if no value provided
|
||||
if (obj === null || typeof obj === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
// Force an array if not already something iterable
|
||||
if (typeof obj !== 'object') {
|
||||
/*eslint no-param-reassign:0*/
|
||||
obj = [obj]
|
||||
}
|
||||
|
||||
if (isArray(obj)) {
|
||||
// Iterate over array values
|
||||
for (var i = 0, l = obj.length; i < l; i++) {
|
||||
fn.call(null, obj[i], i, obj)
|
||||
}
|
||||
} else {
|
||||
// Iterate over object keys
|
||||
for (var key in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
fn.call(null, obj[key], key, obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为boolean 值
|
||||
* @param val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isBoolean(val) {
|
||||
return typeof val === 'boolean'
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 下了列表混入
|
||||
* @type {{data(): *, methods: {upCallback(*): void, downCallback(): void, loadList(*): void}}}
|
||||
*/
|
||||
const ListMixin = {
|
||||
data() {
|
||||
return {
|
||||
downOption:{
|
||||
auto:false,//是否在初始化完毕之后自动执行下拉回调callback; 默认true
|
||||
},
|
||||
upOption:{
|
||||
page:{
|
||||
num : 0 ,
|
||||
size : 8 ,
|
||||
time : null
|
||||
}
|
||||
},
|
||||
queryParam:{
|
||||
pageNo:1,
|
||||
pageSize:8
|
||||
},
|
||||
list:[],
|
||||
pageNo:1,
|
||||
pageSize:8,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/*下拉刷新的回调 */
|
||||
downCallback(){
|
||||
//加载列表数据
|
||||
this.loadList('down');
|
||||
},
|
||||
/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
|
||||
upCallback(page) {
|
||||
let param = this.queryParam
|
||||
param.pageNo= page.num,
|
||||
param.pageSize= page.size
|
||||
|
||||
if(page.num == 1){
|
||||
this.list = [];
|
||||
}
|
||||
console.log("upCallback==param::",param)
|
||||
this.$http.get(this.url,{params:param}).then(res=>{
|
||||
console.log("upCallback请求返回res",res)
|
||||
if(res.data.success){
|
||||
let rec=res.data.result.records;
|
||||
let hasNext=true;
|
||||
if(!rec || rec.length<this.pageSize){
|
||||
console.log("加载完成!没有更多了")
|
||||
hasNext=false;
|
||||
}
|
||||
console.log("hasNext",hasNext)
|
||||
//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据.
|
||||
this.mescroll.endSuccess(rec.length);
|
||||
|
||||
//设置列表数据
|
||||
this.list=this.list.concat(rec);
|
||||
this.$forceUpdate();
|
||||
}else{
|
||||
this.mescroll.endErr();
|
||||
}
|
||||
}).catch(()=>{
|
||||
//加载失败, 结束
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
},
|
||||
loadList(flag){
|
||||
let param = this.queryParam
|
||||
param.pageNo=this.pageNo,
|
||||
param.pageSize=this.pageSize
|
||||
console.log("请求参数",param)
|
||||
this.$http.get(this.url,{params:param}).then(res=>{
|
||||
if(res.data.success){
|
||||
console.log("请求返回res.data",res.data)
|
||||
let rec=res.data.result.records
|
||||
if(flag=='down'){
|
||||
//下拉刷新成功的回调,隐藏下拉刷新的状态
|
||||
this.mescroll.endSuccess();
|
||||
}
|
||||
//添加新数据
|
||||
this.list=rec;
|
||||
/* if(!rec || rec.length<this.pageSize){
|
||||
console.log("加载完成!")
|
||||
} */
|
||||
}else{
|
||||
console.log("请求返回else",res)
|
||||
this.mescroll.endErr();
|
||||
}
|
||||
}).catch((err)=>{
|
||||
console.log("请求返回err",err)
|
||||
//加载失败, 结束
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ListMixin;
|
@ -0,0 +1,31 @@
|
||||
import modules from './modules'
|
||||
import Vue from 'vue'
|
||||
import Router from '@/plugin/uni-simple-router/index.js'
|
||||
import {ACCESS_TOKEN} from '@/common/util/constants.js'
|
||||
|
||||
Vue.use(Router)
|
||||
//初始化
|
||||
const router = new Router({
|
||||
encodeURI:true,
|
||||
routes: [...modules]//路由表
|
||||
});
|
||||
|
||||
const whiteList = ['/pages/login/login']
|
||||
//全局路由前置守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
let token=uni.getStorageSync(ACCESS_TOKEN);
|
||||
if(token){
|
||||
next()
|
||||
}else{
|
||||
if (whiteList.indexOf(to.path) !== -1) {
|
||||
next()
|
||||
}else{
|
||||
next({ path: '/pages/login/login'})
|
||||
}
|
||||
}
|
||||
})
|
||||
// 全局路由后置守卫
|
||||
router.afterEach((to, from) => {
|
||||
console.log("afterEach")
|
||||
})
|
||||
export default router;
|
@ -0,0 +1,10 @@
|
||||
const files = require.context('.', false, /\.js$/)
|
||||
const modules = []
|
||||
|
||||
files.keys().forEach(key => {
|
||||
if (key === './index.js') return
|
||||
const item = files(key).default
|
||||
modules.push(...item)
|
||||
})
|
||||
|
||||
export default modules
|
@ -0,0 +1,34 @@
|
||||
/* flex */
|
||||
.flex {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.flex-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
.flex-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.flex-row-center {
|
||||
|
||||
align-items: center;
|
||||
}
|
||||
.flex-row-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
.flex-col-center {
|
||||
justify-content: center;
|
||||
}
|
||||
.flex-col-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
.flex-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
let BASE_URL = ''
|
||||
|
||||
|
||||
if (process.env.NODE_ENV == 'development') {
|
||||
BASE_URL = 'https://devops.nhet.cloud/jeecg-boot' // 开发环境
|
||||
} else {
|
||||
BASE_URL = 'https://devops.nhet.cloud/jeecg-boot' // 生产环境
|
||||
}
|
||||
let staticDomainURL = BASE_URL+ '/sys/common/static';
|
||||
|
||||
const configService = {
|
||||
apiUrl: BASE_URL,
|
||||
staticDomainURL: staticDomainURL
|
||||
};
|
||||
|
||||
export default configService
|
@ -0,0 +1,101 @@
|
||||
let cacheMap = new Map()
|
||||
let timeoutDefault = 1200
|
||||
|
||||
function isTimeout (name) {
|
||||
const data = cacheMap.get(name)
|
||||
if (!data) return true
|
||||
if (data.timeout === 0) return false
|
||||
const currentTime = Date.now()
|
||||
const overTime = (currentTime - data.createTime) / 1000
|
||||
if (overTime > data.timeout) {
|
||||
cacheMap.delete(name)
|
||||
if (name.startsWith('_')) {
|
||||
try {
|
||||
uni.removeStorageSync(name)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
class CacheCell {
|
||||
constructor (data, timeout) {
|
||||
this.data = data
|
||||
this.timeout = timeout
|
||||
this.createTime = Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
class MinCache {
|
||||
constructor (timeout) {
|
||||
try {
|
||||
const res = uni.getStorageInfoSync()
|
||||
res.keys.forEach(name => {
|
||||
try {
|
||||
const value = uni.getStorageSync(name)
|
||||
cacheMap.set(name, value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
timeoutDefault = timeout
|
||||
}
|
||||
set (name, data, timeout = timeoutDefault) {
|
||||
const cachecell = new CacheCell(data, timeout)
|
||||
let cache = null
|
||||
if (name.startsWith('_')) {
|
||||
try {
|
||||
uni.setStorageSync(name, cachecell)
|
||||
cache = cacheMap.set(name, cachecell)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
} else {
|
||||
cache = cacheMap.set(name, cachecell)
|
||||
}
|
||||
return cache
|
||||
}
|
||||
get (name) {
|
||||
return isTimeout(name) ? null : cacheMap.get(name).data
|
||||
}
|
||||
delete (name) {
|
||||
let value = false
|
||||
if (name.startsWith('_')) {
|
||||
try {
|
||||
uni.removeStorageSync(name)
|
||||
value = cacheMap.delete(name)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
} else {
|
||||
value = cacheMap.delete(name)
|
||||
}
|
||||
return value
|
||||
}
|
||||
has (name) {
|
||||
return !isTimeout(name)
|
||||
}
|
||||
clear () {
|
||||
let value = false
|
||||
try {
|
||||
uni.clearStorageSync()
|
||||
cacheMap.clear()
|
||||
value = true
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
MinCache.install = function (Vue, {timeout = 1200} = {}) {
|
||||
Vue.prototype.$cache = new MinCache(timeout)
|
||||
}
|
||||
|
||||
export default MinCache
|
@ -0,0 +1,73 @@
|
||||
//APP更新
|
||||
|
||||
export default function appUpdate() {
|
||||
uni.request({
|
||||
url: 'http://app.jeecg.com/update.json', //检查更新的服务器地址
|
||||
data: {
|
||||
appid: plus.runtime.appid,
|
||||
version: plus.runtime.version,
|
||||
imei: plus.device.imei
|
||||
},
|
||||
success: (res) => {
|
||||
plus.runtime.getProperty(plus.runtime.appid, function(wgtinfo) {
|
||||
let client_version = wgtinfo.version
|
||||
var flag_update = client_version.split(".").splice(0, 2).join(".") != res.data.version.split(".").splice(0, 2)
|
||||
.join(".")
|
||||
var flag_hot = (Number(client_version.split(".")[2]) < Number(res.data.version.split(".")[2])) & !flag_update
|
||||
console.log(client_version)
|
||||
console.log(flag_update)
|
||||
console.log(flag_hot)
|
||||
|
||||
if (flag_update) {
|
||||
// 提醒用户更新
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: res.data.note,
|
||||
success: (showResult) => {
|
||||
if (showResult.confirm) {
|
||||
plus.nativeUI.toast("正在准备环境,请稍后!");
|
||||
console.log(res.data.url, )
|
||||
var dtask = plus.downloader.createDownload(res.data.url, {
|
||||
method: 'GET',
|
||||
filename: '_doc/update/'
|
||||
}, function(d, status) {
|
||||
if (status == 200) {
|
||||
var path = d.filename; //下载apk
|
||||
plus.runtime.install(path); // 自动安装apk文件
|
||||
} else {
|
||||
plus.nativeUI.alert('版本更新失败:' + status);
|
||||
}
|
||||
});
|
||||
dtask.start();
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if (flag_hot) {
|
||||
uni.downloadFile({
|
||||
url: res.data.wgtUrl,
|
||||
success: (downloadResult) => {
|
||||
console.log(downloadResult.tempFilePath)
|
||||
if (downloadResult.statusCode === 200) {
|
||||
plus.nativeUI.toast(`正在热更新!${res.data.versionCode}`);
|
||||
plus.runtime.install(downloadResult.tempFilePath, {
|
||||
force: false
|
||||
}, function() {
|
||||
plus.nativeUI.toast("热更新成功");
|
||||
plus.runtime.restart();
|
||||
}, function(e) {
|
||||
console.log(e)
|
||||
plus.nativeUI.toast(`热更新失败:${e.message}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
export const ACCESS_TOKEN = 'Access-Token'
|
||||
export const USER_NAME = 'login_username'
|
||||
export const USER_INFO = 'login_user_info'
|
||||
|
||||
|
||||
const STORAGE_OPTIONS = {
|
||||
namespace: 'pro__', // key prefix
|
||||
name: 'ls', // name variable Vue.[ls] or this.[$ls],
|
||||
storage: 'local', // storage name session, local, memory
|
||||
}
|
||||
|
||||
export default STORAGE_OPTIONS;
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
export const scrollSmoothTo = function (position = 0) {
|
||||
// #ifdef H5
|
||||
if (!window.requestAnimationFrame) {
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
return setTimeout(callback, 17);
|
||||
};
|
||||
}
|
||||
// 当前滚动高度
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
// 滚动step方法
|
||||
var step = function () {
|
||||
// 距离目标滚动距离
|
||||
var distance = position - scrollTop;
|
||||
// 目标滚动位置
|
||||
scrollTop = scrollTop + distance / 5;
|
||||
if (Math.abs(distance) < 1) {
|
||||
window.scrollTo(0, position);
|
||||
} else {
|
||||
window.scrollTo(0, scrollTop);
|
||||
requestAnimationFrame(step);
|
||||
}
|
||||
};
|
||||
step();
|
||||
// #endif
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
import { pinyin } from './constants.js';
|
||||
export default {
|
||||
chineseToPinYin: function (l1) {
|
||||
var l2 = l1.length;
|
||||
var I1 = '';
|
||||
var reg = new RegExp('[a-zA-Z0-9]');
|
||||
for (var i = 0; i < l2; i++) {
|
||||
var val = l1.substr(i, 1);
|
||||
var name = this.arraySearch(val, pinyin);
|
||||
if (reg.test(val)) {
|
||||
I1 += val;
|
||||
} else if (name !== false) {
|
||||
I1 += name;
|
||||
}
|
||||
}
|
||||
I1 = I1.replace(/ /g, '-');
|
||||
while (I1.indexOf('--') > 0) {
|
||||
I1 = I1.replace('--', '-');
|
||||
}
|
||||
return I1;
|
||||
},
|
||||
arraySearch: function (l1, l2) {
|
||||
for (var name in pinyin) {
|
||||
if (pinyin[name].indexOf(l1) !== -1) {
|
||||
return this.ucfirst(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
ucfirst: function (l1) {
|
||||
if (l1.length > 0) {
|
||||
var first = l1.substr(0, 1).toUpperCase();
|
||||
var spare = l1.substr(1, l1.length);
|
||||
return first + spare;
|
||||
}
|
||||
}
|
||||
};
|
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* 常用服务
|
||||
* useful server
|
||||
*/
|
||||
const icon_prefix = "/static/home/128/"
|
||||
|
||||
export const us = {
|
||||
data: [{
|
||||
title: "户用光伏",
|
||||
icon: icon_prefix + "richang.png",
|
||||
description: "户用光伏业务",
|
||||
useCount: 1000,
|
||||
page: 'stationList'
|
||||
}, {
|
||||
title: "储能",
|
||||
icon: icon_prefix + "zhoubao.png",
|
||||
description: "商业园区大型储能柜业务",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "重卡换电",
|
||||
icon: icon_prefix + "kaoqin.png",
|
||||
description: "重卡换电",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "分布式光伏电站",
|
||||
icon: icon_prefix + "richeng.png",
|
||||
description: "分布式光伏电站",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "垃圾热解",
|
||||
icon: icon_prefix + "qingjia1.png",
|
||||
description: "垃圾热解",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "家庭储能",
|
||||
icon: icon_prefix + "gongwen.png",
|
||||
description: "家庭储能",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "通知公告",
|
||||
icon: icon_prefix + "tongzhi.png",
|
||||
description: "查看企业对员工下发的通知公告",
|
||||
useCount: 10000,
|
||||
page: 'annotationList'
|
||||
}, {
|
||||
title: "内部邮件",
|
||||
icon: icon_prefix + "youjian.png",
|
||||
description: "查看内部消息",
|
||||
useCount: 10000,
|
||||
dot: false,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "通讯录",
|
||||
icon: icon_prefix + "tongxun.png",
|
||||
description: "查看部门,组员",
|
||||
useCount: 10000,
|
||||
page: 'levelAddressBook'
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* other server 其他服务
|
||||
*/
|
||||
export const os = {
|
||||
data: [{
|
||||
title: "签约中心",
|
||||
icon: icon_prefix + "xinwen.png",
|
||||
description: "新闻中心",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "会展中心",
|
||||
icon: icon_prefix + "toupiao.png",
|
||||
description: "投票中心",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "任务中心",
|
||||
icon: icon_prefix + "renwu.png",
|
||||
description: "任务中心",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "文档中心",
|
||||
icon: icon_prefix + "wendang.png",
|
||||
description: "文档中心",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "合同",
|
||||
icon: icon_prefix + "hetong.png",
|
||||
description: "合同",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "会议",
|
||||
icon: icon_prefix + "huiyi.png",
|
||||
description: "会议",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}, {
|
||||
title: "客户关系",
|
||||
icon: icon_prefix + "tongzhi.png",
|
||||
description: "客户关系",
|
||||
useCount: 10000,
|
||||
page: 'helloWorld'
|
||||
}]
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
<template>
|
||||
<!-- #ifdef MP-WEIXIN || MP-TOUTIAO -->
|
||||
<canvas type="2d" class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart"
|
||||
@touchmove="touchMove" @touchend="touchEnd" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN || MP-TOUTIAO -->
|
||||
<canvas class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart" @touchmove="touchMove"
|
||||
@touchend="touchEnd" />
|
||||
<!-- #endif -->
|
||||
|
||||
</template>
|
||||
<script>
|
||||
|
||||
/**
|
||||
* echartsForUniApp echart兼容uni-app
|
||||
* @description echart兼容uni-app
|
||||
* @property {Object} option 图表数据
|
||||
* @property {String} canvasId 画布id
|
||||
* @example <echarts ref="echarts" :option="option" canvasId="echarts"></echarts>
|
||||
*/
|
||||
import WxCanvas from './wx-canvas.js';
|
||||
import * as echarts from './echarts.min.js';
|
||||
|
||||
var chartList = {}
|
||||
export default {
|
||||
props: {
|
||||
canvasId: {
|
||||
type: String,
|
||||
default: 'echarts'
|
||||
},
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
option(newValue, oldValue) {
|
||||
if(Object.keys(newValue).length){
|
||||
this.initChart(newValue)
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ctx:null
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// Disable prograssive because drawImage doesn't support DOM as parameter
|
||||
// See https://developers.weixin.qq.com/miniprogram/dev/api/canvas/CanvasContext.drawImage.html
|
||||
echarts.registerPreprocessor(option => {
|
||||
if (option && option.series) {
|
||||
if (option.series.length > 0) {
|
||||
option.series.forEach(series => {
|
||||
series.progressive = 0;
|
||||
});
|
||||
} else if (typeof option.series === 'object') {
|
||||
option.series.progressive = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
getCanvasAttr2d() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query
|
||||
.select('#' + this.canvasId)
|
||||
.fields({
|
||||
node: true,
|
||||
size: true
|
||||
})
|
||||
.exec(res => {
|
||||
const canvasNode = res[0].node
|
||||
this.canvasNode = canvasNode
|
||||
const canvasDpr = uni.getSystemInfoSync().pixelRatio
|
||||
const canvasWidth = res[0].width
|
||||
const canvasHeight = res[0].height
|
||||
this.ctx = canvasNode.getContext('2d')
|
||||
|
||||
const canvas = new WxCanvas(this.ctx, this.canvasId, true, canvasNode)
|
||||
echarts.setCanvasCreator(() => {
|
||||
return canvas
|
||||
})
|
||||
resolve({
|
||||
canvas,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
canvasDpr
|
||||
})
|
||||
})
|
||||
});
|
||||
},
|
||||
getCanvasAttr() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.ctx = uni.createCanvasContext(this.canvasId, this);
|
||||
var canvas = new WxCanvas(this.ctx, this.canvasId, false);
|
||||
echarts.setCanvasCreator(() => {
|
||||
return canvas;
|
||||
});
|
||||
const canvasDpr = 1
|
||||
var query = uni.createSelectorQuery()
|
||||
// #ifndef MP-ALIPAY
|
||||
.in(this)
|
||||
// #endif
|
||||
query.select('#' + this.canvasId).boundingClientRect(res => {
|
||||
const canvasWidth = res.width
|
||||
const canvasHeight = res.height
|
||||
resolve({
|
||||
canvas,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
canvasDpr
|
||||
})
|
||||
}).exec();
|
||||
});
|
||||
},
|
||||
// #ifdef H5
|
||||
//H5绘制图表
|
||||
initChart(option) {
|
||||
this.ctx = uni.createCanvasContext(this.canvasId, this);
|
||||
if (chartList[this.canvasId]) {
|
||||
chartList[this.canvasId].dispose()
|
||||
chartList[this.canvasId] = null
|
||||
}
|
||||
chartList[this.canvasId] = echarts.init(document.getElementById(this.canvasId));
|
||||
chartList[this.canvasId].setOption(option?option:this.option);
|
||||
},
|
||||
//H5生成图片
|
||||
canvasToTempFilePath(opt) {
|
||||
const base64 = chartList[this.canvasId].getDataURL()
|
||||
opt.success && opt.success({tempFilePath:base64})
|
||||
},
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
//绘制图表
|
||||
async initChart(option) {
|
||||
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||
const canvasAttr = await this.getCanvasAttr2d();
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN || MP-TOUTIAO
|
||||
const canvasAttr = await this.getCanvasAttr();
|
||||
// #endif
|
||||
const {
|
||||
canvas,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
canvasDpr
|
||||
} = canvasAttr
|
||||
chartList[this.canvasId] = echarts.init(canvas, null, {
|
||||
width: canvasWidth,
|
||||
height: canvasHeight,
|
||||
devicePixelRatio: canvasDpr // new
|
||||
});
|
||||
canvas.setChart(chartList[this.canvasId]);
|
||||
chartList[this.canvasId].setOption(option?option:this.option);
|
||||
},
|
||||
//生成图片
|
||||
canvasToTempFilePath(opt) {
|
||||
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||
var query = uni.createSelectorQuery()
|
||||
// #ifndef MP-ALIPAY
|
||||
.in(this)
|
||||
// #endif
|
||||
query.select('#' + this.canvasId).fields({ node: true, size: true }).exec(res => {
|
||||
const canvasNode = res[0].node
|
||||
opt.canvas = canvasNode
|
||||
uni.canvasToTempFilePath(opt, this)
|
||||
})
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN || MP-TOUTIAO
|
||||
if (!opt.canvasId) {
|
||||
opt.canvasId = this.canvasId;
|
||||
}
|
||||
this.ctx.draw(true, () => {
|
||||
uni.canvasToTempFilePath(opt, this);
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
// #endif
|
||||
|
||||
touchStart(e) {
|
||||
if (chartList[this.canvasId] && e.touches.length > 0) {
|
||||
var touch = e.touches[0];
|
||||
var handler = chartList[this.canvasId].getZr().handler;
|
||||
handler.dispatch('mousedown', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.dispatch('mousemove', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.processGesture(wrapTouch(e), 'start');
|
||||
}
|
||||
},
|
||||
touchMove(e) {
|
||||
if (chartList[this.canvasId] && e.touches.length > 0) {
|
||||
var touch = e.touches[0];
|
||||
var handler = chartList[this.canvasId].getZr().handler;
|
||||
handler.dispatch('mousemove', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.processGesture(wrapTouch(e), 'change');
|
||||
}
|
||||
},
|
||||
|
||||
touchEnd(e) {
|
||||
if (chartList[this.canvasId]) {
|
||||
const touch = e.changedTouches ? e.changedTouches[0] : {};
|
||||
var handler = chartList[this.canvasId].getZr().handler;
|
||||
handler.dispatch('mouseup', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.dispatch('click', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.processGesture(wrapTouch(e), 'end');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function wrapTouch(event) {
|
||||
for (let i = 0; i < event.touches.length; ++i) {
|
||||
const touch = event.touches[i];
|
||||
touch.offsetX = touch.x;
|
||||
touch.offsetY = touch.y;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.echarts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,105 @@
|
||||
export default class WxCanvas {
|
||||
constructor(ctx, canvasId, isNew, canvasNode) {
|
||||
this.ctx = ctx;
|
||||
this.canvasId = canvasId;
|
||||
this.chart = null;
|
||||
this.isNew = isNew
|
||||
if (isNew) {
|
||||
this.canvasNode = canvasNode;
|
||||
}
|
||||
else {
|
||||
this._initStyle(ctx);
|
||||
}
|
||||
|
||||
// this._initCanvas(zrender, ctx);
|
||||
|
||||
this._initEvent();
|
||||
}
|
||||
|
||||
getContext(contextType) {
|
||||
if (contextType === '2d') {
|
||||
return this.ctx;
|
||||
}
|
||||
}
|
||||
|
||||
// canvasToTempFilePath(opt) {
|
||||
// if (!opt.canvasId) {
|
||||
// opt.canvasId = this.canvasId;
|
||||
// }
|
||||
// return wx.canvasToTempFilePath(opt, this);
|
||||
// }
|
||||
|
||||
setChart(chart) {
|
||||
this.chart = chart;
|
||||
}
|
||||
|
||||
attachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
detachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
_initCanvas(zrender, ctx) {
|
||||
zrender.util.getContext = function () {
|
||||
return ctx;
|
||||
};
|
||||
|
||||
zrender.util.$override('measureText', function (text, font) {
|
||||
ctx.font = font || '12px sans-serif';
|
||||
return ctx.measureText(text);
|
||||
});
|
||||
}
|
||||
|
||||
_initStyle(ctx) {
|
||||
ctx.createRadialGradient = () => {
|
||||
return ctx.createCircularGradient(arguments);
|
||||
};
|
||||
}
|
||||
|
||||
_initEvent() {
|
||||
this.event = {};
|
||||
const eventNames = [{
|
||||
wxName: 'touchStart',
|
||||
ecName: 'mousedown'
|
||||
}, {
|
||||
wxName: 'touchMove',
|
||||
ecName: 'mousemove'
|
||||
}, {
|
||||
wxName: 'touchEnd',
|
||||
ecName: 'mouseup'
|
||||
}, {
|
||||
wxName: 'touchEnd',
|
||||
ecName: 'click'
|
||||
}];
|
||||
|
||||
eventNames.forEach(name => {
|
||||
this.event[name.wxName] = e => {
|
||||
const touch = e.touches[0];
|
||||
this.chart.getZr().handler.dispatch(name.ecName, {
|
||||
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
|
||||
zrY: name.wxName === 'tap' ? touch.clientY : touch.y
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
set width(w) {
|
||||
if (this.canvasNode) this.canvasNode.width = w
|
||||
}
|
||||
set height(h) {
|
||||
if (this.canvasNode) this.canvasNode.height = h
|
||||
}
|
||||
|
||||
get width() {
|
||||
if (this.canvasNode)
|
||||
return this.canvasNode.width
|
||||
return 0
|
||||
}
|
||||
get height() {
|
||||
if (this.canvasNode)
|
||||
return this.canvasNode.height
|
||||
return 0
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<view v-if="tabs && tabs.length" class="app-tabs" :class="{'tabs-fixed': fixed}">
|
||||
<view class="tabs-item">
|
||||
<view class="tab-item" v-for="(tab, i) in tabs" :class="{'active': value===i}" :key="i" @click="tabClick(i)">
|
||||
{{getTabName(tab)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="tabs-line" :style="{left:lineLift}"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
tabs: Array,
|
||||
value: { // 当前显示的下标 (使用v-model语法糖: 1.props需为value; 2.需回调input事件)
|
||||
type: [String, Number],
|
||||
default(){
|
||||
return 0
|
||||
}
|
||||
},
|
||||
fixed: Boolean // 是否悬浮,默认false
|
||||
},
|
||||
computed: {
|
||||
lineLift() {
|
||||
return 100/this.tabs.length*(this.value + 1) - 100/(this.tabs.length*2) + '%'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTabName(tab){
|
||||
return typeof tab === "object" ? tab.name : tab
|
||||
},
|
||||
tabClick(i){
|
||||
if(this.value!=i){
|
||||
this.$emit("input",i);
|
||||
this.$emit("change",i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.app-tabs{
|
||||
position: relative;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
font-size: 24rpx;
|
||||
background-color: #fff;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
.app-tabs .tabs-item{
|
||||
display: flex;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.app-tabs .tabs-item .tab-item{
|
||||
flex: 1;
|
||||
}
|
||||
.app-tabs .tabs-item .active{
|
||||
color: red;
|
||||
}
|
||||
.app-tabs .tabs-line{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 150rpx;
|
||||
height: 4rpx;
|
||||
transform: translateX(-50%);
|
||||
border-radius: 4rpx;
|
||||
transition: left .3s;
|
||||
background: red;
|
||||
}
|
||||
|
||||
/*悬浮*/
|
||||
.app-tabs.tabs-fixed{
|
||||
z-index: 9999;
|
||||
position: fixed;
|
||||
top: var(--window-top);
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,55 @@
|
||||
/* 下拉刷新区域 */
|
||||
.mescroll-downwarp {
|
||||
position: absolute;
|
||||
top: -100%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 下拉刷新--内容区,定位于区域底部 */
|
||||
.mescroll-downwarp .downwarp-content {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
min-height: 60rpx;
|
||||
padding: 20rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 下拉刷新--提示文本 */
|
||||
.mescroll-downwarp .downwarp-tip {
|
||||
display: inline-block;
|
||||
font-size: 28rpx;
|
||||
vertical-align: middle;
|
||||
margin-left: 16rpx;
|
||||
/* color: gray; 已在style设置color,此处删去*/
|
||||
}
|
||||
|
||||
/* 下拉刷新--旋转进度条 */
|
||||
.mescroll-downwarp .downwarp-progress {
|
||||
display: inline-block;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid gray;
|
||||
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* 旋转动画 */
|
||||
.mescroll-downwarp .mescroll-rotate {
|
||||
animation: mescrollDownRotate 0.6s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes mescrollDownRotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
<!--空布局
|
||||
|
||||
可作为独立的组件, 不使用mescroll的页面也能单独引入, 以便APP全局统一管理:
|
||||
import MescrollEmpty from '@/components/mescroll-uni/components/mescroll-empty.vue';
|
||||
<mescroll-empty v-if="isShowEmpty" :option="optEmpty" @emptyclick="emptyClick"></mescroll-empty>
|
||||
|
||||
-->
|
||||
<template>
|
||||
<view class="mescroll-empty" :class="{ 'empty-fixed': option.fixed }" :style="{ 'z-index': option.zIndex, top: option.top }">
|
||||
<image v-if="icon" class="empty-icon" src="/static/nocontent-1.png" mode="widthFix" />
|
||||
<view v-if="tip" class="empty-tip">{{ tip }}</view>
|
||||
<view v-if="option.btnText" class="empty-btn" @click="emptyClick">{{ option.btnText }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 引入全局配置
|
||||
import GlobalOption from './../mescroll-uni-option.js';
|
||||
export default {
|
||||
props: {
|
||||
// empty的配置项: 默认为GlobalOption.up.empty
|
||||
option: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
// 使用computed获取配置,用于支持option的动态配置
|
||||
computed: {
|
||||
// 图标
|
||||
icon() {
|
||||
return this.option.icon == null ? GlobalOption.up.empty.icon : this.option.icon; // 此处不使用短路求值, 用于支持传空串不显示图标
|
||||
},
|
||||
// 文本提示
|
||||
tip() {
|
||||
return this.option.tip == null ? GlobalOption.up.empty.tip : this.option.tip; // 此处不使用短路求值, 用于支持传空串不显示文本提示
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 点击按钮
|
||||
emptyClick() {
|
||||
this.$emit('emptyclick');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 无任何数据的空布局 */
|
||||
.mescroll-empty {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 60% 50rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mescroll-empty.empty-fixed {
|
||||
z-index: 99;
|
||||
position: absolute; /*transform会使fixed失效,最终会降级为absolute */
|
||||
top: 100rpx;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.mescroll-empty .empty-icon {
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
|
||||
.mescroll-empty .empty-tip {
|
||||
font-size: 24rpx;
|
||||
margin-top: -80rpx;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.mescroll-empty .empty-btn {
|
||||
display: inline-block;
|
||||
margin-top: 40rpx;
|
||||
min-width: 200rpx;
|
||||
padding: 18rpx;
|
||||
font-size: 28rpx;
|
||||
border: 1rpx solid #e04b28;
|
||||
border-radius: 60rpx;
|
||||
color: #e04b28;
|
||||
}
|
||||
|
||||
.mescroll-empty .empty-btn:active {
|
||||
opacity: 0.75;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,81 @@
|
||||
<!-- 回到顶部的按钮 -->
|
||||
<template>
|
||||
<image
|
||||
v-if="mOption.src"
|
||||
class="mescroll-totop"
|
||||
:class="[value ? 'mescroll-totop-in' : 'mescroll-totop-out', {'mescroll-safe-bottom': mOption.safearea}]"
|
||||
:style="{'z-index':mOption.zIndex, 'left': left, 'right': right, 'bottom':addUnit(mOption.bottom), 'width':addUnit(mOption.width), 'border-radius':addUnit(mOption.radius)}"
|
||||
:src="mOption.src"
|
||||
mode="widthFix"
|
||||
@click="toTopClick"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// up.toTop的配置项
|
||||
option: Object,
|
||||
// 是否显示
|
||||
value: false
|
||||
},
|
||||
computed: {
|
||||
// 支付宝小程序需写成计算属性,prop定义default仍报错
|
||||
mOption(){
|
||||
return this.option || {}
|
||||
},
|
||||
// 优先显示左边
|
||||
left(){
|
||||
return this.mOption.left ? this.addUnit(this.mOption.left) : 'auto';
|
||||
},
|
||||
// 右边距离 (优先显示左边)
|
||||
right() {
|
||||
return this.mOption.left ? 'auto' : this.addUnit(this.mOption.right);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addUnit(num){
|
||||
if(!num) return 0;
|
||||
if(typeof num === 'number') return num + 'rpx';
|
||||
return num
|
||||
},
|
||||
toTopClick() {
|
||||
this.$emit('input', false); // 使v-model生效
|
||||
this.$emit('click'); // 派发点击事件
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 回到顶部的按钮 */
|
||||
.mescroll-totop {
|
||||
z-index: 9990;
|
||||
position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */
|
||||
right: 20rpx;
|
||||
bottom: 120rpx;
|
||||
width: 72rpx;
|
||||
height: auto;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s; /* 过渡 */
|
||||
margin-bottom: var(--window-bottom); /* css变量 */
|
||||
}
|
||||
|
||||
/* 适配 iPhoneX */
|
||||
.mescroll-safe-bottom{
|
||||
margin-bottom: calc(var(--window-bottom) + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */
|
||||
margin-bottom: calc(var(--window-bottom) + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
/* 显示 -- 淡入 */
|
||||
.mescroll-totop-in {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 隐藏 -- 淡出且不接收事件*/
|
||||
.mescroll-totop-out {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,46 @@
|
||||
/* 上拉加载区域 */
|
||||
.mescroll-upwarp {
|
||||
min-height: 60rpx;
|
||||
padding: 30rpx 0;
|
||||
text-align: center;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/*提示文本 */
|
||||
.mescroll-upwarp .upwarp-tip,
|
||||
.mescroll-upwarp .upwarp-nodata {
|
||||
display: inline-block;
|
||||
font-size: 28rpx;
|
||||
vertical-align: middle;
|
||||
/* color: gray; 已在style设置color,此处删去*/
|
||||
}
|
||||
|
||||
.mescroll-upwarp .upwarp-tip {
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
/*旋转进度条 */
|
||||
.mescroll-upwarp .upwarp-progress {
|
||||
display: inline-block;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid gray;
|
||||
border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* 旋转动画 */
|
||||
.mescroll-upwarp .mescroll-rotate {
|
||||
animation: mescrollUpRotate 0.6s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes mescrollUpRotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
page {
|
||||
-webkit-overflow-scrolling: touch; /* 使iOS滚动流畅 */
|
||||
}
|
||||
|
||||
.mescroll-body {
|
||||
position: relative; /* 下拉刷新区域相对自身定位 */
|
||||
height: auto; /* 不可固定高度,否则overflow: hidden, 可通过设置最小高度使列表不满屏仍可下拉*/
|
||||
overflow: hidden; /* 遮住顶部下拉刷新区域 */
|
||||
box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
// mescroll-body 和 mescroll-uni 通用
|
||||
|
||||
// import MescrollUni from "./mescroll-uni.vue";
|
||||
// import MescrollBody from "./mescroll-body.vue";
|
||||
|
||||
const MescrollMixin = {
|
||||
// components: { // 非H5端无法通过mixin注册组件, 只能在main.js中注册全局组件或具体界面中注册
|
||||
// MescrollUni,
|
||||
// MescrollBody
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
mescroll: null //mescroll实例对象
|
||||
}
|
||||
},
|
||||
// 注册系统自带的下拉刷新 (配置down.native为true时生效, 还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
|
||||
onPullDownRefresh(){
|
||||
this.mescroll && this.mescroll.onPullDownRefresh();
|
||||
},
|
||||
// 注册列表滚动事件,用于判定在顶部可下拉刷新,在指定位置可显示隐藏回到顶部按钮 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
|
||||
onPageScroll(e) {
|
||||
this.mescroll && this.mescroll.onPageScroll(e);
|
||||
},
|
||||
// 注册滚动到底部的事件,用于上拉加载 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
|
||||
onReachBottom() {
|
||||
this.mescroll && this.mescroll.onReachBottom();
|
||||
},
|
||||
methods: {
|
||||
// mescroll组件初始化的回调,可获取到mescroll对象
|
||||
mescrollInit(mescroll) {
|
||||
this.mescroll = mescroll;
|
||||
this.mescrollInitByRef(); // 兼容字节跳动小程序
|
||||
},
|
||||
// 以ref的方式初始化mescroll对象 (兼容字节跳动小程序: http://www.mescroll.com/qa.html?v=20200107#q26)
|
||||
mescrollInitByRef() {
|
||||
if(!this.mescroll || !this.mescroll.resetUpScroll){
|
||||
let mescrollRef = this.$refs.mescrollRef;
|
||||
if(mescrollRef) this.mescroll = mescrollRef.mescroll
|
||||
}
|
||||
},
|
||||
// 下拉刷新的回调
|
||||
downCallback() {
|
||||
// mixin默认resetUpScroll
|
||||
this.mescroll.resetUpScroll()
|
||||
},
|
||||
// 上拉加载的回调
|
||||
upCallback() {
|
||||
// mixin默认延时500自动结束加载
|
||||
setTimeout(()=>{
|
||||
this.mescroll.endErr();
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.mescrollInitByRef(); // 兼容字节跳动小程序, 避免未设置@init或@init此时未能取到ref的情况
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default MescrollMixin;
|
@ -0,0 +1,34 @@
|
||||
// 全局配置
|
||||
// mescroll-body 和 mescroll-uni 通用
|
||||
const GlobalOption = {
|
||||
down: {
|
||||
// 其他down的配置参数也可以写,这里只展示了常用的配置:
|
||||
textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
|
||||
textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
|
||||
textLoading: '加载中 ...', // 加载中的提示文本
|
||||
offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调
|
||||
native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
|
||||
},
|
||||
up: {
|
||||
// 其他up的配置参数也可以写,这里只展示了常用的配置:
|
||||
textLoading: '加载中 ...', // 加载中的提示文本
|
||||
textNoMore: '-- END --', // 没有更多数据的提示文本
|
||||
offset: 80, // 距底部多远时,触发upCallback
|
||||
isBounce: false, // 默认禁止橡皮筋的回弹效果, 必读事项: http://www.mescroll.com/qa.html?v=190725#q25
|
||||
toTop: {
|
||||
// 回到顶部按钮,需配置src才显示
|
||||
src: "http://www.mescroll.com/img/mescroll-totop.png?v=1", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png )
|
||||
offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px
|
||||
right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
|
||||
bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
|
||||
width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
|
||||
},
|
||||
empty: {
|
||||
use: true, // 是否显示空布局
|
||||
icon: "http://www.mescroll.com/img/mescroll-empty.png?v=1", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png )
|
||||
tip: '~ 暂无相关数据 ~' // 提示
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GlobalOption
|
@ -0,0 +1,29 @@
|
||||
page {
|
||||
height: 100%;
|
||||
box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
|
||||
}
|
||||
|
||||
.mescroll-uni-warp{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mescroll-uni {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 200rpx;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
|
||||
}
|
||||
|
||||
/* 定位的方式固定高度 */
|
||||
.mescroll-uni-fixed{
|
||||
z-index: 1;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: auto; /* 使right生效 */
|
||||
height: auto; /* 使bottom生效 */
|
||||
}
|
@ -0,0 +1,862 @@
|
||||
/* mescroll
|
||||
* version 1.2.5
|
||||
* 2020-03-15 wenju
|
||||
* http://www.mescroll.com
|
||||
*/
|
||||
|
||||
export default function MeScroll(options, isScrollBody) {
|
||||
let me = this;
|
||||
me.version = '1.2.5'; // mescroll版本号
|
||||
me.options = options || {}; // 配置
|
||||
me.isScrollBody = isScrollBody || false; // 滚动区域是否为原生页面滚动; 默认为scroll-view
|
||||
|
||||
me.isDownScrolling = false; // 是否在执行下拉刷新的回调
|
||||
me.isUpScrolling = false; // 是否在执行上拉加载的回调
|
||||
let hasDownCallback = me.options.down && me.options.down.callback; // 是否配置了down的callback
|
||||
|
||||
// 初始化下拉刷新
|
||||
me.initDownScroll();
|
||||
// 初始化上拉加载,则初始化
|
||||
me.initUpScroll();
|
||||
|
||||
// 自动加载
|
||||
setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
|
||||
// 自动触发下拉刷新 (只有配置了down的callback才自动触发下拉刷新)
|
||||
if (me.optDown.use && me.optDown.auto && hasDownCallback) {
|
||||
if (me.optDown.autoShowLoading) {
|
||||
me.triggerDownScroll(); // 显示下拉进度,执行下拉回调
|
||||
} else {
|
||||
me.optDown.callback && me.optDown.callback(me); // 不显示下拉进度,直接执行下拉回调
|
||||
}
|
||||
}
|
||||
// 自动触发上拉加载
|
||||
setTimeout(function(){ // 延时确保先执行down的callback,再执行up的callback,因为部分小程序emit是异步,会导致isUpAutoLoad判断有误
|
||||
me.optUp.use && me.optUp.auto && !me.isUpAutoLoad && me.triggerUpScroll();
|
||||
},100)
|
||||
}, 30); // 需让me.optDown.inited和me.optUp.inited先执行
|
||||
}
|
||||
|
||||
/* 配置参数:下拉刷新 */
|
||||
MeScroll.prototype.extendDownScroll = function(optDown) {
|
||||
// 下拉刷新的配置
|
||||
MeScroll.extend(optDown, {
|
||||
use: true, // 是否启用下拉刷新; 默认true
|
||||
auto: true, // 是否在初始化完毕之后自动执行下拉刷新的回调; 默认true
|
||||
native: false, // 是否使用系统自带的下拉刷新; 默认false; 仅mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
|
||||
autoShowLoading: false, // 如果设置auto=true(在初始化完毕之后自动执行下拉刷新的回调),那么是否显示下拉刷新的进度; 默认false
|
||||
isLock: false, // 是否锁定下拉刷新,默认false;
|
||||
offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调
|
||||
startTop: 100, // scroll-view滚动到顶部时,此时的scroll-top不一定为0, 此值用于控制最大的误差
|
||||
fps: 80, // 下拉节流 (值越大每秒刷新频率越高)
|
||||
inOffsetRate: 1, // 在列表顶部,下拉的距离小于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
|
||||
outOffsetRate: 0.2, // 在列表顶部,下拉的距离大于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
|
||||
bottomOffset: 20, // 当手指touchmove位置在距离body底部20px范围内的时候结束上拉刷新,避免Webview嵌套导致touchend事件不执行
|
||||
minAngle: 45, // 向下滑动最少偏移的角度,取值区间 [0,90];默认45度,即向下滑动的角度大于45度则触发下拉;而小于45度,将不触发下拉,避免与左右滑动的轮播等组件冲突;
|
||||
textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
|
||||
textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
|
||||
textLoading: '加载中 ...', // 加载中的提示文本
|
||||
bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorTop)
|
||||
textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
|
||||
inited: null, // 下拉刷新初始化完毕的回调
|
||||
inOffset: null, // 下拉的距离进入offset范围内那一刻的回调
|
||||
outOffset: null, // 下拉的距离大于offset那一刻的回调
|
||||
onMoving: null, // 下拉过程中的回调,滑动过程一直在执行; rate下拉区域当前高度与指定距离的比值(inOffset: rate<1; outOffset: rate>=1); downHight当前下拉区域的高度
|
||||
beforeLoading: null, // 准备触发下拉刷新的回调: 如果return true,将不触发showLoading和callback回调; 常用来完全自定义下拉刷新, 参考案例【淘宝 v6.8.0】
|
||||
showLoading: null, // 显示下拉刷新进度的回调
|
||||
afterLoading: null, // 准备结束下拉的回调. 返回结束下拉的延时执行时间,默认0ms; 常用于结束下拉之前再显示另外一小段动画,才去隐藏下拉刷新的场景, 参考案例【dotJump】
|
||||
endDownScroll: null, // 结束下拉刷新的回调
|
||||
callback: function(mescroll) {
|
||||
// 下拉刷新的回调;默认重置上拉加载列表为第一页
|
||||
mescroll.resetUpScroll();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* 配置参数:上拉加载 */
|
||||
MeScroll.prototype.extendUpScroll = function(optUp) {
|
||||
// 上拉加载的配置
|
||||
MeScroll.extend(optUp, {
|
||||
use: true, // 是否启用上拉加载; 默认true
|
||||
auto: true, // 是否在初始化完毕之后自动执行上拉加载的回调; 默认true
|
||||
isLock: false, // 是否锁定上拉加载,默认false;
|
||||
isBoth: true, // 上拉加载时,如果滑动到列表顶部是否可以同时触发下拉刷新;默认true,两者可同时触发;
|
||||
isBounce: false, // 默认禁止橡皮筋的回弹效果, 必读事项: http://www.mescroll.com/qa.html?v=190725#q25
|
||||
callback: null, // 上拉加载的回调;function(page,mescroll){ }
|
||||
page: {
|
||||
num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
|
||||
size: 10, // 每页数据的数量
|
||||
time: null // 加载第一页数据服务器返回的时间; 防止用户翻页时,后台新增了数据从而导致下一页数据重复;
|
||||
},
|
||||
noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于等于5条才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看
|
||||
offset: 80, // 距底部多远时,触发upCallback
|
||||
textLoading: '加载中 ...', // 加载中的提示文本
|
||||
textNoMore: '-- END --', // 没有更多数据的提示文本
|
||||
bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorBottom)
|
||||
textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
|
||||
inited: null, // 初始化完毕的回调
|
||||
showLoading: null, // 显示加载中的回调
|
||||
showNoMore: null, // 显示无更多数据的回调
|
||||
hideUpScroll: null, // 隐藏上拉加载的回调
|
||||
errDistance: 60, // endErr的时候需往上滑动一段距离,使其往下滑动时再次触发onReachBottom,仅mescroll-body生效
|
||||
toTop: {
|
||||
// 回到顶部按钮,需配置src才显示
|
||||
src: null, // 图片路径,默认null (绝对路径或网络图)
|
||||
offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000
|
||||
duration: 300, // 回到顶部的动画时长,默认300ms (当值为0或300则使用系统自带回到顶部,更流畅; 其他值则通过step模拟,部分机型可能不够流畅,所以非特殊情况不建议修改此项)
|
||||
btnClick: null, // 点击按钮的回调
|
||||
onShow: null, // 是否显示的回调
|
||||
zIndex: 9990, // fixed定位z-index值
|
||||
left: null, // 到左边的距离, 默认null. 此项有值时,right不生效. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
|
||||
right: 20, // 到右边的距离, 默认20 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
|
||||
bottom: 120, // 到底部的距离, 默认120 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
|
||||
safearea: false, // bottom的偏移量是否加上底部安全区的距离, 默认false, 需要适配iPhoneX时使用 (具体的界面如果不配置此项,则取本vue的safearea值)
|
||||
width: 72, // 回到顶部图标的宽度, 默认72 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
|
||||
radius: "50%" // 圆角, 默认"50%" (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
|
||||
},
|
||||
empty: {
|
||||
use: true, // 是否显示空布局
|
||||
icon: null, // 图标路径
|
||||
tip: '~ 暂无相关数据 ~', // 提示
|
||||
btnText: '', // 按钮
|
||||
btnClick: null, // 点击按钮的回调
|
||||
onShow: null, // 是否显示的回调
|
||||
fixed: false, // 是否使用fixed定位,默认false; 配置fixed为true,以下的top和zIndex才生效 (transform会使fixed失效,最终会降级为absolute)
|
||||
top: "100rpx", // fixed定位的top值 (完整的单位值,如 "10%"; "100rpx")
|
||||
zIndex: 99 // fixed定位z-index值
|
||||
},
|
||||
onScroll: false // 是否监听滚动事件
|
||||
})
|
||||
}
|
||||
|
||||
/* 配置参数 */
|
||||
MeScroll.extend = function(userOption, defaultOption) {
|
||||
if (!userOption) return defaultOption;
|
||||
for (let key in defaultOption) {
|
||||
if (userOption[key] == null) {
|
||||
let def = defaultOption[key];
|
||||
if (def != null && typeof def === 'object') {
|
||||
userOption[key] = MeScroll.extend({}, def); // 深度匹配
|
||||
} else {
|
||||
userOption[key] = def;
|
||||
}
|
||||
} else if (typeof userOption[key] === 'object') {
|
||||
MeScroll.extend(userOption[key], defaultOption[key]); // 深度匹配
|
||||
}
|
||||
}
|
||||
return userOption;
|
||||
}
|
||||
|
||||
/* 简单判断是否配置了颜色 (非透明,非白色) */
|
||||
MeScroll.prototype.hasColor = function(color) {
|
||||
if(!color) return false;
|
||||
let c = color.toLowerCase();
|
||||
return c != "#fff" && c != "#ffffff" && c != "transparent" && c != "white"
|
||||
}
|
||||
|
||||
/* -------初始化下拉刷新------- */
|
||||
MeScroll.prototype.initDownScroll = function() {
|
||||
let me = this;
|
||||
// 配置参数
|
||||
me.optDown = me.options.down || {};
|
||||
if(!me.optDown.textColor && me.hasColor(me.optDown.bgColor)) me.optDown.textColor = "#fff"; // 当bgColor有值且textColor未设置,则textColor默认白色
|
||||
me.extendDownScroll(me.optDown);
|
||||
|
||||
// 如果是mescroll-body且配置了native,则禁止自定义的下拉刷新
|
||||
if(me.isScrollBody && me.optDown.native){
|
||||
me.optDown.use = false
|
||||
}else{
|
||||
me.optDown.native = false // 仅mescroll-body支持,mescroll-uni不支持
|
||||
}
|
||||
|
||||
me.downHight = 0; // 下拉区域的高度
|
||||
|
||||
// 在页面中加入下拉布局
|
||||
if (me.optDown.use && me.optDown.inited) {
|
||||
// 初始化完毕的回调
|
||||
setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
|
||||
me.optDown.inited(me);
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/* 列表touchstart事件 */
|
||||
MeScroll.prototype.touchstartEvent = function(e) {
|
||||
if (!this.optDown.use) return;
|
||||
|
||||
this.startPoint = this.getPoint(e); // 记录起点
|
||||
this.startTop = this.getScrollTop(); // 记录此时的滚动条位置
|
||||
this.lastPoint = this.startPoint; // 重置上次move的点
|
||||
this.maxTouchmoveY = this.getBodyHeight() - this.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况)
|
||||
this.inTouchend = false; // 标记不是touchend
|
||||
}
|
||||
|
||||
/* 列表touchmove事件 */
|
||||
MeScroll.prototype.touchmoveEvent = function(e) {
|
||||
// #ifdef H5
|
||||
window.isPreventDefault = false // 标记不需要阻止window事件
|
||||
// #endif
|
||||
|
||||
if (!this.optDown.use) return;
|
||||
if (!this.startPoint) return;
|
||||
let me = this;
|
||||
|
||||
// 节流
|
||||
let t = new Date().getTime();
|
||||
if (me.moveTime && t - me.moveTime < me.moveTimeDiff) { // 小于节流时间,则不处理
|
||||
return;
|
||||
} else {
|
||||
me.moveTime = t
|
||||
if(!me.moveTimeDiff) me.moveTimeDiff = 1000 / me.optDown.fps
|
||||
}
|
||||
|
||||
let scrollTop = me.getScrollTop(); // 当前滚动条的距离
|
||||
let curPoint = me.getPoint(e); // 当前点
|
||||
|
||||
let moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
|
||||
|
||||
// 向下拉 && 在顶部
|
||||
// mescroll-body,直接判定在顶部即可
|
||||
// scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove
|
||||
// scroll-view滚动到顶部时,scrollTop不一定为0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等
|
||||
if (moveY > 0 && (
|
||||
(me.isScrollBody && scrollTop <= 0)
|
||||
||
|
||||
(!me.isScrollBody && (scrollTop <= 0 || (scrollTop <= me.optDown.startTop && scrollTop === me.startTop)) )
|
||||
)) {
|
||||
// 可下拉的条件
|
||||
if (!me.inTouchend && !me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling &&
|
||||
me.optUp.isBoth))) {
|
||||
|
||||
// 下拉的角度是否在配置的范围内
|
||||
let angle = me.getAngle(me.lastPoint, curPoint); // 两点之间的角度,区间 [0,90]
|
||||
if (angle < me.optDown.minAngle) return; // 如果小于配置的角度,则不往下执行下拉刷新
|
||||
|
||||
// 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发
|
||||
if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
|
||||
me.inTouchend = true; // 标记执行touchend
|
||||
me.touchendEvent(); // 提前触发touchend
|
||||
return;
|
||||
}
|
||||
|
||||
// #ifdef H5
|
||||
window.isPreventDefault = true // 标记阻止window事件
|
||||
// #endif
|
||||
me.preventDefault(e); // 阻止默认事件
|
||||
|
||||
let diff = curPoint.y - me.lastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上)
|
||||
|
||||
// 下拉距离 < 指定距离
|
||||
if (me.downHight < me.optDown.offset) {
|
||||
if (me.movetype !== 1) {
|
||||
me.movetype = 1; // 加入标记,保证只执行一次
|
||||
me.optDown.inOffset && me.optDown.inOffset(me); // 进入指定距离范围内那一刻的回调,只执行一次
|
||||
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
|
||||
}
|
||||
me.downHight += diff * me.optDown.inOffsetRate; // 越往下,高度变化越小
|
||||
|
||||
// 指定距离 <= 下拉距离
|
||||
} else {
|
||||
if (me.movetype !== 2) {
|
||||
me.movetype = 2; // 加入标记,保证只执行一次
|
||||
me.optDown.outOffset && me.optDown.outOffset(me); // 下拉超过指定距离那一刻的回调,只执行一次
|
||||
me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
|
||||
}
|
||||
if (diff > 0) { // 向下拉
|
||||
me.downHight += Math.round(diff * me.optDown.outOffsetRate); // 越往下,高度变化越小
|
||||
} else { // 向上收
|
||||
me.downHight += diff; // 向上收回高度,则向上滑多少收多少高度
|
||||
}
|
||||
}
|
||||
|
||||
let rate = me.downHight / me.optDown.offset; // 下拉区域当前高度与指定距离的比值
|
||||
me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight); // 下拉过程中的回调,一直在执行
|
||||
}
|
||||
}
|
||||
|
||||
me.lastPoint = curPoint; // 记录本次移动的点
|
||||
}
|
||||
|
||||
/* 列表touchend事件 */
|
||||
MeScroll.prototype.touchendEvent = function(e) {
|
||||
if (!this.optDown.use) return;
|
||||
// 如果下拉区域高度已改变,则需重置回来
|
||||
if (this.isMoveDown) {
|
||||
if (this.downHight >= this.optDown.offset) {
|
||||
// 符合触发刷新的条件
|
||||
this.triggerDownScroll();
|
||||
} else {
|
||||
// 不符合的话 则重置
|
||||
this.downHight = 0;
|
||||
this.optDown.endDownScroll && this.optDown.endDownScroll(this);
|
||||
}
|
||||
this.movetype = 0;
|
||||
this.isMoveDown = false;
|
||||
} else if (!this.isScrollBody && this.getScrollTop() === this.startTop) { // scroll-view到顶/左/右/底的滑动事件
|
||||
let isScrollUp = this.getPoint(e).y - this.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
|
||||
// 上滑
|
||||
if (isScrollUp) {
|
||||
// 需检查滑动的角度
|
||||
let angle = this.getAngle(this.getPoint(e), this.startPoint); // 两点之间的角度,区间 [0,90]
|
||||
if (angle > 80) {
|
||||
// 检查并触发上拉
|
||||
this.triggerUpScroll(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 根据点击滑动事件获取第一个手指的坐标 */
|
||||
MeScroll.prototype.getPoint = function(e) {
|
||||
if (!e) {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
if (e.touches && e.touches[0]) {
|
||||
return {
|
||||
x: e.touches[0].pageX,
|
||||
y: e.touches[0].pageY
|
||||
}
|
||||
} else if (e.changedTouches && e.changedTouches[0]) {
|
||||
return {
|
||||
x: e.changedTouches[0].pageX,
|
||||
y: e.changedTouches[0].pageY
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
x: e.clientX,
|
||||
y: e.clientY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 计算两点之间的角度: 区间 [0,90]*/
|
||||
MeScroll.prototype.getAngle = function(p1, p2) {
|
||||
let x = Math.abs(p1.x - p2.x);
|
||||
let y = Math.abs(p1.y - p2.y);
|
||||
let z = Math.sqrt(x * x + y * y);
|
||||
let angle = 0;
|
||||
if (z !== 0) {
|
||||
angle = Math.asin(y / z) / Math.PI * 180;
|
||||
}
|
||||
return angle
|
||||
}
|
||||
|
||||
/* 触发下拉刷新 */
|
||||
MeScroll.prototype.triggerDownScroll = function() {
|
||||
if (this.optDown.beforeLoading && this.optDown.beforeLoading(this)) {
|
||||
//return true则处于完全自定义状态
|
||||
} else {
|
||||
this.showDownScroll(); // 下拉刷新中...
|
||||
this.optDown.callback && this.optDown.callback(this); // 执行回调,联网加载数据
|
||||
}
|
||||
}
|
||||
|
||||
/* 显示下拉进度布局 */
|
||||
MeScroll.prototype.showDownScroll = function() {
|
||||
this.isDownScrolling = true; // 标记下拉中
|
||||
if (this.optDown.native) {
|
||||
uni.startPullDownRefresh(); // 系统自带的下拉刷新
|
||||
this.optDown.showLoading && this.optDown.showLoading(this, 0); // 仍触发showLoading,因为上拉加载用到
|
||||
} else{
|
||||
this.downHight = this.optDown.offset; // 更新下拉区域高度
|
||||
this.optDown.showLoading && this.optDown.showLoading(this, this.downHight); // 下拉刷新中...
|
||||
}
|
||||
}
|
||||
|
||||
/* 显示系统自带的下拉刷新时需要处理的业务 */
|
||||
MeScroll.prototype.onPullDownRefresh = function() {
|
||||
this.isDownScrolling = true; // 标记下拉中
|
||||
this.optDown.showLoading && this.optDown.showLoading(this, 0); // 仍触发showLoading,因为上拉加载用到
|
||||
this.optDown.callback && this.optDown.callback(this); // 执行回调,联网加载数据
|
||||
}
|
||||
|
||||
/* 结束下拉刷新 */
|
||||
MeScroll.prototype.endDownScroll = function() {
|
||||
if (this.optDown.native) { // 结束原生下拉刷新
|
||||
this.isDownScrolling = false;
|
||||
this.optDown.endDownScroll && this.optDown.endDownScroll(this);
|
||||
uni.stopPullDownRefresh();
|
||||
return
|
||||
}
|
||||
let me = this;
|
||||
// 结束下拉刷新的方法
|
||||
let endScroll = function() {
|
||||
me.downHight = 0;
|
||||
me.isDownScrolling = false;
|
||||
me.optDown.endDownScroll && me.optDown.endDownScroll(me);
|
||||
!me.isScrollBody && me.setScrollHeight(0) // scroll-view重置滚动区域,使数据不满屏时仍可检查触发翻页
|
||||
}
|
||||
// 结束下拉刷新时的回调
|
||||
let delay = 0;
|
||||
if (me.optDown.afterLoading) delay = me.optDown.afterLoading(me); // 结束下拉刷新的延时,单位ms
|
||||
if (typeof delay === 'number' && delay > 0) {
|
||||
setTimeout(endScroll, delay);
|
||||
} else {
|
||||
endScroll();
|
||||
}
|
||||
}
|
||||
|
||||
/* 锁定下拉刷新:isLock=ture,null锁定;isLock=false解锁 */
|
||||
MeScroll.prototype.lockDownScroll = function(isLock) {
|
||||
if (isLock == null) isLock = true;
|
||||
this.optDown.isLock = isLock;
|
||||
}
|
||||
|
||||
/* 锁定上拉加载:isLock=ture,null锁定;isLock=false解锁 */
|
||||
MeScroll.prototype.lockUpScroll = function(isLock) {
|
||||
if (isLock == null) isLock = true;
|
||||
this.optUp.isLock = isLock;
|
||||
}
|
||||
|
||||
/* -------初始化上拉加载------- */
|
||||
MeScroll.prototype.initUpScroll = function() {
|
||||
let me = this;
|
||||
// 配置参数
|
||||
me.optUp = me.options.up || {use: false}
|
||||
if(!me.optUp.textColor && me.hasColor(me.optUp.bgColor)) me.optUp.textColor = "#fff"; // 当bgColor有值且textColor未设置,则textColor默认白色
|
||||
me.extendUpScroll(me.optUp);
|
||||
|
||||
if (!me.optUp.isBounce) me.setBounce(false); // 不允许bounce时,需禁止window的touchmove事件
|
||||
|
||||
if (me.optUp.use === false) return; // 配置不使用上拉加载时,则不初始化上拉布局
|
||||
me.optUp.hasNext = true; // 如果使用上拉,则默认有下一页
|
||||
me.startNum = me.optUp.page.num + 1; // 记录page开始的页码
|
||||
|
||||
// 初始化完毕的回调
|
||||
if (me.optUp.inited) {
|
||||
setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
|
||||
me.optUp.inited(me);
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/*滚动到底部的事件 (仅mescroll-body生效)*/
|
||||
MeScroll.prototype.onReachBottom = function() {
|
||||
if (this.isScrollBody && !this.isUpScrolling) { // 只能支持下拉刷新的时候同时可以触发上拉加载,否则滚动到底部就需要上滑一点才能触发onReachBottom
|
||||
if (!this.optUp.isLock && this.optUp.hasNext) {
|
||||
this.triggerUpScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*列表滚动事件 (仅mescroll-body生效)*/
|
||||
MeScroll.prototype.onPageScroll = function(e) {
|
||||
if (!this.isScrollBody) return;
|
||||
|
||||
// 更新滚动条的位置 (主要用于判断下拉刷新时,滚动条是否在顶部)
|
||||
this.setScrollTop(e.scrollTop);
|
||||
|
||||
// 顶部按钮的显示隐藏
|
||||
if (e.scrollTop >= this.optUp.toTop.offset) {
|
||||
this.showTopBtn();
|
||||
} else {
|
||||
this.hideTopBtn();
|
||||
}
|
||||
}
|
||||
|
||||
/*列表滚动事件*/
|
||||
MeScroll.prototype.scroll = function(e, onScroll) {
|
||||
// 更新滚动条的位置
|
||||
this.setScrollTop(e.scrollTop);
|
||||
// 更新滚动内容高度
|
||||
this.setScrollHeight(e.scrollHeight);
|
||||
|
||||
// 向上滑还是向下滑动
|
||||
if (this.preScrollY == null) this.preScrollY = 0;
|
||||
this.isScrollUp = e.scrollTop - this.preScrollY > 0;
|
||||
this.preScrollY = e.scrollTop;
|
||||
|
||||
// 上滑 && 检查并触发上拉
|
||||
this.isScrollUp && this.triggerUpScroll(true);
|
||||
|
||||
// 顶部按钮的显示隐藏
|
||||
if (e.scrollTop >= this.optUp.toTop.offset) {
|
||||
this.showTopBtn();
|
||||
} else {
|
||||
this.hideTopBtn();
|
||||
}
|
||||
|
||||
// 滑动监听
|
||||
this.optUp.onScroll && onScroll && onScroll()
|
||||
}
|
||||
|
||||
/* 触发上拉加载 */
|
||||
MeScroll.prototype.triggerUpScroll = function(isCheck) {
|
||||
if (!this.isUpScrolling && this.optUp.use && this.optUp.callback) {
|
||||
// 是否校验在底部; 默认不校验
|
||||
if (isCheck === true) {
|
||||
let canUp = false;
|
||||
// 还有下一页 && 没有锁定 && 不在下拉中
|
||||
if (this.optUp.hasNext && !this.optUp.isLock && !this.isDownScrolling) {
|
||||
if (this.getScrollBottom() <= this.optUp.offset) { // 到底部
|
||||
canUp = true; // 标记可上拉
|
||||
}
|
||||
}
|
||||
if (canUp === false) return;
|
||||
}
|
||||
this.showUpScroll(); // 上拉加载中...
|
||||
this.optUp.page.num++; // 预先加一页,如果失败则减回
|
||||
this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
|
||||
this.num = this.optUp.page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
|
||||
this.size = this.optUp.page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
|
||||
this.time = this.optUp.page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
|
||||
this.optUp.callback(this); // 执行回调,联网加载数据
|
||||
}
|
||||
}
|
||||
|
||||
/* 显示上拉加载中 */
|
||||
MeScroll.prototype.showUpScroll = function() {
|
||||
this.isUpScrolling = true; // 标记上拉加载中
|
||||
this.optUp.showLoading && this.optUp.showLoading(this); // 回调
|
||||
}
|
||||
|
||||
/* 显示上拉无更多数据 */
|
||||
MeScroll.prototype.showNoMore = function() {
|
||||
this.optUp.hasNext = false; // 标记无更多数据
|
||||
this.optUp.showNoMore && this.optUp.showNoMore(this); // 回调
|
||||
}
|
||||
|
||||
/* 隐藏上拉区域**/
|
||||
MeScroll.prototype.hideUpScroll = function() {
|
||||
this.optUp.hideUpScroll && this.optUp.hideUpScroll(this); // 回调
|
||||
}
|
||||
|
||||
/* 结束上拉加载 */
|
||||
MeScroll.prototype.endUpScroll = function(isShowNoMore) {
|
||||
if (isShowNoMore != null) { // isShowNoMore=null,不处理下拉状态,下拉刷新的时候调用
|
||||
if (isShowNoMore) {
|
||||
this.showNoMore(); // isShowNoMore=true,显示无更多数据
|
||||
} else {
|
||||
this.hideUpScroll(); // isShowNoMore=false,隐藏上拉加载
|
||||
}
|
||||
}
|
||||
this.isUpScrolling = false; // 标记结束上拉加载
|
||||
}
|
||||
|
||||
/* 重置上拉加载列表为第一页
|
||||
*isShowLoading 是否显示进度布局;
|
||||
* 1.默认null,不传参,则显示上拉加载的进度布局
|
||||
* 2.传参true, 则显示下拉刷新的进度布局
|
||||
* 3.传参false,则不显示上拉和下拉的进度 (常用于静默更新列表数据)
|
||||
*/
|
||||
MeScroll.prototype.resetUpScroll = function(isShowLoading) {
|
||||
if (this.optUp && this.optUp.use) {
|
||||
let page = this.optUp.page;
|
||||
this.prePageNum = page.num; // 缓存重置前的页码,加载失败可退回
|
||||
this.prePageTime = page.time; // 缓存重置前的时间,加载失败可退回
|
||||
page.num = this.startNum; // 重置为第一页
|
||||
page.time = null; // 重置时间为空
|
||||
if (!this.isDownScrolling && isShowLoading !== false) { // 如果不是下拉刷新触发的resetUpScroll并且不配置列表静默更新,则显示进度;
|
||||
if (isShowLoading == null) {
|
||||
this.removeEmpty(); // 移除空布局
|
||||
this.showUpScroll(); // 不传参,默认显示上拉加载的进度布局
|
||||
} else {
|
||||
this.showDownScroll(); // 传true,显示下拉刷新的进度布局,不清空列表
|
||||
}
|
||||
}
|
||||
this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
|
||||
this.num = page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
|
||||
this.size = page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
|
||||
this.time = page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
|
||||
this.optUp.callback && this.optUp.callback(this); // 执行上拉回调
|
||||
}
|
||||
}
|
||||
|
||||
/* 设置page.num的值 */
|
||||
MeScroll.prototype.setPageNum = function(num) {
|
||||
this.optUp.page.num = num - 1;
|
||||
}
|
||||
|
||||
/* 设置page.size的值 */
|
||||
MeScroll.prototype.setPageSize = function(size) {
|
||||
this.optUp.page.size = size;
|
||||
}
|
||||
|
||||
/* 联网回调成功,结束下拉刷新和上拉加载
|
||||
* dataSize: 当前页的数据量(必传)
|
||||
* totalPage: 总页数(必传)
|
||||
* systime: 服务器时间 (可空)
|
||||
*/
|
||||
MeScroll.prototype.endByPage = function(dataSize, totalPage, systime) {
|
||||
let hasNext;
|
||||
if (this.optUp.use && totalPage != null) hasNext = this.optUp.page.num < totalPage; // 是否还有下一页
|
||||
this.endSuccess(dataSize, hasNext, systime);
|
||||
}
|
||||
|
||||
/* 联网回调成功,结束下拉刷新和上拉加载
|
||||
* dataSize: 当前页的数据量(必传)
|
||||
* totalSize: 列表所有数据总数量(必传)
|
||||
* systime: 服务器时间 (可空)
|
||||
*/
|
||||
MeScroll.prototype.endBySize = function(dataSize, totalSize, systime) {
|
||||
let hasNext;
|
||||
if (this.optUp.use && totalSize != null) {
|
||||
let loadSize = (this.optUp.page.num - 1) * this.optUp.page.size + dataSize; // 已加载的数据总数
|
||||
hasNext = loadSize < totalSize; // 是否还有下一页
|
||||
}
|
||||
this.endSuccess(dataSize, hasNext, systime);
|
||||
}
|
||||
|
||||
/* 联网回调成功,结束下拉刷新和上拉加载
|
||||
* dataSize: 当前页的数据个数(不是所有页的数据总和),用于上拉加载判断是否还有下一页.如果不传,则会判断还有下一页
|
||||
* hasNext: 是否还有下一页,布尔类型;用来解决这个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据dataSize判断,则需翻到第三页才会知道无更多数据,如果传了hasNext,则翻到第二页即可显示无更多数据.
|
||||
* systime: 服务器时间(可空);用来解决这个小问题:当准备翻下一页时,数据库新增了几条记录,此时翻下一页,前面的几条数据会和上一页的重复;这里传入了systime,那么upCallback的page.time就会有值,把page.time传给服务器,让后台过滤新加入的那几条记录
|
||||
*/
|
||||
MeScroll.prototype.endSuccess = function(dataSize, hasNext, systime) {
|
||||
let me = this;
|
||||
// 结束下拉刷新
|
||||
if (me.isDownScrolling) me.endDownScroll();
|
||||
|
||||
// 结束上拉加载
|
||||
if (me.optUp.use) {
|
||||
let isShowNoMore; // 是否已无更多数据
|
||||
if (dataSize != null) {
|
||||
let pageNum = me.optUp.page.num; // 当前页码
|
||||
let pageSize = me.optUp.page.size; // 每页长度
|
||||
// 如果是第一页
|
||||
if (pageNum === 1) {
|
||||
if (systime) me.optUp.page.time = systime; // 设置加载列表数据第一页的时间
|
||||
}
|
||||
if (dataSize < pageSize || hasNext === false) {
|
||||
// 返回的数据不满一页时,则说明已无更多数据
|
||||
me.optUp.hasNext = false;
|
||||
if (dataSize === 0 && pageNum === 1) {
|
||||
// 如果第一页无任何数据且配置了空布局
|
||||
isShowNoMore = false;
|
||||
me.showEmpty();
|
||||
} else {
|
||||
// 总列表数少于配置的数量,则不显示无更多数据
|
||||
let allDataSize = (pageNum - 1) * pageSize + dataSize;
|
||||
if (allDataSize < me.optUp.noMoreSize) {
|
||||
isShowNoMore = false;
|
||||
} else {
|
||||
isShowNoMore = true;
|
||||
}
|
||||
me.removeEmpty(); // 移除空布局
|
||||
}
|
||||
} else {
|
||||
// 还有下一页
|
||||
isShowNoMore = false;
|
||||
me.optUp.hasNext = true;
|
||||
me.removeEmpty(); // 移除空布局
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏上拉
|
||||
me.endUpScroll(isShowNoMore);
|
||||
}
|
||||
}
|
||||
|
||||
/* 回调失败,结束下拉刷新和上拉加载 */
|
||||
MeScroll.prototype.endErr = function(errDistance) {
|
||||
// 结束下拉,回调失败重置回原来的页码和时间
|
||||
if (this.isDownScrolling) {
|
||||
let page = this.optUp.page;
|
||||
if (page && this.prePageNum) {
|
||||
page.num = this.prePageNum;
|
||||
page.time = this.prePageTime;
|
||||
}
|
||||
this.endDownScroll();
|
||||
}
|
||||
// 结束上拉,回调失败重置回原来的页码
|
||||
if (this.isUpScrolling) {
|
||||
this.optUp.page.num--;
|
||||
this.endUpScroll(false);
|
||||
// 如果是mescroll-body,则需往回滚一定距离
|
||||
if(this.isScrollBody && errDistance !== 0){ // 不处理0
|
||||
if(!errDistance) errDistance = this.optUp.errDistance; // 不传,则取默认
|
||||
this.scrollTo(this.getScrollTop() - errDistance, 0) // 往上回滚的距离
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 显示空布局 */
|
||||
MeScroll.prototype.showEmpty = function() {
|
||||
this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(true)
|
||||
}
|
||||
|
||||
/* 移除空布局 */
|
||||
MeScroll.prototype.removeEmpty = function() {
|
||||
this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(false)
|
||||
}
|
||||
|
||||
/* 显示回到顶部的按钮 */
|
||||
MeScroll.prototype.showTopBtn = function() {
|
||||
if (!this.topBtnShow) {
|
||||
this.topBtnShow = true;
|
||||
this.optUp.toTop.onShow && this.optUp.toTop.onShow(true);
|
||||
}
|
||||
}
|
||||
|
||||
/* 隐藏回到顶部的按钮 */
|
||||
MeScroll.prototype.hideTopBtn = function() {
|
||||
if (this.topBtnShow) {
|
||||
this.topBtnShow = false;
|
||||
this.optUp.toTop.onShow && this.optUp.toTop.onShow(false);
|
||||
}
|
||||
}
|
||||
|
||||
/* 获取滚动条的位置 */
|
||||
MeScroll.prototype.getScrollTop = function() {
|
||||
return this.scrollTop || 0
|
||||
}
|
||||
|
||||
/* 记录滚动条的位置 */
|
||||
MeScroll.prototype.setScrollTop = function(y) {
|
||||
this.scrollTop = y;
|
||||
}
|
||||
|
||||
/* 滚动到指定位置 */
|
||||
MeScroll.prototype.scrollTo = function(y, t) {
|
||||
this.myScrollTo && this.myScrollTo(y, t) // scrollview需自定义回到顶部方法
|
||||
}
|
||||
|
||||
/* 自定义scrollTo */
|
||||
MeScroll.prototype.resetScrollTo = function(myScrollTo) {
|
||||
this.myScrollTo = myScrollTo
|
||||
}
|
||||
|
||||
/* 滚动条到底部的距离 */
|
||||
MeScroll.prototype.getScrollBottom = function() {
|
||||
return this.getScrollHeight() - this.getClientHeight() - this.getScrollTop()
|
||||
}
|
||||
|
||||
/* 计步器
|
||||
star: 开始值
|
||||
end: 结束值
|
||||
callback(step,timer): 回调step值,计步器timer,可自行通过window.clearInterval(timer)结束计步器;
|
||||
t: 计步时长,传0则直接回调end值;不传则默认300ms
|
||||
rate: 周期;不传则默认30ms计步一次
|
||||
* */
|
||||
MeScroll.prototype.getStep = function(star, end, callback, t, rate) {
|
||||
let diff = end - star; // 差值
|
||||
if (t === 0 || diff === 0) {
|
||||
callback && callback(end);
|
||||
return;
|
||||
}
|
||||
t = t || 300; // 时长 300ms
|
||||
rate = rate || 30; // 周期 30ms
|
||||
let count = t / rate; // 次数
|
||||
let step = diff / count; // 步长
|
||||
let i = 0; // 计数
|
||||
let timer = setInterval(function() {
|
||||
if (i < count - 1) {
|
||||
star += step;
|
||||
callback && callback(star, timer);
|
||||
i++;
|
||||
} else {
|
||||
callback && callback(end, timer); // 最后一次直接设置end,避免计算误差
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, rate);
|
||||
}
|
||||
|
||||
/* 滚动容器的高度 */
|
||||
MeScroll.prototype.getClientHeight = function(isReal) {
|
||||
let h = this.clientHeight || 0
|
||||
if (h === 0 && isReal !== true) { // 未获取到容器的高度,可临时取body的高度 (可能会有误差)
|
||||
h = this.getBodyHeight()
|
||||
}
|
||||
return h
|
||||
}
|
||||
MeScroll.prototype.setClientHeight = function(h) {
|
||||
this.clientHeight = h;
|
||||
}
|
||||
|
||||
/* 滚动内容的高度 */
|
||||
MeScroll.prototype.getScrollHeight = function() {
|
||||
return this.scrollHeight || 0;
|
||||
}
|
||||
MeScroll.prototype.setScrollHeight = function(h) {
|
||||
this.scrollHeight = h;
|
||||
}
|
||||
|
||||
/* body的高度 */
|
||||
MeScroll.prototype.getBodyHeight = function() {
|
||||
return this.bodyHeight || 0;
|
||||
}
|
||||
MeScroll.prototype.setBodyHeight = function(h) {
|
||||
this.bodyHeight = h;
|
||||
}
|
||||
|
||||
/* 阻止浏览器默认滚动事件 */
|
||||
MeScroll.prototype.preventDefault = function(e) {
|
||||
// 小程序不支持e.preventDefault
|
||||
// app的bounce只能通过配置pages.json的style.app-plus.bounce为"none"来禁止
|
||||
// cancelable:是否可以被禁用; defaultPrevented:是否已经被禁用
|
||||
if (e && e.cancelable && !e.defaultPrevented) e.preventDefault()
|
||||
}
|
||||
|
||||
/* 是否允许下拉回弹(橡皮筋效果); true或null为允许; false禁止bounce */
|
||||
MeScroll.prototype.setBounce = function(isBounce) {
|
||||
// #ifdef H5
|
||||
if (isBounce === false) {
|
||||
this.optUp.isBounce = false; // 禁止
|
||||
// 标记当前页使用了mescroll (需延时,确保page已切换)
|
||||
setTimeout(function() {
|
||||
let uniPageDom = document.getElementsByTagName('uni-page')[0];
|
||||
uniPageDom && uniPageDom.setAttribute('use_mescroll', true)
|
||||
}, 30);
|
||||
// 避免重复添加事件
|
||||
if (window.isSetBounce) return;
|
||||
window.isSetBounce = true;
|
||||
// 需禁止window的touchmove事件才能有效的阻止bounce
|
||||
window.bounceTouchmove = function(e) {
|
||||
if(!window.isPreventDefault) return; // 根据标记判断是否阻止
|
||||
|
||||
let el = e.target;
|
||||
// 当前touch的元素及父元素是否要拦截touchmove事件
|
||||
let isPrevent = true;
|
||||
while (el !== document.body && el !== document) {
|
||||
if (el.tagName === 'UNI-PAGE') { // 只扫描当前页
|
||||
if (!el.getAttribute('use_mescroll')) {
|
||||
isPrevent = false; // 如果当前页没有使用mescroll,则不阻止
|
||||
}
|
||||
break;
|
||||
}
|
||||
let cls = el.classList;
|
||||
if (cls) {
|
||||
if (cls.contains('mescroll-touch')) { // 采用scroll-view 此处不能过滤mescroll-uni,否则下拉仍然有回弹
|
||||
isPrevent = false; // mescroll-touch无需拦截touchmove事件
|
||||
break;
|
||||
} else if (cls.contains('mescroll-touch-x') || cls.contains('mescroll-touch-y')) {
|
||||
// 如果配置了水平或者垂直滑动
|
||||
let curX = e.touches ? e.touches[0].pageX : e.clientX; // 当前第一个手指距离列表顶部的距离x
|
||||
let curY = e.touches ? e.touches[0].pageY : e.clientY; // 当前第一个手指距离列表顶部的距离y
|
||||
if (!this.preWinX) this.preWinX = curX; // 设置上次移动的距离x
|
||||
if (!this.preWinY) this.preWinY = curY; // 设置上次移动的距离y
|
||||
// 计算两点之间的角度
|
||||
let x = Math.abs(this.preWinX - curX);
|
||||
let y = Math.abs(this.preWinY - curY);
|
||||
let z = Math.sqrt(x * x + y * y);
|
||||
this.preWinX = curX; // 记录本次curX的值
|
||||
this.preWinY = curY; // 记录本次curY的值
|
||||
if (z !== 0) {
|
||||
let angle = Math.asin(y / z) / Math.PI * 180; // 角度区间 [0,90]
|
||||
if ((angle <= 45 && cls.contains('mescroll-touch-x')) || (angle > 45 && cls.contains('mescroll-touch-y'))) {
|
||||
isPrevent = false; // 水平滑动或者垂直滑动,不拦截touchmove事件
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
el = el.parentNode; // 继续检查其父元素
|
||||
}
|
||||
// 拦截touchmove事件:是否可以被禁用&&是否已经被禁用 (这里不使用me.preventDefault(e)的方法,因为某些情况下会报找不到方法的异常)
|
||||
if (isPrevent && e.cancelable && !e.defaultPrevented && typeof e.preventDefault === "function") e.preventDefault();
|
||||
}
|
||||
window.addEventListener('touchmove', window.bounceTouchmove, {
|
||||
passive: false
|
||||
});
|
||||
} else {
|
||||
this.optUp.isBounce = true; // 允许
|
||||
if (window.bounceTouchmove) {
|
||||
window.removeEventListener('touchmove', window.bounceTouchmove);
|
||||
window.bounceTouchmove = null;
|
||||
window.isSetBounce = false;
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例)
|
||||
*/
|
||||
const MescrollMoreItemMixin = {
|
||||
props:{
|
||||
i: Number, // 每个tab页的专属下标
|
||||
index: { // 当前tab的下标
|
||||
type: Number,
|
||||
default(){
|
||||
return 0
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
downOption:{
|
||||
auto:false // 不自动加载
|
||||
},
|
||||
upOption:{
|
||||
auto:false // 不自动加载
|
||||
},
|
||||
isInit: false // 当前tab是否已初始化
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
// 监听下标的变化
|
||||
index(val){
|
||||
if (this.i === val && !this.isInit) {
|
||||
this.isInit = true; // 标记为true
|
||||
this.mescroll && this.mescroll.triggerDownScroll();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// mescroll组件初始化的回调,可获取到mescroll对象
|
||||
mescrollInit(mescroll) {
|
||||
this.mescroll = mescroll;
|
||||
this.mescrollInitByRef && this.mescrollInitByRef(); // 兼容字节跳动小程序 (mescroll-mixins.js)
|
||||
// 自动加载当前tab的数据
|
||||
if(this.i === this.index){
|
||||
this.isInit = true; // 标记为true
|
||||
this.mescroll.triggerDownScroll();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default MescrollMoreItemMixin;
|
@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<view class="cu-form-group" style="z-index:10">
|
||||
<view class="flex align-center">
|
||||
<view class="title">
|
||||
<text class="text-red" v-if="required">*</text>
|
||||
<text space="ensp">{{label}}</text>
|
||||
</view>
|
||||
<picker
|
||||
@change="pickerChange"
|
||||
:range="selections"
|
||||
:value="valueIndex"
|
||||
:disabled="disabled">
|
||||
<input
|
||||
:placeholder="placeholder"
|
||||
name="input"
|
||||
v-model="selected"
|
||||
:disabled="true"
|
||||
></input>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "AppSecelt",
|
||||
behaviors: ['uni://form-field'],
|
||||
props:{
|
||||
display:{
|
||||
type:String,
|
||||
default:'inline-block',
|
||||
required:false
|
||||
},
|
||||
placeholder:{
|
||||
type:String,
|
||||
default:'请选择',
|
||||
required:false
|
||||
},
|
||||
label:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
value:{
|
||||
type:String,
|
||||
required:false
|
||||
},
|
||||
border:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
dict:{
|
||||
type:Array,
|
||||
default:()=>[],
|
||||
required:true
|
||||
},
|
||||
name:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
required:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
space:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
show:false,
|
||||
selected:'',
|
||||
valueIndex:0,
|
||||
selections:[]
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value:{
|
||||
immediate:true,
|
||||
handler(val){
|
||||
if(!val){
|
||||
this.selected = ''
|
||||
this.valueIndex = 0
|
||||
}else{
|
||||
this.dict.map((item,index)=>{
|
||||
if(item.value == val){
|
||||
this.selected = item.text;
|
||||
this.valueIndex = index
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
dict(){
|
||||
this.initSelections();
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.initSelections();
|
||||
},
|
||||
methods:{
|
||||
initSelections(){
|
||||
let arr = [];
|
||||
this.dict.map(item=>{
|
||||
arr.push(item.text)
|
||||
});
|
||||
this.selections = arr
|
||||
},
|
||||
pickerChange(e){
|
||||
console.log("appselect::pickerChange",e.detail.value)
|
||||
let backString = '';
|
||||
let obj=this.dict[e.detail.value];
|
||||
this.selected=obj.text;
|
||||
backString=obj.value;
|
||||
console.log("backString",backString)
|
||||
console.log("this.selected",this.selected)
|
||||
|
||||
this.$emit('input',backString);
|
||||
// #ifndef MP-WEIXIN
|
||||
this.$emit('change',backString);
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event:'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.cu-form-group uni-picker::after {
|
||||
font-family: cuIcon;
|
||||
display: block;
|
||||
content: "\e6a3";
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 42px;
|
||||
width: 25px;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: -8px;
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<view class="cu-form-group" @click="timechange">
|
||||
<view class="title"><text class="text-red" v-if="required">*</text>{{label}}</view>
|
||||
<input
|
||||
:placeholder="placeholder"
|
||||
name="input"
|
||||
v-model="selected"
|
||||
disabled="true"
|
||||
></input>
|
||||
<w-picker
|
||||
:visible.sync="visible"
|
||||
ref="picker"
|
||||
mode="date"
|
||||
startYear="2020"
|
||||
endYear="2100"
|
||||
:value="value"
|
||||
:fields="fields"
|
||||
@confirm="onConfirm($event,'date')"
|
||||
></w-picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AppSecelt",
|
||||
props:{
|
||||
placeholder:{
|
||||
type:String,
|
||||
default:'请选择',
|
||||
required:false
|
||||
},
|
||||
label:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
fields:{
|
||||
type:String,
|
||||
default:'second',
|
||||
required:false
|
||||
},
|
||||
value:{
|
||||
type:String,
|
||||
required:false
|
||||
} ,
|
||||
required:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
visible:false,
|
||||
selected:''
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value:{
|
||||
immediate:true,
|
||||
handler(val){
|
||||
if(!val){
|
||||
this.selected = ''
|
||||
}else{
|
||||
this.selected = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
methods:{
|
||||
timechange(){
|
||||
this.$refs.picker.show()
|
||||
},
|
||||
onConfirm(e){
|
||||
console.log("confirm",e)
|
||||
let backString = e.value;
|
||||
this.selected=e.value;
|
||||
this.$emit('input',backString);
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'input'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="cu-custom" :style="[{height:CustomBar + 'px',zIndex:zIndex}]">
|
||||
<view class="cu-bar fixed" :style="style" :class="[bgImage!=''?'none-bg text-white bg-img':'',bgColor]">
|
||||
<view class="action" @tap="BackPage" v-if="isBack">
|
||||
<text class="cuIcon-back"></text>
|
||||
<slot name="backText"></slot>
|
||||
</view>
|
||||
<view class="content" :style="[{top:StatusBar + 'px'}]">
|
||||
<slot name="content"></slot>
|
||||
</view>
|
||||
<view class="action">
|
||||
<slot name="right"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
StatusBar: this.StatusBar,
|
||||
CustomBar: this.CustomBar
|
||||
};
|
||||
},
|
||||
name: 'cu-custom',
|
||||
computed: {
|
||||
style() {
|
||||
var StatusBar= this.StatusBar;
|
||||
var CustomBar= this.CustomBar;
|
||||
var bgImage = this.bgImage;
|
||||
var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
|
||||
if (this.bgImage) {
|
||||
style = `${style}background-image:url(${bgImage});`;
|
||||
}
|
||||
return style
|
||||
}
|
||||
},
|
||||
props: {
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isBack: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
bgImage: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
zIndex:{
|
||||
type: String,
|
||||
default: '10'
|
||||
},
|
||||
backRouterName:{
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
BackPage() {
|
||||
if(!this.backRouterName){
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}else{
|
||||
this.$Router.replace({name:this.backRouterName})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<view>
|
||||
<scroll-view :scroll-y="modalName==null" class="page" :class="modalName!=null?'show':''">
|
||||
<cu-custom bgColor="bg-gradual-pink" :isBack="true">
|
||||
<block slot="backText">{{back}}</block>
|
||||
<block slot="content">{{title}}</block>
|
||||
</cu-custom>
|
||||
<slot></slot>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MyPage',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '标题'
|
||||
},
|
||||
back: {
|
||||
type: String,
|
||||
default: '返回'
|
||||
},
|
||||
modalName: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<view class="cu-form-group">
|
||||
<view class="title">{{label}}</view>
|
||||
<picker @change="PickerChange" :value="index" :range-key="rangeKey" :range="dictOptions">
|
||||
<view class="picker">
|
||||
{{index>-1?dictOptions[index][rangeKey]:'请选择'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MySelect',
|
||||
props: {
|
||||
dictCode: String,
|
||||
value: String,
|
||||
label:String,
|
||||
rangeKey:{type:String,default:'label'},
|
||||
valueKey:{type:String,default:'value'},
|
||||
searchUrl:String,
|
||||
|
||||
},
|
||||
watch: {
|
||||
dictCode: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initDictData()
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
index: -1,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initDictData() {
|
||||
//根据字典Code, 初始化字典数组
|
||||
if (this.searchUrl){
|
||||
this.$http.get(this.searchUrl,{"code":this.dictCode}).then(res=>{
|
||||
if(res.data.success){
|
||||
this.dictOptions = res;
|
||||
this.getIndex()
|
||||
}
|
||||
})
|
||||
}else{
|
||||
let code = this.dictCode;
|
||||
this.$http.get(`/sys/dict/getDictItems/${code}`).then(res=>{
|
||||
if(res.data.success){
|
||||
this.dictOptions = res.data.result;
|
||||
this.getIndex()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
PickerChange(e) {
|
||||
this.index=e.detail.value
|
||||
if(this.index==-1){
|
||||
this.index=0
|
||||
this.$emit('input',this.dictOptions[0][this.valueKey])
|
||||
}else{
|
||||
this.$emit('input', this.dictOptions[this.index][this.valueKey]);
|
||||
}
|
||||
},
|
||||
getIndex() {
|
||||
for (var i = 0; i < this.dictOptions.length; i++) {
|
||||
if (this.dictOptions[i].value == this.value) {
|
||||
this.index = i
|
||||
return
|
||||
}
|
||||
}
|
||||
this.index=-1
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<view class="uni-calendar-item__weeks-box" :class="{
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
|
||||
'uni-calendar-item--before-checked':weeks.beforeMultiple,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--after-checked':weeks.afterMultiple,
|
||||
}"
|
||||
@click="choiceDate(weeks)">
|
||||
<view class="uni-calendar-item__weeks-box-item">
|
||||
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
|
||||
<text class="uni-calendar-item__weeks-box-text" :class="{
|
||||
'uni-calendar-item--isDay-text': weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--before-checked':weeks.beforeMultiple,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--after-checked':weeks.afterMultiple,
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
}">{{weeks.date}}</text>
|
||||
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
|
||||
'uni-calendar-item--isDay-text':weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--before-checked':weeks.beforeMultiple,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--after-checked':weeks.afterMultiple,
|
||||
}">今天</text>
|
||||
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
|
||||
'uni-calendar-item--isDay-text':weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--before-checked':weeks.beforeMultiple,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--after-checked':weeks.afterMultiple,
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
|
||||
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
|
||||
'uni-calendar-item--extra':weeks.extraInfo.info,
|
||||
'uni-calendar-item--isDay-text':weeks.isDay,
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
|
||||
'uni-calendar-item--before-checked':weeks.beforeMultiple,
|
||||
'uni-calendar-item--multiple': weeks.multiple,
|
||||
'uni-calendar-item--after-checked':weeks.afterMultiple,
|
||||
'uni-calendar-item--disable':weeks.disable,
|
||||
}">{{weeks.extraInfo.info}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
weeks: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
selected: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
},
|
||||
lunar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
choiceDate(weeks) {
|
||||
this.$emit('change', weeks)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uni-calendar-item__weeks-box {
|
||||
flex: 1;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.uni-calendar-item__weeks-box-text {
|
||||
font-size: $uni-font-size-base;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
|
||||
.uni-calendar-item__weeks-lunar-text {
|
||||
font-size: $uni-font-size-sm;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
|
||||
.uni-calendar-item__weeks-box-item {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
/* .uni-calendar-item__weeks-box-circle {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 8px;
|
||||
background-color: $uni-color-error;
|
||||
} */
|
||||
.uni-calendar-item__weeks-box-circle{
|
||||
position: absolute;
|
||||
top: 37px;
|
||||
right: 23px;
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
border-radius: 3px;
|
||||
//background-color: $uni-color-primary;
|
||||
background-color: $uni-color-error;
|
||||
}
|
||||
|
||||
.uni-calendar-item--disable {
|
||||
background-color: rgba(249, 249, 249, $uni-opacity-disabled);
|
||||
color: $uni-text-color-disable;
|
||||
}
|
||||
|
||||
.uni-calendar-item--isDay-text {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
|
||||
.uni-calendar-item--isDay {
|
||||
background-color: $uni-color-primary;
|
||||
opacity: 0.8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.uni-calendar-item--extra {
|
||||
color: $uni-color-error;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.uni-calendar-item--checked {
|
||||
background-color: $uni-color-primary;
|
||||
color: #fff;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.uni-calendar-item--multiple {
|
||||
background-color: $uni-color-primary;
|
||||
color: #fff;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.uni-calendar-item--before-checked {
|
||||
background-color: #ff5a5f;
|
||||
color: #fff;
|
||||
}
|
||||
.uni-calendar-item--after-checked {
|
||||
background-color: #ff5a5f;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<view class="uni-collapse">
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'UniCollapse',
|
||||
props: {
|
||||
accordion: {
|
||||
// 是否开启手风琴效果
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
collapse: this
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.childrens = []
|
||||
},
|
||||
methods: {
|
||||
onChange() {
|
||||
let activeItem = []
|
||||
this.childrens.forEach((vm, index) => {
|
||||
if (vm.isOpen) {
|
||||
activeItem.push(vm.nameSync)
|
||||
}
|
||||
})
|
||||
this.$emit('change', activeItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/uni.scss';
|
||||
|
||||
.uni-collapse {
|
||||
/* #ifndef APP-NVUE */
|
||||
width: 100%;
|
||||
display: flex;
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
flex: 1;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
background-color: $uni-bg-color;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,29 @@
|
||||
export default {
|
||||
created() {
|
||||
if (this.type === 'message') {
|
||||
// 获取自组件对象
|
||||
this.maskShow = false
|
||||
this.children = null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.type === 'message') {
|
||||
// 不显示遮罩
|
||||
this.maskShow = false
|
||||
// 获取子组件对象
|
||||
this.childrenMsg = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
customOpen() {
|
||||
if (this.childrenMsg) {
|
||||
this.childrenMsg.open()
|
||||
}
|
||||
},
|
||||
customClose() {
|
||||
if (this.childrenMsg) {
|
||||
this.childrenMsg.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<view class="uni-popup-share">
|
||||
<view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view>
|
||||
<view class="uni-share-content">
|
||||
<view class="uni-share-content-box">
|
||||
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
|
||||
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
|
||||
<text class="uni-share-text">{{item.text}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-share-button-box">
|
||||
<button class="uni-share-button" @click="close">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UniPopupShare',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '分享到'
|
||||
}
|
||||
},
|
||||
inject: ['popup'],
|
||||
data() {
|
||||
return {
|
||||
bottomData: [{
|
||||
text: '微信',
|
||||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-2.png',
|
||||
name: 'wx'
|
||||
},
|
||||
{
|
||||
text: '支付宝',
|
||||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-8.png',
|
||||
name: 'wx'
|
||||
},
|
||||
{
|
||||
text: 'QQ',
|
||||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/gird-3.png',
|
||||
name: 'qq'
|
||||
},
|
||||
{
|
||||
text: '新浪',
|
||||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-1.png',
|
||||
name: 'sina'
|
||||
},
|
||||
{
|
||||
text: '百度',
|
||||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-7.png',
|
||||
name: 'copy'
|
||||
},
|
||||
{
|
||||
text: '其他',
|
||||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-5.png',
|
||||
name: 'more'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
/**
|
||||
* 选择内容
|
||||
*/
|
||||
select(item, index) {
|
||||
this.$emit('select', {
|
||||
item,
|
||||
index
|
||||
}, () => {
|
||||
this.popup.close()
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 关闭窗口
|
||||
*/
|
||||
close() {
|
||||
this.popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.uni-popup-share {
|
||||
background-color: #fff;
|
||||
}
|
||||
.uni-share-title {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
}
|
||||
.uni-share-title-text {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
.uni-share-content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.uni-share-content-box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.uni-share-content-item {
|
||||
width: 90px;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.uni-share-content-item:active {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.uni-share-image {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.uni-share-text {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
color: #3B4144;
|
||||
}
|
||||
|
||||
.uni-share-button-box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.uni-share-button {
|
||||
flex: 1;
|
||||
border-radius: 50px;
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.uni-share-button::after {
|
||||
border-radius: 50px;
|
||||
}
|
||||
</style>
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.provinces" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.citys" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column v-if="!hideArea">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.areas" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import areaData from "./areadata/areadata.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:{
|
||||
provinces:[],
|
||||
citys:[],
|
||||
areas:[]
|
||||
},
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
value:{
|
||||
type:[Array,String],
|
||||
default:""
|
||||
},
|
||||
defaultType:{
|
||||
type:String,
|
||||
default:"label"
|
||||
},
|
||||
hideArea:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods:{
|
||||
getData(){
|
||||
//用来处理初始化数据
|
||||
let provinces=areaData;
|
||||
let dVal=[];
|
||||
let value=this.value;
|
||||
let a1=value[0];//默认值省
|
||||
let a2=value[1];//默认值市
|
||||
let a3=value[2];//默认值区、县
|
||||
let province,city,area;
|
||||
let provinceIndex=provinces.findIndex((v)=>{
|
||||
return v[this.defaultType]==a1
|
||||
});
|
||||
provinceIndex=value?(provinceIndex!=-1?provinceIndex:0):0;
|
||||
let citys=provinces[provinceIndex].children;
|
||||
let cityIndex=citys.findIndex((v)=>{
|
||||
return v[this.defaultType]==a2
|
||||
});
|
||||
cityIndex=value?(cityIndex!=-1?cityIndex:0):0;
|
||||
let areas=citys[cityIndex].children;
|
||||
let areaIndex=areas.findIndex((v)=>{
|
||||
return v[this.defaultType]==a3;
|
||||
});
|
||||
areaIndex=value?(areaIndex!=-1?areaIndex:0):0;
|
||||
dVal=this.hideArea?[provinceIndex,cityIndex]:[provinceIndex,cityIndex,areaIndex];
|
||||
province=provinces[provinceIndex];
|
||||
city=citys[cityIndex];
|
||||
area=areas[areaIndex];
|
||||
let obj=this.hideArea?{
|
||||
province,
|
||||
city
|
||||
}:{
|
||||
province,
|
||||
city,
|
||||
area
|
||||
}
|
||||
return this.hideArea?{
|
||||
provinces,
|
||||
citys,
|
||||
dVal,
|
||||
obj
|
||||
}:{
|
||||
provinces,
|
||||
citys,
|
||||
areas,
|
||||
dVal,
|
||||
obj
|
||||
}
|
||||
},
|
||||
initData(){
|
||||
let dataData=this.getData();
|
||||
let provinces=dataData.provinces;
|
||||
let citys=dataData.citys;
|
||||
let areas=this.hideArea?[]:dataData.areas;
|
||||
let obj=dataData.obj;
|
||||
let province=obj.province,city=obj.city,area=this.hideArea?{}:obj.area;
|
||||
let value=this.hideArea?[province.value,city.value]:[province.value,city.value,area.value];
|
||||
let result=this.hideArea?`${province.label+city.label}`:`${province.label+city.label+area.label}`;
|
||||
this.range=this.hideArea?{
|
||||
provinces,
|
||||
citys,
|
||||
}:{
|
||||
provinces,
|
||||
citys,
|
||||
areas
|
||||
};
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=dataData.dVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:value,
|
||||
obj:obj
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let provinceIndex=arr[0],cityIndex=arr[1],areaIndex=this.hideArea?0:arr[2];
|
||||
let provinces=areaData;
|
||||
let citys=(provinces[provinceIndex]&&provinces[provinceIndex].children)||provinces[provinces.length-1].children||[];
|
||||
let areas=this.hideArea?[]:((citys[cityIndex]&&citys[cityIndex].children)||citys[citys.length-1].children||[]);
|
||||
let province=provinces[provinceIndex]||provinces[provinces.length-1],
|
||||
city=citys[cityIndex]||[citys.length-1],
|
||||
area=this.hideArea?{}:(areas[areaIndex]||[areas.length-1]);
|
||||
let obj=this.hideArea?{
|
||||
province,
|
||||
city
|
||||
}:{
|
||||
province,
|
||||
city,
|
||||
area
|
||||
}
|
||||
if(this.checkObj.province.label!=province.label){
|
||||
//当省更新的时候需要刷新市、区县的数据;
|
||||
this.range.citys=citys;
|
||||
if(!this.hideArea){
|
||||
this.range.areas=areas;
|
||||
}
|
||||
|
||||
}
|
||||
if(this.checkObj.city.label!=city.label){
|
||||
//当市更新的时候需要刷新区县的数据;
|
||||
if(!this.hideArea){
|
||||
this.range.areas=areas;
|
||||
}
|
||||
}
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=arr;
|
||||
})
|
||||
let result=this.hideArea?`${province.label+city.label}`:`${province.label+city.label+area.label}`;
|
||||
let value=this.hideArea?[province.value,city.value]:[province.value,city.value,area.value];
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:value,
|
||||
obj:obj
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
||||
|
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range" :key="index">{{item[nodeKey]}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
options:{
|
||||
type:[Array,Object],
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
value:{
|
||||
type:String,
|
||||
default:""
|
||||
},
|
||||
defaultType:{
|
||||
type:String,
|
||||
default:"label"
|
||||
},
|
||||
defaultProps:{
|
||||
type:Object,
|
||||
default(){
|
||||
return{
|
||||
label:"label",
|
||||
value:"value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pickVal:[]
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
nodeKey(){
|
||||
return this.defaultProps.label;
|
||||
},
|
||||
nodeValue(){
|
||||
return this.defaultProps.value;
|
||||
},
|
||||
range(){
|
||||
return this.options
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
if(this.options.length!=0){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
options(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if(this.options.length!=0){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
initData(){
|
||||
let dVal=this.value||"";
|
||||
let data=this.range;
|
||||
let pickVal=[0];
|
||||
let cur=null;
|
||||
let label="";
|
||||
let value,idx;
|
||||
if(this.defaultType==this.nodeValue){
|
||||
value=data.find((v)=>v[this.nodeValue]==dVal);
|
||||
idx=data.findIndex((v)=>v[this.nodeValue]==dVal);
|
||||
}else{
|
||||
value=data.find((v)=>v[this.nodeKey]==dVal);
|
||||
idx=data.findIndex((v)=>v[this.nodeKey]==dVal);
|
||||
}
|
||||
pickVal=[idx!=-1?idx:0];
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
if(this.defaultType==this.nodeValue){
|
||||
this.$emit("change",{
|
||||
result:value?value[this.nodeKey]:data[0][this.nodeKey],
|
||||
value:dVal||data[0][this.nodeKey],
|
||||
obj:value?value:data[0]
|
||||
})
|
||||
}else{
|
||||
this.$emit("change",{
|
||||
result:dVal||data[0][this.nodeKey],
|
||||
value:value?value[this.nodeValue]:data[0][this.nodeValue],
|
||||
obj:value?value:data[0]
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let pickVal=[arr[0]||0];
|
||||
let data=this.range;
|
||||
let cur=data[arr[0]];
|
||||
let label="";
|
||||
let value="";
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:cur[this.nodeKey],
|
||||
value:cur[this.nodeValue],
|
||||
obj:cur
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
@ -0,0 +1,26 @@
|
||||
.w-picker-flex2{
|
||||
flex:2;
|
||||
}
|
||||
.w-picker-flex1{
|
||||
flex:1;
|
||||
}
|
||||
.w-picker-view {
|
||||
width: 100%;
|
||||
height: 476upx;
|
||||
overflow: hidden;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
z-index: 666;
|
||||
}
|
||||
.d-picker-view{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.w-picker-item {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 88upx;
|
||||
line-height: 88upx;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 30upx;
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import MinCache from'./common/util/MinCache.js'
|
||||
import tip from'./common/util/tip.js'
|
||||
import configService from'./common/service/config.service.js'
|
||||
|
||||
import router from './common/router'
|
||||
import {RouterMount} from './plugin/uni-simple-router/index.js'
|
||||
import uView from '@/uni_modules/uview-ui'
|
||||
Vue.use(uView)
|
||||
|
||||
// 注册缓存器
|
||||
Vue.use(MinCache,{timeout: 6})
|
||||
|
||||
// store
|
||||
Vue.prototype.$store=store;
|
||||
// tip
|
||||
Vue.prototype.$tip=tip;
|
||||
// config
|
||||
Vue.prototype.$config=configService;
|
||||
|
||||
// request请求
|
||||
import { http } from '@/common/service/service.js'
|
||||
Vue.prototype.$http = http
|
||||
|
||||
import home from './pages/home/home.vue'
|
||||
Vue.component('home',home)
|
||||
|
||||
|
||||
import people from './pages/user/people.vue'
|
||||
Vue.component('people',people)
|
||||
|
||||
// 自定义组件
|
||||
import mySelect from './components/my-componets/my-select.vue'
|
||||
Vue.component('mySelect',mySelect)
|
||||
|
||||
import myImageUpload from './components/my-componets/my-image-upload.vue'
|
||||
Vue.component('myImageUpload',myImageUpload)
|
||||
|
||||
|
||||
import myPage from './components/my-componets/my-page.vue'
|
||||
Vue.component('myPage',myPage)
|
||||
|
||||
|
||||
|
||||
import basics from './pages/basics/home.vue'
|
||||
Vue.component('basics',basics)
|
||||
|
||||
import components from './pages/component/home.vue'
|
||||
Vue.component('components',components)
|
||||
|
||||
import plugin from './pages/plugin/home.vue'
|
||||
Vue.component('plugin',plugin)
|
||||
|
||||
import cuCustom from './plugin/colorui/components/cu-custom.vue'
|
||||
Vue.component('cu-custom',cuCustom)
|
||||
|
||||
// import VConsole from './js_sdk/vconsole.min'
|
||||
|
||||
// var vConsole = new VConsole();
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
App.mpType = 'app'
|
||||
|
||||
const app = new Vue({
|
||||
store,
|
||||
MinCache,
|
||||
...App
|
||||
})
|
||||
//v1.3.5起 H5端 你应该去除原有的app.$mount();使用路由自带的渲染方式
|
||||
// #ifdef H5
|
||||
RouterMount(app,'#app');
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
app.$mount(); //为了兼容小程序及app端必须这样写才有效果
|
||||
// #endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -0,0 +1,44 @@
|
||||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
|
||||
},
|
||||
"prettier": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "http://registry.npm.taobao.org/prettier/download/prettier-1.12.1.tgz",
|
||||
"integrity": "sha1-wa0g6APndJ+vkFpAnSNn4Gu+cyU="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "6.12.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.12.1.tgz",
|
||||
"integrity": "sha512-OHj+zzfRMyj3rmo/6G8a5Ifvw3AleL/EbcHMD27YA31Q+cO5lfmQxECkImuNVjcskLcvBRVHNAB3w6udMs1eAA==",
|
||||
"requires": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"split-on-first": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
|
||||
},
|
||||
"uni-simple-router": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-1.5.5.tgz",
|
||||
"integrity": "sha512-VjBnwhvmWYHVNsj2zcPjYBwb9TqG7miR87qLBBLI4gHOnJVYmCyjZK/bj06f9slvTMbWXrze7LJ9/Hi/8DB0ag==",
|
||||
"requires": {
|
||||
"query-string": "^6.12.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": "echarts-uniapp",
|
||||
"name": "echarts for uniapp",
|
||||
"version": "0.0.1",
|
||||
"description": "echarts适配uni-app",
|
||||
"keywords": [
|
||||
"echarts",
|
||||
"图表"
|
||||
],
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,251 @@
|
||||
<template>
|
||||
|
||||
<view>
|
||||
<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
|
||||
<block slot="backText">返回</block>
|
||||
<block slot="content">通讯录</block>
|
||||
</cu-custom>
|
||||
<view class="cu-bar bg-white search fixed" :style="[{top:CustomBar + 'px'}]">
|
||||
<view class="search-form round">
|
||||
<text class="cuIcon-search"></text>
|
||||
<input type="text" v-model="keyword" placeholder="输入搜索的关键词" confirm-type="search" @confirm="searchUserByKey"></input>
|
||||
</view>
|
||||
<view class="action">
|
||||
<button class="cu-btn bg-gradual-blue shadow-blur round" @tap="searchUserByKey">搜索</button>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y class="indexes margin-top-xl" :scroll-into-view="'indexes-'+ listCurID" :style="[{top:'calc('+ CustomBar + 'px - 20px)',height:'calc(100vh - '+ CustomBar + 'px - 70px)'}]"
|
||||
:scroll-with-animation="true" :enable-back-to-top="true">
|
||||
<block v-for="(item,index) in list" :key="index">
|
||||
<view :class="'indexItem-' + item.name" :id="'indexes-' + item.name" :data-index="item.name">
|
||||
<view class="padding">{{item.name}}</view>
|
||||
<view class="cu-list menu-avatar no-padding" >
|
||||
<view class="cu-item" v-for="(items,sub) in userList" :key="sub" v-if="items.szm==item.name" @tap="toAddressDetail(items)">
|
||||
<view class="cu-avatar round lg" v-if="items.avatar" :style="[{ backgroundImage:'url(' + items.avatar + ')' }]"></view>
|
||||
<view class="cu-avatar round lg" v-else>{{item.name}}</view>
|
||||
<view class="content">
|
||||
<view class="text-grey">{{items.realname?items.realname:items.username}}</view>
|
||||
<view class="text-gray text-sm">
|
||||
{{items.orgCode}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
<view class="indexBar" :style="[{height:'calc(110vh - ' + CustomBar + 'px - 50px)'}]">
|
||||
<view class="indexBar-box" @touchstart="tStart" @touchend="tEnd" @touchmove.stop="tMove">
|
||||
<view class="indexBar-item" v-for="(item,index) in list" :key="index" :id="index" @touchstart="getCur" @touchend="setCur"> {{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!--选择显示-->
|
||||
<view v-show="!hidden" class="indexToast">
|
||||
{{listCur}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import vPinyin from '@/common/util/vue-py.js';
|
||||
import {getFileAccessHttpUrl} from '@/api/api.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
StatusBar: this.StatusBar,
|
||||
CustomBar: this.CustomBar,
|
||||
hidden: true,
|
||||
listCurID: '',
|
||||
list: [],
|
||||
userList: [],
|
||||
listCur: '',
|
||||
keyword: '',
|
||||
queryUserByKeyWord:'/sys/user/appQueryUser'
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
let list = [{}];
|
||||
for (let i = 0; i < 26; i++) {
|
||||
list[i] = {};
|
||||
list[i].name = String.fromCharCode(65 + i);
|
||||
}
|
||||
this.list = list;
|
||||
this.listCur = list[0];
|
||||
this.loadInfo()
|
||||
},
|
||||
onReady() {
|
||||
let that = this;
|
||||
uni.createSelectorQuery().select('.indexBar-box').boundingClientRect(function(res) {
|
||||
that.boxTop = res.top
|
||||
}).exec();
|
||||
uni.createSelectorQuery().select('.indexes').boundingClientRect(function(res) {
|
||||
that.barTop = res.top
|
||||
}).exec()
|
||||
},
|
||||
methods: {
|
||||
backTap(){
|
||||
this.$Router.replace({name:'index'})
|
||||
},
|
||||
toAddressDetail(item){
|
||||
let parmas = {...item}
|
||||
parmas.departName=parmas.orgCode
|
||||
this.$Router.push({name: 'addressDetail',params:parmas})
|
||||
},
|
||||
searchUserByKey(){
|
||||
this.loadInfo()
|
||||
},
|
||||
loadInfo(){
|
||||
this.$http.get(this.queryUserByKeyWord,{params:{'keyword':this.keyword}}).then(res=>{
|
||||
if (res.data.success) {
|
||||
console.log("res",res)
|
||||
let arr=res.data.result;
|
||||
let szuArr=[];
|
||||
this.userList = arr.map(item => {
|
||||
let { id,realname,avatar,username,phone,email,post,orgCode} = item
|
||||
let pinYin = username.toUpperCase();
|
||||
if(realname){
|
||||
//TODO 判断汉字的位置
|
||||
if(/.*[\u4e00-\u9fa5]+.*$/.test(realname)){
|
||||
pinYin=vPinyin.chineseToPinYin(realname);
|
||||
}
|
||||
}
|
||||
if(avatar){
|
||||
avatar=getFileAccessHttpUrl(avatar);
|
||||
}
|
||||
let event = {
|
||||
id, realname ,avatar,username,phone,email,post,orgCode,
|
||||
szm:pinYin.substr(0,1)
|
||||
}
|
||||
szuArr.push(event.szm)
|
||||
return event
|
||||
})
|
||||
|
||||
this.list=this.list.filter(item=>szuArr.indexOf(item.name)!=-1)
|
||||
//this.list.unshift({name:"#"})
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
},
|
||||
//获取文字信息
|
||||
getCur(e) {
|
||||
this.hidden = false;
|
||||
this.listCur = this.list[e.target.id].name;
|
||||
},
|
||||
setCur(e) {
|
||||
this.hidden = true;
|
||||
this.listCur = this.listCur
|
||||
},
|
||||
//滑动选择Item
|
||||
tMove(e) {
|
||||
let y = e.touches[0].clientY,
|
||||
offsettop = this.boxTop,
|
||||
that = this;
|
||||
//判断选择区域,只有在选择区才会生效
|
||||
if (y > offsettop) {
|
||||
let num = parseInt((y - offsettop) / 20);
|
||||
this.listCur = that.list[num].name
|
||||
};
|
||||
},
|
||||
|
||||
//触发全部开始选择
|
||||
tStart() {
|
||||
this.hidden = false
|
||||
},
|
||||
|
||||
//触发结束选择
|
||||
tEnd() {
|
||||
this.hidden = true;
|
||||
this.listCurID = this.listCur
|
||||
},
|
||||
indexSelect(e) {
|
||||
let that = this;
|
||||
let barHeight = this.barHeight;
|
||||
let list = this.list;
|
||||
let scrollY = Math.ceil(list.length * e.detail.y / barHeight);
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (scrollY < i + 1) {
|
||||
that.listCur = list[i].name;
|
||||
that.movableY = i * 20
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
padding-top: 100upx;
|
||||
}
|
||||
|
||||
.indexes {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.indexBar {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
padding: 20upx 20upx 20upx 60upx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.indexBar .indexBar-box {
|
||||
width: 40upx;
|
||||
height: auto;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 0 20upx rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10upx;
|
||||
}
|
||||
|
||||
.indexBar-item {
|
||||
flex: 1;
|
||||
width: 40upx;
|
||||
height: 40upx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24upx;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
movable-view.indexBar-item {
|
||||
width: 40upx;
|
||||
height: 40upx;
|
||||
z-index: 9;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
movable-view.indexBar-item::before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 10upx;
|
||||
height: 20upx;
|
||||
width: 4upx;
|
||||
background-color: #f37b1d;
|
||||
}
|
||||
|
||||
.indexToast {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 80upx;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
width: 100upx;
|
||||
height: 100upx;
|
||||
border-radius: 10upx;
|
||||
margin: auto;
|
||||
color: #fff;
|
||||
line-height: 100upx;
|
||||
text-align: center;
|
||||
font-size: 48upx;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<view>
|
||||
<scroll-view :scroll-y="modalName==null" class="page">
|
||||
<cu-custom :bgColor="NavBarColor" :isBack="true">
|
||||
<block slot="backText">返回</block>
|
||||
<block slot="content">个人信息</block>
|
||||
</cu-custom>
|
||||
<view class="cu-list menu-avatar margin-top">
|
||||
<view class="cu-item">
|
||||
<view class="cu-avatar round lg" v-if="infoList.avatar" :style="[{backgroundImage:'url('+ infoList.avatar +')'}]"></view>
|
||||
<view class="cu-avatar round lg" v-else :style="[{backgroundImage:'url('+ avatar +')'}]"></view>
|
||||
<view class="content">
|
||||
<view class="text-grey text-lg">{{infoList.realname?infoList.realname:infoList.username}}<text class="cuIcon-peoplefill margin-left-sm" :class="infoList.sex=='2'?'text-pink':'text-blue'"></text></view>
|
||||
<view class="text-gray text-sm flex">
|
||||
<view class="text-cut">
|
||||
{{infoList.post}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cu-list menu margin-top">
|
||||
<view class="cu-item animation-slide-bottom" :style="[{animationDelay: '0.2s'}]">
|
||||
<view class="content">
|
||||
<text class="text-grey">手机</text>
|
||||
</view>
|
||||
<view class="action">
|
||||
<text class="text-grey">{{infoList.phone?infoList.phone:phone}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-item animation-slide-bottom" :style="[{animationDelay: '0.3s'}]">
|
||||
<view class="content">
|
||||
<text class="text-grey">邮箱</text>
|
||||
</view>
|
||||
<view class="action">
|
||||
<text class="text-grey">{{infoList.email?infoList.email:email}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-item animation-slide-bottom" :style="[{animationDelay: '0.4s'}]">
|
||||
<view class="content">
|
||||
<text class="text-grey">部门</text>
|
||||
</view>
|
||||
<view class="action">
|
||||
<text class="text-grey">{{infoList.departName?infoList.departName:company}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {phone,email,company} from "@/common/util/constants"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
phone,
|
||||
email,
|
||||
company,
|
||||
NavBarColor:this.NavBarColor,
|
||||
avatar:'/static/login4.png',
|
||||
modalName: null,
|
||||
infoList:{
|
||||
realname:'',
|
||||
post:'',
|
||||
avatar:'',
|
||||
phone:null,
|
||||
email:'',
|
||||
department:'',
|
||||
title:''
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.infoList = this.$Route.query;
|
||||
console.log("this.infoList>>>",this.infoList)
|
||||
},
|
||||
methods: {
|
||||
backRoute() {
|
||||
//通讯录个人信息页面返回问题
|
||||
if(this.infoList.page){
|
||||
this.$Router.push({name:this.infoList.page})
|
||||
}else{
|
||||
let parmas={
|
||||
title:this.$Route.query.departName,
|
||||
orgCode:this.$Route.query.orgCode
|
||||
}
|
||||
this.$Router.push({name: 'member',params:parmas})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page {
|
||||
height: 100Vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.page.show {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.switch-sex::after {
|
||||
content: "\e716";
|
||||
}
|
||||
|
||||
.switch-sex::before {
|
||||
content: "\e7a9";
|
||||
}
|
||||
|
||||
.switch-music::after {
|
||||
content: "\e66a";
|
||||
}
|
||||
|
||||
.switch-music::before {
|
||||
content: "\e6db";
|
||||
}
|
||||
</style>
|
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
|
||||
<view>
|
||||
<view class="cu-bar fixed" :style="style" :class="[NavBarColor]">
|
||||
<view class="cuIcon-back margin-left" @tap="backRoute()"><text class="margin-left-sm">返回</text></view>
|
||||
<view class="content" :style="[{top:StatusBar + 'px'}]">
|
||||
通讯录
|
||||
</view>
|
||||
</view>
|
||||
<!-- 展示标题 -->
|
||||
<view class="bg-gray text-gray padding" :style="[{marginTop:CustomBar+'px'}]">
|
||||
{{ levelTitle }}
|
||||
</view>
|
||||
<!-- 展示部门和用户 -->
|
||||
<view class="cu-list menu sm-border">
|
||||
<view class="cu-item" v-for="(item, index) in comList" :key="item.key" @tap="goMember(item)">
|
||||
<image class="line2-icon" src="/static/folder.png"></image>
|
||||
<view class="content margin-left-sm">
|
||||
<view class="text-grey">{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-item" v-for="(item,index) in childrenUserList" :key="index" @click="goMemberInfo(item)">
|
||||
<view class="cu-avatar round lx" :style="[{backgroundImage:'url('+ item.avatar +')'}]"></view>
|
||||
<view class="content margin-left-sm">
|
||||
<view class="text-grey">{{item.realname}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getFileAccessHttpUrl } from "../../api/api.js"
|
||||
export default {
|
||||
name: "level-address-book",
|
||||
data(){
|
||||
return{
|
||||
CustomBar:this.CustomBar,
|
||||
StatusBar:this.StatusBar,
|
||||
NavBarColor:this.NavBarColor,
|
||||
value:"",
|
||||
derpartment:'通讯录',
|
||||
comList:[],
|
||||
childrenUserList:[],
|
||||
metaList:[],
|
||||
depart2Url:'/sys/sysDepart/queryTreeList',
|
||||
queryTreeByKeyWord:'/sys/sysDepart/queryTreeByKeyWord',
|
||||
queryUserByDid:'/sys/user/appQueryByDepartId',
|
||||
// departUrl:'/sys/user/userDepartList',
|
||||
level:0,
|
||||
titleArray:[],
|
||||
parentId:''
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
levelTitle(){
|
||||
if(this.titleArray && this.titleArray.length>0){
|
||||
return this.titleArray.join(' > ')
|
||||
}
|
||||
console.log("this.titleArray",this.titleArray)
|
||||
return '企业通讯录'
|
||||
},
|
||||
style() {
|
||||
var StatusBar= this.StatusBar;
|
||||
var CustomBar= this.CustomBar;
|
||||
var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
|
||||
return style
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
console.log("this.CustomBar",this.CustomBar)
|
||||
this.loadList()
|
||||
},
|
||||
methods: {
|
||||
backRoute() {
|
||||
console.log("this.level",this.level)
|
||||
console.log("this.parentId",this.parentId)
|
||||
if(this.level==0){
|
||||
// 返回首页
|
||||
this.$Router.replaceAll({name: 'index'})
|
||||
}else{
|
||||
//正常列表的回退 只要找parentId的parent的data
|
||||
this.getCyclePnode(this.metaList,'');
|
||||
//还需要设置 title
|
||||
this.titleArray.pop();
|
||||
this.level--;
|
||||
}
|
||||
},
|
||||
onRefresh(){
|
||||
this.comList=[]
|
||||
this.childrenUserList=[]
|
||||
this.titleArray=[]
|
||||
this.loadList()
|
||||
},
|
||||
loadList() {
|
||||
console.log("loadList==>$Route",this.$Route)
|
||||
if(this.$Route.query.level){
|
||||
let params=this.$Route.query
|
||||
this.level=params.level;
|
||||
this.comList=params.comList;
|
||||
this.metaList=params.metaList;
|
||||
this.childrenUserList=params.childrenUserList;
|
||||
this.derpartment=params.derpartment;
|
||||
this.parentId=params.parentId;
|
||||
this.titleArray=params.titleArray;
|
||||
return;
|
||||
}
|
||||
|
||||
this.$http.get(this.queryTreeByKeyWord).then(res => {
|
||||
console.log("部门通讯树::", res)
|
||||
if (res.data.success) {
|
||||
console.log("部门::", res.data.result.departList)
|
||||
if(res.data.result.departList && res.data.result.departList.length >0){
|
||||
for (let item of res.data.result.departList) {
|
||||
console.log("item::",item);
|
||||
this.comList.push(item)
|
||||
this.metaList.push(item)
|
||||
}
|
||||
this.derpartment = this.comList[0].title
|
||||
}
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log("queryTreeByKeyWord 请求错误", e)
|
||||
})
|
||||
},
|
||||
getUser(departId,title){
|
||||
this.$http.get(this.queryUserByDid,{params:{departId:departId}}).then(res => {
|
||||
this.childrenUserList=res.data.result;
|
||||
for(let item of this.childrenUserList){
|
||||
item.departName=title
|
||||
this.avatarHandler(item)
|
||||
}
|
||||
})
|
||||
},
|
||||
avatarHandler(item){
|
||||
let avatar = item.avatar
|
||||
if(avatar){
|
||||
let url = getFileAccessHttpUrl(avatar);
|
||||
item.avatar = url
|
||||
}else{
|
||||
if(item.sex=='2'){
|
||||
item.avatar = 'https://static.jeecg.com/upload/test/avatar_girl_1595818025488.png';
|
||||
}else{
|
||||
item.avatar = 'https://static.jeecg.com/upload/test/avatar_boy_1595818012577.png';
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
goMember(item){
|
||||
let params = {...item}
|
||||
if (params.children && params.children.length>0){
|
||||
this.level++;
|
||||
this.comList=[];
|
||||
this.childrenUserList=[];
|
||||
for (let item of params.children) {
|
||||
this.comList.push(item)
|
||||
}
|
||||
this.getUser(params.id,params.title)
|
||||
this.titleArray.push(params.title);
|
||||
this.parentId = params.id;
|
||||
this.derpartment = params.title;
|
||||
}else{
|
||||
console.log("params==>toMember",params)
|
||||
params.level=this.level;
|
||||
params.comList=this.comList;
|
||||
params.metaList=this.metaList;
|
||||
params.childrenUserList=this.childrenUserList;
|
||||
params.derpartment=this.derpartment;
|
||||
params.parentId=this.parentId;
|
||||
params.titleArray=this.titleArray;
|
||||
this.$Router.push({name: 'member',params:params})
|
||||
}
|
||||
},
|
||||
getCyclePnode(arr, pid){
|
||||
for(let item of arr){
|
||||
if(item.id == this.parentId){
|
||||
this.comList = arr;
|
||||
this.childrenUserList=[];
|
||||
this.derpartment = this.comList[0].title
|
||||
this.parentId = pid;
|
||||
this.getUser(this.parentId,item.title)
|
||||
break;
|
||||
}
|
||||
if(item.children && item.children.length>0){
|
||||
this.getCyclePnode(item.children, item.id)
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
goMemberInfo: function (item){
|
||||
console.log("item",item)
|
||||
|
||||
let parmas = {...item}
|
||||
console.log("parmas",parmas)
|
||||
parmas.page='levelAddressBook'
|
||||
this.$Router.push({name: 'addressDetail',params:parmas})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.line2-icon {
|
||||
width: 25px;
|
||||
height: 20px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="cu-bar fixed" :class="[NavBarColor]" :style="style" >
|
||||
<view class="cuIcon-back margin-left" @tap="backRoute()"><text class="margin-left-sm">返回</text></view>
|
||||
<view class="content" :style="[{top:StatusBar + 'px'}]">
|
||||
{{ memberTitle }}
|
||||
</view>
|
||||
</view>
|
||||
<!-- 展示部门和用户 -->
|
||||
<view class="cu-list menu-avatar sm-border" :style="[{marginTop:'calc('+CustomBar+ 'px + 10px)'}]">
|
||||
<view class="cu-item" v-for="(item, index) in memberList" :key="index" @click="goMemberInfo(item)">
|
||||
<view class="cu-avatar round lg" :style="[{backgroundImage:'url('+ item.avatar +')'}]"></view>
|
||||
<view class="content">
|
||||
<view class="text-grey">{{item.realname}}</view>
|
||||
<view class="text-grey">{{item.post}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-center text-lg"><text>共{{ memberTotal}}人</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getFileAccessHttpUrl } from "../../api/api.js"
|
||||
export default {
|
||||
name: "member",
|
||||
data(){
|
||||
return{
|
||||
CustomBar:this.CustomBar,
|
||||
StatusBar:this.StatusBar,
|
||||
NavBarColor:this.NavBarColor,
|
||||
departUrl:'/sys/sysDepart/queryTreeList',
|
||||
addressSourceUrl:'/sys/user/queryByOrgCodeForAddressList',
|
||||
queryByOrgCodeKeyword:'/sys/user/queryByOrgCodeKeyword',
|
||||
positionUrl:'/sys/position/list',
|
||||
value:'',
|
||||
memberTitle:'',
|
||||
memberList:[],
|
||||
userId:'',
|
||||
orgCode:'',
|
||||
ids:{},
|
||||
memberTotal:0,
|
||||
}
|
||||
},
|
||||
onLoad(){
|
||||
console.log("this.$Router", this.$Route);
|
||||
this.memberTitle = this.$Route.query.title
|
||||
this.orgCode = this.$Route.query.orgCode
|
||||
this.loadList()
|
||||
},
|
||||
computed:{
|
||||
style() {
|
||||
var StatusBar= this.StatusBar;
|
||||
var CustomBar= this.CustomBar;
|
||||
var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
|
||||
return style
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
backRoute() {
|
||||
this.$Router.push({name: 'levelAddressBook',params:this.$Route.query})
|
||||
},
|
||||
goMemberInfo(item){
|
||||
let parmas = {...item}
|
||||
parmas.orgCode= this.orgCode
|
||||
this.$Router.push({name: 'addressDetail',params:parmas})
|
||||
},
|
||||
loadList() {
|
||||
let param = {
|
||||
orgCode:this.orgCode,
|
||||
realname:this.value
|
||||
}
|
||||
this.$http.get(this.addressSourceUrl,{params:param}).then(res => {
|
||||
console.log("用户2", res)
|
||||
if (res.data.success) {
|
||||
let memberArr = res.data.result.records;
|
||||
//memberArr = memberArr.filter(item => item.departName == this.memberTitle)
|
||||
for (let item of memberArr) {
|
||||
this.avatarHandler(item);
|
||||
this.memberList.push(item)
|
||||
// this.userId = item.userId
|
||||
this.memberTotal = memberArr.length
|
||||
if (this.memberTotal == undefined){
|
||||
this.memberTotal = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log("请求错误", e)
|
||||
})
|
||||
|
||||
this.$http.get(this.positionUrl).then(res=> {
|
||||
console.log("用户1",res)
|
||||
if (res.data.success) {
|
||||
let postArr = res.data.result.records
|
||||
for (let item of postArr ){
|
||||
for (let it of this.memberList){
|
||||
if (it.post == item.code){
|
||||
it.post = item.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).catch(e=>{
|
||||
console.log("请求错误",e)
|
||||
})
|
||||
},
|
||||
avatarHandler(item){
|
||||
let avatar = item.avatar
|
||||
if(avatar){
|
||||
let url = getFileAccessHttpUrl(avatar);
|
||||
item.avatar = url
|
||||
}else{
|
||||
if(item.sex=='2'){
|
||||
item.avatar = 'static/avatar_girl.png';
|
||||
}else{
|
||||
item.avatar = 'static/avatar_boy.png';
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<view class="bg-white" style="height: 100vh;">
|
||||
<cu-custom :bgColor="NavBarColor" :isBack="true" backFlag="navigate">
|
||||
<block slot="backText">返回</block>
|
||||
<block slot="content">详情</block>
|
||||
</cu-custom>
|
||||
<view>
|
||||
<view class="title">
|
||||
<view class="padding" style="font-family: '宋体';">
|
||||
<text class="text-black title text-bold text-xl">{{annotation.titile}} </text>
|
||||
</view>
|
||||
</view>
|
||||
<view class=" text-df padding-left " style="color: #999;">
|
||||
<text class="title padding-right-xl" style="color: #999;">
|
||||
{{annotation.sender||''}}
|
||||
</text>
|
||||
<text class="" v-html="annotation.sendTime">
|
||||
</text>
|
||||
</view>
|
||||
<view class="desc" style="font-family: '仿宋';font-size: 18px;">
|
||||
<view class="text-content padding" v-html="annotation.msgContent">
|
||||
<!-- <annotation-block :content="annotation.msgContent"/> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-gray padding-left padding-bottom text-gray">
|
||||
<text class="cuIcon-attentionfill margin-lr-xs" @click="numberPlus"></text> 10
|
||||
<text class="cuIcon-appreciatefill padding-left margin-lr-xs" @click="numberPlus"></text> 20
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
export default {
|
||||
data(){
|
||||
return{
|
||||
NavBarColor:this.NavBarColor,
|
||||
annotation:{
|
||||
id:"",
|
||||
titile:"",
|
||||
startTime:"",
|
||||
sender:"",
|
||||
msgContent:"",
|
||||
|
||||
},
|
||||
goodNumber:null,
|
||||
flg:true,
|
||||
}
|
||||
},
|
||||
// onLoad:function(){
|
||||
// console.log("this.$Route.query",this.$Route);
|
||||
// let query = this.$Route.query
|
||||
// if(query){
|
||||
// this.annotation = query;
|
||||
// }
|
||||
// },
|
||||
onLoad: function (option) {
|
||||
const annItem = JSON.parse(decodeURIComponent(option.item));
|
||||
console.log("ann",annItem)
|
||||
this.annotation = annItem
|
||||
this.readOk();
|
||||
},
|
||||
created(){
|
||||
console.log("created")
|
||||
//this.readOk();
|
||||
},
|
||||
methods:{
|
||||
readOk(){
|
||||
console.log("readOk")
|
||||
let param = {anntId:this.annotation.anntId}
|
||||
this.$http.put('/sys/sysAnnouncementSend/editByAnntIdAndUserId',param);
|
||||
},
|
||||
|
||||
numberPlus(){
|
||||
if (this.flg){
|
||||
this.goodNumber++
|
||||
this.flg = false
|
||||
} else {
|
||||
this.goodNumber--
|
||||
if (this.goodNumber == 0){
|
||||
this.goodNumber = null
|
||||
}
|
||||
this.flg = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<view class="bg-white" >
|
||||
<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
|
||||
<block slot="backText">返回</block>
|
||||
<block slot="content">公告消息</block>
|
||||
</cu-custom>
|
||||
<view class="container">
|
||||
<view class="solid-bottom">
|
||||
<scroll-view scroll-x class="bg-white nav text-center ">
|
||||
<view class="flex text-center justify-around">
|
||||
<view class="cu-item" :class="item.value==TabCur?'text-blue cur':''" v-for="(item,index) in tabs" :key="index" @tap="tabSelect" :data-id="item.value">
|
||||
{{item.title}}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
|
||||
<!-- 数据列表 -->
|
||||
<view class="al-list cu-list">
|
||||
<view class="message_text bg-white cu-item flex justify-around align-center solid-bottom margin-bottom-sm margin-top-sm" style="width: 100vw;" v-for="(item,index) in msgList" :key="index" @tap="goAnnotationDetail(item)" :class="modalName=='move-box-'+ index?'move-cur':''"
|
||||
@touchstart="ListTouchStart" @touchmove="ListTouchMove" @touchend="ListTouchEnd" :data-target="'move-box-' + index">
|
||||
<view v-if="isEmail(item)" class="padding-left">
|
||||
<view class="cu-avatar radius cuIcon-mail bg-orange" ></view>
|
||||
</view>
|
||||
<view v-if="item.msgCategory == '1'&&!isEmail(item)" class="padding-left">
|
||||
<view class="cu-avatar radius cuIcon-notification bg-orange" ></view>
|
||||
</view>
|
||||
<view v-if="item.msgCategory == '2'&&!isEmail(item)" class="padding-left">
|
||||
<view class="cu-avatar radius cuIcon-notice bg-orange" ></view>
|
||||
</view>
|
||||
<view v-if="item.msgCategory == '3'&&!isEmail(item)" class="padding-left">
|
||||
<view class="cu-avatar radius cuIcon-question bg-orange" ></view>
|
||||
</view>
|
||||
<view class="titlePad content" style="height: 4em;">
|
||||
<view class="flex justify-start text-cut text-lg" style="width:26em;color: #333;font-family: '黑体';">
|
||||
<!-- <view v-if="item.readFlag == '0'" class="cu-tag light bg-blue">未读</view> -->
|
||||
<view v-if="item.readFlag == '0'">
|
||||
<text class="cuIcon-title text-red padding-left-sm" style="margin-right: -0.8em;"></text>
|
||||
</view>
|
||||
<view class="padding-left">
|
||||
<text class="text-black" v-if="isEmail(item)&&item.emailTitle">{{titleFilter(item.emailTitle,12)}} </text>
|
||||
<text class="text-black" v-else>{{titleFilter(item.titile,12)}} </text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-between margin-top-xs" style="font-family: '黑体';color: #999;">
|
||||
<view v-if="isEmail(item)" class="text-content text-cut" style="padding-left: .8rem;width:18em;"
|
||||
v-html="item.msgContent" @click="goEmailDetailPage(item);">
|
||||
</view>
|
||||
<view v-else-if="!isEmail(item)" style="padding-left: .8rem;">
|
||||
<view class="text-content text-cut" v-if="item.msgAbstract && item.msgAbstract.length > 0" style="width:18em;"
|
||||
v-html="item.msgAbstract">
|
||||
</view>
|
||||
<view v-else>
|
||||
无摘要
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="action text-sm" style="color: #aaa;margin-top: -2em;margin-left: -13em;width: 10em;">
|
||||
<text >{{formatDate(item.sendTime,10)}}</text>
|
||||
</view>
|
||||
<view class="move">
|
||||
<view class="bg-red" style="margin-right: 3em;margin-left: 2px;" @tap.stop="deleteAnnotation(item)">删除</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-uni>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const tabs = [{title:'通知公告',value:0}, {title:'系统消息',value:1}, {title:'故障告警',value:2}];
|
||||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
|
||||
|
||||
|
||||
export default {
|
||||
mixins: [MescrollMixin], // 使用mixin
|
||||
data() {
|
||||
return {
|
||||
tabs,
|
||||
TabCur: 0,
|
||||
scrollLeft: 0,
|
||||
NavBarColor:this.NavBarColor,
|
||||
upOption:{
|
||||
page: {
|
||||
num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
|
||||
size: 10 // 每页数据的数量
|
||||
},
|
||||
noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
|
||||
empty:{
|
||||
tip: '~ 暂无数据 ~', // 提示
|
||||
|
||||
},
|
||||
loading:'',
|
||||
text:'全部',
|
||||
isShowNoMore:false,
|
||||
textNoMore:'我是有底线的 >_<'
|
||||
},
|
||||
msgList: [], //列表数据
|
||||
read: "all",
|
||||
announcement1:[],
|
||||
msg1Count:"",
|
||||
msg1Title:"",
|
||||
announcement2:[],
|
||||
msg2Count:"",
|
||||
msg2Title:"",
|
||||
announcement3:[],
|
||||
msg3Count:"",
|
||||
msg3Title:"",
|
||||
url:"/sys/sysAnnouncementSend/getMyAnnouncementSend",
|
||||
delUrl:'/sys/sysAnnouncementSend/delete',
|
||||
listTouchStart: 0,
|
||||
modalName: null,
|
||||
listTouchDirection: null,
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if(this.mescroll){
|
||||
this.mescroll.resetUpScroll()
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
top() {
|
||||
return this.CustomBar * 2 + 95
|
||||
},
|
||||
style() {
|
||||
var StatusBar= this.StatusBar;
|
||||
var CustomBar= this.CustomBar;
|
||||
var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
|
||||
return style
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// unique(arr) {
|
||||
// var obj = {};
|
||||
// return arr.filter(function(item, index, arr){
|
||||
// return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
|
||||
// })
|
||||
// },
|
||||
upCallback(page) {
|
||||
//联网加载数据
|
||||
console.log("tabindex",this.TabCur )
|
||||
let keyword = this.TabCur
|
||||
if(keyword == 0){
|
||||
this.$http.get(this.url,{params:{pageNo: page.num, pageSize:page.size,msgCategory: '1'}}).then(res=>{
|
||||
//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
|
||||
|
||||
this.announcement1 = res.data.result.records
|
||||
this.mescroll.endSuccess(this.announcement1.length);
|
||||
//console.log("url", res)
|
||||
//设置列表数据
|
||||
if (res.data.success) {
|
||||
console.log("res",res.data)
|
||||
this.msg1Count = res.data.result.total
|
||||
this.msg1Title = "通知(" + res.data.result.total + ")";
|
||||
for(let annItem of this.announcement1){
|
||||
this.msgList.push(annItem)
|
||||
}
|
||||
}
|
||||
if(page.num == 1){
|
||||
this.msgList = []; //如果是第一页需手动制空列表
|
||||
this.msgList = this.msgList.concat(this.announcement1); //追加新数据
|
||||
}
|
||||
|
||||
}).catch(()=>{
|
||||
//联网失败, 结束加载
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
}
|
||||
if(keyword == 1){
|
||||
this.$http.get(this.url,{params:{pageNo: page.num,pageSize: page.size,msgCategory: '2'}}).then(res=>{
|
||||
//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
|
||||
this.announcement2 = res.data.result.records
|
||||
this.mescroll.endSuccess(this.announcement2.length,this.msgCount);
|
||||
|
||||
//设置列表数据
|
||||
if (res.data.success) {
|
||||
console.log("res sys",res.data)
|
||||
this.msg2Count = res.data.result.total
|
||||
this.msg2Title = "通知(" + res.data.result.total + ")";
|
||||
// this.announcement2.filter((item,index) => {
|
||||
// // console.log("item",item)
|
||||
// if(item.anntId == this.announcement2[index+1].anntId){
|
||||
// this.announcement2.splice(item,1)
|
||||
for(let item of this.announcement2){
|
||||
this.msgList.push(item)
|
||||
}
|
||||
// }
|
||||
// })
|
||||
}
|
||||
if(page.num == 1){
|
||||
this.msgList = []; //如果是第一页需手动制空列表
|
||||
this.msgList = this.msgList.concat(this.announcement2); //追加新数据
|
||||
}
|
||||
}).catch(()=>{
|
||||
//联网失败, 结束加载
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
}
|
||||
if(keyword == 2){
|
||||
this.$http.get(this.url,{params:{pageNo: page.num,pageSize: page.size,msgCategory: '3'}}).then(res=>{
|
||||
//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
|
||||
this.announcement3 = res.data.result.records
|
||||
this.mescroll.endSuccess(this.announcement3.length,this.msgCount);
|
||||
|
||||
//设置列表数据
|
||||
if (res.data.success) {
|
||||
console.log("res sys",res.data)
|
||||
this.msg3Count = res.data.result.total
|
||||
this.msg3Title = "故障告警(" + res.data.result.total + ")";
|
||||
// this.announcement2.filter((item,index) => {
|
||||
// // console.log("item",item)
|
||||
// if(item.anntId == this.announcement2[index+1].anntId){
|
||||
// this.announcement2.splice(item,1)
|
||||
for(let item of this.announcement2){
|
||||
this.msgList.push(item)
|
||||
}
|
||||
// }
|
||||
// })
|
||||
}
|
||||
if(page.num == 1){
|
||||
this.msgList = []; //如果是第一页需手动制空列表
|
||||
this.msgList = this.msgList.concat(this.announcement3); //追加新数据
|
||||
}
|
||||
}).catch(()=>{
|
||||
//联网失败, 结束加载
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
tabSelect(e) {
|
||||
this.TabCur = e.currentTarget.dataset.id;
|
||||
this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60;
|
||||
this.msgList = []// 先置空列表,显示加载进度
|
||||
this.mescroll.resetUpScroll() // 再刷新列表数据
|
||||
},
|
||||
goAnnotationDetail(item){
|
||||
//item.readFlag = '1'
|
||||
this.mescroll.resetUpScroll()
|
||||
if(item.openType=="component" && item.openPage.indexOf('email')>= 0){
|
||||
this.goEmailDetailPage(item)
|
||||
}else{
|
||||
// console.log("detail",encodeURIComponent(JSON.stringify(item)))
|
||||
uni.navigateTo({
|
||||
url: '/pages/annotation/annotationDetail?item='+ encodeURIComponent(JSON.stringify(item))
|
||||
});
|
||||
}
|
||||
},
|
||||
isEmail(item){
|
||||
if(item.openType=="component" &&item.openPage.indexOf('email')>=0){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
goEmailDetailPage(item){
|
||||
console.log("go",item.anntId)
|
||||
console.log("item",item)
|
||||
if(item.readFlag == '0'){
|
||||
//item.readFlag = '1'
|
||||
this.mescroll.resetUpScroll()
|
||||
let readUrl = '/sys/sysAnnouncementSend/editByAnntIdAndUserId';
|
||||
this.$http.put(readUrl,{anntId:item.anntId})
|
||||
}
|
||||
// console.log("goe",item.busId)
|
||||
|
||||
uni.navigateTo({
|
||||
url: '/pages/mail/mailDetail?id='+item.busId
|
||||
});
|
||||
|
||||
},
|
||||
ListTouchStart(e) {
|
||||
this.listTouchStart = e.touches[0].pageX
|
||||
},
|
||||
|
||||
// ListTouch计算方向
|
||||
ListTouchMove(e) {
|
||||
this.listTouchDirection = e.touches[0].pageX - this.listTouchStart > 0 ? 'right' : 'left'
|
||||
},
|
||||
|
||||
// ListTouch计算滚动
|
||||
ListTouchEnd(e) {
|
||||
if (this.listTouchDirection == 'left') {
|
||||
this.modalName = e.currentTarget.dataset.target
|
||||
} else {
|
||||
this.modalName = null
|
||||
}
|
||||
this.listTouchDirection = null
|
||||
},
|
||||
deleteAnnotation(item) {
|
||||
this.$http.delete(this.delUrl+'?id='+item.id).then(res => {
|
||||
console.log("结果数据9", res)
|
||||
if (res.data.success) {
|
||||
this.mescroll.resetUpScroll()
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log("al delUrl请求错误2", e)
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
},
|
||||
formatDate(text,len){
|
||||
if(!text || text.length==0){
|
||||
return ''
|
||||
}
|
||||
if(text.length<len){
|
||||
return text;
|
||||
}
|
||||
return text.substr(0,len)
|
||||
},
|
||||
titleFilter(text,len){
|
||||
if(!text || text.length==0){
|
||||
return ''
|
||||
}
|
||||
if(text.length<len){
|
||||
return text;
|
||||
}
|
||||
return text.substr(0,len)+"..."
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.e-btn{margin-bottom: 1rem;}
|
||||
|
||||
.titlePad{margin-top:0.6rem;}
|
||||
.cu-list>.move-cur{
|
||||
transform: translateX(-150rpx);
|
||||
|
||||
}
|
||||
.nav .cu-item.cur {
|
||||
position: flex;
|
||||
z-index: 9;
|
||||
border-bottom: 4upx solid;
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true"><block slot="backText">返回</block><block slot="content">头像</block></cu-custom>
|
||||
<view class="cu-bar bg-white">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>头像形状
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<view class="cu-avatar round" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg)"></view>
|
||||
<view class="cu-avatar radius margin-left" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big81005.jpg);"></view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>头像尺寸
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<view class="cu-avatar sm round margin-left" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg)"></view>
|
||||
<view class="cu-avatar round margin-left" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big81005.jpg);"></view>
|
||||
<view class="cu-avatar lg round margin-left" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big25002.jpg);"></view>
|
||||
<view class="cu-avatar xl round margin-left" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big99008.jpg);"></view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<view class="cu-avatar sm round margin-left bg-red"> A</view>
|
||||
<view class="cu-avatar round margin-left bg-red">B</view>
|
||||
<view class="cu-avatar lg round margin-left bg-red">C</view>
|
||||
<view class="cu-avatar xl round margin-left bg-red">D</view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<view class="cu-avatar sm round margin-left bg-red"> 蔚</view>
|
||||
<view class="cu-avatar round margin-left bg-red">蓝</view>
|
||||
<view class="cu-avatar lg round margin-left bg-red">
|
||||
<text>wl</text>
|
||||
</view>
|
||||
<view class="cu-avatar xl round margin-left bg-red">
|
||||
<text class="avatar-text">网络</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>内嵌文字(图标)
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<view class="cu-avatar radius">
|
||||
<text class="cuIcon-people"></text>
|
||||
</view>
|
||||
<view class="cu-avatar radius margin-left">
|
||||
<text>港</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>头像颜色
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding-sm">
|
||||
<view class="cu-avatar round lg margin-xs" :class="'bg-' + item.name" v-for="(item,index) in ColorList" :key="index">
|
||||
<text class="avatar-text">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>头像组
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<view class="cu-avatar-group">
|
||||
<view class="cu-avatar round lg" v-for="(item,index) in avatar" :key="index" :style="[{ backgroundImage:'url(' + avatar[index] + ')' }]"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>头像标签
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<view class="cu-avatar round lg margin-left" v-for="(item,index) in avatar" :key="index" :style="[{ backgroundImage:'url(' + avatar[index] + ')' }]">
|
||||
<view class="cu-tag badge" :class="index%2==0?'cuIcon-female bg-pink':'cuIcon-male bg-blue'"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ColorList: this.ColorList,
|
||||
avatar: [
|
||||
'https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg',
|
||||
'https://ossweb-img.qq.com/images/lol/web201310/skin/big81005.jpg',
|
||||
'https://ossweb-img.qq.com/images/lol/web201310/skin/big25002.jpg',
|
||||
'https://ossweb-img.qq.com/images/lol/web201310/skin/big91012.jpg'
|
||||
],
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true">
|
||||
<block slot="backText">返回</block>
|
||||
<block slot="content">背景</block>
|
||||
</cu-custom>
|
||||
<view class="cu-bar bg-white solid-bottom">
|
||||
<view class="action">
|
||||
<text class='cuIcon-title text-blue'></text>深色背景
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-3 padding-sm">
|
||||
<view class="padding-sm" v-for="(item,index) in ColorList" :key="index">
|
||||
<view class="padding radius text-center shadow-blur" :class="'bg-' + item.name">
|
||||
<view class="text-lg">{{item.title}}</view>
|
||||
<view class="margin-top-sm text-Abc">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>淡色背景
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-3 bg-white padding-sm">
|
||||
<view class="padding-sm" v-for="(item,index) in ColorList" :key="index" v-if="index<12">
|
||||
<view class="padding radius text-center light" :class="'bg-' + item.name">
|
||||
<view class="text-lg">{{item.title}}</view>
|
||||
<view class="margin-top-sm text-Abc">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white solid-bottom margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>渐变背景
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-2 padding-sm">
|
||||
<view class="padding-sm">
|
||||
<view class="bg-gradual-red padding radius text-center shadow-blur">
|
||||
<view class="text-lg">魅红</view>
|
||||
<view class="margin-top-sm text-Abc">#f43f3b - #ec008c</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding-sm">
|
||||
<view class="bg-gradual-orange padding radius text-center shadow-blur">
|
||||
<view class="text-lg">鎏金</view>
|
||||
<view class="margin-top-sm text-Abc">#ff9700 - #ed1c24</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding-sm">
|
||||
<view class="bg-gradual-green padding radius text-center shadow-blur">
|
||||
<view class="text-lg">翠柳</view>
|
||||
<view class="margin-top-sm text-Abc">#39b54a - #8dc63f</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding-sm">
|
||||
<view class="bg-gradual-blue padding radius text-center shadow-blur">
|
||||
<view class="text-lg">靛青</view>
|
||||
<view class="margin-top-sm text-Abc">#0081ff - #1cbbb4</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding-sm">
|
||||
<view class="bg-gradual-purple padding radius text-center shadow-blur">
|
||||
<view class="text-lg">惑紫</view>
|
||||
<view class="margin-top-sm text-Abc">#9000ff - #5e00ff</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding-sm">
|
||||
<view class="bg-gradual-pink padding radius text-center shadow-blur">
|
||||
<view class="text-lg">霞彩</view>
|
||||
<view class="margin-top-sm text-Abc">#ec008c - #6739b6</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>图片背景
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-img bg-mask flex align-center" style="background-image: url('https://ossweb-img.qq.com/images/lol/web201310/skin/big10006.jpg');height: 414upx;">
|
||||
<view class="padding-xl text-white">
|
||||
<view class="padding-xs text-xxl text-bold">
|
||||
钢铁之翼
|
||||
</view>
|
||||
<view class="padding-xs text-lg">
|
||||
Only the guilty need fear me.
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>视频背景
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-video bg-mask flex align-center" style="height: 422upx;">
|
||||
<video src="https://yz.lol.qq.com/v1/assets/videos/aatrox-splashvideo.webm" autoplay loop muted :show-play-btn="false"
|
||||
:controls="false" objectFit="cover"></video>
|
||||
<cover-view class="padding-xl text-white ">
|
||||
<cover-view class="padding-xs text-xxl text-bold">
|
||||
暗裔剑魔
|
||||
</cover-view>
|
||||
<cover-view class="padding-xs">
|
||||
我必须连同希望一起毁坏……
|
||||
</cover-view>
|
||||
</cover-view>
|
||||
</view> -->
|
||||
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>透明背景(文字层)
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-2">
|
||||
<view class="bg-img padding-bottom-xl" style="background-image: url('https://ossweb-img.qq.com/images/lol/web201310/skin/big10007.jpg');height: 207upx;">
|
||||
<view class="bg-shadeTop padding padding-bottom-xl">
|
||||
上面开始
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-img padding-top-xl flex align-end" style="background-image: url('https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg');height: 207upx;">
|
||||
<view class="bg-shadeBottom padding padding-top-xl flex-sub">
|
||||
下面开始
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ColorList: this.ColorList,
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true"><block slot="backText">返回</block><block slot="content">按钮</block></cu-custom>
|
||||
<view class="cu-bar bg-white solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>按钮形状
|
||||
</view>
|
||||
<view class="action">
|
||||
<navigator class="action" url="design" hover-class="none">
|
||||
<text class="cuIcon-skinfill"></text>
|
||||
<text class="text-df">设计</text>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding flex flex-wrap justify-between align-center bg-white">
|
||||
<button class="cu-btn">默认</button>
|
||||
<button class="cu-btn round">圆角</button>
|
||||
<button class="cu-btn cuIcon">
|
||||
<text class="cuIcon-emojifill"></text>
|
||||
</button>
|
||||
</view>
|
||||
<view class="cu-bar margin-top bg-white solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>按钮尺寸
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding flex flex-wrap justify-between align-center bg-white">
|
||||
<button class="cu-btn round sm">小尺寸</button>
|
||||
<button class="cu-btn round">默认</button>
|
||||
<button class="cu-btn round lg">大尺寸</button>
|
||||
</view>
|
||||
<view class="cu-bar margin-top bg-white">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>按钮颜色
|
||||
</view>
|
||||
<view class="action">
|
||||
<text class="text-df margin-right-sm">阴影</text>
|
||||
<switch @change="SetShadow" :class="shadow?'checked':''" color="#39B54A"></switch>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-5 padding-sm">
|
||||
<view class="margin-tb-sm text-center" v-for="(item,index) in ColorList" :key="index">
|
||||
<button class="cu-btn round" :class="['bg-' + item.name , shadow?'shadow':'']">{{item.title}}</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar margin-top bg-white">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>镂空按钮
|
||||
</view>
|
||||
<view class="action">
|
||||
<radio-group @change="SetBorderSize">
|
||||
<label class="margin-left-sm">
|
||||
<radio class="blue radio" value="" checked></radio>
|
||||
<text class="margin-left-sm">小</text>
|
||||
</label>
|
||||
<label class="margin-left-sm">
|
||||
<radio class="blue radio" value="s"></radio>
|
||||
<text class="margin-left-sm">大</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-5 padding-sm">
|
||||
<view class="margin-tb-sm text-center" v-for="(item,index) in ColorList" :key="index" v-if="item.name!='white'">
|
||||
<button class="cu-btn round" :class="[bordersize?'lines-' + item.name:'line-' + item.name, shadow?'shadow':'']">{{item.title}}</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar margin-top bg-white">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>块状按钮
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding flex flex-direction">
|
||||
<button class="cu-btn bg-grey lg">玄灰</button>
|
||||
<button class="cu-btn bg-red margin-tb-sm lg">嫣红</button>
|
||||
</view>
|
||||
<view class="cu-bar margin-top bg-white">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>无效状态
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding">
|
||||
<button class="cu-btn block bg-blue margin-tb-sm lg" disabled type="">无效状态</button>
|
||||
<button class="cu-btn block line-blue margin-tb-sm lg" disabled>无效状态</button>
|
||||
</view>
|
||||
<view class="cu-bar margin-top bg-white">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>按钮加图标
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding-xl">
|
||||
<button class="cu-btn block line-orange lg">
|
||||
<text class="cuIcon-upload"></text> 图标</button>
|
||||
<button class="cu-btn block bg-blue margin-tb-sm lg">
|
||||
<text class="cuIcon-loading2 cuIconfont-spin"></text> 加载</button>
|
||||
<button class="cu-btn block bg-black margin-tb-sm lg" loading> 原生加载</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ColorList: this.ColorList,
|
||||
shadow: false,
|
||||
bordersize: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
SetShadow(e) {
|
||||
this.shadow = e.detail.value
|
||||
},
|
||||
SetBorderSize(e) {
|
||||
this.bordersize = e.detail.value
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true"><block slot="backText">返回</block><block slot="content"> 按钮 / 设计</block></cu-custom>
|
||||
<view class="padding-xl">
|
||||
<view class="box bg-white text-center radius">
|
||||
<button class="cu-btn" :class="[border?bordersize?'lines-' + color:'line-' + color:'bg-'+ color,round?'round':'',size,shadow?'shadow':'']">我是一个按钮</button>
|
||||
</view>
|
||||
<view class="padding text-center">
|
||||
class="cu-btn <text v-if="color">{{' '}} {{border?bordersize?'lines-' + color:'line-' + color:'bg-'+ color}} {{round?'round':''}} {{size}} {{shadow?'shadow':''}}</text>"
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-form-group margin-top" @tap="showModal" data-target="ColorModal">
|
||||
<view class="title">选择颜色</view>
|
||||
<view class="padding solid radius shadow-blur" :class="'bg-'+color"></view>
|
||||
</view>
|
||||
<view class="cu-form-group">
|
||||
<view class="title">是否圆角</view>
|
||||
<switch @change="SetRound" class="blue" :class="round?'checked':''"></switch>
|
||||
</view>
|
||||
<view class="cu-form-group">
|
||||
<view class="title">选择尺寸</view>
|
||||
<radio-group @change="SetSize">
|
||||
<label class="margin-left-sm">
|
||||
<radio class="blue radio" value="sm"></radio>
|
||||
<text class="margin-left-sm"> 小</text>
|
||||
</label>
|
||||
<label class="margin-left-sm">
|
||||
<radio class="blue radio" value="" checked></radio>
|
||||
<text class="margin-left-sm"> 中</text>
|
||||
</label>
|
||||
<label class="margin-left-sm">
|
||||
<radio class="blue radio" value="lg"></radio>
|
||||
<text class="margin-left-sm"> 大</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<view class="cu-form-group">
|
||||
<view class="title">是否添加阴影</view>
|
||||
<switch @change="SetShadow" :class="shadow?'checked':''"></switch>
|
||||
</view>
|
||||
<view class="cu-form-group">
|
||||
<view class="title">是否镂空</view>
|
||||
<switch @change="SetBorder" :class="border?'checked':''"></switch>
|
||||
</view>
|
||||
<view class="cu-form-group" v-if="border">
|
||||
<view class="title">边框大小</view>
|
||||
<radio-group @change="SetBorderSize">
|
||||
<label class="margin-left-sm">
|
||||
<radio class="blue radio" value="" checked></radio>
|
||||
<text class="margin-left-sm"> 小</text>
|
||||
</label>
|
||||
<label class="margin-left-sm">
|
||||
<radio class="blue radio" value="s"></radio>
|
||||
<text class="margin-left-sm"> 大</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<view class="cu-modal" :class="modalName=='ColorModal'?'show':''">
|
||||
<view class="cu-dialog">
|
||||
<view class="cu-bar justify-end solid-bottom">
|
||||
<view class="content">选择颜色</view>
|
||||
<view class="action" @tap="hideModal">
|
||||
<text class="cuIcon-close text-red"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-5 padding">
|
||||
<view class="padding-xs" v-for="(item,index) in ColorList" :key="index" @tap="SetColor" :data-color="item.name" v-if="item.name!='white'">
|
||||
<view class="padding-tb radius" :class="'bg-' + item.name"> {{item.title}} </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ColorList: this.ColorList,
|
||||
modalName: '',
|
||||
round: false,
|
||||
size: '',
|
||||
color: 'red',
|
||||
shadow: false,
|
||||
border: false,
|
||||
bordersize: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showModal(e) {
|
||||
this.modalName = e.currentTarget.dataset.target
|
||||
},
|
||||
hideModal(e) {
|
||||
this.modalName = null
|
||||
},
|
||||
SetRound(e) {
|
||||
this.round = e.detail.value
|
||||
},
|
||||
SetSize(e) {
|
||||
this.size = e.detail.value
|
||||
},
|
||||
SetColor(e) {
|
||||
this.color = e.currentTarget.dataset.color;
|
||||
this.modalName = null
|
||||
},
|
||||
SetShadow(e) {
|
||||
this.shadow = e.detail.value
|
||||
},
|
||||
SetBorder(e) {
|
||||
this.border = e.detail.value
|
||||
if (!e.detail.value) {
|
||||
this.bordersize = false
|
||||
}
|
||||
},
|
||||
SetBorderSize(e) {
|
||||
this.bordersize = e.detail.value
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,97 @@
|
||||
<template name="basics">
|
||||
<view>
|
||||
<scroll-view scroll-y class="page">
|
||||
<image src="/static/componentBg.png "
|
||||
mode="widthFix" class="response"></image>
|
||||
<view class="nav-list">
|
||||
<navigator hover-class="none" :url="'/pages/basics/' + item.name" class="nav-li" navigateTo :class="'bg-'+item.color"
|
||||
:style="[{animation: 'show ' + ((index+1)*0.2+1) + 's 1'}]" v-for="(item,index) in elements" :key="index">
|
||||
<view class="nav-title">{{item.title}}</view>
|
||||
<view class="nav-name">{{item.name}}</view>
|
||||
<text :class="'cuIcon-' + item.cuIcon"></text>
|
||||
</navigator>
|
||||
</view>
|
||||
<view class="cu-tabbar-height"></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "basics",
|
||||
data() {
|
||||
return {
|
||||
elements: [{
|
||||
title: '布局',
|
||||
name: 'layout',
|
||||
color: 'cyan',
|
||||
cuIcon: 'newsfill'
|
||||
},
|
||||
{
|
||||
title: '背景',
|
||||
name: 'background',
|
||||
color: 'blue',
|
||||
cuIcon: 'colorlens'
|
||||
},
|
||||
{
|
||||
title: '文本',
|
||||
name: 'text',
|
||||
color: 'purple',
|
||||
cuIcon: 'font'
|
||||
},
|
||||
{
|
||||
title: '图标 ',
|
||||
name: 'icon',
|
||||
color: 'mauve',
|
||||
cuIcon: 'cuIcon'
|
||||
},
|
||||
{
|
||||
title: '按钮',
|
||||
name: 'button',
|
||||
color: 'pink',
|
||||
cuIcon: 'btn'
|
||||
},
|
||||
{
|
||||
title: '标签',
|
||||
name: 'tag',
|
||||
color: 'brown',
|
||||
cuIcon: 'tagfill'
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
name: 'avatar',
|
||||
color: 'red',
|
||||
cuIcon: 'myfill'
|
||||
},
|
||||
{
|
||||
title: '进度条',
|
||||
name: 'progress',
|
||||
color: 'orange',
|
||||
cuIcon: 'icloading'
|
||||
},
|
||||
{
|
||||
title: '边框阴影',
|
||||
name: 'shadow',
|
||||
color: 'olive',
|
||||
cuIcon: 'copy'
|
||||
},
|
||||
{
|
||||
title: '加载',
|
||||
name: 'loading',
|
||||
color: 'green',
|
||||
cuIcon: 'loading2'
|
||||
}
|
||||
],
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
console.log("success")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,939 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true"><block slot="backText">返回</block><block slot="content">图标</block></cu-custom>
|
||||
<view class="cu-bar bg-white search fixed" :style="[{top:CustomBar + 'px'}]">
|
||||
<view class="search-form round">
|
||||
<text class="cuIcon-search"></text>
|
||||
<input type="text" placeholder="搜索cuIcon" confirm-type="search" @input="searchIcon"></input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-list grid col-3">
|
||||
<view class="cu-item" v-for="(item,index) in cuIcon" :key="index" v-if="item.isShow">
|
||||
<text class="lg text-gray" :class="'cuIcon-' + item.name"></text>
|
||||
<text>{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
CustomBar: this.CustomBar,
|
||||
cuIcon: [{
|
||||
name: 'appreciate',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'check',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'close',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'edit',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'emoji',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'favorfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'favor',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'loading',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'locationfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'location',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'phone',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundcheckfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundcheck',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundclosefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundclose',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundrightfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundright',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'search',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'taxi',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'timefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'time',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'unfold',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'warnfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'warn',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'camerafill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'camera',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'commentfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'comment',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'likefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'like',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'notificationfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'notification',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'order',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'samefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'same',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'deliver',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'evaluate',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'pay',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'send',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'shop',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'ticket',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'back',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cascades',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'discover',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'list',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'more',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'scan',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'settings',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'questionfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'question',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'shopfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'form',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'pic',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'filter',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'footprint',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'top',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'pulldown',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'pullup',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'right',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'refresh',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'moreandroid',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'deletefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'refund',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cart',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'qrcode',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'remind',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'delete',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'profile',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'home',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cartfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'discoverfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'homefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'message',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'addressbook',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'link',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'lock',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'unlock',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'vip',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'weibo',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'activity',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'friendaddfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'friendadd',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'friendfamous',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'friend',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'goods',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'selection',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'explore',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'present',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'squarecheckfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'square',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'squarecheck',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'round',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundaddfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundadd',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'add',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'notificationforbidfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'explorefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'fold',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'game',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'redpacket',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'selectionfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'similar',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'appreciatefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'infofill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'info',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'forwardfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'forward',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'rechargefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'recharge',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'vipcard',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'voice',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'voicefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'friendfavor',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'wifi',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'share',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'wefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'we',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'lightauto',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'lightforbid',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'lightfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'camerarotate',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'light',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'barcode',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'flashlightclose',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'flashlightopen',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'searchlist',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'service',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'sort',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'down',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'mobile',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'mobilefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'copy',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'countdownfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'countdown',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'noticefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'notice',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'upstagefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'upstage',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'babyfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'baby',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'brandfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'brand',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'choicenessfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'choiceness',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'clothesfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'clothes',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'creativefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'creative',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'female',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'keyboard',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'male',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'newfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'new',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'pullleft',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'pullright',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'rankfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'rank',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'bad',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cameraadd',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'focus',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'friendfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cameraaddfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'apps',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'paintfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'paint',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'picfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'refresharrow',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'colorlens',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'markfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'mark',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'presentfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'repeal',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'album',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'peoplefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'people',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'servicefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'repair',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'file',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'repairfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'taoxiaopu',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'weixin',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'attentionfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'attention',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'commandfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'command',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'communityfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'community',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'read',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'calendar',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cut',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'magic',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'backwardfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'playfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'stop',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'tagfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'tag',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'group',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'all',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'backdelete',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'hotfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'hot',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'post',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'radiobox',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'rounddown',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'upload',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'writefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'write',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'radioboxfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'punch',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'shake',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'move',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'safe',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'activityfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'crownfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'crown',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'goodsfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'messagefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'profilefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'sound',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'sponsorfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'sponsor',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'upblock',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'weblock',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'weunblock',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'my',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'myfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'emojifill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'emojiflashfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'flashbuyfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'text',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'goodsfavor',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'musicfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'musicforbidfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'card',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'triangledownfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'triangleupfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'roundleftfill-copy',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'font',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'title',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'recordfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'record',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cardboardfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cardboard',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'formfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'coin',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cardboardforbid',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'circlefill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'circle',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'attentionforbid',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'attentionforbidfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'attentionfavorfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'attentionfavor',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'titles',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'icloading',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'full',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'mail',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'peoplelist',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'goodsnewfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'goodsnew',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'medalfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'medal',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'newsfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'newshotfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'newshot',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'news',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'videofill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'video',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'exit',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'skinfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'skin',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'moneybagfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'usefullfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'usefull',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'moneybag',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'redpacket_fill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'subscription',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'loading1',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'github',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'global',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'settingsfill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'back_android',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'expressman',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'evaluate_fill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'group_fill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'play_forward_fill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'deliver_fill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'notice_forbid_fill',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'fork',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'pick',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'wenzi',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'ellipse',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'qr_code',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'dianhua',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'cuIcon',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'loading2',
|
||||
isShow: true
|
||||
}, {
|
||||
name: 'btn',
|
||||
isShow: true
|
||||
}]
|
||||
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
searchIcon(e) {
|
||||
let key = e.detail.value.toLowerCase();
|
||||
let list = this.cuIcon;
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let a = key;
|
||||
let b = list[i].name.toLowerCase();
|
||||
if (b.search(a) != -1) {
|
||||
list[i].isShow = true
|
||||
} else {
|
||||
list[i].isShow = false
|
||||
}
|
||||
}
|
||||
this.cuIcon = list
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
padding-top: 50px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true"><block slot="backText">返回</block><block slot="content">布局</block></cu-custom>
|
||||
<scroll-view scroll-x class="bg-white nav text-center fixed" :style="[{top:CustomBar + 'px'}]">
|
||||
<view class="cu-item" :class="index==TabCur?'text-blue cur':''" v-for="(item,index) in tabNav" :key="index" @tap="tabSelect"
|
||||
:data-id="index">
|
||||
{{tabNav[index]}}
|
||||
</view>
|
||||
</scroll-view>
|
||||
<block v-if="TabCur==0">
|
||||
<view class="cu-bar bg-white solid-bottom margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>固定尺寸
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding bg-white">
|
||||
<view class="flex flex-wrap">
|
||||
<view class="basis-xs bg-grey margin-xs padding-sm radius">xs(20%)</view>
|
||||
<view class="basis-df"></view>
|
||||
<view class="basis-sm bg-grey margin-xs padding-sm radius">sm(40%)</view>
|
||||
<view class="basis-df"></view>
|
||||
<view class="basis-df bg-grey margin-xs padding-sm radius">sub(50%)</view>
|
||||
<view class="basis-lg bg-grey margin-xs padding-sm radius">lg(60%)</view>
|
||||
<view class="basis-xl bg-grey margin-xs padding-sm radius">xl(80%)</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>比例布局
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding bg-white">
|
||||
<view class="flex">
|
||||
<view class="flex-sub bg-grey padding-sm margin-xs radius">1</view>
|
||||
<view class="flex-sub bg-grey padding-sm margin-xs radius">1</view>
|
||||
</view>
|
||||
<view class="flex p-xs margin-bottom-sm mb-sm">
|
||||
<view class="flex-sub bg-grey padding-sm margin-xs radius">1</view>
|
||||
<view class="flex-twice bg-grey padding-sm margin-xs radius">2</view>
|
||||
</view>
|
||||
<view class="flex p-xs margin-bottom-sm mb-sm">
|
||||
<view class="flex-sub bg-grey padding-sm margin-xs radius">1</view>
|
||||
<view class="flex-twice bg-grey padding-sm margin-xs radius">2</view>
|
||||
<view class="flex-treble bg-grey padding-sm margin-xs radius">3</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>水平对齐(justify)
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white">
|
||||
<view class="flex solid-bottom padding justify-start">
|
||||
<view class="bg-grey padding-sm margin-xs radius">start</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">start</view>
|
||||
</view>
|
||||
<view class="flex solid-bottom padding justify-end">
|
||||
<view class="bg-grey padding-sm margin-xs radius">end</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">end</view>
|
||||
</view>
|
||||
<view class="flex solid-bottom padding justify-center">
|
||||
<view class="bg-grey padding-sm margin-xs radius">center</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">center</view>
|
||||
</view>
|
||||
<view class="flex solid-bottom padding justify-between">
|
||||
<view class="bg-grey padding-sm margin-xs radius">between</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">between</view>
|
||||
</view>
|
||||
<view class="flex solid-bottom padding justify-around">
|
||||
<view class="bg-grey padding-sm margin-xs radius">around</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">around</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>垂直对齐(align)
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white">
|
||||
<view class="flex solid-bottom padding align-start">
|
||||
<view class="bg-grey padding-lg margin-xs radius">ColorUi</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">start</view>
|
||||
</view>
|
||||
<view class="flex solid-bottom padding align-end">
|
||||
<view class="bg-grey padding-lg margin-xs radius">ColorUi</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">end</view>
|
||||
</view>
|
||||
<view class="flex solid-bottom padding align-center">
|
||||
<view class="bg-grey padding-lg margin-xs radius">ColorUi</view>
|
||||
<view class="bg-grey padding-sm margin-xs radius">center</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="TabCur==1">
|
||||
<view class="cu-bar bg-white margin-top solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>等分列
|
||||
</view>
|
||||
<view class="action"></view>
|
||||
</view>
|
||||
<view class="bg-white padding">
|
||||
<view class="grid margin-bottom text-center" v-for="(item,index) in 5" :key="index" :class="'col-' + (index+1)">
|
||||
<view class="padding" :class="indexs%2==0?'bg-cyan':'bg-blue'" v-for="(item,indexs) in (index+1)*2" :key="indexs">{{indexs+1}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>等高
|
||||
</view>
|
||||
<view class="action"></view>
|
||||
</view>
|
||||
<view class="bg-white padding">
|
||||
<view class="grid col-4 grid-square">
|
||||
<view class="bg-img" v-for="(item,index) in avatar" :key="index" :style="[{ backgroundImage:'url(' + avatar[index] + ')' }]"></view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="TabCur==2">
|
||||
<view class="cu-bar bg-white margin-top solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>浮动
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white padding">
|
||||
<view class=" cf padding-sm">
|
||||
<view class="bg-grey radius fl padding-sm">ColorUi fl</view>
|
||||
<view class="bg-grey radius fr padding-sm">ColorUi fr</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white solid-bottom margin-top solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>内外边距
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white">
|
||||
<view class="padding bg-gray">{size}的尺寸有xs/sm/df/lg/xl</view>
|
||||
<view class="flex flex-wrap padding solid-top">
|
||||
<view class="basis-df padding-bottom-xs">外边距</view>
|
||||
<view class="basis-df padding-bottom-xs">内边距</view>
|
||||
<view class="basis-df">.margin-{size}</view>
|
||||
<view class="basis-df">.padding-{size}</view>
|
||||
</view>
|
||||
<view class="flex flex-wrap padding solid-top">
|
||||
<view class="basis-df padding-bottom-xs">水平方向外边距</view>
|
||||
<view class="basis-df padding-bottom-xs">水平方向内边距</view>
|
||||
<view class="basis-df">.margin-lr-{size}</view>
|
||||
<view class="basis-df">.padding-lr-{size}</view>
|
||||
</view>
|
||||
<view class="flex flex-wrap padding solid-top">
|
||||
<view class="basis-df padding-bottom-xs">垂直方向外边距</view>
|
||||
<view class="basis-df padding-bottom-xs">垂直方向内边距</view>
|
||||
<view class="basis-df">.margin-tb-{size}</view>
|
||||
<view class="basis-df">.padding-tb-{size}</view>
|
||||
</view>
|
||||
<view class="flex flex-wrap padding solid-top">
|
||||
<view class="basis-df padding-bottom-xs">上外边距</view>
|
||||
<view class="basis-df padding-bottom-xs">上内边距</view>
|
||||
<view class="basis-df">.margin-top-{size}</view>
|
||||
<view class="basis-df">.padding-top-{size}</view>
|
||||
</view>
|
||||
<view class="flex flex-wrap padding solid-top">
|
||||
<view class="basis-df padding-bottom-xs">右外边距</view>
|
||||
<view class="basis-df padding-bottom-xs">右内边距</view>
|
||||
<view class="basis-df">.margin-right-{size}</view>
|
||||
<view class="basis-df">.padding-right-{size}</view>
|
||||
</view>
|
||||
<view class="flex flex-wrap padding solid-top">
|
||||
<view class="basis-df padding-bottom-xs">下外边距</view>
|
||||
<view class="basis-df padding-bottom-xs">下内边距</view>
|
||||
<view class="basis-df">margin-bottom-{size}</view>
|
||||
<view class="basis-df">.padding-bottom-{size}</view>
|
||||
</view>
|
||||
<view class="flex flex-wrap padding solid-top">
|
||||
<view class="basis-df padding-bottom-xs">左外边距</view>
|
||||
<view class="basis-df padding-bottom-xs">左内边距</view>
|
||||
<view class="basis-df">.margin-left-{size}</view>
|
||||
<view class="basis-df">.padding-left-{size}</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
CustomBar: this.CustomBar,
|
||||
TabCur: 0,
|
||||
avatar:['https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg','https://ossweb-img.qq.com/images/lol/web201310/skin/big81005.jpg','https://ossweb-img.qq.com/images/lol/web201310/skin/big25002.jpg','https://ossweb-img.qq.com/images/lol/web201310/skin/big99008.jpg'],
|
||||
tabNav: ['Flex布局', 'Grid布局', '辅助布局']
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
tabSelect(e) {
|
||||
this.TabCur = e.currentTarget.dataset.id;
|
||||
this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
padding-top: 45px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true"><block slot="backText">返回</block><block slot="content">加载</block>
|
||||
<block slot="right">
|
||||
<view class="action">
|
||||
<view class="cu-load load-cuIcon" :class="!isLoad?'loading':'over'"></view>
|
||||
</view>
|
||||
</block>
|
||||
</cu-custom>
|
||||
<view class="cu-bar bg-white">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>背景
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-load bg-blue" :class="!isLoad?'loading':'over'"></view>
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>加载状态
|
||||
</view>
|
||||
<view class="action">
|
||||
<switch @change="isLoading" :class="isLoad?'checked':''"></switch>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-load bg-grey" :class="!isLoad?'loading':'over'"></view>
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>加载错误
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-load bg-red erro"></view>
|
||||
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>弹框加载
|
||||
</view>
|
||||
<view class="action">
|
||||
<button class="cu-btn bg-green shadow" @tap="LoadModal">
|
||||
点我
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-load load-modal" v-if="loadModal">
|
||||
<!-- <view class="cuIcon-emojifill text-orange"></view> -->
|
||||
<image src="/static/logo.png" mode="aspectFit"></image>
|
||||
<view class="gray-text">加载中...</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>进度条加载
|
||||
</view>
|
||||
<view class="action">
|
||||
<button class="cu-btn bg-green shadow" @tap="LoadProgress">
|
||||
点我
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="load-progress" :class="loadProgress!=0?'show':'hide'" :style="[{top:CustomBar+'px'}]">
|
||||
<view class="load-progress-bar bg-green" :style="[{transform: 'translate3d(-' + (100-loadProgress) + '%, 0px, 0px)'}]"></view>
|
||||
<view class="load-progress-spinner text-green"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
CustomBar: this.CustomBar,
|
||||
isLoad:false,
|
||||
loadModal: false,
|
||||
loadProgress: 0
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isLoading(e) {
|
||||
this.isLoad = e.detail.value;
|
||||
},
|
||||
LoadModal(e) {
|
||||
this.loadModal = true;
|
||||
setTimeout(() => {
|
||||
this.loadModal = false;
|
||||
}, 2000)
|
||||
},
|
||||
LoadProgress(e) {
|
||||
this.loadProgress = this.loadProgress + 3;
|
||||
if (this.loadProgress < 100) {
|
||||
setTimeout(() => {
|
||||
this.LoadProgress();
|
||||
}, 100)
|
||||
} else {
|
||||
this.loadProgress = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<view>
|
||||
<cu-custom bgColor="bg-gradual-blue" :isBack="true"><block slot="backText">返回</block><block slot="content">进度条</block></cu-custom>
|
||||
<view class="cu-bar bg-white solid-bottom">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>进度条形状
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding bg-white">
|
||||
<view class="cu-progress">
|
||||
<view class="bg-red" :style="[{ width:loading?'61.8%':''}]">61.8%</view>
|
||||
</view>
|
||||
<view class="cu-progress radius margin-top">
|
||||
<view class="bg-red" :style="[{ width:loading?'61.8%':''}]">61.8%</view>
|
||||
</view>
|
||||
<view class="cu-progress round margin-top">
|
||||
<view class="bg-red" :style="[{ width:loading?'61.8%':''}]">61.8%</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white solid-bottom margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>进度条尺寸
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding bg-white">
|
||||
<view class="cu-progress round">
|
||||
<view class="bg-red" :style="[{ width:loading?'61.8%':''}]"></view>
|
||||
</view>
|
||||
<view class="cu-progress round margin-top sm">
|
||||
<view class="bg-red" :style="[{ width:loading?'61.8%':''}]"></view>
|
||||
</view>
|
||||
<view class="cu-progress round margin-top xs">
|
||||
<view class="bg-red" :style="[{ width:loading?'61.8%':''}]"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cu-bar bg-white solid-bottom margin-top" @tap="showModal" data-target="ColorModal">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>进度条颜色
|
||||
</view>
|
||||
<view class="action">
|
||||
<view class="padding solid radius shadow-blur" :class="'bg-' + color"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding" :class="color=='white'?'bg-grey':'bg-white'">
|
||||
<view class="cu-progress round">
|
||||
<view :class="'bg-' + color" :style="[{ width:loading?'61.8%':''}]"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="cu-bar bg-white solid-bottom margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>进度条条纹
|
||||
</view>
|
||||
<switch class="margin-right-sm" :class="active?'checked':''" @change="SetActive"></switch>
|
||||
</view>
|
||||
<view class="padding bg-white">
|
||||
<view class="cu-progress round sm striped" :class="active?'active':''">
|
||||
<view class="bg-green" :style="[{ width:loading?'60%':''}]"></view>
|
||||
</view>
|
||||
<view class="cu-progress round sm margin-top-sm striped" :class="active?'active':''">
|
||||
<view class="bg-black" :style="[{ width:loading?'40%':''}]"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white solid-bottom margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>进度条比例
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding bg-white">
|
||||
<view class="cu-progress radius striped active">
|
||||
<view class="bg-red" :style="[{ width:loading?'30%':''}]">30%</view>
|
||||
<view class="bg-olive" :style="[{ width:loading?'45%':''}]">45%</view>
|
||||
<view class="bg-cyan" :style="[{ width:loading?'25%':''}]">25%</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cu-bar bg-white solid-bottom margin-top">
|
||||
<view class="action">
|
||||
<text class="cuIcon-title text-blue"></text>进度条布局
|
||||
</view>
|
||||
</view>
|
||||
<view class="padding bg-white ">
|
||||
<view class="flex">
|
||||
<view class="cu-progress round">
|
||||
<view class="bg-green" :style="[{ width:loading?'100%':''}]"></view>
|
||||
</view>
|
||||
<text class="cuIcon-roundcheckfill text-green margin-left-sm"></text>
|
||||
</view>
|
||||
<view class="flex margin-top">
|
||||
<view class="cu-progress round">
|
||||
<view class="bg-green" :style="[{ width:loading?'80%':''}]"></view>
|
||||
</view>
|
||||
<text class="margin-left">80%</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cu-modal" :class="modalName=='ColorModal'?'show':''">
|
||||
<view class="cu-dialog">
|
||||
<view class="cu-bar justify-end solid-bottom">
|
||||
<view class="content">选择颜色</view>
|
||||
<view class="action" @tap="hideModal">
|
||||
<text class="cuIcon-close text-red"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid col-5 padding">
|
||||
<view class="padding-xs" v-for="(item,index) in ColorList" :key="index" @tap="SetColor" :data-color="item.name" v-if="item.name!='gray' && item.name!='white'">
|
||||
<view class="padding-tb radius" :class="'bg-' + item.name"> {{item.title}} </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ColorList: this.ColorList,
|
||||
color: 'red',
|
||||
loading: false,
|
||||
modalName: '',
|
||||
active: false
|
||||
};
|
||||
},
|
||||
onLoad: function() {
|
||||
let that = this;
|
||||
setTimeout(function() {
|
||||
that.loading = true
|
||||
}, 500)
|
||||
},
|
||||
methods: {
|
||||
showModal(e) {
|
||||
this.modalName = e.currentTarget.dataset.target
|
||||
},
|
||||
hideModal(e) {
|
||||
this.modalName = null
|
||||
},
|
||||
SetColor(e) {
|
||||
this.color = e.currentTarget.dataset.color;
|
||||
this.modalName = null
|
||||
},
|
||||
SetActive(e) {
|
||||
this.active = e.detail.value
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue