commit 85d1e7efbfed37751e27797362ed1f0782b4318c Author: zmt Date: Fri Feb 11 14:20:28 2022 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a3b95a5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +.DS_Store +node_modules/ +unpackage/ +dist/ +pageTemp.vue +.hbuilderx/ + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.project +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..5fc7797 --- /dev/null +++ b/App.vue @@ -0,0 +1,21 @@ + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..40eb1fc --- /dev/null +++ b/README.md @@ -0,0 +1,128 @@ + + + + + +## 1、全局路由守卫 + +##### (1) 路由拦截 +[uni-simple-router](https://hhyang.cn/) 路由、拦截、最优雅的解决方案 + +##### (2) 路由配置 +通过 vue.config.js 配合[uni-read-pages](https://github.com/SilurianYang/uni-read-pages),可以随心所欲的读取 pages.json 下的所有配置 + + +## 2、Request封装 + 适用于一项目多域名请求、七牛云图片上传、本地服务器图片上传、支持 Promise. + +## 3、api集中管理 +api集中管理; 为简化逻辑代码量整洁的原则,像调用函数一样调用api,做到代码分离,在apis目录统一创建api函数 + +## 4、小程序更新提示代码,配置分包,等必备代码 +sub目录分包管理 由于微信小程序的限制,上传发布机制总包大小不能大于2m,所以项目若超出该限制,要在page.json中做分包处理,分包处理的配置与pages目录保持一致,封装更新提示代码 + +## 5、配置vuex +不需要引入每个子store模块 + +```javascript +import Vue from "vue"; +import Vuex from "vuex"; + +Vue.use(Vuex); +const files = require.context("./modules", false, /\.js$/); +let modules = { + state: {}, + mutations: {}, + actions: {} +}; + +files.keys().forEach((key) => { + Object.assign(modules.state, files(key)["state"]); + Object.assign(modules.mutations, files(key)["mutations"]); + Object.assign(modules.actions, files(key)["actions"]); +}); +const store = new Vuex.Store(modules); +export default store; +``` +页面使用Vuex + +```javascript +import { mapState,mapActions } from 'vuex'; + +computed: { + ...mapState(['userInfo']) + } +methods: { + ...mapActions(['getUserInfo']) + } + +``` + +通用的mutations方法,只需要写一个就行了 + +```javascript + //更新state数据 + setStateAttr(state, param) { + if (param instanceof Array) { + for (let item of param) { + state[item.key] = item.val; + } + } else { + state[param.key] = param.val; + } + } +``` +actions调用 + +```javascript + async setUserData({ + state, + commit + }, data) { + commit('setStateAttr', { + key: 'userInfo', + val: data + }) + uni.setStorageSync('userInfo', data); + }, +``` + +## 6、全局过滤器filters +main.js引入filters,使用如下 +```javascript +{{shop.shopAddress|autoAddPoints}} +``` + +## 7、无关系组件间的通信=>事件车 +> 事件车的基本原理就是在本项目Vue的原型对象里新生成一个Vue对象专门用来负责无关系,跨级组件间的通信 + +main.js声明事件bus +```javascript +Vue.prototype.$bus = new Vue() // event Bus 用于无关系组件间的通信。 +``` +A组件 监听($on) + +```javascript +// onload 里面 + this.$bus.$on('updateChecked', this.updateChecked) + +// methods 里面 +updateChecked(index){ + console.log('这里就拿到了跨级组件的index',index) + } +``` +B组件 触发($emit) +> B组件触发A组件的updateChecked 传index值给A组件 +```javascript + this.$bus.$emit('updateChecked', index); +``` + +## [github源码下载](https://github.com/mgbq/uni-template) + +## [插件市场源码](https://ext.dcloud.net.cn/plugin?id=4008) + +## 常见问题 +#### 1 运行不了,控制台报错,请安装依赖 + +```npm install ``` + diff --git a/components/nx-search/nx-search.vue b/components/nx-search/nx-search.vue new file mode 100644 index 0000000..f7ed77b --- /dev/null +++ b/components/nx-search/nx-search.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/main.js b/main.js new file mode 100644 index 0000000..5c5c477 --- /dev/null +++ b/main.js @@ -0,0 +1,33 @@ +import Vue from "vue"; +import App from "./App"; +import { + router, + RouterMount +} from "@/nxTemp/router"; +import store from "@/nxTemp/store"; +import uView from "@/uview-ui"; +import nxTemp from "@/nxTemp"; + + +async function bootstrap() { + App.mpType = "app"; + //引入路由 + Vue.use(router); + // 引入全局uView + Vue.use(uView); + // 加载nxTemp + Vue.use(nxTemp); + + const app = new Vue({ + store, + ...App + }); + // #ifdef H5 + RouterMount(app, router, "#app"); + // #endif + // #ifndef H5 + app.$mount(); + // #endif +} + +bootstrap(); diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..a71bf42 --- /dev/null +++ b/manifest.json @@ -0,0 +1,85 @@ +{ + "name" : "events-helper", + "appid" : "", + "description" : "", + "versionName" : "1.0.0", + "versionCode" : "100", + "transformPx" : false, + "app-plus" : { + "usingComponents" : true, + "nvueCompiler" : "uni-app", + "compilerVersion" : 3, + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + "modules" : {}, + "distribute" : { + "android" : { + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "ios" : {}, + "sdkConfigs" : {} + } + }, + "quickapp" : {}, + "mp-weixin" : { + "appid" : "wxacdbba29503f6351", + "setting" : { + "urlCheck" : false, + "minified" : false, + "es6" : true + }, + "optimization" : { + "subPackages" : true + }, + "usingComponents" : true + }, + "mp-alipay" : { + "usingComponents" : true + }, + "mp-baidu" : { + "usingComponents" : true + }, + "mp-toutiao" : { + "usingComponents" : true + }, + "uniStatistics" : { + "enable" : false + }, + "h5" : { + "template" : "template.h5.html", + "router" : { + "mode" : "history", + "base" : "" + }, + "devServer" : { + "https" : false + } + } +} diff --git a/nxTemp/apis/userAPI.js b/nxTemp/apis/userAPI.js new file mode 100644 index 0000000..c01a2e1 --- /dev/null +++ b/nxTemp/apis/userAPI.js @@ -0,0 +1,30 @@ +import http from '@/nxTemp/config/requestConfig' +import config from "@/nxTemp/config/index.config.js"; + +// 用户登录 +export function postLogin(data) { + return http.post(`${config.baseUrl}/gaMatchAssistant/login`, data ,{ + needLogin:false + }); +} + +//发送验证码 +export function postSendSMS(data) { + return http.post(`${config.baseUrl}/gaMatchAssistant/captchaSms/send`, data); +} + +/** +* @description: 小程序授权手机号码 +* @param + code: loginRes.code, + appid: this.APPID, + encryptedData: e.detail.encryptedData, + iv: e.detail.iv, +* @return: {*} +* @author: +*/ +export function wechatGetPhoneNumber(data) { + return http.post(`${config.baseUrl}/user/wechatGetPhoneNumber`, data); +} + + diff --git a/nxTemp/config/index.config.js b/nxTemp/config/index.config.js new file mode 100644 index 0000000..cda907b --- /dev/null +++ b/nxTemp/config/index.config.js @@ -0,0 +1,30 @@ +const CONFIG = { + //开发环境配置 + development: { + loginTitleTxt: "development_wx", // 登录页标题 + copyrightTxt: "XXXv1.0", // 版本信息 + assetsPath: "http://cdn.com/img", // 静态资源路径 + baseUrl: "http://testmanager.ouxuanzhineng.cn", + tokenKey: "wxf368fa7316d6952f", // 登录标识 + testOpenId: "", // 小程序测试openId + forcedLogin: false, // touristMode游客模式下APP是否强制用户登录 场景:当用户进入登录页面后无法后退。 + touristMode: true, // APP是否开启游客模式, 游客模式true开启:APP打开后可以进入首页和无权限的页面,游客模式false关闭:APP打开后首先需要登录才能进入, 此时forcedLogin配置项失效。 + showLog:true, //是否开启log + }, + + //生产环境配置 + production: { + loginTitleTxt: "production_wx", // 登录页标题 + copyrightTxt: "XXXv1.0", // 版本信息 + assetsPath: "/static/img", // 静态资源路径 + baseUrl: "http://testmanager.ouxuanzhineng.cn", + tokenKey: "WECHAT_TRADE", // 登录标识 + testOpenId: "wxf368fa7316d6952f", // 小程序测试openId + forcedLogin: false, // touristMode游客模式下APP是否强制用户登录 场景:当用户进入登录页面后无法后退。 + touristMode: true, // APP是否开启游客模式, 游客模式true开启:APP打开后可以进入首页和无权限的页面,游客模式false关闭:APP打开后首先需要登录才能进入, 此时forcedLogin配置项失效。 + showLog:true, //是否开启log + } + +} + +export default CONFIG[process.env.NODE_ENV]; diff --git a/nxTemp/config/requestConfig.js b/nxTemp/config/requestConfig.js new file mode 100644 index 0000000..cbad30b --- /dev/null +++ b/nxTemp/config/requestConfig.js @@ -0,0 +1,278 @@ +import request from "@/nxTemp/request"; +import store from '@/nxTemp/store'; +import config from '@/nxTemp/config/index.config.js'; + +//可以new多个request来支持多个域名请求 +let $http = new request({ + //接口请求地址 + baseUrl: config.baseUrl, + //服务器本地上传文件地址 + fileUrl: config.baseUrl, + // 服务器上传图片默认url + defaultUploadUrl: "api/common/v1/upload_image", + //设置请求头(如果使用报错跨域问题,可能是content-type请求类型和后台那边设置的不一致) + header: { + 'Content-Type': 'application/json;charset=UTF-8', + // 'project_token': config.projectToken, //项目token(可删除) + } +}); +// 添加获取七牛云token的方法 +$http.getQnToken = function(callback) { + //该地址需要开发者自行配置(每个后台的接口风格都不一样) + $http.get("api/common/v1/qn_upload").then(data => { + /* + *接口返回参数: + *visitPrefix:访问文件的域名 + *token:七牛云上传token + *folderPath:上传的文件夹 + *region: 地区 默认为:SCN + */ + callback({ + visitPrefix: data.visitPrefix, + token: data.token, + folderPath: data.folderPath + }); + }); +} +//请求开始拦截器 +$http.requestStart = function(options) { + // console.log("请求开始", options); + if (options.load) { + //打开加载动画 + store.commit("setLoadingShow", true); + } + // 图片上传大小限制 + if (options.method == "FILE" && options.maxSize) { + // 文件最大字节: options.maxSize 可以在调用方法的时候加入参数 + let maxSize = options.maxSize; + for (let item of options.files) { + if (item.size > maxSize) { + setTimeout(() => { + uni.showToast({ + title: "图片过大,请重新上传", + icon: "none" + }); + }, 500); + return false; + } + } + } + + //请求前加入token & token验证 + if (options.url) { + if (options.needLogin) { + let token = uni.getStorageSync('token'); + if (!token) { + store.dispatch('reLogin', '');//无token时,触发重新登录 + console.error(options.url,"缺少token,触发重新登录",options); + } else { + options.header['token'] = token; //header中带上token + options.data['token'] = token; //请求data中带上token + } + } + } + // if (options.url) { + // //请求前加入token + // let url = options.url.substring(options.url.lastIndexOf('/') + 1); + // if (url != 'login') { + // let token = uni.getStorageSync('token'); + // if (!token) { + // console.log(url,"缺少token",options); + // store.dispatch('reLogin', ''); + // } else { + // options.header['token'] = uni.getStorageSync('token'); + // } + // } + // } + + + return options; +} +//请求结束 +$http.requestEnd = function(options) { + //判断当前接口是否需要加载动画 + if (options.load) { + // 关闭加载动画 + store.commit("setLoadingShow", false); + } +} +//所有接口数据处理(此方法需要开发者根据各自的接口返回类型修改,以下只是模板) +$http.dataFactory = async function(res) { + + //显示调试信息 + if(config.showLog){ + // console.log("接口请求数据", { + // url: res.url, + // resolve: res.response, + // header: res.header, + // data: res.data, + // method: res.method, + // }); + console.log("requestConfig:",res); + showLog(res.data,res.url,res.response) + } + + //验证需登录接口状态并给与提示 + if(res.needLogin&&!res.data.token){ + return Promise.reject({ + statusCode: 0, + errMsg: "requestConfig.js:该接口需登录后调用,请检查userAPI配置及逻辑", + data: res.url + }); + } + + if (res.response.statusCode && res.response.statusCode == 200) { + let httpData = res.response.data; + if (typeof(httpData) == "string") { + httpData = JSON.parse(httpData); + } + /*********以下只是模板(及共参考),需要开发者根据各自的接口返回类型修改*********/ + + //判断数据是否请求成功 + // if (httpData.success || httpData.code == 200) { + if (httpData.code == 0) { + // 返回正确的结果(then接受数据) + return Promise.resolve(httpData.data); + } else if (httpData.code == "1000" || httpData.code == "1001" || httpData.code == 1100 || httpData.code == 402) { + + // 失败重新请求(最多重新请求3次) + // if(res.resend < 3){ + // let result = await $http.request({ + // url: res.url, + // data: res.data, + // method: res.method, + // header: res.header, + // isPrompt: res.isPrompt,//(默认 true 说明:本接口抛出的错误是否提示) + // load: res.load,//(默认 true 说明:本接口是否提示加载动画) + // isFactory: res.isFactory, //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数将失去作用) + // resend: res.resend += 1 // 当前重发次数 + // }); + // // 返回正确的结果(then接受数据) + // return Promise.resolve(result); + // } + // 返回错误的结果(catch接受数据) + // return Promise.reject({ + // statusCode: 0, + // errMsg: "【request】" + (httpData.info || httpData.msg) + // }); + + //----------------------------------------分割线--------------------------------------------------- + + // 刷新token在重新请求(最多重新请求2次) + // if(res.resend < 2){ + // let tokenResult = await $http.request({ + // url: "http://localhost:7001/api/common/v1/protocol", // 获取token接口地址 + // data: { + // type: 1000 + // }, // 获取接口参数 + // method: "GET", + // load: false,//(默认 true 说明:本接口是否提示加载动画) + // }); + // // 储存token + // store.commit("userInfo", tokenResult); + // let result = await $http.request({ + // url: res.url, + // data: res.data, + // method: res.method, + // header: res.header, + // isPrompt: res.isPrompt,//(默认 true 说明:本接口抛出的错误是否提示) + // load: res.load,//(默认 true 说明:本接口是否提示加载动画) + // isFactory: res.isFactory, //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数将失去作用) + // resend: res.resend += 1 // 当前重发次数 + // }); + // // 返回正确的结果(then接受数据) + // return Promise.resolve(result); + // } + // 返回错误的结果(catch接受数据) + // return Promise.reject({ + // statusCode: 0, + // errMsg: "【request】" + (httpData.info || httpData.msg) + // }); + + + store.commit("emptyUserInfo"); + // #ifdef MP-WEIXIN + // onLogin();跳转登录页面 + // #endif + + + // 返回错误的结果(catch接受数据) + return Promise.reject({ + statusCode: 0, + errMsg: "【request】" + (httpData.info || httpData.msg), + data: res.data + }); + } else if (httpData.code == "401") { // token失效 + + uni.showToast({ + title: "登录状态失效请重新登录", + icon: "none" + }); + + + // 返回错误的结果(catch接受数据) + // return Promise.reject({ + // statusCode: 0, + // errMsg: "【request】" + (httpData.info || httpData.msg), + // data: res.data + // }); + } else { //其他错误提示 + if (res.isPrompt) { + uni.showToast({ + title: httpData.info || httpData.msg|| httpData.message, + icon: "none", + duration: 3000 + }); + } + // 返回错误的结果(catch接受数据) + return Promise.reject({ + statusCode: 0, + errMsg: "【request】" + (httpData.info || httpData.msg|| httpData.message), + data: res.data + }); + } + + /*********以上只是模板(及共参考),需要开发者根据各自的接口返回类型修改*********/ + + } else { + // 返回错误的结果(catch接受数据) + return Promise.reject({ + statusCode: res.response.statusCode, + errMsg: "【request】数据工厂验证不通过", + data: res.data + }); + } +}; +// 错误回调 +$http.requestError = function(e) { + // e.statusCode === 0 是参数效验错误抛出的 + console.log("-requestError-"); + if (e.statusCode === 0) { + throw e; + } else { + console.log(e); + uni.showToast({ + title: "网络错误,请检查一下网络", + icon: "none" + }); + } +} +function showLog(data,url,response){ + let weburl = getWebURL(data,url) + let temp = url.split("?")[0].split("/") + let postName = temp[temp.length-1] + console.warn("-------------------->> ["+postName+"][log]\n" + +"请求 Data: \n" + JSON.stringify(data) + +"\n URL:\n"+weburl + +"\n 服务端返回:\n"+JSON.stringify(response.data) + +"\n <<-------------------- ["+postName+"][log] ↑↑↑\n") +} + +function getWebURL(data,url){ + let result = "" + for(var i in data){ + result+=`&${i}=${data[i]}` + } + return url+"?"+result.slice(1) +} +export default $http; diff --git a/nxTemp/filter/index.js b/nxTemp/filter/index.js new file mode 100644 index 0000000..ea9d788 --- /dev/null +++ b/nxTemp/filter/index.js @@ -0,0 +1,11 @@ + +// 自动添加省略号 +export function autoAddPoints(address) { + if (address && address.length > 17) { + return '...'.padStart(17, address); + } else { + return address; + } + +} + diff --git a/nxTemp/index.js b/nxTemp/index.js new file mode 100644 index 0000000..4e0afe6 --- /dev/null +++ b/nxTemp/index.js @@ -0,0 +1,26 @@ +import store from '@/nxTemp/store'; +import wechat from '@/nxTemp/wechat/wechat'; +import tools from '@/nxTemp/utils/tools' +import * as filter from '@/nxTemp/filter'; +const install = Vue => { + // global filter + Object.keys(filter).forEach(item => { + Vue.filter(item, filter[item]); + }); + // 挂载函数 + Vue.prototype.$store = store; + Vue.prototype.$tools = tools; + // event Bus 用于无关系组件间的通信。 + Vue.prototype.$bus = new Vue() +} + +export async function init(options) { + // #ifdef MP-WEIXIN + // 检测小程序更新(如果从朋友圈场景进入则无此API) + options.scene !== 1154 && wechat.checkMiniProgramUpdate(); + // #endif +} + +export default { + install +} diff --git a/nxTemp/request/core/request.js b/nxTemp/request/core/request.js new file mode 100644 index 0000000..f6c8912 --- /dev/null +++ b/nxTemp/request/core/request.js @@ -0,0 +1,129 @@ +import { mergeConfig, dispatchRequest, jsonpRequest} from "./utils.js"; +export default class request { + constructor(options) { + //请求公共地址 + this.baseUrl = options.baseUrl || ""; + //公共文件上传请求地址 + this.fileUrl = options.fileUrl || ""; + // 服务器上传图片默认url + this.defaultUploadUrl = options.defaultUploadUrl || ""; + //默认请求头 + this.header = options.header || {}; + //默认配置 + this.config = options.config || { + isPrompt: true, + load: false, + isFactory: true, + resend: 0, + needLogin:true,//默认所有接口需要登录验证,不需登录验证的如login接口需传参false声明 + }; + } + //post请求 + post(url = '', data = {}, options = {}) { + return this.request({ + method: "POST", + data: data, + url: url, + ...options + }); + } + + //get请求 + get(url = '', data = {}, options = {}) { + return this.request({ + method: "GET", + data: data, + url: url, + ...options + }); + } + + //put请求 + put(url = '', data = {}, options = {}) { + return this.request({ + method: "PUT", + data: data, + url: url, + ...options + }); + } + + //delete请求 + delete(url = '', data = {}, options = {}) { + return this.request({ + method: "DELETE", + data: data, + url: url, + ...options + }); + } + //jsonp请求(只限于H5使用) + jsonp(url = '', data = {}, options = {}) { + return this.request({ + method: "JSONP", + data: data, + url: url, + ...options + }); + } + //接口请求方法 + async request(data) { + // 请求数据 + let requestInfo, + // 是否运行过请求开始钩子 + runRequestStart = false; + try { + if (!data.url) { + throw { errMsg: "【request】缺失数据url", statusCode: 0} + } + // 数据合并 + requestInfo = mergeConfig(this, data); + // 代表之前运行到这里 + runRequestStart = true; + //请求前回调 + if (this.requestStart) { + let requestStart = this.requestStart(requestInfo); + if (typeof requestStart == "object") { + let changekeys = ["data", "header", "isPrompt", "load", "isFactory"]; + changekeys.forEach(key => { + requestInfo[key] = requestStart[key]; + }); + } else { + throw { + errMsg: "【request】请求开始拦截器未通过", + statusCode: 0, + data: requestInfo.data, + method: requestInfo.method, + header: requestInfo.header, + url: requestInfo.url, + } + } + } + let requestResult = {}; + if(requestInfo.method == "JSONP"){ + requestResult = await jsonpRequest(requestInfo); + } else { + requestResult = await dispatchRequest(requestInfo); + } + //是否用外部的数据处理方法 + if (requestInfo.isFactory && this.dataFactory) { + //数据处理 + let result = await this.dataFactory({ + ...requestInfo, + response: requestResult + }); + return Promise.resolve(result); + } else { + return Promise.resolve(requestResult); + } + } catch (err){ + this.requestError && this.requestError(err); + return Promise.reject(err); + } finally { + // 如果请求开始未运行到,请求结束也不运行 + if(runRequestStart){ + this.requestEnd && this.requestEnd(requestInfo); + } + } + } +} diff --git a/nxTemp/request/core/utils.js b/nxTemp/request/core/utils.js new file mode 100644 index 0000000..a45a7dc --- /dev/null +++ b/nxTemp/request/core/utils.js @@ -0,0 +1,84 @@ +// 获取合并的数据 +export const mergeConfig = function(_this, options) { + //判断url是不是链接 + let urlType = /^(http|https):\/\//.test(options.url); + let config = Object.assign({}, _this.config, options); + if (options.method == "FILE") { + config.url = urlType ? options.url : _this.fileUrl + options.url; + } else { + config.url = urlType ? options.url : _this.baseUrl + options.url; + } + //请求头 + if (options.header) { + config.header = Object.assign({}, _this.header, options.header); + } else { + config.header = _this.header; + } + return config; +} +// 请求 +export const dispatchRequest = function(requestInfo) { + return new Promise((resolve, reject) => { + let requestData = { + url: requestInfo.url, + header: requestInfo.header, //加入请求头 + success: (res) => { + resolve(res); + }, + fail: (err) => { + reject(err); + } + }; + //请求类型 + if (requestInfo.method) { + requestData.method = requestInfo.method; + } + if (requestInfo.data) { + requestData.data = requestInfo.data; + } + // #ifdef MP-WEIXIN || MP-ALIPAY + if (requestInfo.timeout) { + requestData.timeout = requestInfo.timeout; + } + // #endif + if (requestInfo.dataType) { + requestData.dataType = requestInfo.dataType; + } + // #ifndef APP-PLUS || MP-ALIPAY + if (requestInfo.responseType) { + requestData.responseType = requestInfo.responseType; + } + // #endif + // #ifdef H5 + if (requestInfo.withCredentials) { + requestData.withCredentials = requestInfo.withCredentials; + } + // #endif + uni.request(requestData); + }) +} +// jsonp请求 +export const jsonpRequest = function(requestInfo) { + return new Promise((resolve, reject) => { + let dataStr = ''; + Object.keys(requestInfo.data).forEach(key => { + dataStr += key + '=' + requestInfo.data[key] + '&'; + }); + //匹配最后一个&并去除 + if (dataStr !== '') { + dataStr = dataStr.substr(0, dataStr.lastIndexOf('&')); + } + requestInfo.url = requestInfo.url + '?' + dataStr; + let callbackName = "callback" + Math.ceil(Math.random() * 1000000); + // #ifdef H5 + window[callbackName] = function(data) { + resolve(data); + } + let script = document.createElement("script"); + script.src = requestInfo.url + "&callback=" + callbackName; + document.head.appendChild(script); + // 及时删除,防止加载过多的JS + document.head.removeChild(script); + // #endif + }); +} \ No newline at end of file diff --git a/nxTemp/request/index.js b/nxTemp/request/index.js new file mode 100644 index 0000000..6f3b951 --- /dev/null +++ b/nxTemp/request/index.js @@ -0,0 +1,7 @@ +/***************纯粹的数据请求(如果使用这种可以删除掉fileUpload.js)******************/ +// import request from "./core/request.js"; +// export default request; + +/********数据请求同时继承了文件上传(包括七牛云上传)************/ +import upload from "./upload/upload.js"; +export default upload; \ No newline at end of file diff --git a/nxTemp/request/request.md b/nxTemp/request/request.md new file mode 100644 index 0000000..fc0c838 --- /dev/null +++ b/nxTemp/request/request.md @@ -0,0 +1,313 @@ +# request请求、配置简单、批量上传图片、视频、超强适应性(支持多域名请求) +1. 配置简单、源码清晰注释多、适用于一项目多域名请求、第三方请求、七牛云图片上传、本地服务器图片上传等等 +2. 支持请求`get`、`post`、`put`、`delete` +3. 自动显示请求加载动画(可单个接口关闭) +4. 全局`api`数据处理函数,只回调请求正确的数据(可单个接口关闭) +5. 未登录或登录失效自动拦截并调用登录方法(可单个接口关闭) +6. 全局自动提示接口抛出的错误信息(可单个接口关闭) +7. 支持 Promise +8. 支持拦截器 +9. 支持七牛云文件(图片、视频)批量上传 +10. 支持本地服务器文件(图片、视频)批量上传 +11. 支持上传文件拦截过滤 +12. 支持上传文件进度监听 +13. 支持上传文件单张成功回调 + +### 常见问题 +1.接口请求成功了,没有返回数据或者数据是走的catch回调 + +答:`requestConfig.js` 请求配置文件里面,有一个`$http.dataFactory`方法,里面写的只是参考示例,`此方法需要开发者根据各自的接口返回类型修改` + +2.官方的方法有数据,本插件方法请求报错跨域问题 + +答:`requestConfig.js` 请求配置文件里面,`header`请求头设置的`content-type`请求类型需求和后台保持一致 + +3.登录后用户`token`怎么设置? + +答:`requestConfig.js` 请求配置文件里面,`$http.requestStart`请求开始拦截器里面设置 + +4.怎么判断上传的文件(图片)太大?怎么过滤掉太大的文件(图片)? + +答:`requestConfig.js` 请求配置文件里面,`$http.requestStart`请求开始拦截器里面设置 + +### 本次更新注意事项 +1. 所有的headers都改成了header(和官方统一) +2. 七牛云的获取token等信息提取到了`requestConfig.js`文件,参考如下 + +``` +// 添加获取七牛云token的方法 +$http.getQnToken = function(callback){ + //该地址需要开发者自行配置(每个后台的接口风格都不一样) + $http.get("api/kemean/aid/qn_upload").then(data => { + /* + *接口返回参数: + *visitPrefix:访问文件的域名 + *token:七牛云上传token + *folderPath:上传的文件夹 + *region: 地区 默认为:SCN + */ + callback({ + visitPrefix: data.visitPrefix, + token: data.token, + folderPath: data.folderPath, + region: "SCN" + }); + }); +} +``` + +### 文件说明 +1. `request => core` 请求方法的目录 +2. `request => core => request.js` 请求方法的class文件 +3. `request => core => utils.js` 请求方法的源码文件 +4. `request => upload` 上传方法的目录 +5. `request => upload => upload.js` 上传方法的class文件 +6. `request => upload => utils.js` 上传方法源码文件 +7. `request => upload => qiniuUploader.js` 七牛云官方上传文件 +8. `request => index.js` 输出方法的文件 +9. `requestConfig.js` 请求配置文件(具体看代码) + +### 在main.js引入并挂在Vue上 +``` +import $http from '@/zhouWei-request/requestConfig'; +Vue.prototype.$http = $http; +``` + +### 通用请求方法 +``` +this.$http.request({ + url: 'aid/region', + method: "GET", // POST、GET、PUT、DELETE、JSONP,具体说明查看官方文档 + data: {pid:0}, + timeout: 30000, // 默认 30000 说明:超时时间,单位 ms,具体说明查看官方文档 + dataType: "json", // 默认 json 说明:如果设为 json,会尝试对返回的数据做一次 JSON.parse,具体说明查看官方文档 + responseType: "text", // 默认 text 说明:设置响应的数据类型。合法值:text、arraybuffer,具体说明查看官方文档 + withCredentials: false, // 默认 false 说明:跨域请求时是否携带凭证(cookies),具体说明查看官方文档 + isPrompt: true,//(默认 true 说明:本接口抛出的错误是否提示) + load: true,//(默认 true 说明:本接口是否提示加载动画) + header: { //默认 无 说明:请求头 + 'Content-Type': 'application/json' + }, + isFactory: true, //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数将失去作用) +}).then(function (response) { + //这里只会在接口是成功状态返回 +}).catch(function (error) { + //这里只会在接口是失败状态返回,不需要去处理错误提示 + console.log(error); +}); +``` + +### get请求 正常写法 +``` +this.$http.get('aid/region',{pid:0}). +then(function (response) { + //这里只会在接口是成功状态返回 +}).catch(function (error) { + //这里只会在接口是失败状态返回,不需要去处理错误提示 + console.log(error); +}); +``` + +### post请求 async写法 +``` +async request(){ + let data = await this.$http.post('aid/region',{pid:0}); + console.log(data); +} +``` + +### 其他功能配置项 +``` +let data = await this.$http.post( + 'http://www.aaa.com/aid/region', //可以直接放链接(将不启用全局定义域名) + { + pid:0 + }, + { + isPrompt: true,//(默认 true 说明:本接口抛出的错误是否提示) + load: true,//(默认 true 说明:本接口是否提示加载动画) + header: { //默认 无 说明:请求头 + 'Content-Type': 'application/json' + }, + isFactory: true //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数将失去作用) + } +); +``` + +### `requestConfig.js`可以设置服务器上传图片默认url +``` +//可以new多个request来支持多个域名请求 +let $http = new request({ + //服务器本地上传文件地址 + fileUrl: base.baseUrl, + // 服务器上传图片默认url + defaultUploadUrl: "api/common/v1/upload_image", +}); +``` +``` +// 上传可以不用传递url(使用全局的上传图片url) +this.$http.urlImgUpload({ + name:"后台接受文件key名称", //默认 file + count:"最大选择数",//默认 9 + sizeType:"选择压缩图原图,默认两个都选",//默认 ['original', 'compressed'] + sourceType:"选择相机拍照或相册上传 默认两个都选",//默认 ['album','camera'] + data:"而外参数" //可不填, +}); +// 上传可以不用传递url(使用全局的上传图片url) +this.$http.urlVideoUpload({ + sourceType:"选择相机拍照或相册上传 默认两个都选",//默认 ['album','camera'] + compressed:"是否压缩所选的视频源文件,默认值为 true,需要压缩",//默认 false + maxDuration: "拍摄视频最长拍摄时间,单位秒。最长支持 60 秒", //默认 60 + camera: '前置还是后置摄像头', //'front'、'back',默认'back' + name:"后台接受文件key名称", //默认 file + data:"而外参数" //可不填, +}); +// 上传可以不用传递url(使用全局的上传图片url) +this.$http.urlFileUpload({ + files: [], // 必填 临时文件路径 格式: [{path: "图片地址"}] + data:"向服务器传递的参数", //可不填 + name:"后台接受文件key名称", //默认 file +}); +``` + +### 本地服务器图片上传(支持多张上传) +``` +this.$http.urlImgUpload('flie/upload',{ + name:"后台接受文件key名称", //默认 file + count:"最大选择数",//默认 9 + sizeType:"选择压缩图原图,默认两个都选",//默认 ['original', 'compressed'] + sourceType:"选择相机拍照或相册上传 默认两个都选",//默认 ['album','camera'] + data:"而外参数" //可不填, + isPrompt: true,//(默认 true 说明:本接口抛出的错误是否提示) + load: true,//(默认 true 说明:本接口是否提示加载动画) + header: { //默认 无 说明:请求头 + 'Content-Type': 'application/json' + }, + isFactory: true, //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数奖失去作用) + maxSize: 300000, //(默认 无 说明:上传的文件最大字节数限制,默认不限制) + onSelectComplete: res => { + console.log("选择完成返回:",res); + }, + onEachUpdate: res => { + console.log("单张上传成功返回:",res); + }, + onProgressUpdate: res => { + console.log("上传进度返回:",res); + } +}).then(res => { + console.log("全部上传完返回结果:",res); +}); +``` +### 本地服务器视频上传 +``` +this.$http.urlVideoUpload('flie/upload',{ + sourceType:"选择相机拍照或相册上传 默认两个都选",//默认 ['album','camera'] + compressed:"是否压缩所选的视频源文件,默认值为 true,需要压缩",//默认 false + maxDuration: "拍摄视频最长拍摄时间,单位秒。最长支持 60 秒", //默认 60 + camera: '前置还是后置摄像头', //'front'、'back',默认'back' + name:"后台接受文件key名称", //默认 file + data:"而外参数" //可不填, + isPrompt: true,//(默认 true 说明:本接口抛出的错误是否提示) + load: true,//(默认 true 说明:本接口是否提示加载动画) + header: { //默认 无 说明:请求头 + 'Content-Type': 'application/json' + }, + isFactory: true, //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数奖失去作用) + maxSize: 300000, //(默认 无 说明:上传的文件最大字节数限制,默认不限制) + onProgressUpdate: res => { + console.log("上传进度返回:",res); + }, + onSelectComplete: res => { + console.log("选择完成返回:",res); + }, +}).then(res => { + console.log("全部上传完返回结果:",res); +}); +``` +### 本地服务器文件上传(支持多张上传) +``` +this.$http.urlFileUpload("flie/upload",{ + files: [], // 必填 临时文件路径 格式: [{path: "图片地址"}] + data:"向服务器传递的参数", //可不填 + name:"后台接受文件key名称", //默认 file + isPrompt: true,//(默认 true 说明:本接口抛出的错误是否提示) + load: true,//(默认 true 说明:本接口是否提示加载动画) + header: { //默认 无 说明:请求头 + 'Content-Type': 'application/json' + }, + isFactory: true, //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数奖失去作用) + maxSize: 300000, //(默认 无 说明:上传的文件最大字节数限制,默认不限制) + onEachUpdate: res => { + console.log("单张上传成功返回:",res); + }, + onProgressUpdate: res => { + console.log("上传进度返回:",res); + } +}).then(res => { + console.log("全部上传完返回结果:",res); +}); +``` + +### 七牛云图片上传(支持多张上传) +``` +this.$http.qnImgUpload({ + count:"最大选择数", // 默认 9 + sizeType:"选择压缩图原图,默认两个都选", // 默认 ['original', 'compressed'] + sourceType:"选择相机拍照或相册上传 默认两个都选", // 默认 ['album','camera'] + load: true, //(默认 true 说明:本接口是否提示加载动画) + maxSize: 300000, //(默认 无 说明:上传的文件最大字节数限制,默认不限制) + onSelectComplete: res => { + console.log("选择完成返回:",res); + }, + onEachUpdate: res => { + console.log("单张上传成功返回:",res); + }, + onProgressUpdate: res => { + console.log("上传进度返回:",res); + } +}).then(res => { + console.log("全部上传完返回结果:",res); +}); +``` +### 七牛云视频上传 +``` +this.$http.qnVideoUpload({ + sourceType:"选择相机拍照或相册上传 默认两个都选",//默认 ['album','camera'] + compressed:"是否压缩所选的视频源文件,默认值为 true,需要压缩",//默认 false + maxDuration: "拍摄视频最长拍摄时间,单位秒。最长支持 60 秒", //默认 60 + camera: '前置还是后置摄像头', //'front'、'back',默认'back' + load: true,//(默认 true 说明:本接口是否提示加载动画) + maxSize: 300000, //(默认 无 说明:上传的文件最大字节数限制,默认不限制) + onSelectComplete: res => { + console.log("选择完成返回:",res); + }, + onProgressUpdate: res => { + console.log("上传进度返回:",res); + } +}).then(res => { + console.log("全部上传完返回结果:",res); +}); +``` +### 七牛云文件上传(支持多张上传) +``` +this.$http.qnFileUpload( +{ + files:[], // 必填 临时文件路径 格式: [{path: "图片地址"}] + load: true, //(默认 true 说明:本接口是否提示加载动画) + maxSize: 300000, //(默认 无 说明:上传的文件最大字节数限制,默认不限制) + onEachUpdate: res => { + console.log("单张上传成功返回:",res); + }, + onProgressUpdate: res => { + console.log("上传进度返回:",res); + } +}).then(res => { + console.log("全部上传完返回结果:",res); +}); +``` +### jsonp 跨域请求(只支持H5) +``` +let data = await this.$http.jsonp('http://www.aaa.com/aid/region',{pid:0}, { + isFactory: false, //(默认 true 说明:本接口是否调用公共的数据处理方法,设置false后isPrompt参数奖失去作用) +}); +``` diff --git a/nxTemp/request/upload/qiniuUploader.js b/nxTemp/request/upload/qiniuUploader.js new file mode 100644 index 0000000..2cb3790 --- /dev/null +++ b/nxTemp/request/upload/qiniuUploader.js @@ -0,0 +1,169 @@ +// created by gpake +(function () { + + var config = { + qiniuRegion: '', + qiniuImageURLPrefix: '', + qiniuUploadToken: '', + qiniuUploadTokenURL: '', + qiniuUploadTokenFunction: null, + qiniuShouldUseQiniuFileName: false + } + + module.exports = { + init: init, + upload: upload, + } + + // 在整个程序生命周期中,只需要 init 一次即可 + // 如果需要变更参数,再调用 init 即可 + function init(options) { + config = { + qiniuRegion: '', + qiniuImageURLPrefix: '', + qiniuUploadToken: '', + qiniuUploadTokenURL: '', + qiniuUploadTokenFunction: null, + qiniuShouldUseQiniuFileName: false + }; + updateConfigWithOptions(options); + } + + function updateConfigWithOptions(options) { + if (options.region) { + config.qiniuRegion = options.region; + } else { + console.error('qiniu uploader need your bucket region'); + } + if (options.uptoken) { + config.qiniuUploadToken = options.uptoken; + } else if (options.uptokenURL) { + config.qiniuUploadTokenURL = options.uptokenURL; + } else if (options.uptokenFunc) { + config.qiniuUploadTokenFunction = options.uptokenFunc; + } + if (options.domain) { + config.qiniuImageURLPrefix = options.domain; + } + config.qiniuShouldUseQiniuFileName = options.shouldUseQiniuFileName + } + + function upload(filePath, success, fail, options, progress, cancelTask) { + if (null == filePath) { + console.error('qiniu uploader need filePath to upload'); + return; + } + if (options) { + updateConfigWithOptions(options); + } + if (config.qiniuUploadToken) { + doUpload(filePath, success, fail, options, progress, cancelTask); + } else if (config.qiniuUploadTokenURL) { + getQiniuToken(function () { + doUpload(filePath, success, fail, options, progress, cancelTask); + }); + } else if (config.qiniuUploadTokenFunction) { + config.qiniuUploadToken = config.qiniuUploadTokenFunction(); + if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) { + console.error('qiniu UploadTokenFunction result is null, please check the return value'); + return + } + doUpload(filePath, success, fail, options, progress, cancelTask); + } else { + console.error('qiniu uploader need one of [uptoken, uptokenURL, uptokenFunc]'); + return; + } + } + + function doUpload(filePath, success, fail, options, progress, cancelTask) { + if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) { + console.error('qiniu UploadToken is null, please check the init config or networking'); + return + } + var url = uploadURLFromRegionCode(config.qiniuRegion); + var fileName = filePath.split('//')[1]; + if (options && options.key) { + fileName = options.key; + } + var formData = { + 'token': config.qiniuUploadToken + }; + if (!config.qiniuShouldUseQiniuFileName) { + formData['key'] = fileName + } + var uploadTask = wx.uploadFile({ + url: url, + filePath: filePath, + name: 'file', + formData: formData, + success: function (res) { + var dataString = res.data + if (res.data.hasOwnProperty('type') && res.data.type === 'Buffer') { + dataString = String.fromCharCode.apply(null, res.data.data) + } + try { + var dataObject = JSON.parse(dataString); + //do something + var imageUrl = config.qiniuImageURLPrefix + '/' + dataObject.key; + dataObject.imageURL = imageUrl; + if (success) { + success(dataObject); + } + } catch (e) { + console.log('parse JSON failed, origin String is: ' + dataString) + if (fail) { + fail(e); + } + } + }, + fail: function (error) { + console.error(error); + if (fail) { + fail(error); + } + } + }) + + uploadTask.onProgressUpdate((res) => { + progress && progress(res) + }) + + cancelTask && cancelTask(() => { + uploadTask.abort() + }) + } + + function getQiniuToken(callback) { + wx.request({ + url: config.qiniuUploadTokenURL, + success: function (res) { + var token = res.data.uptoken; + if (token && token.length > 0) { + config.qiniuUploadToken = token; + if (callback) { + callback(); + } + } else { + console.error('qiniuUploader cannot get your token, please check the uptokenURL or server') + } + }, + fail: function (error) { + console.error('qiniu UploadToken is null, please check the init config or networking: ' + error); + } + }) + } + + function uploadURLFromRegionCode(code) { + var uploadURL = null; + switch (code) { + case 'ECN': uploadURL = 'https://up.qbox.me'; break; + case 'NCN': uploadURL = 'https://up-z1.qbox.me'; break; + case 'SCN': uploadURL = 'https://up-z2.qbox.me'; break; + case 'NA': uploadURL = 'https://up-na0.qbox.me'; break; + case 'ASG': uploadURL = 'https://up-as0.qbox.me'; break; + default: console.error('please make the region is with one of [ECN, SCN, NCN, NA, ASG]'); + } + return uploadURL; + } + +})(); \ No newline at end of file diff --git a/nxTemp/request/upload/upload.js b/nxTemp/request/upload/upload.js new file mode 100644 index 0000000..dd4f147 --- /dev/null +++ b/nxTemp/request/upload/upload.js @@ -0,0 +1,214 @@ +import request from "./../core/request.js"; +const { + chooseImage, + chooseVideo, + qiniuUpload, + urlUpload +} = require("./utils"); +import { + mergeConfig +} from "./../core/utils.js"; +export default class fileUpload extends request { + constructor(props) { + // 调用实现父类的构造函数 + super(props); + } + //七牛云上传图片 + async qnImgUpload(options = {}) { + let files; + try { + files = await chooseImage(options); + // 选择完成回调 + options.onSelectComplete && options.onSelectComplete(files); + } catch (err) { + this.requestError && this.requestError(err); + return Promise.reject(err); + } + if (files) { + return this.qnFileUpload({ + ...options, + files: files + }); + } + } + //七牛云上传视频 + async qnVideoUpload(options = {}) { + let files; + try { + files = await chooseVideo(options); + // 选择完成回调 + options.onSelectComplete && options.onSelectComplete(files); + } catch (err) { + this.requestError && this.requestError(err); + return Promise.reject(err); + } + if (files) { + return this.qnFileUpload({ + ...options, + files: files + }); + } + } + + //七牛云文件上传(支持多张上传) + async qnFileUpload(options = {}) { + let requestInfo; + try { + // 数据合并 + requestInfo = { + ...this.config, + ...options, + header: {}, + method: "FILE" + }; + //请求前回调 + if (this.requestStart) { + let requestStart = this.requestStart(requestInfo); + if (typeof requestStart == "object") { + let changekeys = ["load", "files"]; + changekeys.forEach(key => { + requestInfo[key] = requestStart[key]; + }); + } else { + throw { + errMsg: "【request】请求开始拦截器未通过", + statusCode: 0, + data: requestInfo.data, + method: requestInfo.method, + header: requestInfo.header, + url: requestInfo.url, + } + } + } + let requestResult = await qiniuUpload(requestInfo, this.getQnToken); + return Promise.resolve(requestResult); + } catch (err) { + this.requestError && this.requestError(err); + return Promise.reject(err); + } finally { + this.requestEnd && this.requestEnd(requestInfo); + } + } + //本地服务器图片上传 + async urlImgUpload() { + let options = {}; + if (arguments[0]) { + if (typeof(arguments[0]) == "string") { + options.url = arguments[0]; + } else if (typeof(arguments[0]) == "object") { + options = Object.assign(options, arguments[0]); + } + } + if (arguments[1] && typeof(arguments[1]) == "object") { + options = Object.assign(options, arguments[1]); + } + try { + options.files = await chooseImage(options); + // 选择完成回调 + options.onSelectComplete && options.onSelectComplete(options.files); + } catch (err) { + this.requestError && this.requestError(err); + return Promise.reject(err); + } + if (options.files) { + return this.urlFileUpload(options); + } + } + //本地服务器上传视频 + async urlVideoUpload() { + let options = {}; + if (arguments[0]) { + if (typeof(arguments[0]) == "string") { + options.url = arguments[0]; + } else if (typeof(arguments[0]) == "object") { + options = Object.assign(options, arguments[0]); + } + } + if (arguments[1] && typeof(arguments[1]) == "object") { + options = Object.assign(options, arguments[1]); + } + try { + options.files = await chooseVideo(options); + console.log('files888888',options.files); + // 选择完成回调 + options.onSelectComplete && options.onSelectComplete(options.files); + } catch (err) { + this.requestError && this.requestError(err); + return Promise.reject(err); + } + if (options.files) { + return this.urlFileUpload(options); + } + } + //本地服务器文件上传方法 + async urlFileUpload() { + console.log('urlFileUpload'); + let requestInfo = { + method: "FILE" + }; + if (arguments[0]) { + if (typeof(arguments[0]) == "string") { + requestInfo.url = arguments[0]; + } else if (typeof(arguments[0]) == "object") { + requestInfo = Object.assign(requestInfo, arguments[0]); + } + } + if (arguments[1] && typeof(arguments[1]) == "object") { + requestInfo = Object.assign(requestInfo, arguments[1]); + } + if (!requestInfo.url && this.defaultUploadUrl) { + requestInfo.url = this.defaultUploadUrl; + } + // 请求数据 + // 是否运行过请求开始钩子 + let runRequestStart = false; + try { + if (!requestInfo.url) { + throw { + errMsg: "【request】文件上传缺失数据url", + statusCode: 0, + data: requestInfo.data, + method: requestInfo.method, + header: requestInfo.header, + url: requestInfo.url, + } + } + // 数据合并 + requestInfo = mergeConfig(this, requestInfo); + // 代表之前运行到这里 + runRequestStart = true; + //请求前回调 + if (this.requestStart) { + let requestStart = this.requestStart(requestInfo); + if (typeof requestStart == "object") { + console.log('objects789'); + let changekeys = ["data", "header", "isPrompt", "load", "isFactory", "files"]; + changekeys.forEach(key => { + requestInfo[key] = requestStart[key]; + }); + console.log('objects78910111213141516 requestInfo',requestInfo); + } else { + throw { + errMsg: "【request】请求开始拦截器未通过", + statusCode: 0, + data: requestInfo.data, + method: requestInfo.method, + header: requestInfo.header, + url: requestInfo.url, + } + } + } + console.log('789465'); + let requestResult = await urlUpload(requestInfo, this.dataFactory); + console.log('321456',requestResult); + return Promise.resolve(requestResult); + } catch (err) { + this.requestError && this.requestError(err); + return Promise.reject(err); + } finally { + if (runRequestStart) { + this.requestEnd && this.requestEnd(requestInfo); + } + } + } +} diff --git a/nxTemp/request/upload/utils.js b/nxTemp/request/upload/utils.js new file mode 100644 index 0000000..e09e487 --- /dev/null +++ b/nxTemp/request/upload/utils.js @@ -0,0 +1,234 @@ +const qiniuUploader = require("./qiniuUploader"); +//七牛云上传文件命名 +export const randomChar = function(l, url = "") { + const x = "0123456789qwertyuioplkjhgfdsazxcvbnm"; + let tmp = ""; + let time = new Date(); + for (let i = 0; i < l; i++) { + tmp += x.charAt(Math.ceil(Math.random() * 100000000) % x.length); + } + return ( + "file/" + + url + + time.getTime() + + tmp + ); +} +//图片选择 +export const chooseImage = function(data) { + return new Promise((resolve, reject) => { + uni.chooseImage({ + count: data.count || 9, //默认9 + sizeType: data.sizeType || ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 + sourceType: data.sourceType || ['album', 'camera'], //从相册选择 + success: function(res) { + resolve(res.tempFiles); + }, + fail: err => { + reject(err); + } + }); + }); +} +//视频选择 +export const chooseVideo = function(data) { + return new Promise((resolve, reject) => { + uni.chooseVideo({ + sourceType: data.sourceType || ['album', 'camera'], //从相册选择 + compressed: data.compressed || false, //是否压缩所选的视频源文件,默认值为 true,需要压缩。 + maxDuration: data.maxDuration || 60, //拍摄视频最长拍摄时间,单位秒。最长支持 60 秒。 + camera: data.camera || 'back', //'front'、'back',默认'back' + success: function(res) { + let files = [{ + path: res.tempFilePath + }]; + // #ifdef APP-PLUS || H5 || MP-WEIXIN + files[0].duration = res.duration; + files[0].size = res.size; + files[0].height = res.height; + files[0].width = res.width; + // #endif + // #ifdef H5 + files[0].name = res.name; + // #endif + resolve(files); + }, + fail: err => { + reject(err); + } + }); + }); +} +// 七牛云上传 +export const qiniuUpload = function(requestInfo, getQnToken) { + return new Promise((resolve, reject) => { + if (Array.isArray(requestInfo.files)) { + let len = requestInfo.files.length; + let fileList = new Array; + if (getQnToken) { + getQnToken(qnRes => { + /* + *接口返回参数: + *visitPrefix:访问文件的域名 + *token:七牛云上传token + *folderPath:上传的文件夹 + *region: 地区 默认为:SCN + */ + let prefixLen = qnRes.visitPrefix.length; + if(qnRes.visitPrefix.charAt(prefixLen - 1) == '/'){ + qnRes.visitPrefix = qnRes.visitPrefix.substring(0, prefixLen - 1) + } + uploadFile(0); + + function uploadFile(i) { + let item = requestInfo.files[i]; + let updateUrl = randomChar(10, qnRes.folderPath); + let fileData = { + fileIndex: i, + files: requestInfo.files, + ...item + }; + if (item.name) { + fileData.name = item.name; + let nameArr = item.name.split("."); + updateUrl += "." + nameArr[nameArr.length - 1]; + } + // 交给七牛上传 + qiniuUploader.upload(item.path || item, (res) => { + fileData.url = res.imageURL; + requestInfo.onEachUpdate && requestInfo.onEachUpdate({ + url: res.imageURL, + ...fileData + }); + fileList.push(res.imageURL); + if (len - 1 > i) { + uploadFile(i + 1); + } else { + resolve(fileList); + } + }, (error) => { + reject(error); + }, { + region: qnRes.region || 'SCN', //地区 + domain: qnRes.visitPrefix, // bucket 域名,下载资源时用到。 + key: updateUrl, + uptoken: qnRes.token, // 由其他程序生成七牛 uptoken + uptokenURL: 'UpTokenURL.com/uptoken' // 上传地址 + }, (res) => { + console.log(requestInfo); + requestInfo.onProgressUpdate && requestInfo.onProgressUpdate(Object.assign({}, fileData, res)); + // console.log('上传进度', res.progress) + // console.log('已经上传的数据长度', res.totalBytesSent) + // console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend) + }); + } + }); + } else { + reject({ + errMsg: "请添加七牛云回调方法:getQnToken", + statusCode: 0 + }); + } + } else { + reject({ + errMsg: "files 必须是数组类型", + statusCode: 0 + }); + }; + }); +} +// 服务器URL上传 +export const urlUpload = function(requestInfo, dataFactory) { + console.log('urlUpload',requestInfo); + return new Promise((resolve, reject) => { + // 本地文件上传去掉默认Content-Type + if (requestInfo.header['Content-Type']) { + delete requestInfo.header['Content-Type']; + } + // 本地文件上传去掉默认Content-Type + if (requestInfo.header['content-type']) { + delete requestInfo.header['content-type']; + } + if (Array.isArray(requestInfo.files)) { + console.log('requestInfo.files',requestInfo.files); + + // #ifdef MP + console.log('456mp') + const len = requestInfo.files.length - 1; + let fileList = new Array; + fileUpload(0); + + function fileUpload(i) { + console.log('fileUpload'); + let item = requestInfo.files[i]; + let fileData = { + fileIndex: i, + files: requestInfo.files, + ...item + }; + let config = { + url: requestInfo.url, + filePath: item.path, + files:requestInfo.files, + header: requestInfo.header, //加入请求头 + name: requestInfo.name || "file", + success: (response) => { + console.log('456123'); + //是否用外部的数据处理方法 + if (requestInfo.isFactory && dataFactory) { + console.log('waibu'); + //数据处理 + dataFactory({ + ...requestInfo, + response: response, + }).then(data => { + console.log('data888',data); + fileList.push(data); + requestInfo.onEachUpdate && requestInfo.onEachUpdate({ + data: data, + ...fileData + }); + if (len <= i) { + resolve(fileList); + } else { + fileUpload(i + 1); + } + },err => { + reject(err); + }); + } else { + console.log('nb'); + requestInfo.onEachUpdate && requestInfo.onEachUpdate({ + data: response, + ...fileData + }); + fileList.push(response); + if (len <= i) { + resolve(fileList); + } else { + fileUpload(i + 1); + } + } + }, + fail: (err) => { + reject(err); + } + }; + if (requestInfo.data) { + config.formData = requestInfo.data; + } + const uploadTask = uni.uploadFile(config); + uploadTask.onProgressUpdate(res => { + requestInfo.onProgressUpdate && requestInfo.onProgressUpdate(Object.assign({}, fileData, res)); + }); + } + // #endif + } else { + reject({ + errMsg: "files 必须是数组类型", + statusCode: 0 + }); + } + }); + console.log('urlUploadEND'); +} diff --git a/nxTemp/router/index.js b/nxTemp/router/index.js new file mode 100644 index 0000000..2fa4c36 --- /dev/null +++ b/nxTemp/router/index.js @@ -0,0 +1,73 @@ +// 路由 +import { + RouterMount, + createRouter +} from './uni-simple-router.js' +import store from '@/nxTemp/store' +const router = createRouter({ + platform: process.env.VUE_APP_PLATFORM, + applet: { + animationDuration: 0 //默认 300ms + }, + routerErrorEach: ({ + type, + msg + }) => { + console.log(55555,type,msg) + + switch (type) { + case 3: // APP退出应用 + // #ifdef APP-PLUS + router.$lockStatus = false; + uni.showModal({ + title: '提示', + content: '您确定要退出应用吗?', + success: function(res) { + if (res.confirm) { + plus.runtime.quit(); + } + } + }); + // #endif + break; + case 2: + case 0: + console.log(66666,type) + router.$lockStatus = false; + break; + default: + console.log(77777,type) + break; + } + + }, + // 通配符,非定义页面,跳转404 + routes: [...ROUTES, + { + path: '*', + redirect: (to) => { + return { + name: '404' + } + } + }, + ] +}); + +//全局路由前置守卫 +router.beforeEach((to, from, next) => { + // 权限控制登录 + next() + // // 有两个个判断条件,一个是token,还有一个路由元信息 + // let userInfo = Boolean(uni.getStorageSync('userInfo')); + // // 权限控制 + // if (to.meta && to.meta.auth && !userInfo) {//没有登录信息执行登录操作 + // } else { + // next() + // } +}); + +export { + router, + RouterMount +} diff --git a/nxTemp/router/uni-simple-router.js b/nxTemp/router/uni-simple-router.js new file mode 100644 index 0000000..a68ff67 --- /dev/null +++ b/nxTemp/router/uni-simple-router.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Router=t():e.Router=t()}(self,(function(){return e={779:(e,t,r)=>{var o=r(173);e.exports=function e(t,r,n){return o(r)||(n=r||n,r=[]),n=n||{},t instanceof RegExp?function(e,t){var r=e.source.match(/\((?!\?)/g);if(r)for(var o=0;o{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},844:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return(o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r0?t.vueEachArray[r](e,o,(function(){n&&n()})):t.myEachHook(e,o,(function(a){!1===a?n(!1):t.vueEachArray[r](e,o,(function(e){n(a)}))}),t.router,!0)}},t}(Array);t.MyArray=n,t.proxyEachHook=function(e,t){for(var r=["beforeHooks","afterHooks"],o=0;o0)return!1;window.location.reload()}),0)}else e.mount[0].app.$mount(),e.mount=[]}},814:function(e,t){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getEnterPath=void 0,t.getEnterPath=function(e,t){switch(t.options.platform){case"mp-alipay":case"mp-weixin":case"mp-toutiao":case"mp-qq":return e.$options.mpInstance.route;case"mp-baidu":return e.$options.mpInstance.is||e.$options.mpInstance.pageinstance.route}return e.$options.mpInstance.route}},282:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return(o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createRouteMap=void 0;var o=r(883),n=r(789);t.createRouteMap=function(e,t){var r={finallyPathList:[],finallyPathMap:Object.create(null),aliasPathMap:Object.create(null),pathMap:Object.create(null),vueRouteMap:Object.create(null),nameMap:Object.create(null)};return t.forEach((function(t){var a=n.getRoutePath(t,e),i=a.finallyPath,u=a.aliasPath,l=a.path;if(null==l)throw new Error("请提供一个完整的路由对象,包括以绝对路径开始的 ‘path’ 字符串 "+JSON.stringify(t));if(i instanceof Array&&!e.options.h5.vueRouterDev&&"h5"===e.options.platform)throw new Error("非 vueRouterDev 模式下,route.alias 目前无法提供数组类型! "+JSON.stringify(t));var p=i,c=u;"h5"!==e.options.platform&&0!==p.indexOf("/")&&"*"!==l&&o.warn("当前路由对象下,route:"+JSON.stringify(t)+" 是否缺少了前缀 ‘/’",e,!0),r.finallyPathMap[p]||(r.finallyPathMap[p]=t,r.aliasPathMap[c]=t,r.pathMap[l]=t,r.finallyPathList.push(p),null!=t.name&&(r.nameMap[t.name]=t))})),r}},662:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.registerEachHooks=t.registerRouterHooks=t.registerHook=void 0;var o=r(366),n=r(169);function a(e,t){e[0]=t}t.registerHook=a,t.registerRouterHooks=function(e,t){return a(e.routerBeforeHooks,(function(e,r,o){t.routerBeforeEach(e,r,o)})),a(e.routerAfterHooks,(function(e,r){t.routerAfterEach(e,r)})),a(e.routerErrorHooks,(function(e,r){t.routerErrorEach(e,r)})),e},t.registerEachHooks=function(e,t,r){a(e.lifeCycle[t],(function(e,a,i,u,l){l?n.onTriggerEachHook(e,a,u,o.hookToggle[t],i):r(e,a,i)}))}},460:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return(o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r0)return P}if(""!==u)return h(t);throw new Error(r+" 路径无法在路由表中找到!检查跳转路径及路由表")},t.getDataType=v,t.copyData=function(e){return JSON.parse(JSON.stringify(e))},t.getUniCachePage=function(e){var t=getCurrentPages();if(null==e)return t;if(0===t.length)return t;var r=t.reverse()[e];return null==r?[]:r},t.urlToJson=function(e){var t={},r=e.split("?"),o=r[0],n=r[1];if(null!=n)for(var a=0,i=n.split("&");a3},t.baseClone=y,t.deepClone=g,t.lockDetectWarn=function(e,t,r,o,n){if("afterHooks"===n)o();else{var a=e.options.detectBeforeLock;a&&a(e,t,r),e.$lockStatus?e.options.routerErrorEach({type:2,msg:"当前页面正在处于跳转状态,请稍后再进行跳转...."},e):o()}},t.replaceHook=function(e,t,r,o){var n=t.$options,a=e[r][o],u={};if("[object Array]"===v(a)&&(u={beforeCreate:[],created:[],beforeMount:[],mounted:[],beforeDestroy:[],destroyed:[]}),null!=a){for(var l=i.proxyVueSortHookName[o],p=function(r){var p=l[r],c=n[p];if("[object Array]"===v(c)){if(1===c.length&&c.toString().includes("UNI-SIMPLE-ROUTER"))return"continue";var s={options:[],hook:Function},f=c.splice(c.length-1,1,(function(){for(var e=[],t=0;t0?u[p]=[s]:a[p]=[s]}},c=0;c0&&a.push(u)}},t.callHook=d,t.resetPageHook=function(e,t){var r=t.trim().match(/^(\/?[^\?\s]+)(\?[\s\S]*$)?$/);if(null==r)throw new Error("还原hook失败。请检查 【"+t+"】 路径是否正确。");t=r[1];var o="appletsProxyHook";"app-plus"===e.options.platform&&(o="appProxyHook");for(var n=[],a=0,i=Object.entries(e[o]);a{"use strict";function r(e,t,r,o){if(void 0===o&&(o=!1),!o){var n="[object Object]"===t.toString();if(!1===t)return!1;if(n&&!1===t[e])return!1}return console[e](r),!0}Object.defineProperty(t,"__esModule",{value:!0}),t.warnLock=t.log=t.warn=t.err=t.isLog=void 0,t.isLog=r,t.err=function(e,t,o){r("error",t.options.debugger,e,o)},t.warn=function(e,t,o){r("warn",t.options.debugger,e,o)},t.log=function(e,t,o){r("log",t.options.debugger,e,o)},t.warnLock=function(e){console.warn(e)}},607:function(e,t,r){"use strict";var o=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),n=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||o(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),t.createRouter=t.RouterMount=t.runtimeQuit=void 0,n(r(366),t),n(r(309),t);var a=r(814);Object.defineProperty(t,"runtimeQuit",{enumerable:!0,get:function(){return a.runtimeQuit}});var i=r(963);Object.defineProperty(t,"RouterMount",{enumerable:!0,get:function(){return i.RouterMount}}),Object.defineProperty(t,"createRouter",{enumerable:!0,get:function(){return i.createRouter}})},366:(e,t)=>{"use strict";var r,o,n;Object.defineProperty(t,"__esModule",{value:!0}),t.rewriteMethodToggle=t.navtypeToggle=t.hookToggle=void 0,(n=t.hookToggle||(t.hookToggle={})).beforeHooks="beforeEach",n.afterHooks="afterEach",n.enterHooks="beforeEnter",(o=t.navtypeToggle||(t.navtypeToggle={})).push="navigateTo",o.replace="redirectTo",o.replaceAll="reLaunch",o.pushTab="switchTab",o.back="navigateBack",(r=t.rewriteMethodToggle||(t.rewriteMethodToggle={})).navigateTo="push",r.navigate="push",r.redirectTo="replace",r.reLaunch="replaceAll",r.switchTab="pushTab",r.navigateBack="back"},309:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},169:function(e,t,r){"use strict";var o=this&&this.__rest||function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n0){var u=void 0;switch("h5"===e.options.platform?u=i.$options.beforeRouteLeave:null!=i.$vm&&(u=i.$vm.$options.beforeRouteLeave),n.getDataType(u)){case"[object Array]":a=(a=u[0]).bind(i);break;case"[object Function]":a=u.bind(i.$vm)}}return p(a,t,r,e,o)}function p(e,t,r,o,n,a){void 0===a&&(a=!0),null!=e&&e instanceof Function?!0===a?e(t,r,n,o,!1):(e(t,r,(function(){}),o,!1),n()):n()}function c(e,t,r,o,a,i){var u=n.forMatNextToFrom(e,t,r),l=u.matTo,p=u.matFrom;"h5"===e.options.platform?s(a,0,i,e,l,p,o):s(a.slice(0,4),0,(function(){i((function(){s(a.slice(4),0,n.voidFun,e,l,p,o)}))}),e,l,p,o)}function s(e,r,i,l,p,c,f){var h=n.routesForMapRoute(l,p.path,["finallyPathMap","pathMap"]);if(e.length-1{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.proxyPageHook=t.createFullPath=t.createToFrom=void 0;var o=r(789),n=r(890),a=r(99);t.createToFrom=function(e,t){var r=o.getUniCachePage(0);return"[object Array]"===o.getDataType(r)?o.deepClone(e):n.createRoute(t)},t.createFullPath=function(e,t){if(null==e.fullPath){var r=a.stringifyQuery(e.query);e.fullPath=e.path+r}null==t.fullPath&&(r=a.stringifyQuery(t.query),t.fullPath=t.path+r)},t.proxyPageHook=function(e,t,r,n){o.replaceHook(t,e,r,n)}},99:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return(o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{[propName: string]: any;}",t):e[r]=u}else{if(!n.assertDeepObject(o))return e;var l=JSON.stringify(o);e[r]={query:l}}return e},t.parseQuery=function(e,t){var r=t.options.parseQuery;if(r)e=r(n.copyData(e)),"[object Object]"!==n.getDataType(e)&&i.warn("请按格式返回参数: parseQuery?:(jsonQuery:{[propName: string]: any;})=>{[propName: string]: any;}",t);else if(Reflect.get(e,"query")){var o=Reflect.get(e,"query");if("string"==typeof o)try{o=JSON.parse(o)}catch(e){i.warn("尝试解析深度对象失败,按原样输出。"+e,t)}if("object"==typeof o)return n.deepDecodeQuery(o)}return e},t.stringifyQuery=function(e){var t=e?Object.keys(e).map((function(t){var r=e[t];if(void 0===r)return"";if(null===r)return c(t);if(Array.isArray(r)){var o=[];return r.forEach((function(e){void 0!==e&&(null===e?o.push(c(t)):o.push(c(t)+"="+c(e)))})),o.join("&")}return c(t)+"="+c(r)})).filter((function(e){return e.length>0})).join("&"):null;return t?"?"+t:""}},314:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.rewriteMethod=void 0;var o=r(366),n=r(789),a=r(883),i=r(809),u=["navigateTo","redirectTo","reLaunch","switchTab","navigateBack"];t.rewriteMethod=function(e){!1===e.options.keepUniOriginNav&&u.forEach((function(t){var r=uni[t];uni[t]=function(u,l,p,c){void 0===l&&(l=!1),l?i.uniOriginJump(e,r,t,u,p,c):("app-plus"===e.options.platform&&0===Object.keys(e.appMain).length&&(e.appMain={NAVTYPE:t,path:u.url}),function(e,t,r){if("app-plus"===r.options.platform){var i=null;e&&(i=e.openType),null!=i&&"appLaunch"===i&&(t="reLaunch")}if("reLaunch"===t&&'{"url":"/"}'===JSON.stringify(e)&&(a.warn("uni-app 原生方法:reLaunch({url:'/'}) 默认被重写啦!你可以使用 this.$Router.replaceAll() 或者 uni.reLaunch({url:'/?xxx=xxx'})",r,!0),t="navigateBack",e={from:"backbutton"}),"navigateBack"===t){var u=1;null==e&&(e={delta:1}),"[object Number]"===n.getDataType(e.delta)&&(u=e.delta),r.back(u,e)}else{var l=o.rewriteMethodToggle[t],p=e.url;if(!p.startsWith("/")){var c=n.resolveAbsolutePath(p,r);p=c,e.url=c}if("switchTab"===t){var s=n.routesForMapRoute(r,p,["pathMap","finallyPathList"]),f=n.getRoutePath(s,r).finallyPath;if("[object Array]"===n.getDataType(f)&&a.warn("uni-app 原生方法跳转路径为:"+p+"。此路为是tab页面时,不允许设置 alias 为数组的情况,并且不能为动态路由!当然你可以通过通配符*解决!",r,!0),"*"===f&&a.warn("uni-app 原生方法跳转路径为:"+p+"。在路由表中找不到相关路由表!当然你可以通过通配符*解决!",r,!0),"h5"===r.options.platform){var h=e.success;e.success=function(){for(var t=[],r=0;r0&&Reflect.has(t,"index")){var r=n.getUniCachePage(0);if(0===Object.keys(r).length)return!1;var o=r,a=o.$options.onTabItemTap;if(a)for(var i=0;i0&&n[n.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!n||a[1]>n[0]&&a[1] { + Object.assign(modules.state, files(key)["state"]); + Object.assign(modules.mutations, files(key)["mutations"]); + Object.assign(modules.actions, files(key)["actions"]); +}); +const store = new Vuex.Store(modules); +export default store; + diff --git a/nxTemp/store/modules/user.js b/nxTemp/store/modules/user.js new file mode 100644 index 0000000..ab73e1a --- /dev/null +++ b/nxTemp/store/modules/user.js @@ -0,0 +1,67 @@ +// 用户数据模块 +import {router} from '@/nxTemp/router/index.js' +const TOKEN = uni.getStorageSync("token") || ""; +const OPENID = uni.getStorageSync("openId") || ""; +const USER_INFO = uni.getStorageSync("userInfo") || {}; + +export const state = { + // 前端token + token: TOKEN, + // 用户openid + openId: OPENID, + // 用户信息 头像 昵称 + userInfo: USER_INFO +} + +export const actions = { + async setUserData({ + state, + commit + }, data) { + commit('setStateAttr', { + key: 'userInfo', + val: data + }) + uni.setStorageSync('userInfo', data); + }, + // 登录过期 重新登录 + reLogin({ + commit + }, info) { + commit('setStateAttr', { + key: 'token', + val: '' + }) + uni.setStorageSync("token", ''); + //过期跳转登录页重新登录 + router.push({ + path: '/pages/login/login' + }); + } +} + +export const mutations = { + //更新state数据 + setStateAttr(state, param) { + if (param instanceof Array) { + for (let item of param) { + state[item.key] = item.val; + } + } else { + state[param.key] = param.val; + } + } + +} + +export const getters = { + // 用户是否登录 + hasLogin: state => { + if (state.token) { + return true; + } else { + return false + } + } +} + diff --git a/nxTemp/utils/tools.js b/nxTemp/utils/tools.js new file mode 100644 index 0000000..5ccb60d --- /dev/null +++ b/nxTemp/utils/tools.js @@ -0,0 +1,165 @@ +export default { + /** + * 图片处理-预览图片 + * @param {Array} urls - 图片列表 + * @param {Number} current - 首个预览下标 + */ + previewImage(urls = [], current = 0) { + uni.previewImage({ + urls: urls, + current: current, + indicator: 'default', + loop: true, + fail(err) { + console.log('previewImage出错', urls, err) + }, + }) + }, + + /** + * 打电话 + * @param {String} phoneNumber - 数字字符串 + */ + callPhone(phoneNumber = '') { + let num = phoneNumber.toString() + uni.makePhoneCall({ + phoneNumber: num, + fail(err) { + console.log('makePhoneCall出错', err) + }, + }); + }, + + /** + * @description: 弹窗封装 + * @param {String} msg + * @return: {*} + */ + showNone(msg){ + uni.showToast({ + title: msg, + icon: 'none', + duration:2000 + }); + }, + + /** + * @description: 自动封装promise + * @param {Function} api + * @return {Promise API} + */ + promisify(api){ + return (options, ...params) => { + return new Promise((resolve, reject) => { + api(Object.assign({}, options, { success: resolve, fail: reject }), ...params); + }); + } + }, + + /** + * @description: 获取URL拼接 + * @param {JSON Object} data + * @param {String} url + * @return {String} + */ + getWebURL(data,url){ + let result = "" + for(var i in data){ + result+=`&${i}=${data[i]}` + } + return url+"?"+result.slice(1) + }, + + /** + * @description: 休眠指定时间 + * @param {Int} time + * @return: {*} + */ + async sleep(time){ + const res = await new Promise(resolve => { + setTimeout(() => resolve("asyncSetTimeOut"), time||1000); + }); + return res + }, + + /** + * @description: 解析onload传递参数,兼容多种传参方式 + * @param {String ,JSON Object } param + * @return: {*} + */ + getDecodeObj(param) { //解析传递参数 - 兼容开发者工具快速调试参数,并做promise封装 + return new Promise((rs, rj) => { + let res = decodeURIComponent(param) + try { + res = JSON.parse(res) + } catch (e) { + //TODO handle the exception + res = JSON.parse(decodeURIComponent(res)) || res + } finally { + if (typeof(res) == 'object') rs(res) + rj(res) + } + }) + }, + + /** + * @description: 防抖函数封装 + * @param {Function} func + * @param {Int} wait + * @param {Bool} immediate + * @return {debounce Function} + */ + debounce(func, wait, immediate) { + let timeout, args, context, timestamp, result; + const later = function() { + // 据上一次触发时间间隔 + const last = +new Date() - timestamp; + // 上次被包装函数被调用时间间隔last小于设定时间间隔wait + if (last < wait && last > 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + } + return function(...args) { + context = this; + timestamp = +new Date(); + const callNow = immediate && !timeout; + // 如果延时不存在,重新设定延时 + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + return result; + } + }, + + /** + * @description: 路由跳转,uni版(未兼容路由) + * @param {String Path} url + * @param {String } type + * @return: {*} + */ + routeTo(url,type){ + switch(type){ + case 'nT': uni.navigateTo({url}); + break + case 'rT': uni.redirectTo({url}); + break + case 'rL': uni.reLaunch({url}); + break + case 'sT': uni.switchTab({url}); + break + default: uni.navigateBack({delta: 1}) + break + } + }, + + +} diff --git a/nxTemp/wechat/wechat.js b/nxTemp/wechat/wechat.js new file mode 100644 index 0000000..dad9ca6 --- /dev/null +++ b/nxTemp/wechat/wechat.js @@ -0,0 +1,35 @@ +export default { + // #ifdef MP-WEIXIN + // 小程序更新 + checkMiniProgramUpdate() { + if (uni.canIUse("getUpdateManager")) { + const updateManager = uni.getUpdateManager(); + updateManager.onCheckForUpdate(function(res) { + // 请求完新版本信息的回调 + if (res.hasUpdate) { + updateManager.onUpdateReady(function() { + uni.showModal({ + title: "更新提示", + content: "新版本已经准备好,是否重启应用?", + success: function(res) { + if (res.confirm) { + // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 + updateManager.applyUpdate(); + } + } + }); + }); + updateManager.onUpdateFailed(function() { + // 新的版本下载失败 + uni.showModal({ + title: "已经有新版本了哟~", + content: "新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~" + }); + }); + } + }); + } + }, + // #endif + +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0bc44a8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,16 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "uni-read-pages": { + "version": "1.0.5", + "resolved": "https://registry.nlark.com/uni-read-pages/download/uni-read-pages-1.0.5.tgz", + "integrity": "sha1-RSyNyqiXe7rvYAkJvpJsjZcEOHw=" + }, + "uni-simple-router": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/uni-simple-router/download/uni-simple-router-2.0.7.tgz", + "integrity": "sha1-BOC1vmzXM6HsudNaPb6C8n9IIE4=" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..39d5749 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "uni-read-pages": "^1.0.5", + "uni-simple-router": "^2.0.1" + } +} diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..bd5a6d8 --- /dev/null +++ b/pages.json @@ -0,0 +1,152 @@ +{ + "easycom": { //easycom,按需自动注册组件。原则上可以把所有页面引入组件方法删掉,会自动引入。 + "autoscan": true, + "custom": { + "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue", + "^uni-(.*)": "@/components/uni-$1/uni-$1.vue", + "^nx-(.*)": "@/components/nx-$1/nx-$1.vue" + } + }, + "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages + { + "path": "pages/index/index", + "aliasPath": "/", + "name":"index", + "style": { + "navigationBarTitleText": "赛事助手", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/message/center_list", + "name":"messageList", + "style": { + "navigationBarTitleText": "消息列表", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + + + { + "path": "pages/message/detail", + "name":"messageDetail", + "style": { + "navigationBarTitleText": "消息详情", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/event/event_grade", + "name":"eventGrade", + "style": { + "navigationBarTitleText": "赛事打分", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/event/event_list", + "name":"eventList", + "style": { + "navigationBarTitleText": "赛事列表", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/login/reg", + "name":"reg", + "style": { + "navigationBarTitleText": "注册", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/login/login", + "name":"login", + "style": { + "navigationBarTitleText": "登录", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/login/forget", + "name":"forget", + "style": { + "navigationBarTitleText": "忘记密码", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/login/agreement", + "name":"agreement", + "style": { + "navigationBarTitleText": "用户协议", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + }, + { + "path": "pages/me/index", + "name":"me", + "style": { + "navigationBarTitleText": "我的", + "navigationBarBackgroundColor":"#009874", + "navigationBarTextStyle":"white" + } + } + ], + "subPackages": [{ + "root": "pages/public", + "pages": [{ + "path": "404", + "name": "404", + "style": { + "navigationBarTitleText": "请重试" + } + }] + }], + + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "通用模板", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8" + }, + "tabBar": { + "color": "#7A7E83", + "selectedColor": "#fe519f", + "borderStyle": "black", + "backgroundColor": "#F8F8F8", + "list": [{ + "pagePath": "pages/index/index", + "iconPath": "static/images/tabbar/tab_home_01.png", + "selectedIconPath": "static/images/tabbar/tab_home_02.png", + "text": "首页" + }, + + { + "pagePath": "pages/me/index", + "iconPath": "static/images/tabbar/tab_user_01.png", + "selectedIconPath": "static/images/tabbar/tab_user_02.png", + "text": "我的" + } + ] + }, + "condition": { //模式配置,仅开发期间生效 + "current": 0, //当前激活的模式(list 的索引项) + "list": [ + { + "name": "登录页面", //模式名称 + "path": "pages/login/login", //启动页面,必选 + "query": "" //启动参数,在页面的onLoad函数里面得到 + } + ] + } +} diff --git a/pages/event/event_grade.vue b/pages/event/event_grade.vue new file mode 100644 index 0000000..6ddbf19 --- /dev/null +++ b/pages/event/event_grade.vue @@ -0,0 +1,327 @@ + + + + diff --git a/pages/event/event_list.vue b/pages/event/event_list.vue new file mode 100644 index 0000000..d47f779 --- /dev/null +++ b/pages/event/event_list.vue @@ -0,0 +1,196 @@ + + + + diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..2666346 --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,118 @@ + + + + diff --git a/pages/login/agreement.vue b/pages/login/agreement.vue new file mode 100644 index 0000000..81722e0 --- /dev/null +++ b/pages/login/agreement.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/pages/login/forget.vue b/pages/login/forget.vue new file mode 100644 index 0000000..05272de --- /dev/null +++ b/pages/login/forget.vue @@ -0,0 +1,255 @@ + + + + + diff --git a/pages/login/login.vue b/pages/login/login.vue new file mode 100644 index 0000000..a76bc64 --- /dev/null +++ b/pages/login/login.vue @@ -0,0 +1,242 @@ + + + + + diff --git a/pages/login/reg.vue b/pages/login/reg.vue new file mode 100644 index 0000000..d357836 --- /dev/null +++ b/pages/login/reg.vue @@ -0,0 +1,303 @@ + + + + + diff --git a/pages/me/index.vue b/pages/me/index.vue new file mode 100644 index 0000000..b402206 --- /dev/null +++ b/pages/me/index.vue @@ -0,0 +1,30 @@ + + + + diff --git a/pages/message/center_list.vue b/pages/message/center_list.vue new file mode 100644 index 0000000..eab2294 --- /dev/null +++ b/pages/message/center_list.vue @@ -0,0 +1,74 @@ + + + + diff --git a/pages/message/detail.vue b/pages/message/detail.vue new file mode 100644 index 0000000..fa68a77 --- /dev/null +++ b/pages/message/detail.vue @@ -0,0 +1,69 @@ + + + + diff --git a/pages/public/404.vue b/pages/public/404.vue new file mode 100644 index 0000000..38b2c2d --- /dev/null +++ b/pages/public/404.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/static/colorui/animation.css b/static/colorui/animation.css new file mode 100644 index 0000000..d410ca4 --- /dev/null +++ b/static/colorui/animation.css @@ -0,0 +1,184 @@ +/* + Animation 微动画 + 基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28 + */ + +/* css 滤镜 控制黑白底色gif的 */ +.gif-black{ + mix-blend-mode: screen; +} +.gif-white{ + mix-blend-mode: multiply; +} + + +/* Animation css */ +[class*=animation-] { + animation-duration: .5s; + animation-timing-function: ease-out; + animation-fill-mode: both +} + +.animation-fade { + animation-name: fade; + animation-duration: .8s; + animation-timing-function: linear +} + +.animation-scale-up { + animation-name: scale-up +} + +.animation-scale-down { + animation-name: scale-down +} + +.animation-slide-top { + animation-name: slide-top +} + +.animation-slide-bottom { + animation-name: slide-bottom +} + +.animation-slide-left { + animation-name: slide-left +} + +.animation-slide-right { + animation-name: slide-right +} + +.animation-shake { + animation-name: shake +} + +.animation-reverse { + animation-direction: reverse +} + +@keyframes fade { + 0% { + opacity: 0 + } + + 100% { + opacity: 1 + } +} + +@keyframes scale-up { + 0% { + opacity: 0; + transform: scale(.2) + } + + 100% { + opacity: 1; + transform: scale(1) + } +} + +@keyframes scale-down { + 0% { + opacity: 0; + transform: scale(1.8) + } + + 100% { + opacity: 1; + transform: scale(1) + } +} + +@keyframes slide-top { + 0% { + opacity: 0; + transform: translateY(-100%) + } + + 100% { + opacity: 1; + transform: translateY(0) + } +} + +@keyframes slide-bottom { + 0% { + opacity: 0; + transform: translateY(100%) + } + + 100% { + opacity: 1; + transform: translateY(0) + } +} + +@keyframes shake { + + 0%, + 100% { + transform: translateX(0) + } + + 10% { + transform: translateX(-9px) + } + + 20% { + transform: translateX(8px) + } + + 30% { + transform: translateX(-7px) + } + + 40% { + transform: translateX(6px) + } + + 50% { + transform: translateX(-5px) + } + + 60% { + transform: translateX(4px) + } + + 70% { + transform: translateX(-3px) + } + + 80% { + transform: translateX(2px) + } + + 90% { + transform: translateX(-1px) + } +} + +@keyframes slide-left { + 0% { + opacity: 0; + transform: translateX(-100%) + } + + 100% { + opacity: 1; + transform: translateX(0) + } +} + +@keyframes slide-right { + 0% { + opacity: 0; + transform: translateX(100%) + } + + 100% { + opacity: 1; + transform: translateX(0) + } +} \ No newline at end of file diff --git a/static/colorui/components/cu-custom.vue b/static/colorui/components/cu-custom.vue new file mode 100644 index 0000000..2ca3feb --- /dev/null +++ b/static/colorui/components/cu-custom.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/static/colorui/icon.css b/static/colorui/icon.css new file mode 100644 index 0000000..972d080 --- /dev/null +++ b/static/colorui/icon.css @@ -0,0 +1,1226 @@ +@keyframes cuIcon-spin { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +.cuIconfont-spin { + -webkit-animation: cuIcon-spin 2s infinite linear; + animation: cuIcon-spin 2s infinite linear; + display: inline-block; +} + +.cuIconfont-pulse { + -webkit-animation: cuIcon-spin 1s infinite steps(8); + animation: cuIcon-spin 1s infinite steps(8); + display: inline-block; +} + +[class*="cuIcon-"] { + font-family: "cuIcon"; + font-size: inherit; + font-style: normal; +} + +@font-face { + font-family: "cuIcon"; + src: url('//at.alicdn.com/t/font_533566_yfq2d9wdij.eot?t=1545239985831'); + /* IE9*/ + src: url('//at.alicdn.com/t/font_533566_yfq2d9wdij.eot?t=1545239985831#iefix') format('embedded-opentype'), + /* IE6-IE8 */ + url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'), + url('//at.alicdn.com/t/font_533566_yfq2d9wdij.ttf?t=1545239985831') format('truetype'), + /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ + url('//at.alicdn.com/t/font_533566_yfq2d9wdij.svg?t=1545239985831#cuIconfont') format('svg'); + /* iOS 4.1- */ +} + +.cuIcon-appreciate:before { + content: "\e644"; +} + +.cuIcon-check:before { + content: "\e645"; +} + +.cuIcon-close:before { + content: "\e646"; +} + +.cuIcon-edit:before { + content: "\e649"; +} + +.cuIcon-emoji:before { + content: "\e64a"; +} + +.cuIcon-favorfill:before { + content: "\e64b"; +} + +.cuIcon-favor:before { + content: "\e64c"; +} + +.cuIcon-loading:before { + content: "\e64f"; +} + +.cuIcon-locationfill:before { + content: "\e650"; +} + +.cuIcon-location:before { + content: "\e651"; +} + +.cuIcon-phone:before { + content: "\e652"; +} + +.cuIcon-roundcheckfill:before { + content: "\e656"; +} + +.cuIcon-roundcheck:before { + content: "\e657"; +} + +.cuIcon-roundclosefill:before { + content: "\e658"; +} + +.cuIcon-roundclose:before { + content: "\e659"; +} + +.cuIcon-roundrightfill:before { + content: "\e65a"; +} + +.cuIcon-roundright:before { + content: "\e65b"; +} + +.cuIcon-search:before { + content: "\e65c"; +} + +.cuIcon-taxi:before { + content: "\e65d"; +} + +.cuIcon-timefill:before { + content: "\e65e"; +} + +.cuIcon-time:before { + content: "\e65f"; +} + +.cuIcon-unfold:before { + content: "\e661"; +} + +.cuIcon-warnfill:before { + content: "\e662"; +} + +.cuIcon-warn:before { + content: "\e663"; +} + +.cuIcon-camerafill:before { + content: "\e664"; +} + +.cuIcon-camera:before { + content: "\e665"; +} + +.cuIcon-commentfill:before { + content: "\e666"; +} + +.cuIcon-comment:before { + content: "\e667"; +} + +.cuIcon-likefill:before { + content: "\e668"; +} + +.cuIcon-like:before { + content: "\e669"; +} + +.cuIcon-notificationfill:before { + content: "\e66a"; +} + +.cuIcon-notification:before { + content: "\e66b"; +} + +.cuIcon-order:before { + content: "\e66c"; +} + +.cuIcon-samefill:before { + content: "\e66d"; +} + +.cuIcon-same:before { + content: "\e66e"; +} + +.cuIcon-deliver:before { + content: "\e671"; +} + +.cuIcon-evaluate:before { + content: "\e672"; +} + +.cuIcon-pay:before { + content: "\e673"; +} + +.cuIcon-send:before { + content: "\e675"; +} + +.cuIcon-shop:before { + content: "\e676"; +} + +.cuIcon-ticket:before { + content: "\e677"; +} + +.cuIcon-back:before { + content: "\e679"; +} + +.cuIcon-cascades:before { + content: "\e67c"; +} + +.cuIcon-discover:before { + content: "\e67e"; +} + +.cuIcon-list:before { + content: "\e682"; +} + +.cuIcon-more:before { + content: "\e684"; +} + +.cuIcon-scan:before { + content: "\e689"; +} + +.cuIcon-settings:before { + content: "\e68a"; +} + +.cuIcon-questionfill:before { + content: "\e690"; +} + +.cuIcon-question:before { + content: "\e691"; +} + +.cuIcon-shopfill:before { + content: "\e697"; +} + +.cuIcon-form:before { + content: "\e699"; +} + +.cuIcon-pic:before { + content: "\e69b"; +} + +.cuIcon-filter:before { + content: "\e69c"; +} + +.cuIcon-footprint:before { + content: "\e69d"; +} + +.cuIcon-top:before { + content: "\e69e"; +} + +.cuIcon-pulldown:before { + content: "\e69f"; +} + +.cuIcon-pullup:before { + content: "\e6a0"; +} + +.cuIcon-right:before { + content: "\e6a3"; +} + +.cuIcon-refresh:before { + content: "\e6a4"; +} + +.cuIcon-moreandroid:before { + content: "\e6a5"; +} + +.cuIcon-deletefill:before { + content: "\e6a6"; +} + +.cuIcon-refund:before { + content: "\e6ac"; +} + +.cuIcon-cart:before { + content: "\e6af"; +} + +.cuIcon-qrcode:before { + content: "\e6b0"; +} + +.cuIcon-remind:before { + content: "\e6b2"; +} + +.cuIcon-delete:before { + content: "\e6b4"; +} + +.cuIcon-profile:before { + content: "\e6b7"; +} + +.cuIcon-home:before { + content: "\e6b8"; +} + +.cuIcon-cartfill:before { + content: "\e6b9"; +} + +.cuIcon-discoverfill:before { + content: "\e6ba"; +} + +.cuIcon-homefill:before { + content: "\e6bb"; +} + +.cuIcon-message:before { + content: "\e6bc"; +} + +.cuIcon-addressbook:before { + content: "\e6bd"; +} + +.cuIcon-link:before { + content: "\e6bf"; +} + +.cuIcon-lock:before { + content: "\e6c0"; +} + +.cuIcon-unlock:before { + content: "\e6c2"; +} + +.cuIcon-vip:before { + content: "\e6c3"; +} + +.cuIcon-weibo:before { + content: "\e6c4"; +} + +.cuIcon-activity:before { + content: "\e6c5"; +} + +.cuIcon-friendaddfill:before { + content: "\e6c9"; +} + +.cuIcon-friendadd:before { + content: "\e6ca"; +} + +.cuIcon-friendfamous:before { + content: "\e6cb"; +} + +.cuIcon-friend:before { + content: "\e6cc"; +} + +.cuIcon-goods:before { + content: "\e6cd"; +} + +.cuIcon-selection:before { + content: "\e6ce"; +} + +.cuIcon-explore:before { + content: "\e6d2"; +} + +.cuIcon-present:before { + content: "\e6d3"; +} + +.cuIcon-squarecheckfill:before { + content: "\e6d4"; +} + +.cuIcon-square:before { + content: "\e6d5"; +} + +.cuIcon-squarecheck:before { + content: "\e6d6"; +} + +.cuIcon-round:before { + content: "\e6d7"; +} + +.cuIcon-roundaddfill:before { + content: "\e6d8"; +} + +.cuIcon-roundadd:before { + content: "\e6d9"; +} + +.cuIcon-add:before { + content: "\e6da"; +} + +.cuIcon-notificationforbidfill:before { + content: "\e6db"; +} + +.cuIcon-explorefill:before { + content: "\e6dd"; +} + +.cuIcon-fold:before { + content: "\e6de"; +} + +.cuIcon-game:before { + content: "\e6df"; +} + +.cuIcon-redpacket:before { + content: "\e6e0"; +} + +.cuIcon-selectionfill:before { + content: "\e6e1"; +} + +.cuIcon-similar:before { + content: "\e6e2"; +} + +.cuIcon-appreciatefill:before { + content: "\e6e3"; +} + +.cuIcon-infofill:before { + content: "\e6e4"; +} + +.cuIcon-info:before { + content: "\e6e5"; +} + +.cuIcon-forwardfill:before { + content: "\e6ea"; +} + +.cuIcon-forward:before { + content: "\e6eb"; +} + +.cuIcon-rechargefill:before { + content: "\e6ec"; +} + +.cuIcon-recharge:before { + content: "\e6ed"; +} + +.cuIcon-vipcard:before { + content: "\e6ee"; +} + +.cuIcon-voice:before { + content: "\e6ef"; +} + +.cuIcon-voicefill:before { + content: "\e6f0"; +} + +.cuIcon-friendfavor:before { + content: "\e6f1"; +} + +.cuIcon-wifi:before { + content: "\e6f2"; +} + +.cuIcon-share:before { + content: "\e6f3"; +} + +.cuIcon-wefill:before { + content: "\e6f4"; +} + +.cuIcon-we:before { + content: "\e6f5"; +} + +.cuIcon-lightauto:before { + content: "\e6f6"; +} + +.cuIcon-lightforbid:before { + content: "\e6f7"; +} + +.cuIcon-lightfill:before { + content: "\e6f8"; +} + +.cuIcon-camerarotate:before { + content: "\e6f9"; +} + +.cuIcon-light:before { + content: "\e6fa"; +} + +.cuIcon-barcode:before { + content: "\e6fb"; +} + +.cuIcon-flashlightclose:before { + content: "\e6fc"; +} + +.cuIcon-flashlightopen:before { + content: "\e6fd"; +} + +.cuIcon-searchlist:before { + content: "\e6fe"; +} + +.cuIcon-service:before { + content: "\e6ff"; +} + +.cuIcon-sort:before { + content: "\e700"; +} + +.cuIcon-down:before { + content: "\e703"; +} + +.cuIcon-mobile:before { + content: "\e704"; +} + +.cuIcon-mobilefill:before { + content: "\e705"; +} + +.cuIcon-copy:before { + content: "\e706"; +} + +.cuIcon-countdownfill:before { + content: "\e707"; +} + +.cuIcon-countdown:before { + content: "\e708"; +} + +.cuIcon-noticefill:before { + content: "\e709"; +} + +.cuIcon-notice:before { + content: "\e70a"; +} + +.cuIcon-upstagefill:before { + content: "\e70e"; +} + +.cuIcon-upstage:before { + content: "\e70f"; +} + +.cuIcon-babyfill:before { + content: "\e710"; +} + +.cuIcon-baby:before { + content: "\e711"; +} + +.cuIcon-brandfill:before { + content: "\e712"; +} + +.cuIcon-brand:before { + content: "\e713"; +} + +.cuIcon-choicenessfill:before { + content: "\e714"; +} + +.cuIcon-choiceness:before { + content: "\e715"; +} + +.cuIcon-clothesfill:before { + content: "\e716"; +} + +.cuIcon-clothes:before { + content: "\e717"; +} + +.cuIcon-creativefill:before { + content: "\e718"; +} + +.cuIcon-creative:before { + content: "\e719"; +} + +.cuIcon-female:before { + content: "\e71a"; +} + +.cuIcon-keyboard:before { + content: "\e71b"; +} + +.cuIcon-male:before { + content: "\e71c"; +} + +.cuIcon-newfill:before { + content: "\e71d"; +} + +.cuIcon-new:before { + content: "\e71e"; +} + +.cuIcon-pullleft:before { + content: "\e71f"; +} + +.cuIcon-pullright:before { + content: "\e720"; +} + +.cuIcon-rankfill:before { + content: "\e721"; +} + +.cuIcon-rank:before { + content: "\e722"; +} + +.cuIcon-bad:before { + content: "\e723"; +} + +.cuIcon-cameraadd:before { + content: "\e724"; +} + +.cuIcon-focus:before { + content: "\e725"; +} + +.cuIcon-friendfill:before { + content: "\e726"; +} + +.cuIcon-cameraaddfill:before { + content: "\e727"; +} + +.cuIcon-apps:before { + content: "\e729"; +} + +.cuIcon-paintfill:before { + content: "\e72a"; +} + +.cuIcon-paint:before { + content: "\e72b"; +} + +.cuIcon-picfill:before { + content: "\e72c"; +} + +.cuIcon-refresharrow:before { + content: "\e72d"; +} + +.cuIcon-colorlens:before { + content: "\e6e6"; +} + +.cuIcon-markfill:before { + content: "\e730"; +} + +.cuIcon-mark:before { + content: "\e731"; +} + +.cuIcon-presentfill:before { + content: "\e732"; +} + +.cuIcon-repeal:before { + content: "\e733"; +} + +.cuIcon-album:before { + content: "\e734"; +} + +.cuIcon-peoplefill:before { + content: "\e735"; +} + +.cuIcon-people:before { + content: "\e736"; +} + +.cuIcon-servicefill:before { + content: "\e737"; +} + +.cuIcon-repair:before { + content: "\e738"; +} + +.cuIcon-file:before { + content: "\e739"; +} + +.cuIcon-repairfill:before { + content: "\e73a"; +} + +.cuIcon-taoxiaopu:before { + content: "\e73b"; +} + +.cuIcon-weixin:before { + content: "\e612"; +} + +.cuIcon-attentionfill:before { + content: "\e73c"; +} + +.cuIcon-attention:before { + content: "\e73d"; +} + +.cuIcon-commandfill:before { + content: "\e73e"; +} + +.cuIcon-command:before { + content: "\e73f"; +} + +.cuIcon-communityfill:before { + content: "\e740"; +} + +.cuIcon-community:before { + content: "\e741"; +} + +.cuIcon-read:before { + content: "\e742"; +} + +.cuIcon-calendar:before { + content: "\e74a"; +} + +.cuIcon-cut:before { + content: "\e74b"; +} + +.cuIcon-magic:before { + content: "\e74c"; +} + +.cuIcon-backwardfill:before { + content: "\e74d"; +} + +.cuIcon-playfill:before { + content: "\e74f"; +} + +.cuIcon-stop:before { + content: "\e750"; +} + +.cuIcon-tagfill:before { + content: "\e751"; +} + +.cuIcon-tag:before { + content: "\e752"; +} + +.cuIcon-group:before { + content: "\e753"; +} + +.cuIcon-all:before { + content: "\e755"; +} + +.cuIcon-backdelete:before { + content: "\e756"; +} + +.cuIcon-hotfill:before { + content: "\e757"; +} + +.cuIcon-hot:before { + content: "\e758"; +} + +.cuIcon-post:before { + content: "\e759"; +} + +.cuIcon-radiobox:before { + content: "\e75b"; +} + +.cuIcon-rounddown:before { + content: "\e75c"; +} + +.cuIcon-upload:before { + content: "\e75d"; +} + +.cuIcon-writefill:before { + content: "\e760"; +} + +.cuIcon-write:before { + content: "\e761"; +} + +.cuIcon-radioboxfill:before { + content: "\e763"; +} + +.cuIcon-punch:before { + content: "\e764"; +} + +.cuIcon-shake:before { + content: "\e765"; +} + +.cuIcon-move:before { + content: "\e768"; +} + +.cuIcon-safe:before { + content: "\e769"; +} + +.cuIcon-activityfill:before { + content: "\e775"; +} + +.cuIcon-crownfill:before { + content: "\e776"; +} + +.cuIcon-crown:before { + content: "\e777"; +} + +.cuIcon-goodsfill:before { + content: "\e778"; +} + +.cuIcon-messagefill:before { + content: "\e779"; +} + +.cuIcon-profilefill:before { + content: "\e77a"; +} + +.cuIcon-sound:before { + content: "\e77b"; +} + +.cuIcon-sponsorfill:before { + content: "\e77c"; +} + +.cuIcon-sponsor:before { + content: "\e77d"; +} + +.cuIcon-upblock:before { + content: "\e77e"; +} + +.cuIcon-weblock:before { + content: "\e77f"; +} + +.cuIcon-weunblock:before { + content: "\e780"; +} + +.cuIcon-my:before { + content: "\e78b"; +} + +.cuIcon-myfill:before { + content: "\e78c"; +} + +.cuIcon-emojifill:before { + content: "\e78d"; +} + +.cuIcon-emojiflashfill:before { + content: "\e78e"; +} + +.cuIcon-flashbuyfill:before { + content: "\e78f"; +} + +.cuIcon-text:before { + content: "\e791"; +} + +.cuIcon-goodsfavor:before { + content: "\e794"; +} + +.cuIcon-musicfill:before { + content: "\e795"; +} + +.cuIcon-musicforbidfill:before { + content: "\e796"; +} + +.cuIcon-card:before { + content: "\e624"; +} + +.cuIcon-triangledownfill:before { + content: "\e79b"; +} + +.cuIcon-triangleupfill:before { + content: "\e79c"; +} + +.cuIcon-roundleftfill-copy:before { + content: "\e79e"; +} + +.cuIcon-font:before { + content: "\e76a"; +} + +.cuIcon-title:before { + content: "\e82f"; +} + +.cuIcon-recordfill:before { + content: "\e7a4"; +} + +.cuIcon-record:before { + content: "\e7a6"; +} + +.cuIcon-cardboardfill:before { + content: "\e7a9"; +} + +.cuIcon-cardboard:before { + content: "\e7aa"; +} + +.cuIcon-formfill:before { + content: "\e7ab"; +} + +.cuIcon-coin:before { + content: "\e7ac"; +} + +.cuIcon-cardboardforbid:before { + content: "\e7af"; +} + +.cuIcon-circlefill:before { + content: "\e7b0"; +} + +.cuIcon-circle:before { + content: "\e7b1"; +} + +.cuIcon-attentionforbid:before { + content: "\e7b2"; +} + +.cuIcon-attentionforbidfill:before { + content: "\e7b3"; +} + +.cuIcon-attentionfavorfill:before { + content: "\e7b4"; +} + +.cuIcon-attentionfavor:before { + content: "\e7b5"; +} + +.cuIcon-titles:before { + content: "\e701"; +} + +.cuIcon-icloading:before { + content: "\e67a"; +} + +.cuIcon-full:before { + content: "\e7bc"; +} + +.cuIcon-mail:before { + content: "\e7bd"; +} + +.cuIcon-peoplelist:before { + content: "\e7be"; +} + +.cuIcon-goodsnewfill:before { + content: "\e7bf"; +} + +.cuIcon-goodsnew:before { + content: "\e7c0"; +} + +.cuIcon-medalfill:before { + content: "\e7c1"; +} + +.cuIcon-medal:before { + content: "\e7c2"; +} + +.cuIcon-newsfill:before { + content: "\e7c3"; +} + +.cuIcon-newshotfill:before { + content: "\e7c4"; +} + +.cuIcon-newshot:before { + content: "\e7c5"; +} + +.cuIcon-news:before { + content: "\e7c6"; +} + +.cuIcon-videofill:before { + content: "\e7c7"; +} + +.cuIcon-video:before { + content: "\e7c8"; +} + +.cuIcon-exit:before { + content: "\e7cb"; +} + +.cuIcon-skinfill:before { + content: "\e7cc"; +} + +.cuIcon-skin:before { + content: "\e7cd"; +} + +.cuIcon-moneybagfill:before { + content: "\e7ce"; +} + +.cuIcon-usefullfill:before { + content: "\e7cf"; +} + +.cuIcon-usefull:before { + content: "\e7d0"; +} + +.cuIcon-moneybag:before { + content: "\e7d1"; +} + +.cuIcon-redpacket_fill:before { + content: "\e7d3"; +} + +.cuIcon-subscription:before { + content: "\e7d4"; +} + +.cuIcon-loading1:before { + content: "\e633"; +} + +.cuIcon-github:before { + content: "\e692"; +} + +.cuIcon-global:before { + content: "\e7eb"; +} + +.cuIcon-settingsfill:before { + content: "\e6ab"; +} + +.cuIcon-back_android:before { + content: "\e7ed"; +} + +.cuIcon-expressman:before { + content: "\e7ef"; +} + +.cuIcon-evaluate_fill:before { + content: "\e7f0"; +} + +.cuIcon-group_fill:before { + content: "\e7f5"; +} + +.cuIcon-play_forward_fill:before { + content: "\e7f6"; +} + +.cuIcon-deliver_fill:before { + content: "\e7f7"; +} + +.cuIcon-notice_forbid_fill:before { + content: "\e7f8"; +} + +.cuIcon-fork:before { + content: "\e60c"; +} + +.cuIcon-pick:before { + content: "\e7fa"; +} + +.cuIcon-wenzi:before { + content: "\e6a7"; +} + +.cuIcon-ellipse:before { + content: "\e600"; +} + +.cuIcon-qr_code:before { + content: "\e61b"; +} + +.cuIcon-dianhua:before { + content: "\e64d"; +} + +.cuIcon-cuIcon:before { + content: "\e602"; +} + +.cuIcon-loading2:before { + content: "\e7f1"; +} + +.cuIcon-btn:before { + content: "\e601"; +} diff --git a/static/colorui/main.css b/static/colorui/main.css new file mode 100644 index 0000000..b9dbc97 --- /dev/null +++ b/static/colorui/main.css @@ -0,0 +1,3912 @@ +/* + ColorUi for uniApp v2.1.6 | by 文晓港 2019-05-31 10:44:24 + 仅供学习交流,如作它用所承受的法律责任一概与作者无关 + + *使用ColorUi开发扩展与插件时,请注明基于ColorUi开发 + + (QQ交流群:240787041) +*/ + +/* ================== + 初始化 + ==================== */ +body { + background-color: #f1f1f1; + font-size: 28upx; + color: #333333; + font-family: Helvetica Neue, Helvetica, sans-serif; +} + +view, +scroll-view, +swiper, +button, +input, +textarea, +label, +navigator, +image { + box-sizing: border-box; +} + +.round { + border-radius: 5000upx; +} + +.radius { + border-radius: 6upx; +} + +/* ================== + 图片 + ==================== */ + +image { + max-width: 100%; + display: inline-block; + position: relative; + z-index: 0; +} + +image.loading::before { + content: ""; + background-color: #f5f5f5; + display: block; + position: absolute; + width: 100%; + height: 100%; + z-index: -2; +} + +image.loading::after { + content: "\e7f1"; + font-family: "cuIcon"; + position: absolute; + top: 0; + left: 0; + width: 32upx; + height: 32upx; + line-height: 32upx; + right: 0; + bottom: 0; + z-index: -1; + font-size: 32upx; + margin: auto; + color: #ccc; + -webkit-animation: cuIcon-spin 2s infinite linear; + animation: cuIcon-spin 2s infinite linear; + display: block; +} + +.response { + width: 100%; +} + +/* ================== + 开关 + ==================== */ + +switch, +checkbox, +radio { + position: relative; +} + +switch::after, +switch::before { + font-family: "cuIcon"; + content: "\e645"; + position: absolute; + color: #ffffff !important; + top: 0%; + left: 0upx; + font-size: 26upx; + line-height: 26px; + width: 50%; + text-align: center; + pointer-events: none; + transform: scale(0, 0); + transition: all 0.3s ease-in-out 0s; + z-index: 9; + bottom: 0; + height: 26px; + margin: auto; +} + +switch::before { + content: "\e646"; + right: 0; + transform: scale(1, 1); + left: auto; +} + +switch[checked]::after, +switch.checked::after { + transform: scale(1, 1); +} + +switch[checked]::before, +switch.checked::before { + transform: scale(0, 0); +} + +/* #ifndef MP-ALIPAY */ +radio::before, +checkbox::before { + font-family: "cuIcon"; + content: "\e645"; + position: absolute; + color: #ffffff !important; + top: 50%; + margin-top: -8px; + right: 5px; + font-size: 32upx; + line-height: 16px; + pointer-events: none; + transform: scale(1, 1); + transition: all 0.3s ease-in-out 0s; + z-index: 9; +} + +radio .wx-radio-input, +checkbox .wx-checkbox-input, +radio .uni-radio-input, +checkbox .uni-checkbox-input { + margin: 0; + width: 24px; + height: 24px; +} + +checkbox.round .wx-checkbox-input, +checkbox.round .uni-checkbox-input { + border-radius: 100upx; +} + +/* #endif */ + +switch[checked]::before { + transform: scale(0, 0); +} + +switch .wx-switch-input, +switch .uni-switch-input { + border: none; + padding: 0 24px; + width: 48px; + height: 26px; + margin: 0; + border-radius: 100upx; +} + +switch .wx-switch-input:not([class*="bg-"]), +switch .uni-switch-input:not([class*="bg-"]) { + background: #8799a3 !important; +} + +switch .wx-switch-input::after, +switch .uni-switch-input::after { + margin: auto; + width: 26px; + height: 26px; + border-radius: 100upx; + left: 0upx; + top: 0upx; + bottom: 0upx; + position: absolute; + transform: scale(0.9, 0.9); + transition: all 0.1s ease-in-out 0s; +} + +switch .wx-switch-input.wx-switch-input-checked::after, +switch .uni-switch-input.uni-switch-input-checked::after { + margin: auto; + left: 22px; + box-shadow: none; + transform: scale(0.9, 0.9); +} + +radio-group { + display: inline-block; +} + + + +switch.radius .wx-switch-input::after, +switch.radius .wx-switch-input, +switch.radius .wx-switch-input::before, +switch.radius .uni-switch-input::after, +switch.radius .uni-switch-input, +switch.radius .uni-switch-input::before { + border-radius: 10upx; +} + +switch .wx-switch-input::before, +radio.radio::before, +checkbox .wx-checkbox-input::before, +radio .wx-radio-input::before, +switch .uni-switch-input::before, +radio.radio::before, +checkbox .uni-checkbox-input::before, +radio .uni-radio-input::before { + display: none; +} + +radio.radio[checked]::after, +radio.radio .uni-radio-input-checked::after { + content: ""; + background-color: transparent; + display: block; + position: absolute; + width: 8px; + height: 8px; + z-index: 999; + top: 0upx; + left: 0upx; + right: 0; + bottom: 0; + margin: auto; + border-radius: 200upx; + /* #ifndef MP */ + border: 7px solid #ffffff !important; + /* #endif */ + + /* #ifdef MP */ + border: 8px solid #ffffff !important; + /* #endif */ +} + +.switch-sex::after { + content: "\e71c"; +} + +.switch-sex::before { + content: "\e71a"; +} + +.switch-sex .wx-switch-input, +.switch-sex .uni-switch-input { + background: #e54d42 !important; + border-color: #e54d42 !important; +} + +.switch-sex[checked] .wx-switch-input, +.switch-sex.checked .uni-switch-input { + background: #0081ff !important; + border-color: #0081ff !important; +} + +switch.red[checked] .wx-switch-input.wx-switch-input-checked, +checkbox.red[checked] .wx-checkbox-input, +radio.red[checked] .wx-radio-input, +switch.red.checked .uni-switch-input.uni-switch-input-checked, +checkbox.red.checked .uni-checkbox-input, +radio.red.checked .uni-radio-input { + background-color: #e54d42 !important; + border-color: #e54d42 !important; + color: #ffffff !important; +} + +switch.orange[checked] .wx-switch-input, +checkbox.orange[checked] .wx-checkbox-input, +radio.orange[checked] .wx-radio-input, +switch.orange.checked .uni-switch-input, +checkbox.orange.checked .uni-checkbox-input, +radio.orange.checked .uni-radio-input { + background-color: #f37b1d !important; + border-color: #f37b1d !important; + color: #ffffff !important; +} + +switch.yellow[checked] .wx-switch-input, +checkbox.yellow[checked] .wx-checkbox-input, +radio.yellow[checked] .wx-radio-input, +switch.yellow.checked .uni-switch-input, +checkbox.yellow.checked .uni-checkbox-input, +radio.yellow.checked .uni-radio-input { + background-color: #fbbd08 !important; + border-color: #fbbd08 !important; + color: #333333 !important; +} + +switch.olive[checked] .wx-switch-input, +checkbox.olive[checked] .wx-checkbox-input, +radio.olive[checked] .wx-radio-input, +switch.olive.checked .uni-switch-input, +checkbox.olive.checked .uni-checkbox-input, +radio.olive.checked .uni-radio-input { + background-color: #8dc63f !important; + border-color: #8dc63f !important; + color: #ffffff !important; +} + +switch.green[checked] .wx-switch-input, +switch[checked] .wx-switch-input, +checkbox.green[checked] .wx-checkbox-input, +checkbox[checked] .wx-checkbox-input, +radio.green[checked] .wx-radio-input, +radio[checked] .wx-radio-input, +switch.green.checked .uni-switch-input, +switch.checked .uni-switch-input, +checkbox.green.checked .uni-checkbox-input, +checkbox.checked .uni-checkbox-input, +radio.green.checked .uni-radio-input, +radio.checked .uni-radio-input { + background-color: #39b54a !important; + border-color: #39b54a !important; + color: #ffffff !important; + border-color: #39B54A !important; +} + +switch.cyan[checked] .wx-switch-input, +checkbox.cyan[checked] .wx-checkbox-input, +radio.cyan[checked] .wx-radio-input, +switch.cyan.checked .uni-switch-input, +checkbox.cyan.checked .uni-checkbox-input, +radio.cyan.checked .uni-radio-input { + background-color: #1cbbb4 !important; + border-color: #1cbbb4 !important; + color: #ffffff !important; +} + +switch.blue[checked] .wx-switch-input, +checkbox.blue[checked] .wx-checkbox-input, +radio.blue[checked] .wx-radio-input, +switch.blue.checked .uni-switch-input, +checkbox.blue.checked .uni-checkbox-input, +radio.blue.checked .uni-radio-input { + background-color: #0081ff !important; + border-color: #0081ff !important; + color: #ffffff !important; +} + +switch.purple[checked] .wx-switch-input, +checkbox.purple[checked] .wx-checkbox-input, +radio.purple[checked] .wx-radio-input, +switch.purple.checked .uni-switch-input, +checkbox.purple.checked .uni-checkbox-input, +radio.purple.checked .uni-radio-input { + background-color: #6739b6 !important; + border-color: #6739b6 !important; + color: #ffffff !important; +} + +switch.mauve[checked] .wx-switch-input, +checkbox.mauve[checked] .wx-checkbox-input, +radio.mauve[checked] .wx-radio-input, +switch.mauve.checked .uni-switch-input, +checkbox.mauve.checked .uni-checkbox-input, +radio.mauve.checked .uni-radio-input { + background-color: #9c26b0 !important; + border-color: #9c26b0 !important; + color: #ffffff !important; +} + +switch.pink[checked] .wx-switch-input, +checkbox.pink[checked] .wx-checkbox-input, +radio.pink[checked] .wx-radio-input, +switch.pink.checked .uni-switch-input, +checkbox.pink.checked .uni-checkbox-input, +radio.pink.checked .uni-radio-input { + background-color: #e03997 !important; + border-color: #e03997 !important; + color: #ffffff !important; +} + +switch.brown[checked] .wx-switch-input, +checkbox.brown[checked] .wx-checkbox-input, +radio.brown[checked] .wx-radio-input, +switch.brown.checked .uni-switch-input, +checkbox.brown.checked .uni-checkbox-input, +radio.brown.checked .uni-radio-input { + background-color: #a5673f !important; + border-color: #a5673f !important; + color: #ffffff !important; +} + +switch.grey[checked] .wx-switch-input, +checkbox.grey[checked] .wx-checkbox-input, +radio.grey[checked] .wx-radio-input, +switch.grey.checked .uni-switch-input, +checkbox.grey.checked .uni-checkbox-input, +radio.grey.checked .uni-radio-input { + background-color: #8799a3 !important; + border-color: #8799a3 !important; + color: #ffffff !important; +} + +switch.gray[checked] .wx-switch-input, +checkbox.gray[checked] .wx-checkbox-input, +radio.gray[checked] .wx-radio-input, +switch.gray.checked .uni-switch-input, +checkbox.gray.checked .uni-checkbox-input, +radio.gray.checked .uni-radio-input { + background-color: #f0f0f0 !important; + border-color: #f0f0f0 !important; + color: #333333 !important; +} + +switch.black[checked] .wx-switch-input, +checkbox.black[checked] .wx-checkbox-input, +radio.black[checked] .wx-radio-input, +switch.black.checked .uni-switch-input, +checkbox.black.checked .uni-checkbox-input, +radio.black.checked .uni-radio-input { + background-color: #333333 !important; + border-color: #333333 !important; + color: #ffffff !important; +} + +switch.white[checked] .wx-switch-input, +checkbox.white[checked] .wx-checkbox-input, +radio.white[checked] .wx-radio-input, +switch.white.checked .uni-switch-input, +checkbox.white.checked .uni-checkbox-input, +radio.white.checked .uni-radio-input { + background-color: #ffffff !important; + border-color: #ffffff !important; + color: #333333 !important; +} + +/* ================== + 边框 + ==================== */ + +/* -- 实线 -- */ + +.solid, +.solid-top, +.solid-right, +.solid-bottom, +.solid-left, +.solids, +.solids-top, +.solids-right, +.solids-bottom, +.solids-left, +.dashed, +.dashed-top, +.dashed-right, +.dashed-bottom, +.dashed-left { + position: relative; +} + +.solid::after, +.solid-top::after, +.solid-right::after, +.solid-bottom::after, +.solid-left::after, +.solids::after, +.solids-top::after, +.solids-right::after, +.solids-bottom::after, +.solids-left::after, +.dashed::after, +.dashed-top::after, +.dashed-right::after, +.dashed-bottom::after, +.dashed-left::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border-radius: inherit; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; +} + +.solid::after { + border: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-top::after { + border-top: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-right::after { + border-right: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-bottom::after { + border-bottom: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solid-left::after { + border-left: 1upx solid rgba(0, 0, 0, 0.1); +} + +.solids::after { + border: 8upx solid #eee; +} + +.solids-top::after { + border-top: 8upx solid #eee; +} + +.solids-right::after { + border-right: 8upx solid #eee; +} + +.solids-bottom::after { + border-bottom: 8upx solid #eee; +} + +.solids-left::after { + border-left: 8upx solid #eee; +} + +/* -- 虚线 -- */ + +.dashed::after { + border: 1upx dashed #ddd; +} + +.dashed-top::after { + border-top: 1upx dashed #ddd; +} + +.dashed-right::after { + border-right: 1upx dashed #ddd; +} + +.dashed-bottom::after { + border-bottom: 1upx dashed #ddd; +} + +.dashed-left::after { + border-left: 1upx dashed #ddd; +} + +/* -- 阴影 -- */ + +.shadow[class*='white'] { + --ShadowSize: 0 1upx 6upx; +} + +.shadow-lg { + --ShadowSize: 0upx 40upx 100upx 0upx; +} + +.shadow-warp { + position: relative; + box-shadow: 0 0 10upx rgba(0, 0, 0, 0.1); +} + +.shadow-warp:before, +.shadow-warp:after { + position: absolute; + content: ""; + top: 20upx; + bottom: 30upx; + left: 20upx; + width: 50%; + box-shadow: 0 30upx 20upx rgba(0, 0, 0, 0.2); + transform: rotate(-3deg); + z-index: -1; +} + +.shadow-warp:after { + right: 20upx; + left: auto; + transform: rotate(3deg); +} + +.shadow-blur { + position: relative; +} + +.shadow-blur::before { + content: ""; + display: block; + background: inherit; + filter: blur(10upx); + position: absolute; + width: 100%; + height: 100%; + top: 10upx; + left: 10upx; + z-index: -1; + opacity: 0.4; + transform-origin: 0 0; + border-radius: inherit; + transform: scale(1, 1); +} + +/* ================== + 按钮 + ==================== */ + +.cu-btn { + position: relative; + border: 0upx; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 0 30upx; + font-size: 28upx; + height: 64upx; + line-height: 1; + text-align: center; + text-decoration: none; + overflow: visible; + margin-left: initial; + transform: translate(0upx, 0upx); + margin-right: initial; +} + +.cu-btn::after { + display: none; +} + +.cu-btn:not([class*="bg-"]) { + background-color: #f0f0f0; +} + +.cu-btn[class*="line"] { + background-color: transparent; +} + +.cu-btn[class*="line"]::after { + content: " "; + display: block; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1upx solid currentColor; + transform: scale(0.5); + transform-origin: 0 0; + box-sizing: border-box; + border-radius: 12upx; + z-index: 1; + pointer-events: none; +} + +.cu-btn.round[class*="line"]::after { + border-radius: 1000upx; +} + +.cu-btn[class*="lines"]::after { + border: 6upx solid currentColor; +} + +.cu-btn[class*="bg-"]::after { + display: none; +} + +.cu-btn.sm { + padding: 0 20upx; + font-size: 20upx; + height: 48upx; +} + +.cu-btn.lg { + padding: 0 40upx; + font-size: 32upx; + height: 80upx; +} + +.cu-btn.cuIcon.sm { + width: 48upx; + height: 48upx; +} + +.cu-btn.cuIcon { + width: 64upx; + height: 64upx; + border-radius: 500upx; + padding: 0; +} + +button.cuIcon.lg { + width: 80upx; + height: 80upx; +} + +.cu-btn.shadow-blur::before { + top: 4upx; + left: 4upx; + filter: blur(6upx); + opacity: 0.6; +} + +.cu-btn.button-hover { + transform: translate(1upx, 1upx); +} + +.block { + display: block; +} + +.cu-btn.block { + display: flex; +} + +.cu-btn[disabled] { + opacity: 0.6; + color: #ffffff; +} + +/* ================== + 徽章 + ==================== */ + +.cu-tag { + font-size: 24upx; + vertical-align: middle; + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 0upx 16upx; + height: 48upx; + font-family: Helvetica Neue, Helvetica, sans-serif; + white-space: nowrap; +} + +.cu-tag:not([class*="bg"]):not([class*="line"]) { + background-color: #f1f1f1; +} + +.cu-tag[class*="line-"]::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1upx solid currentColor; + transform: scale(0.5); + transform-origin: 0 0; + box-sizing: border-box; + border-radius: inherit; + z-index: 1; + pointer-events: none; +} + +.cu-tag.radius[class*="line"]::after { + border-radius: 12upx; +} + +.cu-tag.round[class*="line"]::after { + border-radius: 1000upx; +} + +.cu-tag[class*="line-"]::after { + border-radius: 0; +} + +.cu-tag+.cu-tag { + margin-left: 10upx; +} + +.cu-tag.sm { + font-size: 20upx; + padding: 0upx 12upx; + height: 32upx; +} + +.cu-capsule { + display: inline-flex; + vertical-align: middle; +} + +.cu-capsule+.cu-capsule { + margin-left: 10upx; +} + +.cu-capsule .cu-tag { + margin: 0; +} + +.cu-capsule .cu-tag[class*="line-"]:last-child::after { + border-left: 0upx solid transparent; +} + +.cu-capsule .cu-tag[class*="line-"]:first-child::after { + border-right: 0upx solid transparent; +} + +.cu-capsule.radius .cu-tag:first-child { + border-top-left-radius: 6upx; + border-bottom-left-radius: 6upx; +} + +.cu-capsule.radius .cu-tag:last-child::after, +.cu-capsule.radius .cu-tag[class*="line-"] { + border-top-right-radius: 12upx; + border-bottom-right-radius: 12upx; +} + +.cu-capsule.round .cu-tag:first-child { + border-top-left-radius: 200upx; + border-bottom-left-radius: 200upx; + text-indent: 4upx; +} + +.cu-capsule.round .cu-tag:last-child::after, +.cu-capsule.round .cu-tag:last-child { + border-top-right-radius: 200upx; + border-bottom-right-radius: 200upx; + text-indent: -4upx; +} + +.cu-tag.badge { + border-radius: 200upx; + position: absolute; + top: -10upx; + right: -10upx; + font-size: 20upx; + padding: 0upx 10upx; + height: 28upx; + color: #ffffff; +} + +.cu-tag.badge:not([class*="bg-"]) { + background-color: #dd514c; +} + +.cu-tag:empty:not([class*="cuIcon-"]) { + padding: 0upx; + width: 16upx; + height: 16upx; + top: -4upx; + right: -4upx; +} + +.cu-tag[class*="cuIcon-"] { + width: 32upx; + height: 32upx; + top: -4upx; + right: -4upx; +} + +/* ================== + 头像 + ==================== */ + +.cu-avatar { + font-variant: small-caps; + margin: 0; + padding: 0; + display: inline-flex; + text-align: center; + justify-content: center; + align-items: center; + background-color: #ccc; + color: #ffffff; + white-space: nowrap; + position: relative; + width: 64upx; + height: 64upx; + background-size: cover; + background-position: center; + vertical-align: middle; + font-size: 1.5em; +} + +.cu-avatar.sm { + width: 48upx; + height: 48upx; + font-size: 1em; +} + +.cu-avatar.lg { + width: 96upx; + height: 96upx; + font-size: 2em; +} + +.cu-avatar.xl { + width: 128upx; + height: 128upx; + font-size: 2.5em; +} + +.cu-avatar .avatar-text { + font-size: 0.4em; +} + +.cu-avatar-group { + direction: rtl; + unicode-bidi: bidi-override; + padding: 0 10upx 0 40upx; + display: inline-block; +} + +.cu-avatar-group .cu-avatar { + margin-left: -30upx; + border: 4upx solid #f1f1f1; + vertical-align: middle; +} + +.cu-avatar-group .cu-avatar.sm { + margin-left: -20upx; + border: 1upx solid #f1f1f1; +} + +/* ================== + 进度条 + ==================== */ + +.cu-progress { + overflow: hidden; + height: 28upx; + background-color: #ebeef5; + display: inline-flex; + align-items: center; + width: 100%; +} + +.cu-progress+view, +.cu-progress+text { + line-height: 1; +} + +.cu-progress.xs { + height: 10upx; +} + +.cu-progress.sm { + height: 20upx; +} + +.cu-progress view { + width: 0; + height: 100%; + align-items: center; + display: flex; + justify-items: flex-end; + justify-content: space-around; + font-size: 20upx; + color: #ffffff; + transition: width 0.6s ease; +} + +.cu-progress text { + align-items: center; + display: flex; + font-size: 20upx; + color: #333333; + text-indent: 10upx; +} + +.cu-progress.text-progress { + padding-right: 60upx; +} + +.cu-progress.striped view { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 72upx 72upx; +} + +.cu-progress.active view { + animation: progress-stripes 2s linear infinite; +} + +@keyframes progress-stripes { + from { + background-position: 72upx 0; + } + + to { + background-position: 0 0; + } +} + +/* ================== + 加载 + ==================== */ + +.cu-load { + display: block; + line-height: 3em; + text-align: center; +} + +.cu-load::before { + font-family: "cuIcon"; + display: inline-block; + margin-right: 6upx; +} + +.cu-load.loading::before { + content: "\e67a"; + animation: cuIcon-spin 2s infinite linear; +} + +.cu-load.loading::after { + content: "加载中..."; +} + +.cu-load.over::before { + content: "\e64a"; +} + +.cu-load.over::after { + content: "没有更多了"; +} + +.cu-load.erro::before { + content: "\e658"; +} + +.cu-load.erro::after { + content: "加载失败"; +} + +.cu-load.load-cuIcon::before { + font-size: 32upx; +} + +.cu-load.load-cuIcon::after { + display: none; +} + +.cu-load.load-cuIcon.over { + display: none; +} + +.cu-load.load-modal { + position: fixed; + top: 0; + right: 0; + bottom: 140upx; + left: 0; + margin: auto; + width: 260upx; + height: 260upx; + background-color: #ffffff; + border-radius: 10upx; + box-shadow: 0 0 0upx 2000upx rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + font-size: 28upx; + z-index: 9999; + line-height: 2.4em; +} + +.cu-load.load-modal [class*="cuIcon-"] { + font-size: 60upx; +} + +.cu-load.load-modal image { + width: 70upx; + height: 70upx; +} + +.cu-load.load-modal::after { + content: ""; + position: absolute; + background-color: #ffffff; + border-radius: 50%; + width: 200upx; + height: 200upx; + font-size: 10px; + border-top: 6upx solid rgba(0, 0, 0, 0.05); + border-right: 6upx solid rgba(0, 0, 0, 0.05); + border-bottom: 6upx solid rgba(0, 0, 0, 0.05); + border-left: 6upx solid #f37b1d; + animation: cuIcon-spin 1s infinite linear; + z-index: -1; +} + +.load-progress { + pointer-events: none; + top: 0; + position: fixed; + width: 100%; + left: 0; + z-index: 2000; +} + +.load-progress.hide { + display: none; +} + +.load-progress .load-progress-bar { + position: relative; + width: 100%; + height: 4upx; + overflow: hidden; + transition: all 200ms ease 0s; +} + +.load-progress .load-progress-spinner { + position: absolute; + top: 10upx; + right: 10upx; + z-index: 2000; + display: block; +} + +.load-progress .load-progress-spinner::after { + content: ""; + display: block; + width: 24upx; + height: 24upx; + -webkit-box-sizing: border-box; + box-sizing: border-box; + border: solid 4upx transparent; + border-top-color: inherit; + border-left-color: inherit; + border-radius: 50%; + -webkit-animation: load-progress-spinner 0.4s linear infinite; + animation: load-progress-spinner 0.4s linear infinite; +} + +@-webkit-keyframes load-progress-spinner { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes load-progress-spinner { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +/* ================== + 列表 + ==================== */ +.grayscale { + filter: grayscale(1); +} + +.cu-list+.cu-list { + margin-top: 30upx +} + +.cu-list>.cu-item { + transition: all .6s ease-in-out 0s; + transform: translateX(0upx) +} + +.cu-list>.cu-item.move-cur { + transform: translateX(-260upx) +} + +.cu-list>.cu-item .move { + position: absolute; + right: 0; + display: flex; + width: 260upx; + height: 100%; + transform: translateX(100%) +} + +.cu-list>.cu-item .move view { + display: flex; + flex: 1; + justify-content: center; + align-items: center +} + +.cu-list.menu-avatar { + overflow: hidden; +} + +.cu-list.menu-avatar>.cu-item { + position: relative; + display: flex; + padding-right: 10upx; + height: 140upx; + background-color: #ffffff; + justify-content: flex-end; + align-items: center +} + +.cu-list.menu-avatar>.cu-item>.cu-avatar { + position: absolute; + left: 30upx +} + +.cu-list.menu-avatar>.cu-item .flex .text-cut { + max-width: 510upx +} + +.cu-list.menu-avatar>.cu-item .content { + position: absolute; + left: 146upx; + width: calc(100% - 96upx - 60upx - 120upx - 20upx); + line-height: 1.6em; +} + +.cu-list.menu-avatar>.cu-item .content.flex-sub { + width: calc(100% - 96upx - 60upx - 20upx); +} + +.cu-list.menu-avatar>.cu-item .content>view:first-child { + font-size: 30upx; + display: flex; + align-items: center +} + +.cu-list.menu-avatar>.cu-item .content .cu-tag.sm { + display: inline-block; + margin-left: 10upx; + height: 28upx; + font-size: 16upx; + line-height: 32upx +} + +.cu-list.menu-avatar>.cu-item .action { + width: 100upx; + text-align: center +} + +.cu-list.menu-avatar>.cu-item .action view+view { + margin-top: 10upx +} + +.cu-list.menu-avatar.comment>.cu-item .content { + position: relative; + left: 0; + width: auto; + flex: 1; +} + +.cu-list.menu-avatar.comment>.cu-item { + padding: 30upx 30upx 30upx 120upx; + height: auto +} + +.cu-list.menu-avatar.comment .cu-avatar { + align-self: flex-start +} + +.cu-list.menu>.cu-item { + position: relative; + display: flex; + padding: 0 30upx; + min-height: 100upx; + background-color: #ffffff; + justify-content: space-between; + align-items: center +} + +.cu-list.menu>.cu-item:last-child:after { + border: none +} + +.cu-list.menu-avatar>.cu-item:after, +.cu-list.menu>.cu-item:after { + position: absolute; + top: 0; + left: 0; + box-sizing: border-box; + width: 200%; + height: 200%; + border-bottom: 1upx solid #ddd; + border-radius: inherit; + content: " "; + transform: scale(.5); + transform-origin: 0 0; + pointer-events: none +} + +.cu-list.menu>.cu-item.grayscale { + background-color: #f5f5f5 +} + +.cu-list.menu>.cu-item.cur { + background-color: #fcf7e9 +} + +.cu-list.menu>.cu-item.arrow { + padding-right: 90upx +} + +.cu-list.menu>.cu-item.arrow:before { + position: absolute; + top: 0; + right: 30upx; + bottom: 0; + display: block; + margin: auto; + width: 30upx; + height: 30upx; + color: #8799a3; + content: "\e6a3"; + text-align: center; + font-size: 34upx; + font-family: cuIcon; + line-height: 30upx +} + +.cu-list.menu>.cu-item button.content { + padding: 0; + background-color: transparent; + justify-content: flex-start +} + +.cu-list.menu>.cu-item button.content:after { + display: none +} + +.cu-list.menu>.cu-item .cu-avatar-group .cu-avatar { + border-color: #ffffff +} + +.cu-list.menu>.cu-item .content>view:first-child { + display: flex; + align-items: center +} + +.cu-list.menu>.cu-item .content>text[class*=cuIcon] { + display: inline-block; + margin-right: 10upx; + width: 1.6em; + text-align: center +} + +.cu-list.menu>.cu-item .content>image { + display: inline-block; + margin-right: 10upx; + width: 1.6em; + height: 1.6em; + vertical-align: middle +} + +.cu-list.menu>.cu-item .content { + font-size: 30upx; + line-height: 1.6em; + flex: 1 +} + +.cu-list.menu>.cu-item .content .cu-tag.sm { + display: inline-block; + margin-left: 10upx; + height: 28upx; + font-size: 16upx; + line-height: 32upx +} + +.cu-list.menu>.cu-item .action .cu-tag:empty { + right: 10upx +} + +.cu-list.menu { + display: block; + overflow: hidden +} + +.cu-list.menu.sm-border>.cu-item:after { + left: 30upx; + width: calc(200% - 120upx) +} + +.cu-list.grid>.cu-item { + position: relative; + display: flex; + padding: 20upx 0 30upx; + transition-duration: 0s; + flex-direction: column +} + +.cu-list.grid>.cu-item:after { + position: absolute; + top: 0; + left: 0; + box-sizing: border-box; + width: 200%; + height: 200%; + border-right: 1px solid rgba(0, 0, 0, .1); + border-bottom: 1px solid rgba(0, 0, 0, .1); + border-radius: inherit; + content: " "; + transform: scale(.5); + transform-origin: 0 0; + pointer-events: none +} + +.cu-list.grid>.cu-item text { + display: block; + margin-top: 10upx; + color: #888; + font-size: 26upx; + line-height: 40upx +} + +.cu-list.grid>.cu-item [class*=cuIcon] { + position: relative; + display: block; + margin-top: 20upx; + width: 100%; + font-size: 48upx +} + +.cu-list.grid>.cu-item .cu-tag { + right: auto; + left: 50%; + margin-left: 20upx +} + +.cu-list.grid { + background-color: #ffffff; + text-align: center +} + +.cu-list.grid.no-border>.cu-item { + padding-top: 10upx; + padding-bottom: 20upx +} + +.cu-list.grid.no-border>.cu-item:after { + border: none +} + +.cu-list.grid.no-border { + padding: 20upx 10upx +} + +.cu-list.grid.col-3>.cu-item:nth-child(3n):after, +.cu-list.grid.col-4>.cu-item:nth-child(4n):after, +.cu-list.grid.col-5>.cu-item:nth-child(5n):after { + border-right-width: 0 +} + +.cu-list.card-menu { + overflow: hidden; + margin-right: 30upx; + margin-left: 30upx; + border-radius: 20upx +} + + +/* ================== + 操作条 + ==================== */ + +.cu-bar { + display: flex; + position: relative; + align-items: center; + min-height: 100upx; + justify-content: space-between; +} + +.cu-bar .action { + display: flex; + align-items: center; + height: 100%; + justify-content: center; + max-width: 100%; +} + +.cu-bar .action.border-title { + position: relative; + top: -10upx; +} + +.cu-bar .action.border-title text[class*="bg-"]:last-child { + position: absolute; + bottom: -0.5rem; + min-width: 2rem; + height: 6upx; + left: 0; +} + +.cu-bar .action.sub-title { + position: relative; + top: -0.2rem; +} + +.cu-bar .action.sub-title text { + position: relative; + z-index: 1; +} + +.cu-bar .action.sub-title text[class*="bg-"]:last-child { + position: absolute; + display: inline-block; + bottom: -0.2rem; + border-radius: 6upx; + width: 100%; + height: 0.6rem; + left: 0.6rem; + opacity: 0.3; + z-index: 0; +} + +.cu-bar .action.sub-title text[class*="text-"]:last-child { + position: absolute; + display: inline-block; + bottom: -0.7rem; + left: 0.5rem; + opacity: 0.2; + z-index: 0; + text-align: right; + font-weight: 900; + font-size: 36upx; +} + +.cu-bar.justify-center .action.border-title text:last-child, +.cu-bar.justify-center .action.sub-title text:last-child { + left: 0; + right: 0; + margin: auto; + text-align: center; +} + +.cu-bar .action:first-child { + margin-left: 30upx; + font-size: 30upx; +} + +.cu-bar .action text.text-cut { + text-align: left; + width: 100%; +} + +.cu-bar .cu-avatar:first-child { + margin-left: 20upx; +} + +.cu-bar .action:first-child>text[class*="cuIcon-"] { + margin-left: -0.3em; + margin-right: 0.3em; +} + +.cu-bar .action:last-child { + margin-right: 30upx; +} + +.cu-bar .action>text[class*="cuIcon-"], +.cu-bar .action>view[class*="cuIcon-"] { + font-size: 36upx; +} + +.cu-bar .action>text[class*="cuIcon-"]+text[class*="cuIcon-"] { + margin-left: 0.5em; +} + +.cu-bar .content { + position: absolute; + text-align: center; + width: calc(100% - 340upx); + left: 0; + right: 0; + bottom: 0; + top: 0; + margin: auto; + height: 60upx; + font-size: 32upx; + line-height: 60upx; + cursor: none; + pointer-events: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.cu-bar.ios .content { + bottom: 7px; + height: 30px; + font-size: 32upx; + line-height: 30px; +} + +.cu-bar.btn-group { + justify-content: space-around; +} + +.cu-bar.btn-group button { + padding: 20upx 32upx; +} + +.cu-bar.btn-group button { + flex: 1; + margin: 0 20upx; + max-width: 50%; +} + +.cu-bar .search-form { + background-color: #f5f5f5; + line-height: 64upx; + height: 64upx; + font-size: 24upx; + color: #333333; + flex: 1; + display: flex; + align-items: center; + margin: 0 30upx; +} + +.cu-bar .search-form+.action { + margin-right: 30upx; +} + +.cu-bar .search-form input { + flex: 1; + padding-right: 30upx; + height: 64upx; + line-height: 64upx; + font-size: 26upx; + background-color: transparent; +} + +.cu-bar .search-form [class*="cuIcon-"] { + margin: 0 0.5em 0 0.8em; +} + +.cu-bar .search-form [class*="cuIcon-"]::before { + top: 0upx; +} + +.cu-bar.fixed, +.nav.fixed { + position: fixed; + width: 100%; + top: 0; + z-index: 1024; + box-shadow: 0 1upx 6upx rgba(0, 0, 0, 0.1); +} + +.cu-bar.foot { + position: fixed; + width: 100%; + bottom: 0; + z-index: 1024; + box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1); +} + +.cu-bar.tabbar { + padding: 0; + height: calc(100upx + env(safe-area-inset-bottom) / 2); + padding-bottom: calc(env(safe-area-inset-bottom) / 2); +} + +.cu-tabbar-height { + min-height: 100upx; + height: calc(100upx + env(safe-area-inset-bottom) / 2); +} + +.cu-bar.tabbar.shadow { + box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1); +} + +.cu-bar.tabbar .action { + font-size: 22upx; + position: relative; + flex: 1; + text-align: center; + padding: 0; + display: block; + height: auto; + line-height: 1; + margin: 0; + background-color: inherit; + overflow: initial; +} + +.cu-bar.tabbar.shop .action { + width: 140upx; + flex: initial; +} + +.cu-bar.tabbar .action.add-action { + position: relative; + z-index: 2; + padding-top: 50upx; +} + +.cu-bar.tabbar .action.add-action [class*="cuIcon-"] { + position: absolute; + width: 70upx; + z-index: 2; + height: 70upx; + border-radius: 50%; + line-height: 70upx; + font-size: 50upx; + top: -35upx; + left: 0; + right: 0; + margin: auto; + padding: 0; +} + +.cu-bar.tabbar .action.add-action::after { + content: ""; + position: absolute; + width: 100upx; + height: 100upx; + top: -50upx; + left: 0; + right: 0; + margin: auto; + box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08); + border-radius: 50upx; + background-color: inherit; + z-index: 0; +} + +.cu-bar.tabbar .action.add-action::before { + content: ""; + position: absolute; + width: 100upx; + height: 30upx; + bottom: 30upx; + left: 0; + right: 0; + margin: auto; + background-color: inherit; + z-index: 1; +} + +.cu-bar.tabbar .btn-group { + flex: 1; + display: flex; + justify-content: space-around; + align-items: center; + padding: 0 10upx; +} + +.cu-bar.tabbar button.action::after { + border: 0; +} + +.cu-bar.tabbar .action [class*="cuIcon-"] { + width: 100upx; + position: relative; + display: block; + height: auto; + margin: 0 auto 10upx; + text-align: center; + font-size: 40upx; +} + +.cu-bar.tabbar .action .cuIcon-cu-image { + margin: 0 auto; +} + +.cu-bar.tabbar .action .cuIcon-cu-image image { + width: 50upx; + height: 50upx; + display: inline-block; +} + +.cu-bar.tabbar .submit { + align-items: center; + display: flex; + justify-content: center; + text-align: center; + position: relative; + flex: 2; + align-self: stretch; +} + +.cu-bar.tabbar .submit:last-child { + flex: 2.6; +} + +.cu-bar.tabbar .submit+.submit { + flex: 2; +} + +.cu-bar.tabbar.border .action::before { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + transform: scale(0.5); + transform-origin: 0 0; + border-right: 1upx solid rgba(0, 0, 0, 0.1); + z-index: 3; +} + +.cu-bar.tabbar.border .action:last-child:before { + display: none; +} + +.cu-bar.input { + padding-right: 20upx; + background-color: #ffffff; +} + +.cu-bar.input input { + overflow: initial; + line-height: 64upx; + height: 64upx; + min-height: 64upx; + flex: 1; + font-size: 30upx; + margin: 0 20upx; +} + +.cu-bar.input .action { + margin-left: 20upx; +} + +.cu-bar.input .action [class*="cuIcon-"] { + font-size: 48upx; +} + +.cu-bar.input input+.action { + margin-right: 20upx; + margin-left: 0upx; +} + +.cu-bar.input .action:first-child [class*="cuIcon-"] { + margin-left: 0upx; +} + +.cu-custom { + display: block; + position: relative; +} + +.cu-custom .cu-bar .content { + width: calc(100% - 440upx); +} + +/* #ifdef MP-ALIPAY */ +.cu-custom .cu-bar .action .cuIcon-back { + opacity: 0; +} + +/* #endif */ + +.cu-custom .cu-bar .content image { + height: 60upx; + width: 240upx; +} + +.cu-custom .cu-bar { + min-height: 0px; + /* #ifdef MP-WEIXIN */ + padding-right: 220upx; + /* #endif */ + /* #ifdef MP-ALIPAY */ + padding-right: 150upx; + /* #endif */ + box-shadow: 0upx 0upx 0upx; + z-index: 9999; +} + +.cu-custom .cu-bar .border-custom { + position: relative; + background: rgba(0, 0, 0, 0.15); + border-radius: 1000upx; + height: 30px; +} + +.cu-custom .cu-bar .border-custom::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border-radius: inherit; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; + border: 1upx solid #ffffff; + opacity: 0.5; +} + +.cu-custom .cu-bar .border-custom::before { + content: " "; + width: 1upx; + height: 110%; + position: absolute; + top: 22.5%; + left: 0; + right: 0; + margin: auto; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; + opacity: 0.6; + background-color: #ffffff; +} + +.cu-custom .cu-bar .border-custom text { + display: block; + flex: 1; + margin: auto !important; + text-align: center; + font-size: 34upx; +} + +/* ================== + 导航栏 + ==================== */ + +.nav { + white-space: nowrap; +} + +::-webkit-scrollbar { + display: none; +} + +.nav .cu-item { + height: 90upx; + display: inline-block; + line-height: 90upx; + margin: 0 10upx; + padding: 0 20upx; +} + +.nav .cu-item.cur { + border-bottom: 4upx solid; +} + +/* ================== + 时间轴 + ==================== */ + +.cu-timeline { + display: block; + background-color: #ffffff; +} + +.cu-timeline .cu-time { + width: 120upx; + text-align: center; + padding: 20upx 0; + font-size: 26upx; + color: #888; + display: block; +} + +.cu-timeline>.cu-item { + padding: 30upx 30upx 30upx 120upx; + position: relative; + display: block; + z-index: 0; +} + +.cu-timeline>.cu-item:not([class*="text-"]) { + color: #ccc; +} + +.cu-timeline>.cu-item::after { + content: ""; + display: block; + position: absolute; + width: 1upx; + background-color: #ddd; + left: 60upx; + height: 100%; + top: 0; + z-index: 8; +} + +.cu-timeline>.cu-item::before { + font-family: "cuIcon"; + display: block; + position: absolute; + top: 36upx; + z-index: 9; + background-color: #ffffff; + width: 50upx; + height: 50upx; + text-align: center; + border: none; + line-height: 50upx; + left: 36upx; +} + +.cu-timeline>.cu-item:not([class*="cuIcon-"])::before { + content: "\e763"; +} + +.cu-timeline>.cu-item[class*="cuIcon-"]::before { + background-color: #ffffff; + width: 50upx; + height: 50upx; + text-align: center; + border: none; + line-height: 50upx; + left: 36upx; +} + +.cu-timeline>.cu-item>.content { + padding: 30upx; + border-radius: 6upx; + display: block; + line-height: 1.6; +} + +.cu-timeline>.cu-item>.content:not([class*="bg-"]) { + background-color: #f1f1f1; + color: #333333; +} + +.cu-timeline>.cu-item>.content+.content { + margin-top: 20upx; +} + +/* ================== + 聊天 + ==================== */ + +.cu-chat { + display: flex; + flex-direction: column; +} + +.cu-chat .cu-item { + display: flex; + padding: 30upx 30upx 70upx; + position: relative; +} + +.cu-chat .cu-item>.cu-avatar { + width: 80upx; + height: 80upx; +} + +.cu-chat .cu-item>.main { + max-width: calc(100% - 260upx); + margin: 0 40upx; + display: flex; + align-items: center; +} + +.cu-chat .cu-item>image { + height: 320upx; +} + +.cu-chat .cu-item>.main .content { + padding: 20upx; + border-radius: 6upx; + display: inline-flex; + max-width: 100%; + align-items: center; + font-size: 30upx; + position: relative; + min-height: 80upx; + line-height: 40upx; + text-align: left; +} + +.cu-chat .cu-item>.main .content:not([class*="bg-"]) { + background-color: #ffffff; + color: #333333; +} + +.cu-chat .cu-item .date { + position: absolute; + font-size: 24upx; + color: #8799a3; + width: calc(100% - 320upx); + bottom: 20upx; + left: 160upx; +} + +.cu-chat .cu-item .action { + padding: 0 30upx; + display: flex; + align-items: center; +} + +.cu-chat .cu-item>.main .content::after { + content: ""; + top: 27upx; + transform: rotate(45deg); + position: absolute; + z-index: 100; + display: inline-block; + overflow: hidden; + width: 24upx; + height: 24upx; + left: -12upx; + right: initial; + background-color: inherit; +} + +.cu-chat .cu-item.self>.main .content::after { + left: auto; + right: -12upx; +} + +.cu-chat .cu-item>.main .content::before { + content: ""; + top: 30upx; + transform: rotate(45deg); + position: absolute; + z-index: -1; + display: inline-block; + overflow: hidden; + width: 24upx; + height: 24upx; + left: -12upx; + right: initial; + background-color: inherit; + filter: blur(5upx); + opacity: 0.3; +} + +.cu-chat .cu-item>.main .content:not([class*="bg-"])::before { + background-color: #333333; + opacity: 0.1; +} + +.cu-chat .cu-item.self>.main .content::before { + left: auto; + right: -12upx; +} + +.cu-chat .cu-item.self { + justify-content: flex-end; + text-align: right; +} + +.cu-chat .cu-info { + display: inline-block; + margin: 20upx auto; + font-size: 24upx; + padding: 8upx 12upx; + background-color: rgba(0, 0, 0, 0.2); + border-radius: 6upx; + color: #ffffff; + max-width: 400upx; + line-height: 1.4; +} + +/* ================== + 卡片 + ==================== */ + +.cu-card { + display: block; + overflow: hidden; +} + +.cu-card>.cu-item { + display: block; + background-color: #ffffff; + overflow: hidden; + border-radius: 10upx; + margin: 30upx; +} + +.cu-card>.cu-item.shadow-blur { + overflow: initial; +} + +.cu-card.no-card>.cu-item { + margin: 0upx; + border-radius: 0upx; +} + +.cu-card .grid.grid-square { + margin-bottom: -20upx; +} + +.cu-card.case .image { + position: relative; +} + +.cu-card.case .image image { + width: 100%; +} + +.cu-card.case .image .cu-tag { + position: absolute; + right: 0; + top: 0; +} + +.cu-card.case .image .cu-bar { + position: absolute; + bottom: 0; + width: 100%; + background-color: transparent; + padding: 0upx 30upx; +} + +.cu-card.case.no-card .image { + margin: 30upx 30upx 0; + overflow: hidden; + border-radius: 10upx; +} + +.cu-card.dynamic { + display: block; +} + +.cu-card.dynamic>.cu-item { + display: block; + background-color: #ffffff; + overflow: hidden; +} + +.cu-card.dynamic>.cu-item>.text-content { + padding: 0 30upx 0; + max-height: 6.4em; + overflow: hidden; + font-size: 30upx; + margin-bottom: 20upx; +} + +.cu-card.dynamic>.cu-item .square-img { + width: 100%; + height: 200upx; + border-radius: 6upx; +} + +.cu-card.dynamic>.cu-item .only-img { + width: 100%; + height: 320upx; + border-radius: 6upx; +} + +/* card.dynamic>.cu-item .comment { + padding: 20upx; + background-color: #f1f1f1; + margin: 0 30upx 30upx; + border-radius: 6upx; +} */ + +.cu-card.article { + display: block; +} + +.cu-card.article>.cu-item { + padding-bottom: 30upx; +} + +.cu-card.article>.cu-item .title { + font-size: 30upx; + font-weight: 900; + color: #333333; + line-height: 100upx; + padding: 0 30upx; +} + +.cu-card.article>.cu-item .content { + display: flex; + padding: 0 30upx; +} + +.cu-card.article>.cu-item .content>image { + width: 240upx; + height: 6.4em; + margin-right: 20upx; + border-radius: 6upx; +} + +.cu-card.article>.cu-item .content .desc { + flex: 1; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.cu-card.article>.cu-item .content .text-content { + font-size: 28upx; + color: #888; + height: 4.8em; + overflow: hidden; +} + +/* ================== + 表单 + ==================== */ + +.cu-form-group { + background-color: #ffffff; + padding: 1upx 30upx; + display: flex; + align-items: center; + min-height: 100upx; + justify-content: space-between; +} + +.cu-form-group+.cu-form-group { + border-top: 1upx solid #eee; +} + +.cu-form-group .title { + text-align: justify; + padding-right: 30upx; + font-size: 30upx; + position: relative; + height: 60upx; + line-height: 60upx; +} + +.cu-form-group input { + flex: 1; + font-size: 30upx; + color: #555; + padding-right: 20upx; +} + +.cu-form-group>text[class*="cuIcon-"] { + font-size: 36upx; + padding: 0; + box-sizing: border-box; +} + +.cu-form-group textarea { + margin: 32upx 0 30upx; + height: 4.6em; + width: 100%; + line-height: 1.2em; + flex: 1; + font-size: 28upx; + padding: 0; +} + +.cu-form-group.align-start .title { + height: 1em; + margin-top: 32upx; + line-height: 1em; +} + +.cu-form-group picker { + flex: 1; + padding-right: 40upx; + overflow: hidden; + position: relative; +} + +.cu-form-group picker .picker { + line-height: 100upx; + font-size: 28upx; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + width: 100%; + text-align: right; +} + +.cu-form-group picker::after { + font-family: cuIcon; + display: block; + content: "\e6a3"; + position: absolute; + font-size: 34upx; + color: #8799a3; + line-height: 100upx; + width: 60upx; + text-align: center; + top: 0; + bottom: 0; + right: -20upx; + margin: auto; +} + +.cu-form-group textarea[disabled], +.cu-form-group textarea[disabled] .placeholder { + color: transparent; +} + +/* ================== + 模态窗口 + ==================== */ + +.cu-modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1110; + opacity: 0; + outline: 0; + text-align: center; + -ms-transform: scale(1.185); + transform: scale(1.185); + backface-visibility: hidden; + perspective: 2000upx; + background: rgba(0, 0, 0, 0.6); + transition: all 0.3s ease-in-out 0s; + pointer-events: none; +} + +.cu-modal::before { + content: "\200B"; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +.cu-modal.show { + opacity: 1; + transition-duration: 0.3s; + -ms-transform: scale(1); + transform: scale(1); + overflow-x: hidden; + overflow-y: auto; + pointer-events: auto; +} + +.cu-dialog { + position: relative; + display: inline-block; + vertical-align: middle; + margin-left: auto; + margin-right: auto; + width: 680upx; + max-width: 100%; + background-color: #f8f8f8; + border-radius: 10upx; + overflow: hidden; +} + +.cu-modal.bottom-modal::before { + vertical-align: bottom; +} + +.cu-modal.bottom-modal .cu-dialog { + width: 100%; + border-radius: 0; +} + +.cu-modal.bottom-modal { + margin-bottom: -1000upx; +} + +.cu-modal.bottom-modal.show { + margin-bottom: 0; +} + +.cu-modal.drawer-modal { + transform: scale(1); + display: flex; +} + +.cu-modal.drawer-modal .cu-dialog { + height: 100%; + min-width: 200upx; + border-radius: 0; + margin: initial; + transition-duration: 0.3s; +} + +.cu-modal.drawer-modal.justify-start .cu-dialog { + transform: translateX(-100%); +} + +.cu-modal.drawer-modal.justify-end .cu-dialog { + transform: translateX(100%); +} + +.cu-modal.drawer-modal.show .cu-dialog { + transform: translateX(0%); +} +.cu-modal .cu-dialog>.cu-bar:first-child .action{ + min-width: 100rpx; + margin-right: 0; + min-height: 100rpx; +} +/* ================== + 轮播 + ==================== */ +swiper .a-swiper-dot { + display: inline-block; + width: 16upx; + height: 16upx; + background: rgba(0, 0, 0, .3); + border-radius: 50%; + vertical-align: middle; +} + +swiper[class*="-dot"] .wx-swiper-dots, +swiper[class*="-dot"] .a-swiper-dots, +swiper[class*="-dot"] .uni-swiper-dots { + display: flex; + align-items: center; + width: 100%; + justify-content: center; +} + +swiper.square-dot .wx-swiper-dot, +swiper.square-dot .a-swiper-dot, +swiper.square-dot .uni-swiper-dot { + background-color: #ffffff; + opacity: 0.4; + width: 10upx; + height: 10upx; + border-radius: 20upx; + margin: 0 8upx !important; +} + +swiper.square-dot .wx-swiper-dot.wx-swiper-dot-active, +swiper.square-dot .a-swiper-dot.a-swiper-dot-active, +swiper.square-dot .uni-swiper-dot.uni-swiper-dot-active { + opacity: 1; + width: 30upx; +} + +swiper.round-dot .wx-swiper-dot, +swiper.round-dot .a-swiper-dot, +swiper.round-dot .uni-swiper-dot { + width: 10upx; + height: 10upx; + position: relative; + margin: 4upx 8upx !important; +} + +swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active::after, +swiper.round-dot .a-swiper-dot.a-swiper-dot-active::after, +swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active::after { + content: ""; + position: absolute; + width: 10upx; + height: 10upx; + top: 0upx; + left: 0upx; + right: 0; + bottom: 0; + margin: auto; + background-color: #ffffff; + border-radius: 20upx; +} + +swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active, +swiper.round-dot .a-swiper-dot.a-swiper-dot-active, +swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active { + width: 18upx; + height: 18upx; +} + +.screen-swiper { + min-height: 375upx; +} + +.screen-swiper image, +.screen-swiper video, +.swiper-item image, +.swiper-item video { + width: 100%; + display: block; + height: 100%; + margin: 0; + pointer-events: none; +} + +.card-swiper { + height: 420upx !important; +} + +.card-swiper swiper-item { + width: 610upx !important; + left: 70upx; + box-sizing: border-box; + padding: 40upx 0upx 70upx; + overflow: initial; +} + +.card-swiper swiper-item .swiper-item { + width: 100%; + display: block; + height: 100%; + border-radius: 10upx; + transform: scale(0.9); + transition: all 0.2s ease-in 0s; + overflow: hidden; +} + +.card-swiper swiper-item.cur .swiper-item { + transform: none; + transition: all 0.2s ease-in 0s; +} + + +.tower-swiper { + height: 420upx; + position: relative; + max-width: 750upx; + overflow: hidden; +} + +.tower-swiper .tower-item { + position: absolute; + width: 300upx; + height: 380upx; + top: 0; + bottom: 0; + left: 50%; + margin: auto; + transition: all 0.2s ease-in 0s; + opacity: 1; +} + +.tower-swiper .tower-item.none { + opacity: 0; +} + +.tower-swiper .tower-item .swiper-item { + width: 100%; + height: 100%; + border-radius: 6upx; + overflow: hidden; +} + +/* ================== + 步骤条 + ==================== */ + +.cu-steps { + display: flex; +} + +scroll-view.cu-steps { + display: block; + white-space: nowrap; +} + +scroll-view.cu-steps .cu-item { + display: inline-block; +} + +.cu-steps .cu-item { + flex: 1; + text-align: center; + position: relative; + min-width: 100upx; +} + +.cu-steps .cu-item:not([class*="text-"]) { + color: #8799a3; +} + +.cu-steps .cu-item [class*="cuIcon-"], +.cu-steps .cu-item .num { + display: block; + font-size: 40upx; + line-height: 80upx; +} + +.cu-steps .cu-item::before, +.cu-steps .cu-item::after, +.cu-steps.steps-arrow .cu-item::before, +.cu-steps.steps-arrow .cu-item::after { + content: ""; + display: block; + position: absolute; + height: 0px; + width: calc(100% - 80upx); + border-bottom: 1px solid #ccc; + left: calc(0px - (100% - 80upx) / 2); + top: 40upx; + z-index: 0; +} + +.cu-steps.steps-arrow .cu-item::before, +.cu-steps.steps-arrow .cu-item::after { + content: "\e6a3"; + font-family: 'cuIcon'; + height: 30upx; + border-bottom-width: 0px; + line-height: 30upx; + top: 0; + bottom: 0; + margin: auto; + color: #ccc; +} + +.cu-steps.steps-bottom .cu-item::before, +.cu-steps.steps-bottom .cu-item::after { + bottom: 40upx; + top: initial; +} + +.cu-steps .cu-item::after { + border-bottom: 1px solid currentColor; + width: 0px; + transition: all 0.3s ease-in-out 0s; +} + +.cu-steps .cu-item[class*="text-"]::after { + width: calc(100% - 80upx); + color: currentColor; +} + +.cu-steps .cu-item:first-child::before, +.cu-steps .cu-item:first-child::after { + display: none; +} + +.cu-steps .cu-item .num { + width: 40upx; + height: 40upx; + border-radius: 50%; + line-height: 40upx; + margin: 20upx auto; + font-size: 24upx; + border: 1px solid currentColor; + position: relative; + overflow: hidden; +} + +.cu-steps .cu-item[class*="text-"] .num { + background-color: currentColor; +} + +.cu-steps .cu-item .num::before, +.cu-steps .cu-item .num::after { + content: attr(data-index); + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + transition: all 0.3s ease-in-out 0s; + transform: translateY(0upx); +} + +.cu-steps .cu-item[class*="text-"] .num::before { + transform: translateY(-40upx); + color: #ffffff; +} + +.cu-steps .cu-item .num::after { + transform: translateY(40upx); + color: #ffffff; + transition: all 0.3s ease-in-out 0s; +} + +.cu-steps .cu-item[class*="text-"] .num::after { + content: "\e645"; + font-family: 'cuIcon'; + color: #ffffff; + transform: translateY(0upx); +} + +.cu-steps .cu-item[class*="text-"] .num.err::after { + content: "\e646"; +} + +/* ================== + 布局 + ==================== */ + +/* -- flex弹性布局 -- */ + +.flex { + display: flex; +} + +.basis-xs { + flex-basis: 20%; +} + +.basis-sm { + flex-basis: 40%; +} + +.basis-df { + flex-basis: 50%; +} + +.basis-lg { + flex-basis: 60%; +} + +.basis-xl { + flex-basis: 80%; +} + +.flex-sub { + flex: 1; +} + +.flex-twice { + flex: 2; +} + +.flex-treble { + flex: 3; +} + +.flex-direction { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.align-start { + align-items: flex-start; +} + +.align-end { + align-items: flex-end; +} + +.align-center { + align-items: center; +} + +.align-stretch { + align-items: stretch; +} + +.self-start { + align-self: flex-start; +} + +.self-center { + align-self: flex-center; +} + +.self-end { + align-self: flex-end; +} + +.self-stretch { + align-self: stretch; +} + +.align-stretch { + align-items: stretch; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-around { + justify-content: space-around; +} + +/* grid布局 */ + +.grid { + display: flex; + flex-wrap: wrap; +} + +.grid.grid-square { + overflow: hidden; +} + +.grid.grid-square .cu-tag { + position: absolute; + right: 0; + top: 0; + border-bottom-left-radius: 6upx; + padding: 6upx 12upx; + height: auto; + background-color: rgba(0, 0, 0, 0.5); +} + +.grid.grid-square>view>text[class*="cuIcon-"] { + font-size: 52upx; + position: absolute; + color: #8799a3; + margin: auto; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.grid.grid-square>view { + margin-right: 20upx; + margin-bottom: 20upx; + border-radius: 6upx; + position: relative; + overflow: hidden; +} +.grid.grid-square>view.bg-img image { + width: 100%; + height: 100%; + position: absolute; +} +.grid.col-1.grid-square>view { + padding-bottom: 100%; + height: 0; + margin-right: 0; +} + +.grid.col-2.grid-square>view { + padding-bottom: calc((100% - 20upx)/2); + height: 0; + width: calc((100% - 20upx)/2); +} + +.grid.col-3.grid-square>view { + padding-bottom: calc((100% - 40upx)/3); + height: 0; + width: calc((100% - 40upx)/3); +} + +.grid.col-4.grid-square>view { + padding-bottom: calc((100% - 60upx)/4); + height: 0; + width: calc((100% - 60upx)/4); +} + +.grid.col-5.grid-square>view { + padding-bottom: calc((100% - 80upx)/5); + height: 0; + width: calc((100% - 80upx)/5); +} + +.grid.col-2.grid-square>view:nth-child(2n), +.grid.col-3.grid-square>view:nth-child(3n), +.grid.col-4.grid-square>view:nth-child(4n), +.grid.col-5.grid-square>view:nth-child(5n) { + margin-right: 0; +} + +.grid.col-1>view { + width: 100%; +} + +.grid.col-2>view { + width: 50%; +} + +.grid.col-3>view { + width: 33.33%; +} + +.grid.col-4>view { + width: 25%; +} + +.grid.col-5>view { + width: 20%; +} + +/* -- 内外边距 -- */ + +.margin-0 { + margin: 0; +} + +.margin-xs { + margin: 10upx; +} + +.margin-sm { + margin: 20upx; +} + +.margin { + margin: 30upx; +} + +.margin-lg { + margin: 40upx; +} + +.margin-xl { + margin: 50upx; +} + +.margin-top-xs { + margin-top: 10upx; +} + +.margin-top-sm { + margin-top: 20upx; +} + +.margin-top { + margin-top: 30upx; +} + +.margin-top-lg { + margin-top: 40upx; +} + +.margin-top-xl { + margin-top: 50upx; +} + +.margin-right-xs { + margin-right: 10upx; +} + +.margin-right-sm { + margin-right: 20upx; +} + +.margin-right { + margin-right: 30upx; +} + +.margin-right-lg { + margin-right: 40upx; +} + +.margin-right-xl { + margin-right: 50upx; +} + +.margin-bottom-xs { + margin-bottom: 10upx; +} + +.margin-bottom-sm { + margin-bottom: 20upx; +} + +.margin-bottom { + margin-bottom: 30upx; +} + +.margin-bottom-lg { + margin-bottom: 40upx; +} + +.margin-bottom-xl { + margin-bottom: 50upx; +} + +.margin-left-xs { + margin-left: 10upx; +} + +.margin-left-sm { + margin-left: 20upx; +} + +.margin-left { + margin-left: 30upx; +} + +.margin-left-lg { + margin-left: 40upx; +} + +.margin-left-xl { + margin-left: 50upx; +} + +.margin-lr-xs { + margin-left: 10upx; + margin-right: 10upx; +} + +.margin-lr-sm { + margin-left: 20upx; + margin-right: 20upx; +} + +.margin-lr { + margin-left: 30upx; + margin-right: 30upx; +} + +.margin-lr-lg { + margin-left: 40upx; + margin-right: 40upx; +} + +.margin-lr-xl { + margin-left: 50upx; + margin-right: 50upx; +} + +.margin-tb-xs { + margin-top: 10upx; + margin-bottom: 10upx; +} + +.margin-tb-sm { + margin-top: 20upx; + margin-bottom: 20upx; +} + +.margin-tb { + margin-top: 30upx; + margin-bottom: 30upx; +} + +.margin-tb-lg { + margin-top: 40upx; + margin-bottom: 40upx; +} + +.margin-tb-xl { + margin-top: 50upx; + margin-bottom: 50upx; +} + +.padding-0 { + padding: 0; +} + +.padding-xs { + padding: 10upx; +} + +.padding-sm { + padding: 20upx; +} + +.padding { + padding: 30upx; +} + +.padding-lg { + padding: 40upx; +} + +.padding-xl { + padding: 50upx; +} + +.padding-top-xs { + padding-top: 10upx; +} + +.padding-top-sm { + padding-top: 20upx; +} + +.padding-top { + padding-top: 30upx; +} + +.padding-top-lg { + padding-top: 40upx; +} + +.padding-top-xl { + padding-top: 50upx; +} + +.padding-right-xs { + padding-right: 10upx; +} + +.padding-right-sm { + padding-right: 20upx; +} + +.padding-right { + padding-right: 30upx; +} + +.padding-right-lg { + padding-right: 40upx; +} + +.padding-right-xl { + padding-right: 50upx; +} + +.padding-bottom-xs { + padding-bottom: 10upx; +} + +.padding-bottom-sm { + padding-bottom: 20upx; +} + +.padding-bottom { + padding-bottom: 30upx; +} + +.padding-bottom-lg { + padding-bottom: 40upx; +} + +.padding-bottom-xl { + padding-bottom: 50upx; +} + +.padding-left-xs { + padding-left: 10upx; +} + +.padding-left-sm { + padding-left: 20upx; +} + +.padding-left { + padding-left: 30upx; +} + +.padding-left-lg { + padding-left: 40upx; +} + +.padding-left-xl { + padding-left: 50upx; +} + +.padding-lr-xs { + padding-left: 10upx; + padding-right: 10upx; +} + +.padding-lr-sm { + padding-left: 20upx; + padding-right: 20upx; +} + +.padding-lr { + padding-left: 30upx; + padding-right: 30upx; +} + +.padding-lr-lg { + padding-left: 40upx; + padding-right: 40upx; +} + +.padding-lr-xl { + padding-left: 50upx; + padding-right: 50upx; +} + +.padding-tb-xs { + padding-top: 10upx; + padding-bottom: 10upx; +} + +.padding-tb-sm { + padding-top: 20upx; + padding-bottom: 20upx; +} + +.padding-tb { + padding-top: 30upx; + padding-bottom: 30upx; +} + +.padding-tb-lg { + padding-top: 40upx; + padding-bottom: 40upx; +} + +.padding-tb-xl { + padding-top: 50upx; + padding-bottom: 50upx; +} + +/* -- 浮动 -- */ + +.cf::after, +.cf::before { + content: " "; + display: table; +} + +.cf::after { + clear: both; +} + +.fl { + float: left; +} + +.fr { + float: right; +} + +/* ================== + 背景 + ==================== */ + +.line-red::after, +.lines-red::after { + border-color: #e54d42; +} + +.line-orange::after, +.lines-orange::after { + border-color: #f37b1d; +} + +.line-yellow::after, +.lines-yellow::after { + border-color: #fbbd08; +} + +.line-olive::after, +.lines-olive::after { + border-color: #8dc63f; +} + +.line-green::after, +.lines-green::after { + border-color: #39b54a; +} + +.line-cyan::after, +.lines-cyan::after { + border-color: #1cbbb4; +} + +.line-blue::after, +.lines-blue::after { + border-color: #0081ff; +} + +.line-purple::after, +.lines-purple::after { + border-color: #6739b6; +} + +.line-mauve::after, +.lines-mauve::after { + border-color: #9c26b0; +} + +.line-pink::after, +.lines-pink::after { + border-color: #e03997; +} + +.line-brown::after, +.lines-brown::after { + border-color: #a5673f; +} + +.line-grey::after, +.lines-grey::after { + border-color: #8799a3; +} + +.line-gray::after, +.lines-gray::after { + border-color: #aaaaaa; +} + +.line-black::after, +.lines-black::after { + border-color: #333333; +} + +.line-white::after, +.lines-white::after { + border-color: #ffffff; +} + +.bg-red { + background-color: #e54d42; + color: #ffffff; +} + +.bg-orange { + background-color: #f37b1d; + color: #ffffff; +} + +.bg-yellow { + background-color: #fbbd08; + color: #333333; +} + +.bg-olive { + background-color: #8dc63f; + color: #ffffff; +} + +.bg-green { + background-color: #39b54a; + color: #ffffff; +} + +.bg-cyan { + background-color: #1cbbb4; + color: #ffffff; +} + +.bg-blue { + background-color: #0081ff; + color: #ffffff; +} + +.bg-purple { + background-color: #6739b6; + color: #ffffff; +} + +.bg-mauve { + background-color: #9c26b0; + color: #ffffff; +} + +.bg-pink { + background-color: #e03997; + color: #ffffff; +} + +.bg-brown { + background-color: #a5673f; + color: #ffffff; +} + +.bg-grey { + background-color: #8799a3; + color: #ffffff; +} + +.bg-gray { + background-color: #f0f0f0; + color: #333333; +} + +.bg-black { + background-color: #333333; + color: #ffffff; +} + +.bg-white { + background-color: #ffffff; + color: #666666; +} + +.bg-shadeTop { + background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.01)); + color: #ffffff; +} + +.bg-shadeBottom { + background-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 1)); + color: #ffffff; +} + +.bg-red.light { + color: #e54d42; + background-color: #fadbd9; +} + +.bg-orange.light { + color: #f37b1d; + background-color: #fde6d2; +} + +.bg-yellow.light { + color: #fbbd08; + background-color: #fef2ced2; +} + +.bg-olive.light { + color: #8dc63f; + background-color: #e8f4d9; +} + +.bg-green.light { + color: #39b54a; + background-color: #d7f0dbff; +} + +.bg-cyan.light { + color: #1cbbb4; + background-color: #d2f1f0; +} + +.bg-blue.light { + color: #0081ff; + background-color: #cce6ff; +} + +.bg-purple.light { + color: #6739b6; + background-color: #e1d7f0; +} + +.bg-mauve.light { + color: #9c26b0; + background-color: #ebd4ef; +} + +.bg-pink.light { + color: #e03997; + background-color: #f9d7ea; +} + +.bg-brown.light { + color: #a5673f; + background-color: #ede1d9; +} + +.bg-grey.light { + color: #8799a3; + background-color: #e7ebed; +} + +.bg-gradual-red { + background-image: linear-gradient(45deg, #f43f3b, #ec008c); + color: #ffffff; +} + +.bg-gradual-orange { + background-image: linear-gradient(45deg, #ff9700, #ed1c24); + color: #ffffff; +} + +.bg-gradual-green { + background-image: linear-gradient(45deg, #39b54a, #8dc63f); + color: #ffffff; +} + +.bg-gradual-purple { + background-image: linear-gradient(45deg, #9000ff, #5e00ff); + color: #ffffff; +} + +.bg-gradual-pink { + background-image: linear-gradient(45deg, #ec008c, #6739b6); + color: #ffffff; +} + +.bg-gradual-blue { + background-image: linear-gradient(45deg, #0081ff, #1cbbb4); + color: #ffffff; +} + +.shadow[class*="-red"] { + box-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2); +} + +.shadow[class*="-orange"] { + box-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2); +} + +.shadow[class*="-yellow"] { + box-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2); +} + +.shadow[class*="-olive"] { + box-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2); +} + +.shadow[class*="-green"] { + box-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2); +} + +.shadow[class*="-cyan"] { + box-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2); +} + +.shadow[class*="-blue"] { + box-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2); +} + +.shadow[class*="-purple"] { + box-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2); +} + +.shadow[class*="-mauve"] { + box-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2); +} + +.shadow[class*="-pink"] { + box-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2); +} + +.shadow[class*="-brown"] { + box-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2); +} + +.shadow[class*="-grey"] { + box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.shadow[class*="-gray"] { + box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.shadow[class*="-black"] { + box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2); +} + +.shadow[class*="-white"] { + box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2); +} + +.text-shadow[class*="-red"] { + text-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2); +} + +.text-shadow[class*="-orange"] { + text-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2); +} + +.text-shadow[class*="-yellow"] { + text-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2); +} + +.text-shadow[class*="-olive"] { + text-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2); +} + +.text-shadow[class*="-green"] { + text-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2); +} + +.text-shadow[class*="-cyan"] { + text-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2); +} + +.text-shadow[class*="-blue"] { + text-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2); +} + +.text-shadow[class*="-purple"] { + text-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2); +} + +.text-shadow[class*="-mauve"] { + text-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2); +} + +.text-shadow[class*="-pink"] { + text-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2); +} + +.text-shadow[class*="-brown"] { + text-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2); +} + +.text-shadow[class*="-grey"] { + text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.text-shadow[class*="-gray"] { + text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2); +} + +.text-shadow[class*="-black"] { + text-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2); +} + +.bg-img { + background-size: cover; + background-position: center; + background-repeat: no-repeat; +} + +.bg-mask { + background-color: #333333; + position: relative; +} + +.bg-mask::after { + content: ""; + border-radius: inherit; + width: 100%; + height: 100%; + display: block; + background-color: rgba(0, 0, 0, 0.4); + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; +} + +.bg-mask view, +.bg-mask cover-view { + z-index: 5; + position: relative; +} + +.bg-video { + position: relative; +} + +.bg-video video { + display: block; + height: 100%; + width: 100%; + -o-object-fit: cover; + object-fit: cover; + position: absolute; + top: 0; + z-index: 0; + pointer-events: none; +} + +/* ================== + 文本 + ==================== */ + +.text-xs { + font-size: 20upx; +} + +.text-sm { + font-size: 24upx; +} + +.text-df { + font-size: 28upx; +} + +.text-lg { + font-size: 32upx; +} + +.text-xl { + font-size: 36upx; +} + +.text-xxl { + font-size: 44upx; +} + +.text-sl { + font-size: 80upx; +} + +.text-xsl { + font-size: 120upx; +} + +.text-Abc { + text-transform: Capitalize; +} + +.text-ABC { + text-transform: Uppercase; +} + +.text-abc { + text-transform: Lowercase; +} + +.text-price::before { + content: "¥"; + font-size: 80%; + margin-right: 4upx; +} + +.text-cut { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.text-bold { + font-weight: bold; +} + +.text-center { + text-align: center; +} + +.text-content { + line-height: 1.6; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-red, +.line-red, +.lines-red { + color: #e54d42; +} + +.text-orange, +.line-orange, +.lines-orange { + color: #f37b1d; +} + +.text-yellow, +.line-yellow, +.lines-yellow { + color: #fbbd08; +} + +.text-olive, +.line-olive, +.lines-olive { + color: #8dc63f; +} + +.text-green, +.line-green, +.lines-green { + color: #39b54a; +} + +.text-cyan, +.line-cyan, +.lines-cyan { + color: #1cbbb4; +} + +.text-blue, +.line-blue, +.lines-blue { + color: #0081ff; +} + +.text-purple, +.line-purple, +.lines-purple { + color: #6739b6; +} + +.text-mauve, +.line-mauve, +.lines-mauve { + color: #9c26b0; +} + +.text-pink, +.line-pink, +.lines-pink { + color: #e03997; +} + +.text-brown, +.line-brown, +.lines-brown { + color: #a5673f; +} + +.text-grey, +.line-grey, +.lines-grey { + color: #8799a3; +} + +.text-gray, +.line-gray, +.lines-gray { + color: #aaaaaa; +} + +.text-black, +.line-black, +.lines-black { + color: #333333; +} + +.text-white, +.line-white, +.lines-white { + color: #ffffff; +} diff --git a/static/images/event/enent_none.png b/static/images/event/enent_none.png new file mode 100644 index 0000000..00384cc Binary files /dev/null and b/static/images/event/enent_none.png differ diff --git a/static/images/event/event_close.png b/static/images/event/event_close.png new file mode 100644 index 0000000..b31f6ca Binary files /dev/null and b/static/images/event/event_close.png differ diff --git a/static/images/event/event_location.png b/static/images/event/event_location.png new file mode 100644 index 0000000..749289d Binary files /dev/null and b/static/images/event/event_location.png differ diff --git a/static/images/event/event_lock.png b/static/images/event/event_lock.png new file mode 100644 index 0000000..0e81fe7 Binary files /dev/null and b/static/images/event/event_lock.png differ diff --git a/static/images/index/arrow_right.png b/static/images/index/arrow_right.png new file mode 100644 index 0000000..75f2543 Binary files /dev/null and b/static/images/index/arrow_right.png differ diff --git a/static/images/index/index_bell.png b/static/images/index/index_bell.png new file mode 100644 index 0000000..daba17d Binary files /dev/null and b/static/images/index/index_bell.png differ diff --git a/static/images/index/index_bg.png b/static/images/index/index_bg.png new file mode 100644 index 0000000..02c2c32 Binary files /dev/null and b/static/images/index/index_bg.png differ diff --git a/static/images/index/index_cup.png b/static/images/index/index_cup.png new file mode 100644 index 0000000..7eded34 Binary files /dev/null and b/static/images/index/index_cup.png differ diff --git a/static/images/index/index_logout.png b/static/images/index/index_logout.png new file mode 100644 index 0000000..ab89f05 Binary files /dev/null and b/static/images/index/index_logout.png differ diff --git a/static/images/login/agree_circle.png b/static/images/login/agree_circle.png new file mode 100644 index 0000000..13a6150 Binary files /dev/null and b/static/images/login/agree_circle.png differ diff --git a/static/images/login/agreed_circle.png b/static/images/login/agreed_circle.png new file mode 100644 index 0000000..d8d3e85 Binary files /dev/null and b/static/images/login/agreed_circle.png differ diff --git a/static/images/login/ty0.png b/static/images/login/ty0.png new file mode 100644 index 0000000..8184570 Binary files /dev/null and b/static/images/login/ty0.png differ diff --git a/static/images/login/ty1.png b/static/images/login/ty1.png new file mode 100644 index 0000000..8a8028a Binary files /dev/null and b/static/images/login/ty1.png differ diff --git a/static/images/logo_main.png b/static/images/logo_main.png new file mode 100644 index 0000000..c4100c4 Binary files /dev/null and b/static/images/logo_main.png differ diff --git a/static/images/tabbar/tab_home_01.png b/static/images/tabbar/tab_home_01.png new file mode 100644 index 0000000..1be9e9a Binary files /dev/null and b/static/images/tabbar/tab_home_01.png differ diff --git a/static/images/tabbar/tab_home_02.png b/static/images/tabbar/tab_home_02.png new file mode 100644 index 0000000..f2cd038 Binary files /dev/null and b/static/images/tabbar/tab_home_02.png differ diff --git a/static/images/tabbar/tab_user_01.png b/static/images/tabbar/tab_user_01.png new file mode 100644 index 0000000..ee54f31 Binary files /dev/null and b/static/images/tabbar/tab_user_01.png differ diff --git a/static/images/tabbar/tab_user_02.png b/static/images/tabbar/tab_user_02.png new file mode 100644 index 0000000..875e199 Binary files /dev/null and b/static/images/tabbar/tab_user_02.png differ diff --git a/static/style/base.scss b/static/style/base.scss new file mode 100644 index 0000000..bd4911c --- /dev/null +++ b/static/style/base.scss @@ -0,0 +1,131 @@ +@import './mixin/flex.scss'; // flex(主轴,交叉轴,方向,换行,多轴线对齐) / flex-self(对齐,(布满||固定),顺序) +@import './mixin/text-overflow.scss'; // 文本格式化超出省略号 参数:宽度,单行/多行 +@import './mixin/position-absolute.scss'; // 绝对定位 参数:上,右,下,左 +@import './mixin/triangle.scss'; // 画三角形 参数:宽度,朝向,颜色 +@import './mixin/hr.scss'; // 添加分割线 参数:位置,间隔 +@import './mixin/price-before.scss'; // 价格¥前加 +/*colorui css */ +@import "static/colorui/main.css"; +@import "static/colorui/icon.css"; +/*uview-ui css */ +@import "uview-ui/index.scss"; + +page { + min-height: 100%; + background-color: #f7f7f7; +} + +/*flex布局(colorui里面也有相关基础样式)*/ + /* x水平排列*/ + .x-f { + display: flex; + align-items: center; + } + + /*x两端且水平居中*/ + .x-bc { + display: flex; + justify-content: space-between; + align-items: center; + } + + /*x平分且水平居中*/ + .x-ac { + display: flex; + justify-content: space-around; + align-items: center; + } + + /*x水平靠上对齐*/ + .x-start { + display: flex; + align-items: flex-start; + } + + /*x水平靠下对齐*/ + .x-end { + display: flex; + align-items: flex-end; + } + + /*上下左右居中*/ + .x-c { + display: flex; + justify-content: center; + align-items: center; + } + + /*y竖直靠左*/ + .y-start { + display: flex; + flex-direction: column; + align-items: flex-start; + } + + /*y竖直靠右*/ + .y-end { + display: flex; + flex-direction: column; + align-items: flex-end; + } + + /*y竖直居中*/ + .y-f { + display: flex; + flex-direction: column; + align-items: center; + } + + /* y竖直两端*/ + .y-b { + display: flex; + flex-direction: column; + justify-content: space-between; + } + + /*y竖直两端居中*/ + .y-bc { + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + } + + //常用flex公共代码 + .flex_row{ + display: flex; + flex-direction: row; + flex-wrap: nowrap; + // flex-flow: row nowrap; + justify-content: center; + align-items: center; + } + .flex_col{ + display: flex; + flex-direction: column; + flex-wrap: nowrap; + // flex-flow: column nowrap; //部分环境不支持简写 + justify-content: center; //主轴上的对齐方式 + align-items: center; //交叉轴上如何对齐 + } + .flex_col.flex_wrap{flex-wrap: wrap;} + .flex_row.flex_wrap{flex-wrap: wrap;} + //覆盖主轴属性 + .flex_between{justify-content: space-between;} + .flex_around{justify-content: space-around;} + .flex_start{justify-content: flex-start;} + .flex_end{justify-content: flex-end;} + //覆盖交叉轴属性 + .flex_between_y{align-items: space-between;} + .flex_around_y{align-items: space-around;} + .flex_start_y{align-items: flex-start;} + .flex_end_y{align-items: flex-end;} + + .text-maxline-one { + text-overflow: ellipsis; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + word-break: break-all; + overflow: hidden; + display: -webkit-box; + } \ No newline at end of file diff --git a/static/style/mixin/flex.scss b/static/style/mixin/flex.scss new file mode 100644 index 0000000..5d7d6f0 --- /dev/null +++ b/static/style/mixin/flex.scss @@ -0,0 +1,164 @@ +// flex(主轴,交叉轴,方向,换行,多轴线对齐) +@mixin flex($justify: null, $align: null, $direction: null, $warp: null, $warpAlign: null) { + display: flex; + + @if $direction != null { + @include flex-direction($direction); + } + @if $justify != null { + @include flex-justify($justify); + } + @if $align != null { + @include flex-align($align); + } + @if $warp != null { + @include flex-warp($warp); + } + @if $warpAlign != null { + @include flex-warpAlign($warpAlign); + } +} + +// flex-self(对齐,(布满||固定),顺序) +@mixin flex-self($flex: null, $align: null, $order: null){ + @if $flex != null { + @if $flex == full { + flex: auto; + } @else if $flex == keep { + flex: none; + } @else { + @include flexError($flex, 'flex-self'); + } + } + + @if $align != null { + @include flex-selfAlign($align); + } + + @if $order != null { + @include flex-order($order); + } +} + +// flex错误提示 +@mixin flexError($param, $type) { + position: relative; + background-color: #ff3c00 !important; + overflow: hidden; + + &::after { + position: absolute; + bottom: 0; + right: 0; + padding: 0.5em; + color: #ff3c00 !important; + background-color: white !important; + font-size: 12px; + content: 'ErrorParam: #{$param} in #{$type}'; + } +} + +// 项目的排列方向 +@mixin flex-direction($direction: row) { + @if $direction == column { + flex-direction: column; + } @else if $direction == row { + flex-direction: row; + } @else if $direction == row-reverse { + flex-direction: row-reverse; + } @else if $direction == column-reverse { + flex-direction: column-reverse; + } @else { + @include flexError($direction, 'flex-direction'); + } +} + +// 主轴上的对齐方式 +@mixin flex-justify($justify: start) { + @if $justify == start { + justify-content: start; + } @else if $justify == center { + justify-content: center; + } @else if $justify == end { + justify-content: flex-end; + } @else if $justify == between { + justify-content: space-between; + } @else if $justify == around { + justify-content: space-around; + } @else { + @include flexError($justify, 'flex-justify'); + } +} + +// 交叉轴上的对齐方式 +@mixin flex-align($align: top) { + @if $align == top { + align-items: flex-start; + } @else if $align == center { + align-items: center; + } @else if $align == bottom { + align-items: flex-end; + } @else { + @include flexError($align, 'flex-align'); + } +} + +// 换行 +@mixin flex-warp($warp: wrap) { + @if $warp == wrap { + flex-wrap: wrap; + } @else if $warp == nowrap { + flex-wrap: nowrap; + } @else if $warp == wrap-reverse { + flex-wrap: wrap-reverse; + } @else { + @include flexError($warp, 'flex-wrap'); + } +} + +// 换行多根轴线的对齐方式,如果项目只有一根轴线,该属性不起作用 +@mixin flex-warpAlign($align: stretch) { + @if $align == stretch { + align-content: stretch; + } @else if $align == top { + align-content: flex-start; + } @else if $align == center { + align-content: center; + } @else if $align == bottom { + align-content: flex-end; + } @else if $align == between { + align-content: space-between; + } @else if $align == around { + align-content: space-around; + } @else { + @include flexError($align, 'flex-wrapAlign'); + } +} + +// 单个项目有与其他项目不一样的对齐方式 +@mixin flex-selfAlign($align: auto){ + @if $align == auto { + align-self: auto; + } @else if $align == top { + align-self: flex-start; + } @else if $align == center { + align-self: center; + } @else if $align == bottom { + align-self: flex-end; + } @else if $align == baseline { + align-self: baseline ; + } @else if $align == stretch { + align-self: stretch; + } @else { + @include flexError($align, 'flex-self-align'); + } +} + +// 项目的排列顺序,数值越小,排列越靠前,默认为0 +@mixin flex-order($order: 0){ + @if $order == round($order) { + order: $order; + } @else { + @include flexError($order, 'flex-self-order'); + } +} diff --git a/static/style/mixin/hr.scss b/static/style/mixin/hr.scss new file mode 100644 index 0000000..84f1145 --- /dev/null +++ b/static/style/mixin/hr.scss @@ -0,0 +1,26 @@ +// 添加分割线 参数:位置,间隔 +@mixin hr($direction: top, $margin: 0){ + position: absolute; + z-index: 3; + @if ($direction == top) { // 右三角 + top: 0; + left: $margin; + right: $margin; + } @else if ($direction == bottom){ + bottom: 0; + left: $margin; + right: $margin; + } @else if ($direction == left){ + top: $margin; + bottom: $margin; + left: 0; + } @else if ($direction == right){ + top: $margin; + bottom: $margin; + right: 0; + } + height: 1upx; + content: ''; + transform: scaleY(.5); + background-color: #c8c7cc; +} \ No newline at end of file diff --git a/static/style/mixin/position-absolute.scss b/static/style/mixin/position-absolute.scss new file mode 100644 index 0000000..d9f9522 --- /dev/null +++ b/static/style/mixin/position-absolute.scss @@ -0,0 +1,16 @@ +// 绝对定位 参数:上,右,下,左 +@mixin position-absolute($top: null, $right: null, $bottom: null, $left: null) { + position: absolute; + @if ($left!="" and $left!=null) { + left: $left; + } + @if ($right!="" and $right!=null) { + right: $right; + } + @if ($top!="" and $top!=null) { + top: $top; + } + @if ($bottom!="" and $bottom!=null) { + bottom: $bottom; + } +} \ No newline at end of file diff --git a/static/style/mixin/price-before.scss b/static/style/mixin/price-before.scss new file mode 100644 index 0000000..e72367d --- /dev/null +++ b/static/style/mixin/price-before.scss @@ -0,0 +1,5 @@ +// 价格¥前加 +%__priceBefore{ + font-size: $uni-font-size-sm; + content: "¥"; +} \ No newline at end of file diff --git a/static/style/mixin/text-overflow.scss b/static/style/mixin/text-overflow.scss new file mode 100644 index 0000000..a2f06e1 --- /dev/null +++ b/static/style/mixin/text-overflow.scss @@ -0,0 +1,16 @@ +// 文本格式化超出省略号 参数:宽度,单行/多行 +@mixin text-overflow($width: null, $row: 1){ + @if $width != null{ + width: $width; + } + @if $row == 1{ + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } @else { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: $row; + overflow: hidden; + } +} \ No newline at end of file diff --git a/static/style/mixin/triangle.scss b/static/style/mixin/triangle.scss new file mode 100644 index 0000000..ca9021e --- /dev/null +++ b/static/style/mixin/triangle.scss @@ -0,0 +1,16 @@ +// 画三角形 参数:宽度,朝向,颜色 +@mixin triangle($width: 10px, $direction: top, $color: $uni-color-main) { + border: $width solid transparent; + @if ($direction == top) { // 上三角 + border-bottom-color: $color; + } + @if ($direction == bottom) { // 下三角 + border-top-color: $color; + } + @if ($direction == left) { // 左三角 + border-right-color: $color; + } + @if ($direction == right) { // 右三角 + border-left-color: $color; + } +} \ No newline at end of file diff --git a/template.h5.html b/template.h5.html new file mode 100644 index 0000000..b8c3f89 --- /dev/null +++ b/template.h5.html @@ -0,0 +1,33 @@ + + + + + + + + + <%= htmlWebpackPlugin.options.title %> + + + + + + + + + + + +
+ + + + diff --git a/uni.scss b/uni.scss new file mode 100644 index 0000000..9235071 --- /dev/null +++ b/uni.scss @@ -0,0 +1,76 @@ +/** + * 这里是uni-app内置的常用样式变量 + * + * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 + * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App + * + */ + +/** + * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 + * + * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 + */ +@import 'uview-ui/theme.scss'; +/* 颜色变量 */ + +/* 行为相关颜色 */ +$uni-color-primary: #007aff; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; + +/* 文字基本颜色 */ +$uni-text-color:#333;//基本色 +$uni-text-color-inverse:#fff;//反色 +$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable:#c0c0c0; + +/* 背景颜色 */ +$uni-bg-color:#ffffff; +$uni-bg-color-grey:#f8f8f8; +$uni-bg-color-hover:#f1f1f1;//点击状态颜色 +$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 + +/* 边框颜色 */ +$uni-border-color:#c8c7cc; + +/* 尺寸变量 */ + +/* 文字尺寸 */ +$uni-font-size-sm:24rpx; +$uni-font-size-base:28rpx; +$uni-font-size-lg:32rpx; + +/* 图片尺寸 */ +$uni-img-size-sm:40rpx; +$uni-img-size-base:52rpx; +$uni-img-size-lg:80rpx; + +/* Border Radius */ +$uni-border-radius-sm: 4rpx; +$uni-border-radius-base: 6rpx; +$uni-border-radius-lg: 12rpx; +$uni-border-radius-circle: 50%; + +/* 水平间距 */ +$uni-spacing-row-sm: 10px; +$uni-spacing-row-base: 20rpx; +$uni-spacing-row-lg: 30rpx; + +/* 垂直间距 */ +$uni-spacing-col-sm: 8rpx; +$uni-spacing-col-base: 16rpx; +$uni-spacing-col-lg: 24rpx; + +/* 透明度 */ +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 + +/* 文章场景相关 */ +$uni-color-title: #2C405A; // 文章标题颜色 +$uni-font-size-title:40rpx; +$uni-color-subtitle: #555555; // 二级标题颜色 +$uni-font-size-subtitle:36rpx; +$uni-color-paragraph: #3F536E; // 文章段落颜色 +$uni-font-size-paragraph:30rpx; \ No newline at end of file diff --git a/uview-ui/LICENSE b/uview-ui/LICENSE new file mode 100644 index 0000000..7456959 --- /dev/null +++ b/uview-ui/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 www.uviewui.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/uview-ui/README.md b/uview-ui/README.md new file mode 100644 index 0000000..4d24e12 --- /dev/null +++ b/uview-ui/README.md @@ -0,0 +1,105 @@ +

+ logo +

+

uView

+

多平台快速开发的UI框架

+ + +## 说明 + +uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水 + +## 特性 + +- 兼容安卓,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序 +- 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用 +- 众多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨 +- 众多的常用页面和布局,让您专注逻辑,事半功倍 +- 详尽的文档支持,现代化的演示效果 +- 按需引入,精简打包体积 + + +## 安装 + +```bash +# npm方式安装 +npm i uview-ui +``` + +## 快速上手 + +1. `main.js`引入uView库 +```js +// main.js +import uView from 'uview-ui'; +Vue.use(uView); +``` + +2. `App.vue`引入基础样式(注意style标签需声明scss属性支持) +```css +/* App.vue */ + +``` + +3. `uni.scss`引入全局scss变量文件 +```css +/* uni.scss */ +@import "uview-ui/theme.scss"; +``` + +4. `pages.json`配置easycom规则(按需引入) + +```js +// pages.json +{ + "easycom": { + // npm安装的方式不需要前面的"@/",下载安装的方式需要"@/" + // npm安装方式 + "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue" + // 下载安装方式 + // "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue" + }, + // 此为本身已有的内容 + "pages": [ + // ...... + ] +} +``` + +请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容 + +## 使用方法 +配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。 + +```html + +``` + +请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容 + +## 链接 + +- [官方文档](https://www.uviewui.com/) +- [更新日志](https://www.www.uviewui.com/components/changelog.html) +- [升级指南](https://www.uviewui.com/components/changelog.html) +- [关于我们](https://www.uviewui.com/cooperation/about.html) + +## 预览 + +您可以通过**微信**扫码,查看最佳的演示效果。 +
+
+ + +## 捐赠uView的研发 + +uView文档和源码全部开源免费,如果您认为uView帮到了您的开发工作,您可以捐赠uView的研发工作,捐赠无门槛,哪怕是一杯可乐也好(相信这比打赏主播更有意义)。 + + + +## 版权信息 +uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。 diff --git a/uview-ui/changelog.md b/uview-ui/changelog.md new file mode 100644 index 0000000..3f8c55f --- /dev/null +++ b/uview-ui/changelog.md @@ -0,0 +1,35 @@ +## 2.0.3(2021-11-16) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 处理modal的confirm回调事件拼写错误问题 +6. 处理input组件@input事件参数错误问题 +7. 其他一些修复 +## 2.0.2(2021-11-16) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 修复input组件formatter参数缺失问题 +6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss +## 2.0.0(2020-11-15) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 修复input组件formatter参数缺失问题 + + diff --git a/uview-ui/components/u--form/u--form.vue b/uview-ui/components/u--form/u--form.vue new file mode 100644 index 0000000..92c5a4b --- /dev/null +++ b/uview-ui/components/u--form/u--form.vue @@ -0,0 +1,74 @@ + + + diff --git a/uview-ui/components/u--image/u--image.vue b/uview-ui/components/u--image/u--image.vue new file mode 100644 index 0000000..ce7181c --- /dev/null +++ b/uview-ui/components/u--image/u--image.vue @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/uview-ui/components/u--input/u--input.vue b/uview-ui/components/u--input/u--input.vue new file mode 100644 index 0000000..b4090cf --- /dev/null +++ b/uview-ui/components/u--input/u--input.vue @@ -0,0 +1,63 @@ + + + \ No newline at end of file diff --git a/uview-ui/components/u--text/u--text.vue b/uview-ui/components/u--text/u--text.vue new file mode 100644 index 0000000..0425fef --- /dev/null +++ b/uview-ui/components/u--text/u--text.vue @@ -0,0 +1,46 @@ + + + diff --git a/uview-ui/components/u--textarea/u--textarea.vue b/uview-ui/components/u--textarea/u--textarea.vue new file mode 100644 index 0000000..0cbd9d8 --- /dev/null +++ b/uview-ui/components/u--textarea/u--textarea.vue @@ -0,0 +1,47 @@ + + + diff --git a/uview-ui/components/u-action-sheet/props.js b/uview-ui/components/u-action-sheet/props.js new file mode 100644 index 0000000..a8ae4c9 --- /dev/null +++ b/uview-ui/components/u-action-sheet/props.js @@ -0,0 +1,54 @@ +export default { + props: { + // 操作菜单是否展示 (默认false) + show: { + type: Boolean, + default: uni.$u.props.actionSheet.show + }, + // 标题 + title: { + type: String, + default: uni.$u.props.actionSheet.title + }, + // 选项上方的描述信息 + description: { + type: String, + default: uni.$u.props.actionSheet.description + }, + // 数据 + actions: { + type: Array, + default: uni.$u.props.actionSheet.actions + }, + // 取消按钮的文字,不为空时显示按钮 + cancelText: { + type: String, + default: uni.$u.props.actionSheet.cancelText + }, + // 点击某个菜单项时是否关闭弹窗 + closeOnClickAction: { + type: Boolean, + default: uni.$u.props.actionSheet.closeOnClickAction + }, + // 处理底部安全区(默认true) + safeAreaInsetBottom: { + type: Boolean, + default: uni.$u.props.actionSheet.safeAreaInsetBottom + }, + // 小程序的打开方式 + openType: { + type: String, + default: uni.$u.props.actionSheet.openType + }, + // 点击遮罩是否允许关闭 (默认true) + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.actionSheet.closeOnClickOverlay + }, + // 是否显示圆角 (默认false) + round: { + type: Boolean, + default: uni.$u.props.actionSheet.round + } + } +} diff --git a/uview-ui/components/u-action-sheet/u-action-sheet.vue b/uview-ui/components/u-action-sheet/u-action-sheet.vue new file mode 100644 index 0000000..a74db3d --- /dev/null +++ b/uview-ui/components/u-action-sheet/u-action-sheet.vue @@ -0,0 +1,275 @@ + + + + + + diff --git a/uview-ui/components/u-album/props.js b/uview-ui/components/u-album/props.js new file mode 100644 index 0000000..75cdb37 --- /dev/null +++ b/uview-ui/components/u-album/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 图片地址,Array|Array形式 + urls: { + type: Array, + default: uni.$u.props.album.urls + }, + // 指定从数组的对象元素中读取哪个属性作为图片地址 + keyName: { + type: String, + default: uni.$u.props.album.keyName + }, + // 单图时,图片长边的长度 + singleSize: { + type: [String, Number], + default: uni.$u.props.album.singleSize + }, + // 多图时,图片边长 + multipleSize: { + type: [String, Number], + default: uni.$u.props.album.multipleSize + }, + // 多图时,图片水平和垂直之间的间隔 + space: { + type: [String, Number], + default: uni.$u.props.album.space + }, + // 单图时,图片缩放裁剪的模式 + singleMode: { + type: String, + default: uni.$u.props.album.singleMode + }, + // 多图时,图片缩放裁剪的模式 + multipleMode: { + type: String, + default: uni.$u.props.album.multipleMode + }, + // 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量 + maxCount: { + type: [String, Number], + default: uni.$u.props.album.maxCount + }, + // 是否可以预览图片 + previewFullImage: { + type: Boolean, + default: uni.$u.props.album.previewFullImage + }, + // 每行展示图片数量,如设置,singleSize和multipleSize将会无效 + rowCount: { + type: [String, Number], + default: uni.$u.props.album.rowCount + }, + // 超出maxCount时是否显示查看更多的提示 + showMore: { + type: Boolean, + default: uni.$u.props.album.showMore + } + } +} diff --git a/uview-ui/components/u-album/u-album.vue b/uview-ui/components/u-album/u-album.vue new file mode 100644 index 0000000..ef2d3be --- /dev/null +++ b/uview-ui/components/u-album/u-album.vue @@ -0,0 +1,236 @@ + + + + + diff --git a/uview-ui/components/u-alert/props.js b/uview-ui/components/u-alert/props.js new file mode 100644 index 0000000..d542c98 --- /dev/null +++ b/uview-ui/components/u-alert/props.js @@ -0,0 +1,44 @@ +export default { + props: { + // 显示文字 + title: { + type: String, + default: uni.$u.props.alert.title + }, + // 主题,success/warning/info/error + type: { + type: String, + default: uni.$u.props.alert.type + }, + // 辅助性文字 + description: { + type: String, + default: uni.$u.props.alert.description + }, + // 是否可关闭 + closable: { + type: Boolean, + default: uni.$u.props.alert.closable + }, + // 是否显示图标 + showIcon: { + type: Boolean, + default: uni.$u.props.alert.showIcon + }, + // 浅或深色调,light-浅色,dark-深色 + effect: { + type: String, + default: uni.$u.props.alert.effect + }, + // 文字是否居中 + center: { + type: Boolean, + default: uni.$u.props.alert.center + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.alert.fontSize + } + } +} diff --git a/uview-ui/components/u-alert/u-alert.vue b/uview-ui/components/u-alert/u-alert.vue new file mode 100644 index 0000000..b37a3ce --- /dev/null +++ b/uview-ui/components/u-alert/u-alert.vue @@ -0,0 +1,243 @@ + + + + + diff --git a/uview-ui/components/u-avatar-group/props.js b/uview-ui/components/u-avatar-group/props.js new file mode 100644 index 0000000..6de6a9b --- /dev/null +++ b/uview-ui/components/u-avatar-group/props.js @@ -0,0 +1,46 @@ +export default { + props: { + // 头像图片组 + urls: { + type: Array, + default: uni.$u.props.avatarGroup.urls + }, + // 最多展示的头像数量 + maxCount: { + type: [String, Number], + default: uni.$u.props.avatarGroup.maxCount + }, + // 头像形状 + shape: { + type: String, + default: uni.$u.props.avatarGroup.shape + }, + // 图片裁剪模式 + mode: { + type: String, + default: uni.$u.props.avatarGroup.mode + }, + // 超出maxCount时是否显示查看更多的提示 + showMore: { + type: Boolean, + default: uni.$u.props.avatarGroup.showMore + }, + // 头像大小 + size: { + type: [String, Number], + default: uni.$u.props.avatarGroup.size + }, + // 指定从数组的对象元素中读取哪个属性作为图片地址 + keyName: { + type: String, + default: uni.$u.props.avatarGroup.keyName + }, + gap: { + type: [String, Number], + validator(value) { + return value >= 0 && value <= 1 + }, + default: uni.$u.props.avatarGroup.gap + } + } +} diff --git a/uview-ui/components/u-avatar-group/u-avatar-group.vue b/uview-ui/components/u-avatar-group/u-avatar-group.vue new file mode 100644 index 0000000..0cd9b3d --- /dev/null +++ b/uview-ui/components/u-avatar-group/u-avatar-group.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/uview-ui/components/u-avatar/props.js b/uview-ui/components/u-avatar/props.js new file mode 100644 index 0000000..34ca0f2 --- /dev/null +++ b/uview-ui/components/u-avatar/props.js @@ -0,0 +1,78 @@ +export default { + props: { + // 头像图片路径(不能为相对路径) + src: { + type: String, + default: uni.$u.props.avatar.src + }, + // 头像形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.avatar.shape + }, + // 头像尺寸 + size: { + type: [String, Number], + default: uni.$u.props.avatar.size + }, + // 裁剪模式 + mode: { + type: String, + default: uni.$u.props.avatar.mode + }, + // 显示的文字 + text: { + type: String, + default: uni.$u.props.avatar.text + }, + // 背景色 + bgColor: { + type: String, + default: uni.$u.props.avatar.bgColor + }, + // 文字颜色 + color: { + type: String, + default: uni.$u.props.avatar.color + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.avatar.fontSize + }, + // 显示的图标 + icon: { + type: String, + default: uni.$u.props.avatar.icon + }, + // 显示小程序头像,只对百度,微信,QQ小程序有效 + mpAvatar: { + type: Boolean, + default: uni.$u.props.avatar.mpAvatar + }, + // 是否使用随机背景色 + randomBgColor: { + type: Boolean, + default: uni.$u.props.avatar.randomBgColor + }, + // 加载失败的默认头像(组件有内置默认图片) + defaultUrl: { + type: String, + default: uni.$u.props.avatar.defaultUrl + }, + // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间 + colorIndex: { + type: [String, Number], + // 校验参数规则,索引在0-19之间 + validator(n) { + return uni.$u.test.range(n, [0, 19]) || n === '' + }, + default: uni.$u.props.avatar.colorIndex + }, + // 组件标识符 + name: { + type: String, + default: uni.$u.props.avatar.name + } + } +} diff --git a/uview-ui/components/u-avatar/u-avatar.vue b/uview-ui/components/u-avatar/u-avatar.vue new file mode 100644 index 0000000..f2d01aa --- /dev/null +++ b/uview-ui/components/u-avatar/u-avatar.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/uview-ui/components/u-back-top/props.js b/uview-ui/components/u-back-top/props.js new file mode 100644 index 0000000..6c702c2 --- /dev/null +++ b/uview-ui/components/u-back-top/props.js @@ -0,0 +1,54 @@ +export default { + props: { + // 返回顶部的形状,circle-圆形,square-方形 + mode: { + type: String, + default: uni.$u.props.backtop.mode + }, + // 自定义图标 + icon: { + type: String, + default: uni.$u.props.backtop.icon + }, + // 提示文字 + text: { + type: String, + default: uni.$u.props.backtop.text + }, + // 返回顶部滚动时间 + duration: { + type: [String, Number], + default: uni.$u.props.backtop.duration + }, + // 滚动距离 + scrollTop: { + type: [String, Number], + default: uni.$u.props.backtop.scrollTop + }, + // 距离顶部多少距离显示,单位px + top: { + type: [String, Number], + default: uni.$u.props.backtop.top + }, + // 返回顶部按钮到底部的距离,单位px + bottom: { + type: [String, Number], + default: uni.$u.props.backtop.bottom + }, + // 返回顶部按钮到右边的距离,单位px + right: { + type: [String, Number], + default: uni.$u.props.backtop.right + }, + // 层级 + zIndex: { + type: [String, Number], + default: uni.$u.props.backtop.zIndex + }, + // 图标的样式,对象形式 + iconStyle: { + type: Object, + default: uni.$u.props.backtop.iconStyle + } + } +} diff --git a/uview-ui/components/u-back-top/u-back-top.vue b/uview-ui/components/u-back-top/u-back-top.vue new file mode 100644 index 0000000..432eed2 --- /dev/null +++ b/uview-ui/components/u-back-top/u-back-top.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/uview-ui/components/u-badge/props.js b/uview-ui/components/u-badge/props.js new file mode 100644 index 0000000..74c032c --- /dev/null +++ b/uview-ui/components/u-badge/props.js @@ -0,0 +1,72 @@ +export default { + props: { + // 是否显示圆点 + isDot: { + type: Boolean, + default: uni.$u.props.badge.isDot + }, + // 显示的内容 + value: { + type: [Number, String], + default: uni.$u.props.badge.value + }, + // 是否显示 + show: { + type: Boolean, + default: uni.$u.props.badge.show + }, + // 最大值,超过最大值会显示 '{max}+' + max: { + type: [Number, String], + default: uni.$u.props.badge.max + }, + // 主题类型,error|warning|success|primary + type: { + type: String, + default: uni.$u.props.badge.type + }, + // 当数值为 0 时,是否展示 Badge + showZero: { + type: Boolean, + default: uni.$u.props.badge.showZero + }, + // 背景颜色,优先级比type高,如设置,type参数会失效 + bgColor: { + type: [String, null], + default: uni.$u.props.badge.bgColor + }, + // 字体颜色 + color: { + type: [String, null], + default: uni.$u.props.badge.color + }, + // 徽标形状,circle-四角均为圆角,horn-左下角为直角 + shape: { + type: String, + default: uni.$u.props.badge.shape + }, + // 设置数字的显示方式,overflow|ellipsis|limit + // overflow会根据max字段判断,超出显示`${max}+` + // ellipsis会根据max判断,超出显示`${max}...` + // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数 + numberType: { + type: String, + default: uni.$u.props.badge.numberType + }, + // 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效 + offset: { + type: Array, + default: uni.$u.props.badge.offset + }, + // 是否反转背景和字体颜色 + inverted: { + type: Boolean, + default: uni.$u.props.badge.inverted + }, + // 是否绝对定位 + absolute: { + type: Boolean, + default: uni.$u.props.badge.absolute + } + } +} diff --git a/uview-ui/components/u-badge/u-badge.vue b/uview-ui/components/u-badge/u-badge.vue new file mode 100644 index 0000000..326b202 --- /dev/null +++ b/uview-ui/components/u-badge/u-badge.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/uview-ui/components/u-button/nvue.scss b/uview-ui/components/u-button/nvue.scss new file mode 100644 index 0000000..ebdba7d --- /dev/null +++ b/uview-ui/components/u-button/nvue.scss @@ -0,0 +1,46 @@ +$u-button-active-opacity:0.75 !default; +$u-button-loading-text-margin-left:4px !default; +$u-button-text-color: #FFFFFF !default; +$u-button-text-plain-error-color:$u-error !default; +$u-button-text-plain-warning-color:$u-warning !default; +$u-button-text-plain-success-color:$u-success !default; +$u-button-text-plain-info-color:$u-info !default; +$u-button-text-plain-primary-color:$u-primary !default; +.u-button { + &--active { + opacity: $u-button-active-opacity; + } + + &--active--plain { + background-color: rgb(217, 217, 217); + } + + &__loading-text { + margin-left:$u-button-loading-text-margin-left; + } + + &__text, + &__loading-text { + color:$u-button-text-color; + } + + &__text--plain--error { + color:$u-button-text-plain-error-color; + } + + &__text--plain--warning { + color:$u-button-text-plain-warning-color; + } + + &__text--plain--success{ + color:$u-button-text-plain-success-color; + } + + &__text--plain--info { + color:$u-button-text-plain-info-color; + } + + &__text--plain--primary { + color:$u-button-text-plain-primary-color; + } +} \ No newline at end of file diff --git a/uview-ui/components/u-button/props.js b/uview-ui/components/u-button/props.js new file mode 100644 index 0000000..19746ed --- /dev/null +++ b/uview-ui/components/u-button/props.js @@ -0,0 +1,156 @@ +/* + * @Author : LQ + * @Description : + * @version : 1.0 + * @Date : 2021-08-16 10:04:04 + * @LastAuthor : LQ + * @lastTime : 2021-08-16 10:04:24 + * @FilePath : /u-view2.0/uview-ui/components/u-button/props.js + */ +export default { + props: { + // 是否细边框 + hairline: { + type: Boolean, + default: uni.$u.props.button.hairline + }, + // 按钮的预置样式,info,primary,error,warning,success + type: { + type: String, + default: uni.$u.props.button.type + }, + // 按钮尺寸,large,normal,small,mini + size: { + type: String, + default: uni.$u.props.button.size + }, + // 按钮形状,circle(两边为半圆),square(带圆角) + shape: { + type: String, + default: uni.$u.props.button.shape + }, + // 按钮是否镂空 + plain: { + type: Boolean, + default: uni.$u.props.button.plain + }, + // 是否禁止状态 + disabled: { + type: Boolean, + default: uni.$u.props.button.disabled + }, + // 是否加载中 + loading: { + type: Boolean, + default: uni.$u.props.button.loading + }, + // 加载中提示文字 + loadingText: { + type: [String, Number], + default: uni.$u.props.button.loadingText + }, + // 加载状态图标类型 + loadingMode: { + type: String, + default: uni.$u.props.button.loadingMode + }, + // 加载图标大小 + loadingSize: { + type: [String, Number], + default: uni.$u.props.button.loadingSize + }, + // 开放能力,具体请看uniapp稳定关于button组件部分说明 + // https://uniapp.dcloud.io/component/button + openType: { + type: String, + default: uni.$u.props.button.openType + }, + // 用于
组件,点击分别会触发 组件的 submit/reset 事件 + // 取值为submit(提交表单),reset(重置表单) + formType: { + type: String, + default: uni.$u.props.button.formType + }, + // 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 + // 只微信小程序、QQ小程序有效 + appParameter: { + type: String, + default: uni.$u.props.button.appParameter + }, + // 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效 + hoverStopPropagation: { + type: Boolean, + default: uni.$u.props.button.hoverStopPropagation + }, + // 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效 + lang: { + type: String, + default: uni.$u.props.button.lang + }, + // 会话来源,open-type="contact"时有效。只微信小程序有效 + sessionFrom: { + type: String, + default: uni.$u.props.button.sessionFrom + }, + // 会话内消息卡片标题,open-type="contact"时有效 + // 默认当前标题,只微信小程序有效 + sendMessageTitle: { + type: String, + default: uni.$u.props.button.sendMessageTitle + }, + // 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 + // 默认当前分享路径,只微信小程序有效 + sendMessagePath: { + type: String, + default: uni.$u.props.button.sendMessagePath + }, + // 会话内消息卡片图片,open-type="contact"时有效 + // 默认当前页面截图,只微信小程序有效 + sendMessageImg: { + type: String, + default: uni.$u.props.button.sendMessageImg + }, + // 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示, + // 用户点击后可以快速发送小程序消息,open-type="contact"时有效 + showMessageCard: { + type: Boolean, + default: uni.$u.props.button.showMessageCard + }, + // 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取 + dataName: { + type: String, + default: uni.$u.props.button.dataName + }, + // 节流,一定时间内只能触发一次 + throttleTime: { + type: [String, Number], + default: uni.$u.props.button.throttleTime + }, + // 按住后多久出现点击态,单位毫秒 + hoverStartTime: { + type: [String, Number], + default: uni.$u.props.button.hoverStartTime + }, + // 手指松开后点击态保留时间,单位毫秒 + hoverStayTime: { + type: [String, Number], + default: uni.$u.props.button.hoverStayTime + }, + // 按钮文字,之所以通过props传入,是因为slot传入的话 + // nvue中无法控制文字的样式 + text: { + type: [String, Number], + default: uni.$u.props.button.text + }, + // 按钮图标 + icon: { + type: String, + default: uni.$u.props.button.icon + }, + // 按钮颜色,支持传入linear-gradient渐变色 + color: { + type: String, + default: uni.$u.props.button.color + } + } +} diff --git a/uview-ui/components/u-button/u-button.vue b/uview-ui/components/u-button/u-button.vue new file mode 100644 index 0000000..b3122ed --- /dev/null +++ b/uview-ui/components/u-button/u-button.vue @@ -0,0 +1,485 @@ + + + + + diff --git a/uview-ui/components/u-button/vue.scss b/uview-ui/components/u-button/vue.scss new file mode 100644 index 0000000..6a25e59 --- /dev/null +++ b/uview-ui/components/u-button/vue.scss @@ -0,0 +1,73 @@ +// nvue下hover-class无效 +$u-button-before-top:50% !default; +$u-button-before-left:50% !default; +$u-button-before-width:100% !default; +$u-button-before-height:100% !default; +$u-button-before-transform:translate(-50%, -50%) !default; +$u-button-before-opacity:0 !default; +$u-button-before-background-color:#000 !default; +$u-button-before-border-color:#000 !default; +$u-button-active-before-opacity:.15 !default; +$u-button-icon-margin-left:4px !default; +$u-button-plain-u-button-info-color:$u-info; +$u-button-plain-u-button-success-color:$u-success; +$u-button-plain-u-button-error-color:$u-error; +$u-button-plain-u-button-warning-color:$u-error; + +.u-button { + &:before { + position: absolute; + top:$u-button-before-top; + left:$u-button-before-left; + width:$u-button-before-width; + height:$u-button-before-height; + border: inherit; + border-radius: inherit; + transform:$u-button-before-transform; + opacity:$u-button-before-opacity; + content: " "; + background-color:$u-button-before-background-color; + border-color:$u-button-before-border-color; + } + + &--active { + &:before { + opacity: .15 + } + } + + &__icon+&__text:not(:empty), + &__loading-text { + margin-left:$u-button-icon-margin-left; + } + + &--plain { + &.u-button--primary { + color: $u-primary; + } + } + + &--plain { + &.u-button--info { + color:$u-button-plain-u-button-info-color; + } + } + + &--plain { + &.u-button--success { + color:$u-button-plain-u-button-success-color; + } + } + + &--plain { + &.u-button--error { + color:$u-button-plain-u-button-error-color; + } + } + + &--plain { + &.u-button--warning { + color:$u-button-plain-u-button-warning-color; + } + } +} diff --git a/uview-ui/components/u-calendar/header.vue b/uview-ui/components/u-calendar/header.vue new file mode 100644 index 0000000..210819f --- /dev/null +++ b/uview-ui/components/u-calendar/header.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/uview-ui/components/u-calendar/month.vue b/uview-ui/components/u-calendar/month.vue new file mode 100644 index 0000000..42bf8ed --- /dev/null +++ b/uview-ui/components/u-calendar/month.vue @@ -0,0 +1,570 @@ + + + + + diff --git a/uview-ui/components/u-calendar/props.js b/uview-ui/components/u-calendar/props.js new file mode 100644 index 0000000..b7ed0ad --- /dev/null +++ b/uview-ui/components/u-calendar/props.js @@ -0,0 +1,134 @@ +export default { + props: { + // 日历顶部标题 + title: { + type: String, + default: uni.$u.props.calendar.title + }, + // 是否显示标题 + showTitle: { + type: Boolean, + default: uni.$u.props.calendar.showTitle + }, + // 是否显示副标题 + showSubtitle: { + type: Boolean, + default: uni.$u.props.calendar.showSubtitle + }, + // 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 + mode: { + type: String, + default: uni.$u.props.calendar.mode + }, + // mode=range时,第一个日期底部的提示文字 + startText: { + type: String, + default: uni.$u.props.calendar.startText + }, + // mode=range时,最后一个日期底部的提示文字 + endText: { + type: String, + default: uni.$u.props.calendar.endText + }, + // 自定义列表 + customList: { + type: Array, + default: uni.$u.props.calendar.customList + }, + // 主题色,对底部按钮和选中日期有效 + color: { + type: String, + default: uni.$u.props.calendar.color + }, + // 最小的可选日期 + minDate: { + type: [String, Number], + default: uni.$u.props.calendar.minDate + }, + // 最大可选日期 + maxDate: { + type: [String, Number], + default: uni.$u.props.calendar.maxDate + }, + // 默认选中的日期,mode为multiple或range是必须为数组格式 + defaultDate: { + type: [Array, String, Date, null], + default: uni.$u.props.calendar.defaultDate + }, + // mode=multiple时,最多可选多少个日期 + maxCount: { + type: [String, Number], + default: uni.$u.props.calendar.maxCount + }, + // 日期行高 + rowHeight: { + type: [String, Number], + default: uni.$u.props.calendar.rowHeight + }, + // 日期格式化函数 + formatter: { + type: [Function, null], + default: uni.$u.props.calendar.formatter + }, + // 是否显示农历 + showLunar: { + type: Boolean, + default: uni.$u.props.calendar.showLunar + }, + // 是否显示月份背景色 + showMark: { + type: Boolean, + default: uni.$u.props.calendar.showMark + }, + // 确定按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.calendar.confirmText + }, + // 确认按钮处于禁用状态时的文字 + confirmDisabledText: { + type: String, + default: uni.$u.props.calendar.confirmDisabledText + }, + // 是否显示日历弹窗 + show: { + type: Boolean, + default: uni.$u.props.calendar.show + }, + // 是否允许点击遮罩关闭日历 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.calendar.closeOnClickOverlay + }, + // 是否为只读状态,只读状态下禁止选择日期 + readonly: { + type: Boolean, + default: uni.$u.props.calendar.readonly + }, + // 是否展示确认按钮 + showConfirm: { + type: Boolean, + default: uni.$u.props.calendar.showConfirm + }, + // 日期区间最多可选天数,默认无限制,mode = range时有效 + maxRange: { + type: [Number, String], + default: uni.$u.props.calendar.maxRange + }, + // 范围选择超过最多可选天数时的提示文案,mode = range时有效 + rangePrompt: { + type: String, + default: uni.$u.props.calendar.rangePrompt + }, + // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 + showRangePrompt: { + type: Boolean, + default: uni.$u.props.calendar.showRangePrompt + }, + // 是否允许日期范围的起止时间为同一天,mode = range时有效 + allowSameDay: { + type: Boolean, + default: uni.$u.props.calendar.allowSameDay + } + } +} diff --git a/uview-ui/components/u-calendar/u-calendar.vue b/uview-ui/components/u-calendar/u-calendar.vue new file mode 100644 index 0000000..82469b5 --- /dev/null +++ b/uview-ui/components/u-calendar/u-calendar.vue @@ -0,0 +1,288 @@ + + + + + diff --git a/uview-ui/components/u-calendar/util.js b/uview-ui/components/u-calendar/util.js new file mode 100644 index 0000000..f71ad62 --- /dev/null +++ b/uview-ui/components/u-calendar/util.js @@ -0,0 +1,85 @@ +export default { + methods: { + // 设置月份数据 + setMonth() { + // 月初是周几 + const day = dayjs(this.date).date(1).day() + const start = day == 0 ? 6 : day - 1 + + // 本月天数 + const days = dayjs(this.date).endOf('month').format('D') + + // 上个月天数 + const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D') + + // 日期数据 + const arr = [] + // 清空表格 + this.month = [] + + // 添加上月数据 + arr.push( + ...new Array(start).fill(1).map((e, i) => { + const day = prevDays - start + i + 1 + + return { + value: day, + disabled: true, + date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD') + } + }) + ) + + // 添加本月数据 + arr.push( + ...new Array(days - 0).fill(1).map((e, i) => { + const day = i + 1 + + return { + value: day, + date: dayjs(this.date).date(day).format('YYYY-MM-DD') + } + }) + ) + + // 添加下个月 + arr.push( + ...new Array(42 - days - start).fill(1).map((e, i) => { + const day = i + 1 + + return { + value: day, + disabled: true, + date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD') + } + }) + ) + + // 分割数组 + for (let n = 0; n < arr.length; n += 7) { + this.month.push( + arr.slice(n, n + 7).map((e, i) => { + e.index = i + n + + // 自定义信息 + const custom = this.customList.find((c) => c.date == e.date) + + // 农历 + if (this.lunar) { + const { + IDayCn, + IMonthCn + } = this.getLunar(e.date) + e.lunar = IDayCn == '初一' ? IMonthCn : IDayCn + } + + return { + ...e, + ...custom + } + }) + ) + } + } + } +} diff --git a/uview-ui/components/u-car-keyboard/props.js b/uview-ui/components/u-car-keyboard/props.js new file mode 100644 index 0000000..3553647 --- /dev/null +++ b/uview-ui/components/u-car-keyboard/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: false + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: false + } + } +} diff --git a/uview-ui/components/u-car-keyboard/u-car-keyboard.vue b/uview-ui/components/u-car-keyboard/u-car-keyboard.vue new file mode 100644 index 0000000..7a30afa --- /dev/null +++ b/uview-ui/components/u-car-keyboard/u-car-keyboard.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/uview-ui/components/u-cell-group/props.js b/uview-ui/components/u-cell-group/props.js new file mode 100644 index 0000000..350ef40 --- /dev/null +++ b/uview-ui/components/u-cell-group/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 分组标题 + title: { + type: String, + default: uni.$u.props.cellGroup.title + }, + // 是否显示外边框 + border: { + type: Boolean, + default: uni.$u.props.cellGroup.border + } + } +} diff --git a/uview-ui/components/u-cell-group/u-cell-group.vue b/uview-ui/components/u-cell-group/u-cell-group.vue new file mode 100644 index 0000000..c85f4c1 --- /dev/null +++ b/uview-ui/components/u-cell-group/u-cell-group.vue @@ -0,0 +1,61 @@ + + + + + + diff --git a/uview-ui/components/u-cell/props.js b/uview-ui/components/u-cell/props.js new file mode 100644 index 0000000..3c19543 --- /dev/null +++ b/uview-ui/components/u-cell/props.js @@ -0,0 +1,109 @@ +export default { + props: { + // 标题 + title: { + type: [String, Number], + default: uni.$u.props.cell.title + }, + // 标题下方的描述信息 + label: { + type: [String, Number], + default: uni.$u.props.cell.label + }, + // 右侧的内容 + value: { + type: [String, Number], + default: uni.$u.props.cell.value + }, + // 左侧图标名称,或者图片链接(本地文件建议使用绝对地址) + icon: { + type: String, + default: uni.$u.props.cell.icon + }, + // 标题的宽度,单位任意,数值默认为px单位 + titleWidth: { + type: [String, Number], + default: uni.$u.props.cell.titleWidth + }, + // 是否禁用cell + disabled: { + type: Boolean, + default: uni.$u.props.cell.disabled + }, + // 是否显示下边框 + border: { + type: Boolean, + default: uni.$u.props.cell.border + }, + // 内容是否垂直居中(主要是针对右侧的value部分) + center: { + type: Boolean, + default: uni.$u.props.cell.center + }, + // 点击后跳转的URL地址 + url: { + type: String, + default: uni.$u.props.cell.url + }, + // 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作 + linkType: { + type: String, + default: uni.$u.props.cell.linkType + }, + // 是否开启点击反馈(表现为点击时加上灰色背景) + clickable: { + type: Boolean, + default: uni.$u.props.cell.clickable + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: uni.$u.props.cell.isLink + }, + // 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件) + required: { + type: Boolean, + default: uni.$u.props.cell.required + }, + // 右侧的图标箭头 + rightIcon: { + type: String, + default: uni.$u.props.cell.rightIcon + }, + // 右侧箭头的方向,可选值为:left,up,down + arrowDirection: { + type: String, + default: uni.$u.props.cell.arrowDirection + }, + // 左侧图标样式 + iconStyle: { + type: Object, + default: () => {} + }, + // 右侧箭头图标的样式 + rightIconStyle: { + type: Object, + default: () => uni.$u.props.cell.rightIconStyle + }, + // 标题的样式 + titleStyle: { + type: Object, + default: () => uni.$u.props.cell.titleStyle + }, + // 单位元的大小,可选值为large + size: { + type: String, + default: uni.$u.props.cell.size + }, + // 点击cell是否阻止事件传播 + stop: { + type: Boolean, + default: uni.$u.props.cell.stop + }, + // 标识符,cell被点击时返回 + name: { + type: [Number, String], + default: uni.$u.props.cell.name + } + } +} diff --git a/uview-ui/components/u-cell/u-cell.vue b/uview-ui/components/u-cell/u-cell.vue new file mode 100644 index 0000000..79ea244 --- /dev/null +++ b/uview-ui/components/u-cell/u-cell.vue @@ -0,0 +1,224 @@ + + + + + diff --git a/uview-ui/components/u-checkbox-group/props.js b/uview-ui/components/u-checkbox-group/props.js new file mode 100644 index 0000000..2f818a1 --- /dev/null +++ b/uview-ui/components/u-checkbox-group/props.js @@ -0,0 +1,82 @@ +export default { + props: { + // 标识符 + name: { + type: String, + default: uni.$u.props.checkboxGroup.name + }, + // 绑定的值 + value: { + type: Array, + default: uni.$u.props.checkboxGroup.value + }, + // 形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.checkboxGroup.shape + }, + // 是否禁用全部checkbox + disabled: { + type: Boolean, + default: uni.$u.props.checkboxGroup.disabled + }, + + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: uni.$u.props.checkboxGroup.activeColor + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.checkboxGroup.inactiveColor + }, + + // 整个组件的尺寸,默认px + size: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.size + }, + // 布局方式,row-横向,column-纵向 + placement: { + type: String, + default: uni.$u.props.checkboxGroup.placement + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.labelSize + }, + // label的字体颜色 + labelColor: { + type: [String], + default: uni.$u.props.checkboxGroup.labelColor + }, + // 是否禁止点击文本操作 + labelDisabled: { + type: Boolean, + default: uni.$u.props.checkboxGroup.labelDisabled + }, + // 图标颜色 + iconColor: { + type: String, + default: uni.$u.props.checkboxGroup.iconColor + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.iconSize + }, + // 勾选图标的对齐方式,left-左边,right-右边 + iconPlacement: { + type: String, + default: uni.$u.props.checkboxGroup.iconPlacement + }, + // 竖向配列时,是否显示下划线 + borderBottom: { + type: Boolean, + default: uni.$u.props.checkboxGroup.borderBottom + } + + } +} diff --git a/uview-ui/components/u-checkbox-group/u-checkbox-group.vue b/uview-ui/components/u-checkbox-group/u-checkbox-group.vue new file mode 100644 index 0000000..dc6c9de --- /dev/null +++ b/uview-ui/components/u-checkbox-group/u-checkbox-group.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/uview-ui/components/u-checkbox/props.js b/uview-ui/components/u-checkbox/props.js new file mode 100644 index 0000000..93f4fd9 --- /dev/null +++ b/uview-ui/components/u-checkbox/props.js @@ -0,0 +1,69 @@ +export default { + props: { + // checkbox的名称 + name: { + type: [String, Number, Boolean], + default: uni.$u.props.checkbox.name + }, + // 形状,square为方形,circle为圆型 + shape: { + type: String, + default: uni.$u.props.checkbox.shape + }, + // 整体的大小 + size: { + type: [String, Number], + default: uni.$u.props.checkbox.size + }, + // 是否默认选中 + checked: { + type: Boolean, + default: uni.$u.props.checkbox.checked + }, + // 是否禁用 + disabled: { + type: [String, Boolean], + default: uni.$u.props.checkbox.disabled + }, + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: uni.$u.props.checkbox.activeColor + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.checkbox.inactiveColor + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: uni.$u.props.checkbox.iconSize + }, + // 图标颜色 + iconColor: { + type: String, + default: uni.$u.props.checkbox.iconColor + }, + // label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式 + label: { + type: [String, Number], + default: uni.$u.props.checkbox.label + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: uni.$u.props.checkbox.labelSize + }, + // label的颜色 + labelColor: { + type: String, + default: uni.$u.props.checkbox.labelColor + }, + // 是否禁止点击提示语选中复选框 + labelDisabled: { + type: [String, Boolean], + default: uni.$u.props.checkbox.labelDisabled + } + } +} diff --git a/uview-ui/components/u-checkbox/u-checkbox.vue b/uview-ui/components/u-checkbox/u-checkbox.vue new file mode 100644 index 0000000..601ded9 --- /dev/null +++ b/uview-ui/components/u-checkbox/u-checkbox.vue @@ -0,0 +1,339 @@ + + + + + diff --git a/uview-ui/components/u-circle-progress/props.js b/uview-ui/components/u-circle-progress/props.js new file mode 100644 index 0000000..d776cfb --- /dev/null +++ b/uview-ui/components/u-circle-progress/props.js @@ -0,0 +1,8 @@ +export default { + props: { + percentage: { + type: [String, Number], + default: uni.$u.props.circleProgress.percentage + } + } +} diff --git a/uview-ui/components/u-circle-progress/u-circle-progress.vue b/uview-ui/components/u-circle-progress/u-circle-progress.vue new file mode 100644 index 0000000..d63fd43 --- /dev/null +++ b/uview-ui/components/u-circle-progress/u-circle-progress.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/uview-ui/components/u-code-input/props.js b/uview-ui/components/u-code-input/props.js new file mode 100644 index 0000000..de421ba --- /dev/null +++ b/uview-ui/components/u-code-input/props.js @@ -0,0 +1,69 @@ +export default { + props: { + // 最大输入长度 + maxlength: { + type: [String, Number], + default: uni.$u.props.codeInput.maxlength + }, + // 是否用圆点填充 + dot: { + type: Boolean, + default: uni.$u.props.codeInput.dot + }, + // 显示模式,box-盒子模式,line-底部横线模式 + mode: { + type: String, + default: uni.$u.props.codeInput.mode + }, + // 是否细边框 + hairline: { + type: Boolean, + default: uni.$u.props.codeInput.hairline + }, + // 字符间的距离 + space: { + type: [String, Number], + default: uni.$u.props.codeInput.space + }, + // 预置值 + value: { + type: [String, Number], + default: uni.$u.props.codeInput.value + }, + // 是否自动获取焦点 + focus: { + type: Boolean, + default: uni.$u.props.codeInput.focus + }, + // 字体是否加粗 + bold: { + type: Boolean, + default: uni.$u.props.codeInput.bold + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.codeInput.color + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.codeInput.fontSize + }, + // 输入框的大小,宽等于高 + size: { + type: [String, Number], + default: uni.$u.props.codeInput.size + }, + // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true + disabledKeyboard: { + type: Boolean, + default: uni.$u.props.codeInput.disabledKeyboard + }, + // 边框和线条颜色 + borderColor: { + type: String, + default: uni.$u.props.codeInput.borderColor + } + } +} diff --git a/uview-ui/components/u-code-input/u-code-input.vue b/uview-ui/components/u-code-input/u-code-input.vue new file mode 100644 index 0000000..97a9f41 --- /dev/null +++ b/uview-ui/components/u-code-input/u-code-input.vue @@ -0,0 +1,206 @@ + + + + + diff --git a/uview-ui/components/u-code/props.js b/uview-ui/components/u-code/props.js new file mode 100644 index 0000000..eaf80d0 --- /dev/null +++ b/uview-ui/components/u-code/props.js @@ -0,0 +1,34 @@ +export default { + props: { + // 倒计时总秒数 + seconds: { + type: [String, Number], + default: uni.$u.props.code.seconds + }, + // 尚未开始时提示 + startText: { + type: String, + default: uni.$u.props.code.startText + }, + // 正在倒计时中的提示 + changeText: { + type: String, + default: uni.$u.props.code.changeText + }, + // 倒计时结束时的提示 + endText: { + type: String, + default: uni.$u.props.code.endText + }, + // 是否在H5刷新或各端返回再进入时继续倒计时 + keepRunning: { + type: Boolean, + default: uni.$u.props.code.keepRunning + }, + // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了 + uniqueKey: { + type: String, + default: uni.$u.props.code.uniqueKey + } + } +} diff --git a/uview-ui/components/u-code/u-code.vue b/uview-ui/components/u-code/u-code.vue new file mode 100644 index 0000000..cdf9f82 --- /dev/null +++ b/uview-ui/components/u-code/u-code.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/uview-ui/components/u-col/props.js b/uview-ui/components/u-col/props.js new file mode 100644 index 0000000..0622251 --- /dev/null +++ b/uview-ui/components/u-col/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 占父容器宽度的多少等分,总分为12份 + span: { + type: [String, Number], + default: uni.$u.props.col.span + }, + // 指定栅格左侧的间隔数(总12栏) + offset: { + type: [String, Number], + default: uni.$u.props.col.offset + }, + // 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`) + justify: { + type: String, + default: uni.$u.props.col.justify + }, + // 垂直对齐方式,可选值为top、center、bottom、stretch + align: { + type: String, + default: uni.$u.props.col.align + }, + // 文字对齐方式 + textAlign: { + type: String, + default: uni.$u.props.col.textAlign + } + } +} diff --git a/uview-ui/components/u-col/u-col.vue b/uview-ui/components/u-col/u-col.vue new file mode 100644 index 0000000..816f022 --- /dev/null +++ b/uview-ui/components/u-col/u-col.vue @@ -0,0 +1,159 @@ + + + + + diff --git a/uview-ui/components/u-collapse-item/props.js b/uview-ui/components/u-collapse-item/props.js new file mode 100644 index 0000000..bd5749b --- /dev/null +++ b/uview-ui/components/u-collapse-item/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 标题 + title: { + type: String, + default: uni.$u.props.collapseItem.title + }, + // 标题右侧内容 + value: { + type: String, + default: uni.$u.props.collapseItem.value + }, + // 标题下方的描述信息 + label: { + type: String, + default: uni.$u.props.collapseItem.label + }, + // 是否禁用折叠面板 + disabled: { + type: Boolean, + default: uni.$u.props.collapseItem.disabled + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: uni.$u.props.collapseItem.isLink + }, + // 是否开启点击反馈 + clickable: { + type: Boolean, + default: uni.$u.props.collapseItem.clickable + }, + // 是否显示内边框 + border: { + type: Boolean, + default: uni.$u.props.collapseItem.border + }, + // 标题的对齐方式 + align: { + type: String, + default: uni.$u.props.collapseItem.align + }, + // 唯一标识符 + name: { + type: [String, Number], + default: uni.$u.props.collapseItem.name + }, + // 标题左侧图片,可为绝对路径的图片或内置图标 + icon: { + type: String, + default: uni.$u.props.collapseItem.icon + }, + // 面板展开收起的过渡时间,单位ms + duration: { + type: Number, + default: uni.$u.props.collapseItem.duration + } + } +} diff --git a/uview-ui/components/u-collapse-item/u-collapse-item.vue b/uview-ui/components/u-collapse-item/u-collapse-item.vue new file mode 100644 index 0000000..f99b77e --- /dev/null +++ b/uview-ui/components/u-collapse-item/u-collapse-item.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/uview-ui/components/u-collapse/props.js b/uview-ui/components/u-collapse/props.js new file mode 100644 index 0000000..7ee6d31 --- /dev/null +++ b/uview-ui/components/u-collapse/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 当前展开面板的name,非手风琴模式:[],手风琴模式:string | number + value: { + type: [String, Number, Array, null], + default: uni.$u.props.collapse.value + }, + // 是否手风琴模式 + accordion: { + type: Boolean, + default: uni.$u.props.collapse.accordion + }, + // 是否显示外边框 + border: { + type: Boolean, + default: uni.$u.props.collapse.border + } + } +} diff --git a/uview-ui/components/u-collapse/u-collapse.vue b/uview-ui/components/u-collapse/u-collapse.vue new file mode 100644 index 0000000..a7c3130 --- /dev/null +++ b/uview-ui/components/u-collapse/u-collapse.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/uview-ui/components/u-column-notice/props.js b/uview-ui/components/u-column-notice/props.js new file mode 100644 index 0000000..4809154 --- /dev/null +++ b/uview-ui/components/u-column-notice/props.js @@ -0,0 +1,55 @@ +export default { + props: { + // 显示的内容,字符串 + text: { + type: [Array], + default: uni.$u.props.columnNotice.text + }, + // 是否显示左侧的音量图标 + icon: { + type: String, + default: uni.$u.props.columnNotice.icon + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: uni.$u.props.columnNotice.mode + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: uni.$u.props.columnNotice.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.columnNotice.bgColor + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: uni.$u.props.columnNotice.fontSize + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: uni.$u.props.columnNotice.speed + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: uni.$u.props.columnNotice.step + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.columnNotice.duration + }, + // 是否禁止用手滑动切换 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: uni.$u.props.columnNotice.disableTouch + } + } +} diff --git a/uview-ui/components/u-column-notice/u-column-notice.vue b/uview-ui/components/u-column-notice/u-column-notice.vue new file mode 100644 index 0000000..41576b8 --- /dev/null +++ b/uview-ui/components/u-column-notice/u-column-notice.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/uview-ui/components/u-count-down/props.js b/uview-ui/components/u-count-down/props.js new file mode 100644 index 0000000..d62f025 --- /dev/null +++ b/uview-ui/components/u-count-down/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 倒计时时长,单位ms + time: { + type: [String, Number], + default: uni.$u.props.countDown.time + }, + // 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 + format: { + type: String, + default: uni.$u.props.countDown.format + }, + // 是否自动开始倒计时 + autoStart: { + type: Boolean, + default: uni.$u.props.countDown.autoStart + }, + // 是否展示毫秒倒计时 + millisecond: { + type: Boolean, + default: uni.$u.props.countDown.millisecond + } + } +} diff --git a/uview-ui/components/u-count-down/u-count-down.vue b/uview-ui/components/u-count-down/u-count-down.vue new file mode 100644 index 0000000..21a5d5b --- /dev/null +++ b/uview-ui/components/u-count-down/u-count-down.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/uview-ui/components/u-count-down/utils.js b/uview-ui/components/u-count-down/utils.js new file mode 100644 index 0000000..4cde64d --- /dev/null +++ b/uview-ui/components/u-count-down/utils.js @@ -0,0 +1,62 @@ +// 补0,如1 -> 01 +function padZero(num, targetLength = 2) { + let str = `${num}` + while (str.length < targetLength) { + str = `0${str}` + } + return str +} +const SECOND = 1000 +const MINUTE = 60 * SECOND +const HOUR = 60 * MINUTE +const DAY = 24 * HOUR +export function parseTimeData(time) { + const days = Math.floor(time / DAY) + const hours = Math.floor((time % DAY) / HOUR) + const minutes = Math.floor((time % HOUR) / MINUTE) + const seconds = Math.floor((time % MINUTE) / SECOND) + const milliseconds = Math.floor(time % SECOND) + return { + days, + hours, + minutes, + seconds, + milliseconds + } +} +export function parseFormat(format, timeData) { + let { + days, + hours, + minutes, + seconds, + milliseconds + } = timeData + // 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去 + if (format.indexOf('DD') === -1) { + hours += days * 24 + } else { + // 对天补0 + format = format.replace('DD', padZero(days)) + } + // 其他同理于DD的格式化处理方式 + if (format.indexOf('HH') === -1) { + minutes += hours * 60 + } else { + format = format.replace('HH', padZero(hours)) + } + if (format.indexOf('mm') === -1) { + seconds += minutes * 60 + } else { + format = format.replace('mm', padZero(minutes)) + } + if (format.indexOf('ss') === -1) { + milliseconds += seconds * 1000 + } else { + format = format.replace('ss', padZero(seconds)) + } + return format.replace('SSS', padZero(milliseconds, 3)) +} +export function isSameSecond(time1, time2) { + return Math.floor(time1 / 1000) === Math.floor(time2 / 1000) +} diff --git a/uview-ui/components/u-count-to/props.js b/uview-ui/components/u-count-to/props.js new file mode 100644 index 0000000..86873c1 --- /dev/null +++ b/uview-ui/components/u-count-to/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 开始的数值,默认从0增长到某一个数 + startVal: { + type: [String, Number], + default: uni.$u.props.countTo.startVal + }, + // 要滚动的目标数值,必须 + endVal: { + type: [String, Number], + default: uni.$u.props.countTo.endVal + }, + // 滚动到目标数值的动画持续时间,单位为毫秒(ms) + duration: { + type: [String, Number], + default: uni.$u.props.countTo.duration + }, + // 设置数值后是否自动开始滚动 + autoplay: { + type: Boolean, + default: uni.$u.props.countTo.autoplay + }, + // 要显示的小数位数 + decimals: { + type: [String, Number], + default: uni.$u.props.countTo.decimals + }, + // 是否在即将到达目标数值的时候,使用缓慢滚动的效果 + useEasing: { + type: Boolean, + default: uni.$u.props.countTo.useEasing + }, + // 十进制分割 + decimal: { + type: [String, Number], + default: uni.$u.props.countTo.decimal + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.countTo.color + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.countTo.fontSize + }, + // 是否加粗字体 + bold: { + type: Boolean, + default: uni.$u.props.countTo.bold + }, + // 千位分隔符,类似金额的分割(¥23,321.05中的",") + separator: { + type: String, + default: uni.$u.props.countTo.separator + } + } +} diff --git a/uview-ui/components/u-count-to/u-count-to.vue b/uview-ui/components/u-count-to/u-count-to.vue new file mode 100644 index 0000000..07f363e --- /dev/null +++ b/uview-ui/components/u-count-to/u-count-to.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/uview-ui/components/u-datetime-picker/props.js b/uview-ui/components/u-datetime-picker/props.js new file mode 100644 index 0000000..f44c0f9 --- /dev/null +++ b/uview-ui/components/u-datetime-picker/props.js @@ -0,0 +1,116 @@ +export default { + props: { + // 是否打开组件 + show: { + type: Boolean, + default: uni.$u.props.datetimePicker.show + }, + // 是否展示顶部的操作栏 + showToolbar: { + type: Boolean, + default: uni.$u.props.datetimePicker.showToolbar + }, + // 绑定值 + value: { + type: [String, Number], + default: uni.$u.props.datetimePicker.value + }, + // 顶部标题 + title: { + type: String, + default: uni.$u.props.datetimePicker.title + }, + // 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择 + mode: { + type: String, + default: uni.$u.props.datetimePicker.mode + }, + // 可选的最大时间 + maxDate: { + type: Number, + // 最大默认值为后10年 + default: uni.$u.props.datetimePicker.maxDate + }, + // 可选的最小时间 + minDate: { + type: Number, + // 最小默认值为前10年 + default: uni.$u.props.datetimePicker.minDate + }, + // 可选的最小小时,仅mode=time有效 + minHour: { + type: Number, + default: uni.$u.props.datetimePicker.minHour + }, + // 可选的最大小时,仅mode=time有效 + maxHour: { + type: Number, + default: uni.$u.props.datetimePicker.maxHour + }, + // 可选的最小分钟,仅mode=time有效 + minMinute: { + type: Number, + default: uni.$u.props.datetimePicker.minMinute + }, + // 可选的最大分钟,仅mode=time有效 + maxMinute: { + type: Number, + default: uni.$u.props.datetimePicker.maxMinute + }, + // 选项过滤函数 + filter: { + type: [Function, null], + default: uni.$u.props.datetimePicker.filter + }, + // 选项格式化函数 + formatter: { + type: [Function, null], + default: uni.$u.props.datetimePicker.formatter + }, + // 是否显示加载中状态 + loading: { + type: Boolean, + default: uni.$u.props.datetimePicker.loading + }, + // 各列中,单个选项的高度 + itemHeight: { + type: [String, Number], + default: uni.$u.props.datetimePicker.itemHeight + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: uni.$u.props.datetimePicker.cancelText + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.datetimePicker.confirmText + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: uni.$u.props.datetimePicker.cancelColor + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: uni.$u.props.datetimePicker.confirmColor + }, + // 每列中可见选项的数量 + visibleItemCount: { + type: [String, Number], + default: uni.$u.props.datetimePicker.visibleItemCount + }, + // 是否允许点击遮罩关闭选择器 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.datetimePicker.closeOnClickOverlay + }, + // 各列的默认索引 + defaultIndex: { + type: Array, + default: uni.$u.props.datetimePicker.defaultIndex + } + } +} diff --git a/uview-ui/components/u-datetime-picker/u-datetime-picker.vue b/uview-ui/components/u-datetime-picker/u-datetime-picker.vue new file mode 100644 index 0000000..8f75cba --- /dev/null +++ b/uview-ui/components/u-datetime-picker/u-datetime-picker.vue @@ -0,0 +1,335 @@ + + + + + diff --git a/uview-ui/components/u-divider/props.js b/uview-ui/components/u-divider/props.js new file mode 100644 index 0000000..1fa8359 --- /dev/null +++ b/uview-ui/components/u-divider/props.js @@ -0,0 +1,44 @@ +export default { + props: { + // 是否虚线 + dashed: { + type: Boolean, + default: uni.$u.props.divider.dashed + }, + // 是否细线 + hairline: { + type: Boolean, + default: uni.$u.props.divider.hairline + }, + // 是否以点替代文字,优先于text字段起作用 + dot: { + type: Boolean, + default: uni.$u.props.divider.dot + }, + // 内容文本的位置,left-左边,center-中间,right-右边 + textPosition: { + type: String, + default: uni.$u.props.divider.textPosition + }, + // 文本内容 + text: { + type: [String, Number], + default: uni.$u.props.divider.text + }, + // 文本大小 + textSize: { + type: [String, Number], + default: uni.$u.props.divider.textSize + }, + // 文本颜色 + textColor: { + type: String, + default: uni.$u.props.divider.textColor + }, + // 线条颜色 + lineColor: { + type: String, + default: uni.$u.props.divider.lineColor + } + } +} diff --git a/uview-ui/components/u-divider/u-divider.vue b/uview-ui/components/u-divider/u-divider.vue new file mode 100644 index 0000000..d7d0251 --- /dev/null +++ b/uview-ui/components/u-divider/u-divider.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/uview-ui/components/u-dropdown-item/props.js b/uview-ui/components/u-dropdown-item/props.js new file mode 100644 index 0000000..c73fb3b --- /dev/null +++ b/uview-ui/components/u-dropdown-item/props.js @@ -0,0 +1,36 @@ +export default { + props: { + // 当前选中项的value值 + value: { + type: [Number, String, Array], + default: '' + }, + // 菜单项标题 + title: { + type: [String, Number], + default: '' + }, + // 选项数据,如果传入了默认slot,此参数无效 + options: { + type: Array, + default() { + return [] + } + }, + // 是否禁用此菜单项 + disabled: { + type: Boolean, + default: false + }, + // 下拉弹窗的高度 + height: { + type: [Number, String], + default: 'auto' + }, + // 点击遮罩是否可以收起弹窗 + closeOnClickOverlay: { + type: Boolean, + default: true + } + } +} diff --git a/uview-ui/components/u-dropdown-item/u-dropdown-item.vue b/uview-ui/components/u-dropdown-item/u-dropdown-item.vue new file mode 100644 index 0000000..ccdf1c2 --- /dev/null +++ b/uview-ui/components/u-dropdown-item/u-dropdown-item.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/uview-ui/components/u-dropdown/props.js b/uview-ui/components/u-dropdown/props.js new file mode 100644 index 0000000..5032888 --- /dev/null +++ b/uview-ui/components/u-dropdown/props.js @@ -0,0 +1,65 @@ +export default { + props: { + // 标题选中时的样式 + activeStyle: { + type: [String, Object], + default: () => ({ + color: '#2979ff', + fontSize: '14px' + }) + }, + // 标题未选中时的样式 + inactiveStyle: { + type: [String, Object], + default: () => ({ + color: '#606266', + fontSize: '14px' + }) + }, + // 点击遮罩是否关闭菜单 + closeOnClickMask: { + type: Boolean, + default: true + }, + // 点击当前激活项标题是否关闭菜单 + closeOnClickSelf: { + type: Boolean, + default: true + }, + // 过渡时间 + duration: { + type: [Number, String], + default: 300 + }, + // 标题菜单的高度 + height: { + type: [Number, String], + default: 40 + }, + // 是否显示下边框 + borderBottom: { + type: Boolean, + default: false + }, + // 标题的字体大小 + titleSize: { + type: [Number, String], + default: 14 + }, + // 下拉出来的内容部分的圆角值 + borderRadius: { + type: [Number, String], + default: 0 + }, + // 菜单右侧的icon图标 + menuIcon: { + type: String, + default: 'arrow-down' + }, + // 菜单右侧图标的大小 + menuIconSize: { + type: [Number, String], + default: 14 + } + } +} diff --git a/uview-ui/components/u-dropdown/u-dropdown.vue b/uview-ui/components/u-dropdown/u-dropdown.vue new file mode 100644 index 0000000..c02ef22 --- /dev/null +++ b/uview-ui/components/u-dropdown/u-dropdown.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/uview-ui/components/u-empty/props.js b/uview-ui/components/u-empty/props.js new file mode 100644 index 0000000..78662f8 --- /dev/null +++ b/uview-ui/components/u-empty/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 内置图标名称,或图片路径,建议绝对路径 + icon: { + type: String, + default: uni.$u.props.empty.icon + }, + // 提示文字 + text: { + type: String, + default: uni.$u.props.empty.text + }, + // 文字颜色 + textColor: { + type: String, + default: uni.$u.props.empty.textColor + }, + // 文字大小 + textSize: { + type: [String, Number], + default: uni.$u.props.empty.textSize + }, + // 图标的颜色 + iconColor: { + type: String, + default: uni.$u.props.empty.iconColor + }, + // 图标的大小 + iconSize: { + type: [String, Number], + default: uni.$u.props.empty.iconSize + }, + // 选择预置的图标类型 + mode: { + type: String, + default: uni.$u.props.empty.mode + }, + // 图标宽度,单位px + width: { + type: [String, Number], + default: uni.$u.props.empty.width + }, + // 图标高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.empty.height + }, + // 是否显示组件 + show: { + type: Boolean, + default: uni.$u.props.empty.show + }, + // 组件距离上一个元素之间的距离,默认px单位 + marginTop: { + type: [String, Number], + default: uni.$u.props.empty.marginTop + } + } +} diff --git a/uview-ui/components/u-empty/u-empty.vue b/uview-ui/components/u-empty/u-empty.vue new file mode 100644 index 0000000..5e391e4 --- /dev/null +++ b/uview-ui/components/u-empty/u-empty.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/uview-ui/components/u-form-item/props.js b/uview-ui/components/u-form-item/props.js new file mode 100644 index 0000000..affaa1a --- /dev/null +++ b/uview-ui/components/u-form-item/props.js @@ -0,0 +1,39 @@ +export default { + props: { + // input的label提示语 + label: { + type: String, + default: uni.$u.props.formItem.label + }, + // 绑定的值 + prop: { + type: String, + default: uni.$u.props.formItem.prop + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: [String, Boolean], + default: uni.$u.props.formItem.borderBottom + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: uni.$u.props.formItem.labelWidth + }, + // 右侧图标 + rightIcon: { + type: String, + default: uni.$u.props.formItem.rightIcon + }, + // 左侧图标 + leftIcon: { + type: String, + default: uni.$u.props.formItem.leftIcon + }, + // 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 + required: { + type: Boolean, + default: uni.$u.props.formItem.required + } + } +} diff --git a/uview-ui/components/u-form-item/u-form-item.vue b/uview-ui/components/u-form-item/u-form-item.vue new file mode 100644 index 0000000..6d702ee --- /dev/null +++ b/uview-ui/components/u-form-item/u-form-item.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/uview-ui/components/u-form/props.js b/uview-ui/components/u-form/props.js new file mode 100644 index 0000000..ee77e19 --- /dev/null +++ b/uview-ui/components/u-form/props.js @@ -0,0 +1,45 @@ +export default { + props: { + // 当前form的需要验证字段的集合 + model: { + type: Object, + default: uni.$u.props.form.model + }, + // 验证规则 + rules: { + type: [Object, Function, Array], + default: uni.$u.props.form.rules + }, + // 有错误时的提示方式,message-提示信息,border-如果input设置了边框,变成呈红色, + // border-bottom-下边框呈现红色,none-无提示 + errorType: { + type: Array, + default: uni.$u.props.form.errorType + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: Boolean, + default: uni.$u.props.form.borderBottom + }, + // label的位置,left-左边,top-上边 + labelPosition: { + type: String, + default: uni.$u.props.form.labelPosition + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: uni.$u.props.form.labelWidth + }, + // lable字体的对齐方式 + labelAlign: { + type: String, + default: uni.$u.props.form.labelAlign + }, + // lable的样式,对象形式 + labelStyle: { + type: Object, + default: uni.$u.props.form.labelStyle + } + } +} diff --git a/uview-ui/components/u-form/u-form.vue b/uview-ui/components/u-form/u-form.vue new file mode 100644 index 0000000..f410cf7 --- /dev/null +++ b/uview-ui/components/u-form/u-form.vue @@ -0,0 +1,199 @@ + + + + + diff --git a/uview-ui/components/u-gap/props.js b/uview-ui/components/u-gap/props.js new file mode 100644 index 0000000..89953e3 --- /dev/null +++ b/uview-ui/components/u-gap/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 背景颜色(默认transparent) + bgColor: { + type: String, + default: uni.$u.props.gap.bgColor + }, + // 分割槽高度,单位px(默认30) + height: { + type: [String, Number], + default: uni.$u.props.gap.height + }, + // 与上一个组件的距离 + marginTop: { + type: [String, Number], + default: uni.$u.props.gap.marginTop + }, + // 与下一个组件的距离 + marginBottom: { + type: [String, Number], + default: uni.$u.props.gap.marginBottom + } + } +} diff --git a/uview-ui/components/u-gap/u-gap.vue b/uview-ui/components/u-gap/u-gap.vue new file mode 100644 index 0000000..f50e441 --- /dev/null +++ b/uview-ui/components/u-gap/u-gap.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/uview-ui/components/u-grid-item/props.js b/uview-ui/components/u-grid-item/props.js new file mode 100644 index 0000000..06c3c66 --- /dev/null +++ b/uview-ui/components/u-grid-item/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 宫格的name + name: { + type: [String, Number, null], + default: uni.$u.props.gridItem.name + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.gridItem.bgColor + } + } +} diff --git a/uview-ui/components/u-grid-item/u-grid-item.vue b/uview-ui/components/u-grid-item/u-grid-item.vue new file mode 100644 index 0000000..af07831 --- /dev/null +++ b/uview-ui/components/u-grid-item/u-grid-item.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/uview-ui/components/u-grid/props.js b/uview-ui/components/u-grid/props.js new file mode 100644 index 0000000..87b0f6a --- /dev/null +++ b/uview-ui/components/u-grid/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 分成几列 + col: { + type: [String, Number], + default: uni.$u.props.grid.col + }, + // 是否显示边框 + border: { + type: Boolean, + default: uni.$u.props.grid.border + }, + // 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 + align: { + type: String, + default: uni.$u.props.grid.align + } + } +} diff --git a/uview-ui/components/u-grid/u-grid.vue b/uview-ui/components/u-grid/u-grid.vue new file mode 100644 index 0000000..b0b84a6 --- /dev/null +++ b/uview-ui/components/u-grid/u-grid.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/uview-ui/components/u-icon/icons.js b/uview-ui/components/u-icon/icons.js new file mode 100644 index 0000000..c8214b5 --- /dev/null +++ b/uview-ui/components/u-icon/icons.js @@ -0,0 +1,214 @@ +export default { + 'uicon-level': '\ue693', + 'uicon-column-line': '\ue68e', + 'uicon-checkbox-mark': '\ue807', + 'uicon-folder': '\ue7f5', + 'uicon-movie': '\ue7f6', + 'uicon-star-fill': '\ue669', + 'uicon-star': '\ue65f', + 'uicon-phone-fill': '\ue64f', + 'uicon-phone': '\ue622', + 'uicon-apple-fill': '\ue881', + 'uicon-chrome-circle-fill': '\ue885', + 'uicon-backspace': '\ue67b', + 'uicon-attach': '\ue632', + 'uicon-cut': '\ue948', + 'uicon-empty-car': '\ue602', + 'uicon-empty-coupon': '\ue682', + 'uicon-empty-address': '\ue646', + 'uicon-empty-favor': '\ue67c', + 'uicon-empty-permission': '\ue686', + 'uicon-empty-news': '\ue687', + 'uicon-empty-search': '\ue664', + 'uicon-github-circle-fill': '\ue887', + 'uicon-rmb': '\ue608', + 'uicon-person-delete-fill': '\ue66a', + 'uicon-reload': '\ue788', + 'uicon-order': '\ue68f', + 'uicon-server-man': '\ue6bc', + 'uicon-search': '\ue62a', + 'uicon-fingerprint': '\ue955', + 'uicon-more-dot-fill': '\ue630', + 'uicon-scan': '\ue662', + 'uicon-share-square': '\ue60b', + 'uicon-map': '\ue61d', + 'uicon-map-fill': '\ue64e', + 'uicon-tags': '\ue629', + 'uicon-tags-fill': '\ue651', + 'uicon-bookmark-fill': '\ue63b', + 'uicon-bookmark': '\ue60a', + 'uicon-eye': '\ue613', + 'uicon-eye-fill': '\ue641', + 'uicon-mic': '\ue64a', + 'uicon-mic-off': '\ue649', + 'uicon-calendar': '\ue66e', + 'uicon-calendar-fill': '\ue634', + 'uicon-trash': '\ue623', + 'uicon-trash-fill': '\ue658', + 'uicon-play-left': '\ue66d', + 'uicon-play-right': '\ue610', + 'uicon-minus': '\ue618', + 'uicon-plus': '\ue62d', + 'uicon-info': '\ue653', + 'uicon-info-circle': '\ue7d2', + 'uicon-info-circle-fill': '\ue64b', + 'uicon-question': '\ue715', + 'uicon-error': '\ue6d3', + 'uicon-close': '\ue685', + 'uicon-checkmark': '\ue6a8', + 'uicon-android-circle-fill': '\ue67e', + 'uicon-android-fill': '\ue67d', + 'uicon-ie': '\ue87b', + 'uicon-IE-circle-fill': '\ue889', + 'uicon-google': '\ue87a', + 'uicon-google-circle-fill': '\ue88a', + 'uicon-setting-fill': '\ue872', + 'uicon-setting': '\ue61f', + 'uicon-minus-square-fill': '\ue855', + 'uicon-plus-square-fill': '\ue856', + 'uicon-heart': '\ue7df', + 'uicon-heart-fill': '\ue851', + 'uicon-camera': '\ue7d7', + 'uicon-camera-fill': '\ue870', + 'uicon-more-circle': '\ue63e', + 'uicon-more-circle-fill': '\ue645', + 'uicon-chat': '\ue620', + 'uicon-chat-fill': '\ue61e', + 'uicon-bag-fill': '\ue617', + 'uicon-bag': '\ue619', + 'uicon-error-circle-fill': '\ue62c', + 'uicon-error-circle': '\ue624', + 'uicon-close-circle': '\ue63f', + 'uicon-close-circle-fill': '\ue637', + 'uicon-checkmark-circle': '\ue63d', + 'uicon-checkmark-circle-fill': '\ue635', + 'uicon-question-circle-fill': '\ue666', + 'uicon-question-circle': '\ue625', + 'uicon-share': '\ue631', + 'uicon-share-fill': '\ue65e', + 'uicon-shopping-cart': '\ue621', + 'uicon-shopping-cart-fill': '\ue65d', + 'uicon-bell': '\ue609', + 'uicon-bell-fill': '\ue640', + 'uicon-list': '\ue650', + 'uicon-list-dot': '\ue616', + 'uicon-zhihu': '\ue6ba', + 'uicon-zhihu-circle-fill': '\ue709', + 'uicon-zhifubao': '\ue6b9', + 'uicon-zhifubao-circle-fill': '\ue6b8', + 'uicon-weixin-circle-fill': '\ue6b1', + 'uicon-weixin-fill': '\ue6b2', + 'uicon-twitter-circle-fill': '\ue6ab', + 'uicon-twitter': '\ue6aa', + 'uicon-taobao-circle-fill': '\ue6a7', + 'uicon-taobao': '\ue6a6', + 'uicon-weibo-circle-fill': '\ue6a5', + 'uicon-weibo': '\ue6a4', + 'uicon-qq-fill': '\ue6a1', + 'uicon-qq-circle-fill': '\ue6a0', + 'uicon-moments-circel-fill': '\ue69a', + 'uicon-moments': '\ue69b', + 'uicon-qzone': '\ue695', + 'uicon-qzone-circle-fill': '\ue696', + 'uicon-baidu-circle-fill': '\ue680', + 'uicon-baidu': '\ue681', + 'uicon-facebook-circle-fill': '\ue68a', + 'uicon-facebook': '\ue689', + 'uicon-car': '\ue60c', + 'uicon-car-fill': '\ue636', + 'uicon-warning-fill': '\ue64d', + 'uicon-warning': '\ue694', + 'uicon-clock-fill': '\ue638', + 'uicon-clock': '\ue60f', + 'uicon-edit-pen': '\ue612', + 'uicon-edit-pen-fill': '\ue66b', + 'uicon-email': '\ue611', + 'uicon-email-fill': '\ue642', + 'uicon-minus-circle': '\ue61b', + 'uicon-minus-circle-fill': '\ue652', + 'uicon-plus-circle': '\ue62e', + 'uicon-plus-circle-fill': '\ue661', + 'uicon-file-text': '\ue663', + 'uicon-file-text-fill': '\ue665', + 'uicon-pushpin': '\ue7e3', + 'uicon-pushpin-fill': '\ue86e', + 'uicon-grid': '\ue673', + 'uicon-grid-fill': '\ue678', + 'uicon-play-circle': '\ue647', + 'uicon-play-circle-fill': '\ue655', + 'uicon-pause-circle-fill': '\ue654', + 'uicon-pause': '\ue8fa', + 'uicon-pause-circle': '\ue643', + 'uicon-eye-off': '\ue648', + 'uicon-eye-off-outline': '\ue62b', + 'uicon-gift-fill': '\ue65c', + 'uicon-gift': '\ue65b', + 'uicon-rmb-circle-fill': '\ue657', + 'uicon-rmb-circle': '\ue677', + 'uicon-kefu-ermai': '\ue656', + 'uicon-server-fill': '\ue751', + 'uicon-coupon-fill': '\ue8c4', + 'uicon-coupon': '\ue8ae', + 'uicon-integral': '\ue704', + 'uicon-integral-fill': '\ue703', + 'uicon-home-fill': '\ue964', + 'uicon-home': '\ue965', + 'uicon-hourglass-half-fill': '\ue966', + 'uicon-hourglass': '\ue967', + 'uicon-account': '\ue628', + 'uicon-plus-people-fill': '\ue626', + 'uicon-minus-people-fill': '\ue615', + 'uicon-account-fill': '\ue614', + 'uicon-thumb-down-fill': '\ue726', + 'uicon-thumb-down': '\ue727', + 'uicon-thumb-up': '\ue733', + 'uicon-thumb-up-fill': '\ue72f', + 'uicon-lock-fill': '\ue979', + 'uicon-lock-open': '\ue973', + 'uicon-lock-opened-fill': '\ue974', + 'uicon-lock': '\ue97a', + 'uicon-red-packet-fill': '\ue690', + 'uicon-photo-fill': '\ue98b', + 'uicon-photo': '\ue98d', + 'uicon-volume-off-fill': '\ue659', + 'uicon-volume-off': '\ue644', + 'uicon-volume-fill': '\ue670', + 'uicon-volume': '\ue633', + 'uicon-red-packet': '\ue691', + 'uicon-download': '\ue63c', + 'uicon-arrow-up-fill': '\ue6b0', + 'uicon-arrow-down-fill': '\ue600', + 'uicon-play-left-fill': '\ue675', + 'uicon-play-right-fill': '\ue676', + 'uicon-rewind-left-fill': '\ue679', + 'uicon-rewind-right-fill': '\ue67a', + 'uicon-arrow-downward': '\ue604', + 'uicon-arrow-leftward': '\ue601', + 'uicon-arrow-rightward': '\ue603', + 'uicon-arrow-upward': '\ue607', + 'uicon-arrow-down': '\ue60d', + 'uicon-arrow-right': '\ue605', + 'uicon-arrow-left': '\ue60e', + 'uicon-arrow-up': '\ue606', + 'uicon-skip-back-left': '\ue674', + 'uicon-skip-forward-right': '\ue672', + 'uicon-rewind-right': '\ue66f', + 'uicon-rewind-left': '\ue671', + 'uicon-arrow-right-double': '\ue68d', + 'uicon-arrow-left-double': '\ue68c', + 'uicon-wifi-off': '\ue668', + 'uicon-wifi': '\ue667', + 'uicon-empty-data': '\ue62f', + 'uicon-empty-history': '\ue684', + 'uicon-empty-list': '\ue68b', + 'uicon-empty-page': '\ue627', + 'uicon-empty-order': '\ue639', + 'uicon-man': '\ue697', + 'uicon-woman': '\ue69c', + 'uicon-man-add': '\ue61c', + 'uicon-man-add-fill': '\ue64c', + 'uicon-man-delete': '\ue61a', + 'uicon-man-delete-fill': '\ue66a', + 'uicon-zh': '\ue70a', + 'uicon-en': '\ue692' +} diff --git a/uview-ui/components/u-icon/props.js b/uview-ui/components/u-icon/props.js new file mode 100644 index 0000000..71845b7 --- /dev/null +++ b/uview-ui/components/u-icon/props.js @@ -0,0 +1,89 @@ +export default { + props: { + // 图标类名 + name: { + type: String, + default: uni.$u.props.icon.name + }, + // 图标颜色,可接受主题色 + color: { + type: String, + default: uni.$u.props.icon.color + }, + // 字体大小,单位px + size: { + type: [String, Number], + default: uni.$u.props.icon.size + }, + // 是否显示粗体 + bold: { + type: Boolean, + default: uni.$u.props.icon.bold + }, + // 点击图标的时候传递事件出去的index(用于区分点击了哪一个) + index: { + type: [String, Number], + default: uni.$u.props.icon.index + }, + // 触摸图标时的类名 + hoverClass: { + type: String, + default: uni.$u.props.icon.hoverClass + }, + // 自定义扩展前缀,方便用户扩展自己的图标库 + customPrefix: { + type: String, + default: uni.$u.props.icon.customPrefix + }, + // 图标右边或者下面的文字 + label: { + type: [String, Number], + default: uni.$u.props.icon.label + }, + // label的位置,只能右边或者下边 + labelPos: { + type: String, + default: uni.$u.props.icon.labelPos + }, + // label的大小 + labelSize: { + type: [String, Number], + default: uni.$u.props.icon.labelSize + }, + // label的颜色 + labelColor: { + type: String, + default: uni.$u.props.icon.labelColor + }, + // label与图标的距离 + space: { + type: [String, Number], + default: uni.$u.props.icon.space + }, + // 图片的mode + imgMode: { + type: String, + default: uni.$u.props.icon.imgMode + }, + // 用于显示图片小图标时,图片的宽度 + width: { + type: [String, Number], + default: uni.$u.props.icon.width + }, + // 用于显示图片小图标时,图片的高度 + height: { + type: [String, Number], + default: uni.$u.props.icon.height + }, + // 用于解决某些情况下,让图标垂直居中的用途 + top: { + type: [String, Number], + default: uni.$u.props.icon.top + }, + // 是否阻止事件传播 + stop: { + type: Boolean, + default: uni.$u.props.icon.stop + } + } +} diff --git a/uview-ui/components/u-icon/u-icon.vue b/uview-ui/components/u-icon/u-icon.vue new file mode 100644 index 0000000..a931586 --- /dev/null +++ b/uview-ui/components/u-icon/u-icon.vue @@ -0,0 +1,234 @@ + + + + + diff --git a/uview-ui/components/u-image/props.js b/uview-ui/components/u-image/props.js new file mode 100644 index 0000000..334fdf5 --- /dev/null +++ b/uview-ui/components/u-image/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 图片地址 + src: { + type: String, + default: uni.$u.props.image.src + }, + // 裁剪模式 + mode: { + type: String, + default: uni.$u.props.image.mode + }, + // 宽度,单位任意 + width: { + type: [String, Number], + default: uni.$u.props.image.width + }, + // 高度,单位任意 + height: { + type: [String, Number], + default: uni.$u.props.image.height + }, + // 图片形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.image.shape + }, + // 圆角,单位任意 + radius: { + type: [String, Number], + default: uni.$u.props.image.radius + }, + // 是否懒加载,微信小程序、App、百度小程序、字节跳动小程序 + lazyLoad: { + type: Boolean, + default: uni.$u.props.image.lazyLoad + }, + // 开启长按图片显示识别微信小程序码菜单 + showMenuByLongpress: { + type: Boolean, + default: uni.$u.props.image.showMenuByLongpress + }, + // 加载中的图标,或者小图片 + loadingIcon: { + type: String, + default: uni.$u.props.image.loadingIcon + }, + // 加载失败的图标,或者小图片 + errorIcon: { + type: String, + default: uni.$u.props.image.errorIcon + }, + // 是否显示加载中的图标或者自定义的slot + showLoading: { + type: Boolean, + default: uni.$u.props.image.showLoading + }, + // 是否显示加载错误的图标或者自定义的slot + showError: { + type: Boolean, + default: uni.$u.props.image.showError + }, + // 是否需要淡入效果 + fade: { + type: Boolean, + default: uni.$u.props.image.fade + }, + // 只支持网络资源,只对微信小程序有效 + webp: { + type: Boolean, + default: uni.$u.props.image.webp + }, + // 过渡时间,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.image.duration + }, + // 背景颜色,用于深色页面加载图片时,为了和背景色融合 + bgColor: { + type: String, + default: uni.$u.props.image.bgColor + } + } +} diff --git a/uview-ui/components/u-image/u-image.vue b/uview-ui/components/u-image/u-image.vue new file mode 100644 index 0000000..2e769e6 --- /dev/null +++ b/uview-ui/components/u-image/u-image.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/uview-ui/components/u-index-anchor/props.js b/uview-ui/components/u-index-anchor/props.js new file mode 100644 index 0000000..6d8b59a --- /dev/null +++ b/uview-ui/components/u-index-anchor/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 列表锚点文本内容 + text: { + type: [String, Number], + default: uni.$u.props.indexAnchor.text + }, + // 列表锚点文字颜色 + color: { + type: String, + default: uni.$u.props.indexAnchor.color + }, + // 列表锚点文字大小,单位默认px + size: { + type: [String, Number], + default: uni.$u.props.indexAnchor.size + }, + // 列表锚点背景颜色 + bgColor: { + type: String, + default: uni.$u.props.indexAnchor.bgColor + }, + // 列表锚点高度,单位默认px + height: { + type: [String, Number], + default: uni.$u.props.indexAnchor.height + } + } +} diff --git a/uview-ui/components/u-index-anchor/u-index-anchor.vue b/uview-ui/components/u-index-anchor/u-index-anchor.vue new file mode 100644 index 0000000..a0e8335 --- /dev/null +++ b/uview-ui/components/u-index-anchor/u-index-anchor.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/uview-ui/components/u-index-item/props.js b/uview-ui/components/u-index-item/props.js new file mode 100644 index 0000000..7c11331 --- /dev/null +++ b/uview-ui/components/u-index-item/props.js @@ -0,0 +1,5 @@ +export default { + props: { + + } +} diff --git a/uview-ui/components/u-index-item/u-index-item.vue b/uview-ui/components/u-index-item/u-index-item.vue new file mode 100644 index 0000000..846a4f5 --- /dev/null +++ b/uview-ui/components/u-index-item/u-index-item.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/uview-ui/components/u-index-list/props.js b/uview-ui/components/u-index-list/props.js new file mode 100644 index 0000000..354d459 --- /dev/null +++ b/uview-ui/components/u-index-list/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 右边锚点非激活的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.indexList.inactiveColor + }, + // 右边锚点激活的颜色 + activeColor: { + type: String, + default: uni.$u.props.indexList.activeColor + }, + // 索引字符列表,数组形式 + indexList: { + type: Array, + default: uni.$u.props.indexList.indexList + }, + // 是否开启锚点自动吸顶 + sticky: { + type: Boolean, + default: uni.$u.props.indexList.sticky + }, + // 自定义导航栏的高度 + customNavHeight: { + type: [String, Number], + default: uni.$u.props.indexList.customNavHeight + } + } +} diff --git a/uview-ui/components/u-index-list/u-index-list.vue b/uview-ui/components/u-index-list/u-index-list.vue new file mode 100644 index 0000000..396025f --- /dev/null +++ b/uview-ui/components/u-index-list/u-index-list.vue @@ -0,0 +1,438 @@ + + + + + diff --git a/uview-ui/components/u-input/props.js b/uview-ui/components/u-input/props.js new file mode 100644 index 0000000..44ec751 --- /dev/null +++ b/uview-ui/components/u-input/props.js @@ -0,0 +1,187 @@ +export default { + props: { + // 输入的值 + value: { + type: [String, Number], + default: uni.$u.props.input.value + }, + // 输入框类型 + // number-数字输入键盘,app-vue下可以输入浮点数,app-nvue和小程序平台下只能输入整数 + // idcard-身份证输入键盘,微信、支付宝、百度、QQ小程序 + // digit-带小数点的数字键盘,App的nvue页面、微信、支付宝、百度、头条、QQ小程序 + // text-文本输入键盘 + type: { + type: String, + default: uni.$u.props.input.type + }, + // 如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true, + // 兼容性:微信小程序、百度小程序、字节跳动小程序、QQ小程序 + fixed: { + default: Boolean, + default: uni.$u.props.input.fixed + }, + // 是否禁用输入框 + disabled: { + type: Boolean, + default: uni.$u.props.input.disabled + }, + // 禁用状态时的背景色 + disabledColor: { + type: String, + default: uni.$u.props.input.disabledColor + }, + // 是否显示清除控件 + clearable: { + type: Boolean, + default: uni.$u.props.input.clearable + }, + // 是否密码类型 + password: { + type: Boolean, + default: uni.$u.props.input.password + }, + // 最大输入长度,设置为 -1 的时候不限制最大长度 + maxlength: { + type: [String, Number], + default: uni.$u.props.input.maxlength + }, + // 输入框为空时的占位符 + placeholder: { + type: String, + default: uni.$u.props.input.placeholder + }, + // 指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/ + placeholderClass: { + type: String, + default: uni.$u.props.input.placeholderClass + }, + // 指定placeholder的样式 + placeholderStyle: { + type: [String, Object], + default: uni.$u.props.input.placeholderStyle + }, + // 是否显示输入字数统计,只在 type ="text"或type ="textarea"时有效 + showWordLimit: { + type: Boolean, + default: uni.$u.props.input.showWordLimit + }, + // 设置右下角按钮的文字,有效值:send|search|next|go|done,兼容性详见uni-app文档 + // https://uniapp.dcloud.io/component/input + // https://uniapp.dcloud.io/component/textarea + confirmType: { + type: String, + default: uni.$u.props.input.confirmType + }, + // 点击键盘右下角按钮时是否保持键盘不收起,H5无效 + confirmHold: { + type: Boolean, + default: uni.$u.props.input.confirmHold + }, + // focus时,点击页面的时候不收起键盘,微信小程序有效 + holdKeyboard: { + type: Boolean, + default: uni.$u.props.input.holdKeyboard + }, + // 自动获取焦点 + // 在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。nvue 页面不支持,需使用组件的 focus()、blur() 方法控制焦点 + focus: { + type: Boolean, + default: uni.$u.props.input.focus + }, + // 键盘收起时,是否自动失去焦点,目前仅App3.0.0+有效 + autoBlur: { + type: Boolean, + default: uni.$u.props.input.autoBlur + }, + // 是否去掉 iOS 下的默认内边距,仅微信小程序,且type=textarea时有效 + disableDefaultPadding: { + type: Boolean, + default: uni.$u.props.input.disableDefaultPadding + }, + // 指定focus时光标的位置 + cursor: { + type: [String, Number], + default: uni.$u.props.input.cursor + }, + // 输入框聚焦时底部与键盘的距离 + cursorSpacing: { + type: [String, Number], + default: uni.$u.props.input.cursorSpacing + }, + // 光标起始位置,自动聚集时有效,需与selection-end搭配使用 + selectionStart: { + type: [String, Number], + default: uni.$u.props.input.selectionStart + }, + // 光标结束位置,自动聚集时有效,需与selection-start搭配使用 + selectionEnd: { + type: [String, Number], + default: uni.$u.props.input.selectionEnd + }, + // 键盘弹起时,是否自动上推页面 + adjustPosition: { + type: Boolean, + default: uni.$u.props.input.adjustPosition + }, + // 输入框内容对齐方式,可选值为:left|center|right + inputAlign: { + type: String, + default: uni.$u.props.input.inputAlign + }, + // 是否自适应内容高度,只对type=textarea有效,可传入对象,如{ maxHeight: 100, minHeight: 50 } + autosize: { + type: Boolean, + default: uni.$u.props.input.autosize + }, + // 输入框字体的大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.input.fontSize + }, + // 输入框字体颜色 + color: { + type: String, + default: uni.$u.props.input.color + }, + // 输入框前置图标 + prefixIcon: { + type: String, + default: uni.$u.props.input.prefixIcon + }, + // 前置图标样式,对象或字符串 + prefixIconStyle: { + type: [String, Object], + default: uni.$u.props.input.prefixIconStyle + }, + // 输入框后置图标 + suffixIcon: { + type: String, + default: uni.$u.props.input.suffixIcon + }, + // 后置图标样式,对象或字符串 + suffixIconStyle: { + type: [String, Object], + default: uni.$u.props.input.suffixIconStyle + }, + // 边框类型,surround-四周边框,bottom-底部边框,none-无边框 + border: { + type: String, + default: uni.$u.props.input.border + }, + // 是否只读,与disabled不同之处在于disabled会置灰组件,而readonly则不会 + readonly: { + type: Boolean, + default: uni.$u.props.input.readonly + }, + // 输入框形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.input.shape + }, + // 用于处理或者过滤输入框内容的方法 + formatter: { + type: [Function, null], + default: uni.$u.props.input.formatter + } + } +} diff --git a/uview-ui/components/u-input/u-input.vue b/uview-ui/components/u-input/u-input.vue new file mode 100644 index 0000000..125b52c --- /dev/null +++ b/uview-ui/components/u-input/u-input.vue @@ -0,0 +1,345 @@ + + + + + diff --git a/uview-ui/components/u-keyboard/props.js b/uview-ui/components/u-keyboard/props.js new file mode 100644 index 0000000..cfdb00a --- /dev/null +++ b/uview-ui/components/u-keyboard/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘,car-车牌号键盘 + mode: { + type: String, + default: uni.$u.props.keyboard.mode + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: uni.$u.props.keyboard.dotDisabled + }, + // 是否显示顶部工具条 + tooltip: { + type: Boolean, + default: uni.$u.props.keyboard.tooltip + }, + // 是否显示工具条中间的提示 + showTips: { + type: Boolean, + default: uni.$u.props.keyboard.showTips + }, + // 工具条中间的提示文字 + tips: { + type: String, + default: uni.$u.props.keyboard.tips + }, + // 是否显示工具条左边的"取消"按钮 + showCancel: { + type: Boolean, + default: uni.$u.props.keyboard.showCancel + }, + // 是否显示工具条右边的"完成"按钮 + showConfirm: { + type: Boolean, + default: uni.$u.props.keyboard.showConfirm + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: uni.$u.props.keyboard.random + }, + // 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距 + safeAreaInsetBottom: { + type: Boolean, + default: uni.$u.props.keyboard.safeAreaInsetBottom + }, + // 是否允许通过点击遮罩关闭键盘 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.keyboard.closeOnClickOverlay + }, + // 控制键盘的弹出与收起 + show: { + type: Boolean, + default: uni.$u.props.keyboard.show + }, + // 是否显示遮罩,某些时候数字键盘时,用户希望看到自己的数值,所以可能不想要遮罩 + overlay: { + type: Boolean, + default: uni.$u.props.keyboard.overlay + }, + // z-index值 + zIndex: { + type: [String, Number], + default: uni.$u.props.keyboard.zIndex + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: uni.$u.props.keyboard.cancelText + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.keyboard.confirmText + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: uni.$u.props.keyboard.autoChange + } + } +} diff --git a/uview-ui/components/u-keyboard/u-keyboard.vue b/uview-ui/components/u-keyboard/u-keyboard.vue new file mode 100644 index 0000000..78e5c41 --- /dev/null +++ b/uview-ui/components/u-keyboard/u-keyboard.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/uview-ui/components/u-line-progress/props.js b/uview-ui/components/u-line-progress/props.js new file mode 100644 index 0000000..a4210bd --- /dev/null +++ b/uview-ui/components/u-line-progress/props.js @@ -0,0 +1,28 @@ +export default { + props: { + // 激活部分的颜色 + activeColor: { + type: String, + default: uni.$u.props.lineProgress.activeColor + }, + inactiveColor: { + type: String, + default: uni.$u.props.lineProgress.color + }, + // 进度百分比,数值 + percentage: { + type: [String, Number], + default: uni.$u.props.lineProgress.inactiveColor + }, + // 是否在进度条内部显示百分比的值 + showText: { + type: Boolean, + default: uni.$u.props.lineProgress.showText + }, + // 进度条的高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.lineProgress.height + } + } +} diff --git a/uview-ui/components/u-line-progress/u-line-progress.vue b/uview-ui/components/u-line-progress/u-line-progress.vue new file mode 100644 index 0000000..0be6e78 --- /dev/null +++ b/uview-ui/components/u-line-progress/u-line-progress.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/uview-ui/components/u-line/props.js b/uview-ui/components/u-line/props.js new file mode 100644 index 0000000..866bade --- /dev/null +++ b/uview-ui/components/u-line/props.js @@ -0,0 +1,33 @@ +export default { + props: { + color: { + type: String, + default: uni.$u.props.line.color + }, + // 长度,竖向时表现为高度,横向时表现为长度,可以为百分比,带px单位的值等 + length: { + type: [String, Number], + default: uni.$u.props.line.length + }, + // 线条方向,col-竖向,row-横向 + direction: { + type: String, + default: uni.$u.props.line.direction + }, + // 是否显示细边框 + hairline: { + type: Boolean, + default: uni.$u.props.line.hairline + }, + // 线条与上下左右元素的间距,字符串形式,如"30px"、"20px 30px" + margin: { + type: [String, Number], + default: uni.$u.props.line.margin + }, + // 是否虚线,true-实线,false-虚线 + dashed: { + type: Boolean, + default: uni.$u.props.line.dashed + } + } +} diff --git a/uview-ui/components/u-line/u-line.vue b/uview-ui/components/u-line/u-line.vue new file mode 100644 index 0000000..3934e59 --- /dev/null +++ b/uview-ui/components/u-line/u-line.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/uview-ui/components/u-link/props.js b/uview-ui/components/u-link/props.js new file mode 100644 index 0000000..d39353f --- /dev/null +++ b/uview-ui/components/u-link/props.js @@ -0,0 +1,39 @@ +export default { + props: { + // 文字颜色 + color: { + type: String, + default: uni.$u.props.link.color + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: uni.$u.props.link.fontSize + }, + // 是否显示下划线 + underLine: { + type: Boolean, + default: uni.$u.props.link.underLine + }, + // 要跳转的链接 + href: { + type: String, + default: uni.$u.props.link.href + }, + // 小程序中复制到粘贴板的提示语 + mpTips: { + type: String, + default: uni.$u.props.link.mpTips + }, + // 下划线颜色 + lineColor: { + type: String, + default: uni.$u.props.link.lineColor + }, + // 超链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色 + text: { + type: String, + default: uni.$u.props.link.text + } + } +} diff --git a/uview-ui/components/u-link/u-link.vue b/uview-ui/components/u-link/u-link.vue new file mode 100644 index 0000000..04631e9 --- /dev/null +++ b/uview-ui/components/u-link/u-link.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/uview-ui/components/u-list-item/props.js b/uview-ui/components/u-list-item/props.js new file mode 100644 index 0000000..58ddc49 --- /dev/null +++ b/uview-ui/components/u-list-item/props.js @@ -0,0 +1,9 @@ +export default { + props: { + // 用于滚动到指定item + anchor: { + type: [String, Number], + default: uni.$u.props.listItem.anchor + } + } +} diff --git a/uview-ui/components/u-list-item/u-list-item.vue b/uview-ui/components/u-list-item/u-list-item.vue new file mode 100644 index 0000000..b6f67cb --- /dev/null +++ b/uview-ui/components/u-list-item/u-list-item.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/uview-ui/components/u-list/props.js b/uview-ui/components/u-list/props.js new file mode 100644 index 0000000..25406f4 --- /dev/null +++ b/uview-ui/components/u-list/props.js @@ -0,0 +1,76 @@ +export default { + props: { + // 控制是否出现滚动条,仅nvue有效 + showScrollbar: { + type: Boolean, + default: uni.$u.props.list.showScrollbar + }, + // 距底部多少时触发scrolltolower事件 + lowerThreshold: { + type: [String, Number], + default: uni.$u.props.list.lowerThreshold + }, + // 距顶部多少时触发scrolltoupper事件,非nvue有效 + upperThreshold: { + type: [String, Number], + default: uni.$u.props.list.upperThreshold + }, + // 设置竖向滚动条位置 + scrollTop: { + type: [String, Number], + default: uni.$u.props.list.scrollTop + }, + // 控制 onscroll 事件触发的频率,仅nvue有效 + offsetAccuracy: { + type: [String, Number], + default: uni.$u.props.list.offsetAccuracy + }, + // 启用 flexbox 布局。开启后,当前节点声明了display: flex就会成为flex container,并作用于其孩子节点,仅微信小程序有效 + enableFlex: { + type: Boolean, + default: uni.$u.props.list.enableFlex + }, + // 是否按分页模式显示List,默认值false + pagingEnabled: { + type: Boolean, + default: uni.$u.props.list.pagingEnabled + }, + // 是否允许List滚动 + scrollable: { + type: Boolean, + default: uni.$u.props.list.scrollable + }, + // 值应为某子元素id(id不能以数字开头) + scrollIntoView: { + type: String, + default: uni.$u.props.list.scrollIntoView + }, + // 在设置滚动条位置时使用动画过渡 + scrollWithAnimation: { + type: Boolean, + default: uni.$u.props.list.scrollWithAnimation + }, + // iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只对微信小程序有效 + enableBackToTop: { + type: Boolean, + default: uni.$u.props.list.enableBackToTop + }, + // 列表的高度 + height: { + type: [String, Number], + default: uni.$u.props.list.height + }, + // 列表宽度 + width: { + type: [String, Number], + default: uni.$u.props.list.width + }, + // 列表前后预渲染的屏数,1代表一个屏幕的高度,1.5代表1个半屏幕高度 + preLoadScreen: { + type: [String, Number], + default: uni.$u.props.list.preLoadScreen + } + // vue下,是否开启虚拟列表 + + } +} diff --git a/uview-ui/components/u-list/u-list.vue b/uview-ui/components/u-list/u-list.vue new file mode 100644 index 0000000..86fa9b5 --- /dev/null +++ b/uview-ui/components/u-list/u-list.vue @@ -0,0 +1,159 @@ + + + + + diff --git a/uview-ui/components/u-loading-icon/props.js b/uview-ui/components/u-loading-icon/props.js new file mode 100644 index 0000000..3b8004d --- /dev/null +++ b/uview-ui/components/u-loading-icon/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 是否显示组件 + show: { + type: Boolean, + default: uni.$u.props.loadingIcon.show + }, + // 颜色 + color: { + type: String, + default: uni.$u.props.loadingIcon.color + }, + // 提示文字颜色 + textColor: { + type: String, + default: uni.$u.props.loadingIcon.textColor + }, + // 文字和图标是否垂直排列 + vertical: { + type: Boolean, + default: uni.$u.props.loadingIcon.vertical + }, + // 模式选择,circle-圆形,spinner-花朵形,semicircle-半圆形 + mode: { + type: String, + default: uni.$u.props.loadingIcon.mode + }, + // 图标大小,单位默认px + size: { + type: [String, Number], + default: uni.$u.props.loadingIcon.size + }, + // 文字大小 + textSize: { + type: [String, Number], + default: uni.$u.props.loadingIcon.textSize + }, + // 文字内容 + text: { + type: [String, Number], + default: uni.$u.props.loadingIcon.text + }, + // 动画模式 + timingFunction: { + type: String, + default: uni.$u.props.loadingIcon.timingFunction + }, + // 动画执行周期时间 + duration: { + type: [String, Number], + default: uni.$u.props.loadingIcon.duration + }, + // mode=circle时的暗边颜色 + inactiveColor: { + type: String, + default: uni.$u.props.loadingIcon.inactiveColor + } + } +} diff --git a/uview-ui/components/u-loading-icon/u-loading-icon.vue b/uview-ui/components/u-loading-icon/u-loading-icon.vue new file mode 100644 index 0000000..e732508 --- /dev/null +++ b/uview-ui/components/u-loading-icon/u-loading-icon.vue @@ -0,0 +1,343 @@ + + + + + diff --git a/uview-ui/components/u-loading-page/props.js b/uview-ui/components/u-loading-page/props.js new file mode 100644 index 0000000..438ab64 --- /dev/null +++ b/uview-ui/components/u-loading-page/props.js @@ -0,0 +1,44 @@ +export default { + props: { + // 提示内容 + loadingText: { + type: [String, Number], + default: uni.$u.props.loadingPage.loadingText + }, + // 文字上方用于替换loading动画的图片 + image: { + type: String, + default: uni.$u.props.loadingPage.image + }, + // 加载动画的模式,circle-圆形,spinner-花朵形,semicircle-半圆形 + loadingMode: { + type: String, + default: uni.$u.props.loadingPage.loadingMode + }, + // 是否加载中 + loading: { + type: Boolean, + default: uni.$u.props.loadingPage.loading + }, + // 背景色 + bgColor: { + type: String, + default: uni.$u.props.loadingPage.bgColor + }, + // 文字颜色 + color: { + type: String, + default: uni.$u.props.loadingPage.color + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.loadingPage.fontSize + }, + // 加载中图标的颜色,只能rgb或者十六进制颜色值 + loadingColor: { + type: String, + default: uni.$u.props.loadingPage.loadingColor + } + } +} diff --git a/uview-ui/components/u-loading-page/u-loading-page.vue b/uview-ui/components/u-loading-page/u-loading-page.vue new file mode 100644 index 0000000..7ea6a28 --- /dev/null +++ b/uview-ui/components/u-loading-page/u-loading-page.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/uview-ui/components/u-loadmore/props.js b/uview-ui/components/u-loadmore/props.js new file mode 100644 index 0000000..125ad3e --- /dev/null +++ b/uview-ui/components/u-loadmore/props.js @@ -0,0 +1,80 @@ +export default { + props: { + // 组件状态,loadmore-加载前的状态,loading-加载中的状态,nomore-没有更多的状态 + status: { + type: String, + default: uni.$u.props.loadmore.status + }, + // 组件背景色 + bgColor: { + type: String, + default: uni.$u.props.loadmore.bgColor + }, + // 是否显示加载中的图标 + icon: { + type: Boolean, + default: uni.$u.props.loadmore.icon + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.loadmore.fontSize + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.loadmore.color + }, + + // 加载中状态的图标,spinner-花朵状图标,circle-圆圈状,semicircle-半圆 + loadingIcon: { + type: String, + default: uni.$u.props.loadmore.loadingIcon + }, + // 加载前的提示语 + loadmoreText: { + type: String, + default: uni.$u.props.loadmore.loadmoreText + }, + // 加载中提示语 + loadingText: { + type: String, + default: uni.$u.props.loadmore.loadingText + }, + // 没有更多的提示语 + nomoreText: { + type: String, + default: uni.$u.props.loadmore.nomoreText + }, + // 在“没有更多”状态下,是否显示粗点 + isDot: { + type: Boolean, + default: uni.$u.props.loadmore.isDot + }, + // 加载中图标的颜色 + iconColor: { + type: String, + default: uni.$u.props.loadmore.iconColor + }, + // 上边距 + marginTop: { + type: [String, Number], + default: uni.$u.props.loadmore.marginTop + }, + // 下边距 + marginBottom: { + type: [String, Number], + default: uni.$u.props.loadmore.marginBottom + }, + // 高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.loadmore.height + }, + // 是否显示左边分割线 + line: { + type: Boolean, + default: uni.$u.props.loadmore.line + } + } +} diff --git a/uview-ui/components/u-loadmore/u-loadmore.vue b/uview-ui/components/u-loadmore/u-loadmore.vue new file mode 100644 index 0000000..f9fb9a2 --- /dev/null +++ b/uview-ui/components/u-loadmore/u-loadmore.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/uview-ui/components/u-modal/props.js b/uview-ui/components/u-modal/props.js new file mode 100644 index 0000000..f76672c --- /dev/null +++ b/uview-ui/components/u-modal/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 是否展示modal + show: { + type: Boolean, + default: uni.$u.props.modal.show + }, + // 标题 + title: { + type: [String], + default: uni.$u.props.modal.title + }, + // 弹窗内容 + content: { + type: String, + default: uni.$u.props.modal.content + }, + // 确认文案 + confirmText: { + type: String, + default: uni.$u.props.modal.confirmText + }, + // 取消文案 + cancelText: { + type: String, + default: uni.$u.props.modal.cancelText + }, + // 是否显示确认按钮 + showConfirmButton: { + type: Boolean, + default: uni.$u.props.modal.showConfirmButton + }, + // 是否显示取消按钮 + showCancelButton: { + type: Boolean, + default: uni.$u.props.modal.showCancelButton + }, + // 确认按钮颜色 + confirmColor: { + type: String, + default: uni.$u.props.modal.confirmColor + }, + // 取消文字颜色 + cancelColor: { + type: String, + default: uni.$u.props.modal.cancelColor + }, + // 对调确认和取消的位置 + buttonReverse: { + type: Boolean, + default: uni.$u.props.modal.buttonReverse + }, + // 是否开启缩放效果 + zoom: { + type: Boolean, + default: uni.$u.props.modal.zoom + }, + // 是否异步关闭,只对确定按钮有效 + asyncClose: { + type: Boolean, + default: uni.$u.props.modal.asyncClose + }, + // 是否允许点击遮罩关闭modal + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.modal.closeOnClickOverlay + }, + // 给一个负的margin-top,往上偏移,避免和键盘重合的情况 + negativeTop: { + type: [String, Number], + default: uni.$u.props.modal.negativeTop + }, + // modal宽度,不支持百分比,可以数值,px,rpx单位 + width: { + type: [String, Number], + default: uni.$u.props.modal.width + }, + // 确认按钮的样式,circle-圆形,square-方形,如设置,将不会显示取消按钮 + confirmButtonShape: { + type: String, + default: uni.$u.props.modal.confirmButtonShape + } + } +} diff --git a/uview-ui/components/u-modal/u-modal.vue b/uview-ui/components/u-modal/u-modal.vue new file mode 100644 index 0000000..7164dc9 --- /dev/null +++ b/uview-ui/components/u-modal/u-modal.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/uview-ui/components/u-navbar/props.js b/uview-ui/components/u-navbar/props.js new file mode 100644 index 0000000..2617a10 --- /dev/null +++ b/uview-ui/components/u-navbar/props.js @@ -0,0 +1,64 @@ +export default { + props: { + // 是否开启顶部安全区适配 + safeAreaInsetTop: { + type: Boolean, + default: uni.$u.props.navbar.safeAreaInsetTop + }, + // 固定在顶部时,是否生成一个等高元素,以防止塌陷 + placeholder: { + type: Boolean, + default: uni.$u.props.navbar.placeholder + }, + // 是否固定在顶部 + fixed: { + type: Boolean, + default: uni.$u.props.navbar.fixed + }, + // 是否显示下边框 + border: { + type: Boolean, + default: uni.$u.props.navbar.border + }, + // 左边的图标 + leftIcon: { + type: String, + default: uni.$u.props.navbar.leftIcon + }, + // 左边的提示文字 + leftText: { + type: String, + default: uni.$u.props.navbar.leftText + }, + // 左右的提示文字 + rightText: { + type: String, + default: uni.$u.props.navbar.rightText + }, + // 右边的图标 + rightIcon: { + type: String, + default: uni.$u.props.navbar.rightIcon + }, + // 标题 + title: { + type: [String, Number], + default: uni.$u.props.navbar.title + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.navbar.bgColor + }, + // 标题的宽度 + titleWidth: { + type: [String, Number], + default: uni.$u.props.navbar.titleWidth + }, + // 导航栏高度 + height: { + type: [String, Number], + default: uni.$u.props.navbar.height + } + } +} diff --git a/uview-ui/components/u-navbar/u-navbar.vue b/uview-ui/components/u-navbar/u-navbar.vue new file mode 100644 index 0000000..732b2ab --- /dev/null +++ b/uview-ui/components/u-navbar/u-navbar.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/uview-ui/components/u-no-network/props.js b/uview-ui/components/u-no-network/props.js new file mode 100644 index 0000000..9f3af62 --- /dev/null +++ b/uview-ui/components/u-no-network/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 页面文字提示 + tips: { + type: String, + default: uni.$u.props.noNetwork.tips + }, + // 一个z-index值,用于设置没有网络这个组件的层次,因为页面可能会有其他定位的元素层级过高,导致此组件被覆盖 + zIndex: { + type: [String, Number], + default: uni.$u.props.noNetwork.zIndex + }, + // image 没有网络的图片提示 + image: { + type: String, + default: uni.$u.props.noNetwork.image + } + } +} diff --git a/uview-ui/components/u-no-network/u-no-network.vue b/uview-ui/components/u-no-network/u-no-network.vue new file mode 100644 index 0000000..4349f79 --- /dev/null +++ b/uview-ui/components/u-no-network/u-no-network.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/uview-ui/components/u-notice-bar/props.js b/uview-ui/components/u-notice-bar/props.js new file mode 100644 index 0000000..7040c29 --- /dev/null +++ b/uview-ui/components/u-notice-bar/props.js @@ -0,0 +1,70 @@ +export default { + props: { + // 显示的内容,数组 + text: { + type: [Array, String], + default: uni.$u.props.noticeBar.text + }, + // 通告滚动模式,row-横向滚动,column-竖向滚动 + direction: { + type: String, + default: uni.$u.props.noticeBar.direction + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: uni.$u.props.noticeBar.step + }, + // 是否显示左侧的音量图标 + icon: { + type: String, + default: uni.$u.props.noticeBar.icon + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: uni.$u.props.noticeBar.mode + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: uni.$u.props.noticeBar.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.noticeBar.bgColor + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: uni.$u.props.noticeBar.speed + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.noticeBar.fontSize + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.noticeBar.duration + }, + // 是否禁止用手滑动切换 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: uni.$u.props.noticeBar.disableTouch + }, + // 跳转的页面路径 + url: { + type: String, + default: uni.$u.props.noticeBar.url + }, + // 页面跳转的类型 + linkType: { + type: String, + default: uni.$u.props.noticeBar.linkType + } + } +} diff --git a/uview-ui/components/u-notice-bar/u-notice-bar.vue b/uview-ui/components/u-notice-bar/u-notice-bar.vue new file mode 100644 index 0000000..9048223 --- /dev/null +++ b/uview-ui/components/u-notice-bar/u-notice-bar.vue @@ -0,0 +1,101 @@ + + + + diff --git a/uview-ui/components/u-notify/props.js b/uview-ui/components/u-notify/props.js new file mode 100644 index 0000000..57a9d71 --- /dev/null +++ b/uview-ui/components/u-notify/props.js @@ -0,0 +1,49 @@ +export default { + props: { + // 到顶部的距离 + top: { + type: [String, Number], + default: uni.$u.props.notify.top + }, + // 是否展示组件 + // show: { + // type: Boolean, + // default: uni.$u.props.notify.show + // }, + // type主题,primary,success,warning,error + type: { + type: String, + default: uni.$u.props.notify.type + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.notify.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.notify.bgColor + }, + // 展示的文字内容 + message: { + type: String, + default: uni.$u.props.notify.message + }, + // 展示时长,为0时不消失,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.notify.duration + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.notify.fontSize + }, + // 是否留出顶部安全距离(状态栏高度) + safeAreaInsetTop: { + type: Boolean, + default: uni.$u.props.notify.safeAreaInsetTop + } + } +} diff --git a/uview-ui/components/u-notify/u-notify.vue b/uview-ui/components/u-notify/u-notify.vue new file mode 100644 index 0000000..56cae31 --- /dev/null +++ b/uview-ui/components/u-notify/u-notify.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/uview-ui/components/u-number-box/props.js b/uview-ui/components/u-number-box/props.js new file mode 100644 index 0000000..fb0fa94 --- /dev/null +++ b/uview-ui/components/u-number-box/props.js @@ -0,0 +1,109 @@ +export default { + props: { + // 步进器标识符,在change回调返回 + name: { + type: [String, Number], + default: uni.$u.props.numberBox.name + }, + // 用于双向绑定的值,初始化时设置设为默认min值(最小值) + value: { + type: [String, Number], + default: uni.$u.props.numberBox.value + }, + // 最小值 + min: { + type: [String, Number], + default: uni.$u.props.numberBox.min + }, + // 最大值 + max: { + type: [String, Number], + default: uni.$u.props.numberBox.max + }, + // 加减的步长,可为小数 + step: { + type: [String, Number], + default: uni.$u.props.numberBox.step + }, + // 是否只允许输入整数 + integer: { + type: Boolean, + default: uni.$u.props.numberBox.integer + }, + // 是否禁用,包括输入框,加减按钮 + disabled: { + type: Boolean, + default: uni.$u.props.numberBox.disabled + }, + // 是否禁用输入框 + disabledInput: { + type: Boolean, + default: uni.$u.props.numberBox.disabledInput + }, + // 是否开启异步变更,开启后需要手动控制输入值 + asyncChange: { + type: Boolean, + default: uni.$u.props.numberBox.asyncChange + }, + // 输入框宽度,单位为px + inputWidth: { + type: [String, Number], + default: uni.$u.props.numberBox.inputWidth + }, + // 是否显示减少按钮 + showMinus: { + type: Boolean, + default: uni.$u.props.numberBox.showMinus + }, + // 是否显示增加按钮 + showPlus: { + type: Boolean, + default: uni.$u.props.numberBox.showPlus + }, + // 显示的小数位数 + decimalLength: { + type: [String, Number, null], + default: uni.$u.props.numberBox.decimalLength + }, + // 是否开启长按加减手势 + longPress: { + type: Boolean, + default: uni.$u.props.numberBox.longPress + }, + // 输入框文字和加减按钮图标的颜色 + color: { + type: String, + default: uni.$u.props.numberBox.color + }, + // 按钮大小,宽高等于此值,单位px,输入框高度和此值保持一致 + buttonSize: { + type: [String, Number], + default: uni.$u.props.numberBox.buttonSize + }, + // 输入框和按钮的背景颜色 + bgColor: { + type: String, + default: uni.$u.props.numberBox.bgColor + }, + // 指定光标于键盘的距离,避免键盘遮挡输入框,单位px + cursorSpacing: { + type: [String, Number], + default: uni.$u.props.numberBox.cursorSpacing + }, + // 是否禁用增加按钮 + disablePlus: { + type: Boolean, + default: uni.$u.props.numberBox.disablePlus + }, + // 是否禁用减少按钮 + disableMinus: { + type: Boolean, + default: uni.$u.props.numberBox.disableMinus + }, + // 加减按钮图标的样式 + iconStyle: { + type: [Object, String], + default: uni.$u.props.numberBox.iconStyle + } + } +} diff --git a/uview-ui/components/u-number-box/u-number-box.vue b/uview-ui/components/u-number-box/u-number-box.vue new file mode 100644 index 0000000..2b71de8 --- /dev/null +++ b/uview-ui/components/u-number-box/u-number-box.vue @@ -0,0 +1,412 @@ + + + + + diff --git a/uview-ui/components/u-number-keyboard/props.js b/uview-ui/components/u-number-keyboard/props.js new file mode 100644 index 0000000..5e3bf55 --- /dev/null +++ b/uview-ui/components/u-number-keyboard/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘 + mode: { + type: String, + default: uni.$u.props.numberKeyboard.value + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: uni.$u.props.numberKeyboard.dotDisabled + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: uni.$u.props.numberKeyboard.random + } + } +} diff --git a/uview-ui/components/u-number-keyboard/u-number-keyboard.vue b/uview-ui/components/u-number-keyboard/u-number-keyboard.vue new file mode 100644 index 0000000..aed7f97 --- /dev/null +++ b/uview-ui/components/u-number-keyboard/u-number-keyboard.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/uview-ui/components/u-overlay/props.js b/uview-ui/components/u-overlay/props.js new file mode 100644 index 0000000..e6974df --- /dev/null +++ b/uview-ui/components/u-overlay/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 是否显示遮罩 + show: { + type: Boolean, + default: uni.$u.props.overlay.show + }, + // 层级z-index + zIndex: { + type: [String, Number], + default: uni.$u.props.overlay.zIndex + }, + // 遮罩的过渡时间,单位为ms + duration: { + type: [String, Number], + default: uni.$u.props.overlay.duration + }, + // 不透明度值,当做rgba的第四个参数 + opacity: { + type: [String, Number], + default: uni.$u.props.overlay.opacity + } + } +} diff --git a/uview-ui/components/u-overlay/u-overlay.vue b/uview-ui/components/u-overlay/u-overlay.vue new file mode 100644 index 0000000..4c8e499 --- /dev/null +++ b/uview-ui/components/u-overlay/u-overlay.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/uview-ui/components/u-parse/node/node.vue b/uview-ui/components/u-parse/node/node.vue new file mode 100644 index 0000000..6c4b5a0 --- /dev/null +++ b/uview-ui/components/u-parse/node/node.vue @@ -0,0 +1,499 @@ +