This commit is contained in:
jiangzewen committed 2025-06-11 08:27:38 +08:00
1 parent f0fc06a59d
commit ff1eec09f6
169 files changed
+21555 -21555

No files matched your search

+60 -60
View File
@@ -1,60 +1,60 @@
## 1.3.2(2021-12-09)
-
## 1.3.1(2021-11-19)
- 修复 label 插槽不生效的bug
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-forms](https://uniapp.dcloud.io/component/uniui/uni-forms)
## 1.2.7(2021-08-13)
- 修复 没有添加校验规则的字段依然报错的Bug
## 1.2.6(2021-08-11)
- 修复 重置表单错误信息无法清除的问题
## 1.2.5(2021-08-11)
- 优化 组件文档
## 1.2.4(2021-08-11)
- 修复 表单验证只生效一次的问题
## 1.2.3(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.2.2(2021-07-26)
- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
- 修复 1.2.1 引起的示例在小程序平台报错的Bug
## 1.2.1(2021-07-22)
- 修复 动态校验表单,默认值为空的情况下校验失效的Bug
- 修复 不指定name属性时,运行报错的Bug
- 优化 label默认宽度从65调整至70,使required为true且四字时不换行
- 优化 组件示例,新增动态校验示例代码
- 优化 组件文档,使用方式更清晰
## 1.2.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.2(2021-06-25)
- 修复 pattern 属性在微信小程序平台无效的问题
## 1.1.1(2021-06-22)
- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
## 1.1.0(2021-06-22)
- 修复 只写setRules方法而导致校验不生效的Bug
- 修复 由上个办法引发的错误提示文字错位的Bug
## 1.0.48(2021-06-21)
- 修复 不设置 label 属性 ,无法设置label插槽的问题
## 1.0.47(2021-06-21)
- 修复 不设置label属性,label-width属性不生效的bug
- 修复 setRules 方法与rules属性冲突的问题
## 1.0.46(2021-06-04)
- 修复 动态删减数据导致报错的问题
## 1.0.45(2021-06-04)
- 新增 modelValue 属性 ,value 即将废弃
## 1.0.44(2021-06-02)
- 新增 uni-forms-item 可以设置单独的 rules
- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
- 优化 submit 事件重命名为 validate
## 1.0.43(2021-05-12)
- 新增 组件示例地址
## 1.0.42(2021-04-30)
- 修复 自定义检验器失效的问题
## 1.0.41(2021-03-05)
- 更新 校验器
- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug
## 1.0.40(2021-03-04)
- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug
## 1.0.39(2021-02-05)
- 调整为uni_modules目录规范
- 修复 校验器传入 int 等类型 ,返回String类型的Bug
## 1.3.2(2021-12-09)
-
## 1.3.1(2021-11-19)
- 修复 label 插槽不生效的bug
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-forms](https://uniapp.dcloud.io/component/uniui/uni-forms)
## 1.2.7(2021-08-13)
- 修复 没有添加校验规则的字段依然报错的Bug
## 1.2.6(2021-08-11)
- 修复 重置表单错误信息无法清除的问题
## 1.2.5(2021-08-11)
- 优化 组件文档
## 1.2.4(2021-08-11)
- 修复 表单验证只生效一次的问题
## 1.2.3(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.2.2(2021-07-26)
- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
- 修复 1.2.1 引起的示例在小程序平台报错的Bug
## 1.2.1(2021-07-22)
- 修复 动态校验表单,默认值为空的情况下校验失效的Bug
- 修复 不指定name属性时,运行报错的Bug
- 优化 label默认宽度从65调整至70,使required为true且四字时不换行
- 优化 组件示例,新增动态校验示例代码
- 优化 组件文档,使用方式更清晰
## 1.2.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.2(2021-06-25)
- 修复 pattern 属性在微信小程序平台无效的问题
## 1.1.1(2021-06-22)
- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
## 1.1.0(2021-06-22)
- 修复 只写setRules方法而导致校验不生效的Bug
- 修复 由上个办法引发的错误提示文字错位的Bug
## 1.0.48(2021-06-21)
- 修复 不设置 label 属性 ,无法设置label插槽的问题
## 1.0.47(2021-06-21)
- 修复 不设置label属性,label-width属性不生效的bug
- 修复 setRules 方法与rules属性冲突的问题
## 1.0.46(2021-06-04)
- 修复 动态删减数据导致报错的问题
## 1.0.45(2021-06-04)
- 新增 modelValue 属性 ,value 即将废弃
## 1.0.44(2021-06-02)
- 新增 uni-forms-item 可以设置单独的 rules
- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
- 优化 submit 事件重命名为 validate
## 1.0.43(2021-05-12)
- 新增 组件示例地址
## 1.0.42(2021-04-30)
- 修复 自定义检验器失效的问题
## 1.0.41(2021-03-05)
- 更新 校验器
- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug
## 1.0.40(2021-03-04)
- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug
## 1.0.39(2021-02-05)
- 调整为uni_modules目录规范
- 修复 校验器传入 int 等类型 ,返回String类型的Bug
File diff suppressed because it is too large. Load diff
@@ -1,472 +1,472 @@
<template>
<view class="uni-forms" :class="{ 'uni-forms--top': !border }">
<form @submit.stop="submitForm" @reset="resetForm">
<slot></slot>
</form>
</view>
</template>
<script>
// #ifndef VUE3
import Vue from 'vue';
Vue.prototype.binddata = function(name, value, formName) {
if (formName) {
this.$refs[formName].setValue(name, value);
} else {
let formVm;
for (let i in this.$refs) {
const vm = this.$refs[i];
if (vm && vm.$options && vm.$options.name === 'uniForms') {
formVm = vm;
break;
}
}
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
formVm.setValue(name, value);
}
};
// #endif
import Validator from './validate.js';
/**
* Forms 表单
* @description 由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据
* @tutorial https://ext.dcloud.net.cn/plugin?id=2773
* @property {Object} rules 表单校验规则
* @property {String} validateTrigger = [bind|submit] 校验触发器方式 默认 submit
* @value bind 发生变化时触发
* @value submit 提交时触发
* @property {String} labelPosition = [top|left] label 位置 默认 left
* @value top 顶部显示 label
* @value left 左侧显示 label
* @property {String} labelWidth label 宽度,默认 65px
* @property {String} labelAlign = [left|center|right] label 居中方式 默认 left
* @value left label 左侧显示
* @value center label 居中
* @value right label 右侧对齐
* @property {String} errShowType = [undertext|toast|modal] 校验错误信息提示方式
* @value undertext 错误信息在底部显示
* @value toast 错误信息toast显示
* @value modal 错误信息modal显示
* @event {Function} submit 提交时触发
*/
export default {
name: 'uniForms',
components: {},
emits:['input','reset','validate','submit'],
props: {
// 即将弃用
value: {
type: Object,
default () {
return {};
}
},
// 替换 value 属性
modelValue: {
type: Object,
default () {
return {};
}
},
// 表单校验规则
rules: {
type: Object,
default () {
return {};
}
},
// 校验触发器方式,默认 关闭
validateTrigger: {
type: String,
default: ''
},
// label 位置,可选值 top/left
labelPosition: {
type: String,
default: 'left'
},
// label 宽度,单位 px
labelWidth: {
type: [String, Number],
default: ''
},
// label 居中方式,可选值 left/center/right
labelAlign: {
type: String,
default: 'left'
},
errShowType: {
type: String,
default: 'undertext'
},
border: {
type: Boolean,
default: false
}
},
data() {
return {
formData: {}
};
},
computed: {
dataValue() {
if (JSON.stringify(this.modelValue) === '{}') {
return this.value
} else {
return this.modelValue
}
}
},
watch: {
rules(newVal) {
// 如果规则发生变化,要初始化组件
this.init(newVal);
},
labelPosition() {
this.childrens.forEach(vm => {
vm.init()
})
}
},
created() {
// #ifdef VUE3
let getbinddata = getApp().$vm.$.appContext.config.globalProperties.binddata
if (!getbinddata) {
getApp().$vm.$.appContext.config.globalProperties.binddata = function(name, value, formName) {
if (formName) {
this.$refs[formName].setValue(name, value);
} else {
let formVm;
for (let i in this.$refs) {
const vm = this.$refs[i];
if (vm && vm.$options && vm.$options.name === 'uniForms') {
formVm = vm;
break;
}
}
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
formVm.setValue(name, value);
}
}
}
// #endif
// 存放watch 监听数组
this.unwatchs = [];
// 存放子组件数组
this.childrens = [];
// 存放 easyInput 组件
this.inputChildrens = [];
// 存放 dataCheckbox 组件
this.checkboxChildrens = [];
// 存放规则
this.formRules = [];
this.init(this.rules);
},
// mounted() {
// this.init(this.rules)
// },
methods: {
init(formRules) {
// 判断是否有规则
if (Object.keys(formRules).length === 0) {
this.formData = this.dataValue
return
};
this.formRules = formRules;
this.validator = new Validator(formRules);
this.registerWatch();
},
// 监听 watch
registerWatch() {
// 取消监听,避免多次调用 init 重复执行 $watch
this.unwatchs.forEach(v => v());
this.childrens.forEach((v) => {
v.init()
})
// watch 每个属性 ,需要知道具体那个属性发变化
Object.keys(this.dataValue).forEach(key => {
let watch = this.$watch(
'dataValue.' + key,
value => {
if (!value) return
// 如果是对象 ,则平铺内容
if (value.toString() === '[object Object]') {
for (let i in value) {
let name = `${key}[${i}]`;
this.formData[name] = this._getValue(name, value[i]);
}
} else {
this.formData[key] = this._getValue(key, value);
}
},
{
deep: true,
immediate: true
}
);
this.unwatchs.push(watch);
});
},
/**
* 公开给用户使用
* 设置校验规则
* @param {Object} formRules
*/
setRules(formRules) {
this.init(formRules);
},
/**
* 公开给用户使用
* 设置自定义表单组件 value 值
* @param {String} name 字段名称
* @param {String} value 字段值
*/
setValue(name, value, callback) {
let example = this.childrens.find(child => child.name === name);
if (!example) return null;
value = this._getValue(example.name, value);
this.formData[name] = value;
example.val = value;
return example.triggerCheck(value, callback);
},
/**
* 表单重置
* @param {Object} event
*/
resetForm(event) {
this.childrens.forEach(item => {
item.errMsg = '';
const inputComp = this.inputChildrens.find(child => child.rename === item.name);
if (inputComp) {
inputComp.errMsg = '';
// fix by mehaotian 不触发其他组件的 setValue
inputComp.is_reset = true
inputComp.$emit('input', inputComp.multiple ? [] : '');
inputComp.$emit('update:modelValue', inputComp.multiple ? [] : '');
}
});
this.childrens.forEach(item => {
if (item.name) {
this.formData[item.name] = this._getValue(item.name, '');
}
});
this.$emit('reset', event);
},
/**
* 触发表单校验,通过 @validate 获取
* @param {Object} validate
*/
validateCheck(validate) {
if (validate === null) validate = null;
this.$emit('validate', validate);
},
/**
* 校验所有或者部分表单
*/
async validateAll(invalidFields, type, keepitem, callback) {
let childrens = []
for (let i in invalidFields) {
const item = this.childrens.find(v => v.name === i)
if (item) {
childrens.push(item)
}
}
if (!callback && typeof keepitem === 'function') {
callback = keepitem;
}
let promise;
if (!callback && typeof callback !== 'function' && Promise) {
promise = new Promise((resolve, reject) => {
callback = function(valid, invalidFields) {
!valid ? resolve(invalidFields) : reject(valid);
};
});
}
let results = [];
let newFormData = {};
if (this.validator) {
for (let key in childrens) {
const child = childrens[key];
let name = child.isArray ? child.arrayField : child.name;
if (child.isArray) {
if (child.name.indexOf('[') !== -1 && child.name.indexOf(']') !== -1) {
const fieldData = child.name.split('[');
const fieldName = fieldData[0];
const fieldValue = fieldData[1].replace(']', '');
if (!newFormData[fieldName]) {
newFormData[fieldName] = {};
}
newFormData[fieldName][fieldValue] = this._getValue(name, invalidFields[name]);
}
} else {
newFormData[name] = this._getValue(name, invalidFields[name]);
}
const result = await child.triggerCheck(invalidFields[name], true);
if (result) {
results.push(result);
if (this.errShowType === 'toast' || this.errShowType === 'modal') break;
}
}
} else {
newFormData = invalidFields
}
if (Array.isArray(results)) {
if (results.length === 0) results = null;
}
if (Array.isArray(keepitem)) {
keepitem.forEach(v => {
newFormData[v] = this.dataValue[v];
});
}
if (type === 'submit') {
this.$emit('submit', {
detail: {
value: newFormData,
errors: results
}
});
} else {
this.$emit('validate', results);
}
callback && typeof callback === 'function' && callback(results, newFormData);
if (promise && callback) {
return promise;
} else {
return null;
}
},
submitForm() {},
/**
* 外部调用方法
* 手动提交校验表单
* 对整个表单进行校验的方法,参数为一个回调函数。
*/
submit(keepitem, callback, type) {
for (let i in this.dataValue) {
const itemData = this.childrens.find(v => v.name === i);
if (itemData) {
if (this.formData[i] === undefined) {
this.formData[i] = this._getValue(i, this.dataValue[i]);
}
}
}
if (!type) {
console.warn('submit 方法即将废弃,请使用validate方法代替!');
}
return this.validateAll(this.formData, 'submit', keepitem, callback);
},
/**
* 外部调用方法
* 校验表单
* 对整个表单进行校验的方法,参数为一个回调函数。
*/
validate(keepitem, callback) {
return this.submit(keepitem, callback, true);
},
/**
* 部分表单校验
* @param {Object} props
* @param {Object} cb
*/
validateField(props, callback) {
props = [].concat(props);
let invalidFields = {};
this.childrens.forEach(item => {
if (props.indexOf(item.name) !== -1) {
invalidFields = Object.assign({}, invalidFields, {
[item.name]: this.formData[item.name]
});
}
});
return this.validateAll(invalidFields, 'submit', [], callback);
},
/**
* 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
*/
resetFields() {
this.resetForm();
},
/**
* 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果
*/
clearValidate(props) {
props = [].concat(props);
this.childrens.forEach(item => {
const inputComp = this.inputChildrens.find(child => child.rename === item.name);
if (props.length === 0) {
item.errMsg = '';
if (inputComp) {
inputComp.errMsg = '';
}
} else {
if (props.indexOf(item.name) !== -1) {
item.errMsg = '';
if (inputComp) {
inputComp.errMsg = '';
}
}
}
});
},
/**
* 把 value 转换成指定的类型
* @param {Object} key
* @param {Object} value
*/
_getValue(key, value) {
const rules = (this.formRules[key] && this.formRules[key].rules) || [];
const isRuleNum = rules.find(val => val.format && this.type_filter(val.format));
const isRuleBool = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool');
// 输入值为 number
if (isRuleNum) {
value = isNaN(value) ? value : value === '' || value === null ? null : Number(value);
}
// 简单判断真假值
if (isRuleBool) {
value = !value ? false : true;
}
return value;
},
/**
* 过滤数字类型
* @param {Object} format
*/
type_filter(format) {
return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp';
}
}
};
</script>
<style lang="scss" >
.uni-forms {
// overflow: hidden;
// padding: 10px 15px;
}
.uni-forms--top {
// padding: 10px 15px;
// padding-top: 22px;
}
</style>
<template>
<view class="uni-forms" :class="{ 'uni-forms--top': !border }">
<form @submit.stop="submitForm" @reset="resetForm">
<slot></slot>
</form>
</view>
</template>
<script>
// #ifndef VUE3
import Vue from 'vue';
Vue.prototype.binddata = function(name, value, formName) {
if (formName) {
this.$refs[formName].setValue(name, value);
} else {
let formVm;
for (let i in this.$refs) {
const vm = this.$refs[i];
if (vm && vm.$options && vm.$options.name === 'uniForms') {
formVm = vm;
break;
}
}
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
formVm.setValue(name, value);
}
};
// #endif
import Validator from './validate.js';
/**
* Forms 表单
* @description 由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据
* @tutorial https://ext.dcloud.net.cn/plugin?id=2773
* @property {Object} rules 表单校验规则
* @property {String} validateTrigger = [bind|submit] 校验触发器方式 默认 submit
* @value bind 发生变化时触发
* @value submit 提交时触发
* @property {String} labelPosition = [top|left] label 位置 默认 left
* @value top 顶部显示 label
* @value left 左侧显示 label
* @property {String} labelWidth label 宽度,默认 65px
* @property {String} labelAlign = [left|center|right] label 居中方式 默认 left
* @value left label 左侧显示
* @value center label 居中
* @value right label 右侧对齐
* @property {String} errShowType = [undertext|toast|modal] 校验错误信息提示方式
* @value undertext 错误信息在底部显示
* @value toast 错误信息toast显示
* @value modal 错误信息modal显示
* @event {Function} submit 提交时触发
*/
export default {
name: 'uniForms',
components: {},
emits:['input','reset','validate','submit'],
props: {
// 即将弃用
value: {
type: Object,
default () {
return {};
}
},
// 替换 value 属性
modelValue: {
type: Object,
default () {
return {};
}
},
// 表单校验规则
rules: {
type: Object,
default () {
return {};
}
},
// 校验触发器方式,默认 关闭
validateTrigger: {
type: String,
default: ''
},
// label 位置,可选值 top/left
labelPosition: {
type: String,
default: 'left'
},
// label 宽度,单位 px
labelWidth: {
type: [String, Number],
default: ''
},
// label 居中方式,可选值 left/center/right
labelAlign: {
type: String,
default: 'left'
},
errShowType: {
type: String,
default: 'undertext'
},
border: {
type: Boolean,
default: false
}
},
data() {
return {
formData: {}
};
},
computed: {
dataValue() {
if (JSON.stringify(this.modelValue) === '{}') {
return this.value
} else {
return this.modelValue
}
}
},
watch: {
rules(newVal) {
// 如果规则发生变化,要初始化组件
this.init(newVal);
},
labelPosition() {
this.childrens.forEach(vm => {
vm.init()
})
}
},
created() {
// #ifdef VUE3
let getbinddata = getApp().$vm.$.appContext.config.globalProperties.binddata
if (!getbinddata) {
getApp().$vm.$.appContext.config.globalProperties.binddata = function(name, value, formName) {
if (formName) {
this.$refs[formName].setValue(name, value);
} else {
let formVm;
for (let i in this.$refs) {
const vm = this.$refs[i];
if (vm && vm.$options && vm.$options.name === 'uniForms') {
formVm = vm;
break;
}
}
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
formVm.setValue(name, value);
}
}
}
// #endif
// 存放watch 监听数组
this.unwatchs = [];
// 存放子组件数组
this.childrens = [];
// 存放 easyInput 组件
this.inputChildrens = [];
// 存放 dataCheckbox 组件
this.checkboxChildrens = [];
// 存放规则
this.formRules = [];
this.init(this.rules);
},
// mounted() {
// this.init(this.rules)
// },
methods: {
init(formRules) {
// 判断是否有规则
if (Object.keys(formRules).length === 0) {
this.formData = this.dataValue
return
};
this.formRules = formRules;
this.validator = new Validator(formRules);
this.registerWatch();
},
// 监听 watch
registerWatch() {
// 取消监听,避免多次调用 init 重复执行 $watch
this.unwatchs.forEach(v => v());
this.childrens.forEach((v) => {
v.init()
})
// watch 每个属性 ,需要知道具体那个属性发变化
Object.keys(this.dataValue).forEach(key => {
let watch = this.$watch(
'dataValue.' + key,
value => {
if (!value) return
// 如果是对象 ,则平铺内容
if (value.toString() === '[object Object]') {
for (let i in value) {
let name = `${key}[${i}]`;
this.formData[name] = this._getValue(name, value[i]);
}
} else {
this.formData[key] = this._getValue(key, value);
}
},
{
deep: true,
immediate: true
}
);
this.unwatchs.push(watch);
});
},
/**
* 公开给用户使用
* 设置校验规则
* @param {Object} formRules
*/
setRules(formRules) {
this.init(formRules);
},
/**
* 公开给用户使用
* 设置自定义表单组件 value 值
* @param {String} name 字段名称
* @param {String} value 字段值
*/
setValue(name, value, callback) {
let example = this.childrens.find(child => child.name === name);
if (!example) return null;
value = this._getValue(example.name, value);
this.formData[name] = value;
example.val = value;
return example.triggerCheck(value, callback);
},
/**
* 表单重置
* @param {Object} event
*/
resetForm(event) {
this.childrens.forEach(item => {
item.errMsg = '';
const inputComp = this.inputChildrens.find(child => child.rename === item.name);
if (inputComp) {
inputComp.errMsg = '';
// fix by mehaotian 不触发其他组件的 setValue
inputComp.is_reset = true
inputComp.$emit('input', inputComp.multiple ? [] : '');
inputComp.$emit('update:modelValue', inputComp.multiple ? [] : '');
}
});
this.childrens.forEach(item => {
if (item.name) {
this.formData[item.name] = this._getValue(item.name, '');
}
});
this.$emit('reset', event);
},
/**
* 触发表单校验,通过 @validate 获取
* @param {Object} validate
*/
validateCheck(validate) {
if (validate === null) validate = null;
this.$emit('validate', validate);
},
/**
* 校验所有或者部分表单
*/
async validateAll(invalidFields, type, keepitem, callback) {
let childrens = []
for (let i in invalidFields) {
const item = this.childrens.find(v => v.name === i)
if (item) {
childrens.push(item)
}
}
if (!callback && typeof keepitem === 'function') {
callback = keepitem;
}
let promise;
if (!callback && typeof callback !== 'function' && Promise) {
promise = new Promise((resolve, reject) => {
callback = function(valid, invalidFields) {
!valid ? resolve(invalidFields) : reject(valid);
};
});
}
let results = [];
let newFormData = {};
if (this.validator) {
for (let key in childrens) {
const child = childrens[key];
let name = child.isArray ? child.arrayField : child.name;
if (child.isArray) {
if (child.name.indexOf('[') !== -1 && child.name.indexOf(']') !== -1) {
const fieldData = child.name.split('[');
const fieldName = fieldData[0];
const fieldValue = fieldData[1].replace(']', '');
if (!newFormData[fieldName]) {
newFormData[fieldName] = {};
}
newFormData[fieldName][fieldValue] = this._getValue(name, invalidFields[name]);
}
} else {
newFormData[name] = this._getValue(name, invalidFields[name]);
}
const result = await child.triggerCheck(invalidFields[name], true);
if (result) {
results.push(result);
if (this.errShowType === 'toast' || this.errShowType === 'modal') break;
}
}
} else {
newFormData = invalidFields
}
if (Array.isArray(results)) {
if (results.length === 0) results = null;
}
if (Array.isArray(keepitem)) {
keepitem.forEach(v => {
newFormData[v] = this.dataValue[v];
});
}
if (type === 'submit') {
this.$emit('submit', {
detail: {
value: newFormData,
errors: results
}
});
} else {
this.$emit('validate', results);
}
callback && typeof callback === 'function' && callback(results, newFormData);
if (promise && callback) {
return promise;
} else {
return null;
}
},
submitForm() {},
/**
* 外部调用方法
* 手动提交校验表单
* 对整个表单进行校验的方法,参数为一个回调函数。
*/
submit(keepitem, callback, type) {
for (let i in this.dataValue) {
const itemData = this.childrens.find(v => v.name === i);
if (itemData) {
if (this.formData[i] === undefined) {
this.formData[i] = this._getValue(i, this.dataValue[i]);
}
}
}
if (!type) {
console.warn('submit 方法即将废弃,请使用validate方法代替!');
}
return this.validateAll(this.formData, 'submit', keepitem, callback);
},
/**
* 外部调用方法
* 校验表单
* 对整个表单进行校验的方法,参数为一个回调函数。
*/
validate(keepitem, callback) {
return this.submit(keepitem, callback, true);
},
/**
* 部分表单校验
* @param {Object} props
* @param {Object} cb
*/
validateField(props, callback) {
props = [].concat(props);
let invalidFields = {};
this.childrens.forEach(item => {
if (props.indexOf(item.name) !== -1) {
invalidFields = Object.assign({}, invalidFields, {
[item.name]: this.formData[item.name]
});
}
});
return this.validateAll(invalidFields, 'submit', [], callback);
},
/**
* 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
*/
resetFields() {
this.resetForm();
},
/**
* 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果
*/
clearValidate(props) {
props = [].concat(props);
this.childrens.forEach(item => {
const inputComp = this.inputChildrens.find(child => child.rename === item.name);
if (props.length === 0) {
item.errMsg = '';
if (inputComp) {
inputComp.errMsg = '';
}
} else {
if (props.indexOf(item.name) !== -1) {
item.errMsg = '';
if (inputComp) {
inputComp.errMsg = '';
}
}
}
});
},
/**
* 把 value 转换成指定的类型
* @param {Object} key
* @param {Object} value
*/
_getValue(key, value) {
const rules = (this.formRules[key] && this.formRules[key].rules) || [];
const isRuleNum = rules.find(val => val.format && this.type_filter(val.format));
const isRuleBool = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool');
// 输入值为 number
if (isRuleNum) {
value = isNaN(value) ? value : value === '' || value === null ? null : Number(value);
}
// 简单判断真假值
if (isRuleBool) {
value = !value ? false : true;
}
return value;
},
/**
* 过滤数字类型
* @param {Object} format
*/
type_filter(format) {
return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp';
}
}
};
</script>
<style lang="scss" >
.uni-forms {
// overflow: hidden;
// padding: 10px 15px;
}
.uni-forms--top {
// padding: 10px 15px;
// padding-top: 22px;
}
</style>
@@ -1,486 +1,486 @@
var pattern = {
email: /^\S+?@\S+?\.\S+?$/,
idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
url: new RegExp(
"^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$",
'i')
};
const FORMAT_MAPPING = {
"int": 'integer',
"bool": 'boolean',
"double": 'number',
"long": 'number',
"password": 'string'
// "fileurls": 'array'
}
function formatMessage(args, resources = '') {
var defaultMessage = ['label']
defaultMessage.forEach((item) => {
if (args[item] === undefined) {
args[item] = ''
}
})
let str = resources
for (let key in args) {
let reg = new RegExp('{' + key + '}')
str = str.replace(reg, args[key])
}
return str
}
function isEmptyValue(value, type) {
if (value === undefined || value === null) {
return true;
}
if (typeof value === 'string' && !value) {
return true;
}
if (Array.isArray(value) && !value.length) {
return true;
}
if (type === 'object' && !Object.keys(value).length) {
return true;
}
return false;
}
const types = {
integer(value) {
return types.number(value) && parseInt(value, 10) === value;
},
string(value) {
return typeof value === 'string';
},
number(value) {
if (isNaN(value)) {
return false;
}
return typeof value === 'number';
},
"boolean": function(value) {
return typeof value === 'boolean';
},
"float": function(value) {
return types.number(value) && !types.integer(value);
},
array(value) {
return Array.isArray(value);
},
object(value) {
return typeof value === 'object' && !types.array(value);
},
date(value) {
return value instanceof Date;
},
timestamp(value) {
if (!this.integer(value) || Math.abs(value).toString().length > 16) {
return false
}
return true;
},
file(value) {
return typeof value.url === 'string';
},
email(value) {
return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255;
},
url(value) {
return typeof value === 'string' && !!value.match(pattern.url);
},
pattern(reg, value) {
try {
return new RegExp(reg).test(value);
} catch (e) {
return false;
}
},
method(value) {
return typeof value === 'function';
},
idcard(value) {
return typeof value === 'string' && !!value.match(pattern.idcard);
},
'url-https'(value) {
return this.url(value) && value.startsWith('https://');
},
'url-scheme'(value) {
return value.startsWith('://');
},
'url-web'(value) {
return false;
}
}
class RuleValidator {
constructor(message) {
this._message = message
}
async validateRule(fieldKey, fieldValue, value, data, allData) {
var result = null
let rules = fieldValue.rules
let hasRequired = rules.findIndex((item) => {
return item.required
})
if (hasRequired < 0) {
if (value === null || value === undefined) {
return result
}
if (typeof value === 'string' && !value.length) {
return result
}
}
var message = this._message
if (rules === undefined) {
return message['default']
}
for (var i = 0; i < rules.length; i++) {
let rule = rules[i]
let vt = this._getValidateType(rule)
Object.assign(rule, {
label: fieldValue.label || `["${fieldKey}"]`
})
if (RuleValidatorHelper[vt]) {
result = RuleValidatorHelper[vt](rule, value, message)
if (result != null) {
break
}
}
if (rule.validateExpr) {
let now = Date.now()
let resultExpr = rule.validateExpr(value, allData, now)
if (resultExpr === false) {
result = this._getMessage(rule, rule.errorMessage || this._message['default'])
break
}
}
if (rule.validateFunction) {
result = await this.validateFunction(rule, value, data, allData, vt)
if (result !== null) {
break
}
}
}
if (result !== null) {
result = message.TAG + result
}
return result
}
async validateFunction(rule, value, data, allData, vt) {
let result = null
try {
let callbackMessage = null
const res = await rule.validateFunction(rule, value, allData || data, (message) => {
callbackMessage = message
})
if (callbackMessage || (typeof res === 'string' && res) || res === false) {
result = this._getMessage(rule, callbackMessage || res, vt)
}
} catch (e) {
result = this._getMessage(rule, e.message, vt)
}
return result
}
_getMessage(rule, message, vt) {
return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default'])
}
_getValidateType(rule) {
var result = ''
if (rule.required) {
result = 'required'
} else if (rule.format) {
result = 'format'
} else if (rule.arrayType) {
result = 'arrayTypeFormat'
} else if (rule.range) {
result = 'range'
} else if (rule.maximum !== undefined || rule.minimum !== undefined) {
result = 'rangeNumber'
} else if (rule.maxLength !== undefined || rule.minLength !== undefined) {
result = 'rangeLength'
} else if (rule.pattern) {
result = 'pattern'
} else if (rule.validateFunction) {
result = 'validateFunction'
}
return result
}
}
const RuleValidatorHelper = {
required(rule, value, message) {
if (rule.required && isEmptyValue(value, rule.format || typeof value)) {
return formatMessage(rule, rule.errorMessage || message.required);
}
return null
},
range(rule, value, message) {
const {
range,
errorMessage
} = rule;
let list = new Array(range.length);
for (let i = 0; i < range.length; i++) {
const item = range[i];
if (types.object(item) && item.value !== undefined) {
list[i] = item.value;
} else {
list[i] = item;
}
}
let result = false
if (Array.isArray(value)) {
result = (new Set(value.concat(list)).size === list.length);
} else {
if (list.indexOf(value) > -1) {
result = true;
}
}
if (!result) {
return formatMessage(rule, errorMessage || message['enum']);
}
return null
},
rangeNumber(rule, value, message) {
if (!types.number(value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
let {
minimum,
maximum,
exclusiveMinimum,
exclusiveMaximum
} = rule;
let min = exclusiveMinimum ? value <= minimum : value < minimum;
let max = exclusiveMaximum ? value >= maximum : value > maximum;
if (minimum !== undefined && min) {
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ?
'exclusiveMinimum' : 'minimum'
])
} else if (maximum !== undefined && max) {
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ?
'exclusiveMaximum' : 'maximum'
])
} else if (minimum !== undefined && maximum !== undefined && (min || max)) {
return formatMessage(rule, rule.errorMessage || message['number'].range)
}
return null
},
rangeLength(rule, value, message) {
if (!types.string(value) && !types.array(value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
let min = rule.minLength;
let max = rule.maxLength;
let val = value.length;
if (min !== undefined && val < min) {
return formatMessage(rule, rule.errorMessage || message['length'].minLength)
} else if (max !== undefined && val > max) {
return formatMessage(rule, rule.errorMessage || message['length'].maxLength)
} else if (min !== undefined && max !== undefined && (val < min || val > max)) {
return formatMessage(rule, rule.errorMessage || message['length'].range)
}
return null
},
pattern(rule, value, message) {
if (!types['pattern'](rule.pattern, value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
return null
},
format(rule, value, message) {
var customTypes = Object.keys(types);
var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType);
if (customTypes.indexOf(format) > -1) {
if (!types[format](value)) {
return formatMessage(rule, rule.errorMessage || message.typeError);
}
}
return null
},
arrayTypeFormat(rule, value, message) {
if (!Array.isArray(value)) {
return formatMessage(rule, rule.errorMessage || message.typeError);
}
for (let i = 0; i < value.length; i++) {
const element = value[i];
let formatResult = this.format(rule, element, message)
if (formatResult !== null) {
return formatResult
}
}
return null
}
}
class SchemaValidator extends RuleValidator {
constructor(schema, options) {
super(SchemaValidator.message);
this._schema = schema
this._options = options || null
}
updateSchema(schema) {
this._schema = schema
}
async validate(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidate(data, false, allData)
}
return result.length ? result[0] : null
}
async validateAll(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidate(data, true, allData)
}
return result
}
async validateUpdate(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidateUpdate(data, false, allData)
}
return result.length ? result[0] : null
}
async invokeValidate(data, all, allData) {
let result = []
let schema = this._schema
for (let key in schema) {
let value = schema[key]
let errorMessage = await this.validateRule(key, value, data[key], data, allData)
if (errorMessage != null) {
result.push({
key,
errorMessage
})
if (!all) break
}
}
return result
}
async invokeValidateUpdate(data, all, allData) {
let result = []
for (let key in data) {
let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData)
if (errorMessage != null) {
result.push({
key,
errorMessage
})
if (!all) break
}
}
return result
}
_checkFieldInSchema(data) {
var keys = Object.keys(data)
var keys2 = Object.keys(this._schema)
if (new Set(keys.concat(keys2)).size === keys2.length) {
return ''
}
var noExistFields = keys.filter((key) => {
return keys2.indexOf(key) < 0;
})
var errorMessage = formatMessage({
field: JSON.stringify(noExistFields)
}, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid'])
return [{
key: 'invalid',
errorMessage
}]
}
}
function Message() {
return {
TAG: "",
default: '验证错误',
defaultInvalid: '提交的字段{field}在数据库中并不存在',
validateFunction: '验证无效',
required: '{label}必填',
'enum': '{label}超出范围',
timestamp: '{label}格式无效',
whitespace: '{label}不能为空',
typeError: '{label}类型无效',
date: {
format: '{label}日期{value}格式无效',
parse: '{label}日期无法解析,{value}无效',
invalid: '{label}日期{value}无效'
},
length: {
minLength: '{label}长度不能少于{minLength}',
maxLength: '{label}长度不能超过{maxLength}',
range: '{label}必须介于{minLength}和{maxLength}之间'
},
number: {
minimum: '{label}不能小于{minimum}',
maximum: '{label}不能大于{maximum}',
exclusiveMinimum: '{label}不能小于等于{minimum}',
exclusiveMaximum: '{label}不能大于等于{maximum}',
range: '{label}必须介于{minimum}and{maximum}之间'
},
pattern: {
mismatch: '{label}格式不匹配'
}
};
}
SchemaValidator.message = new Message();
export default SchemaValidator
var pattern = {
email: /^\S+?@\S+?\.\S+?$/,
idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
url: new RegExp(
"^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$",
'i')
};
const FORMAT_MAPPING = {
"int": 'integer',
"bool": 'boolean',
"double": 'number',
"long": 'number',
"password": 'string'
// "fileurls": 'array'
}
function formatMessage(args, resources = '') {
var defaultMessage = ['label']
defaultMessage.forEach((item) => {
if (args[item] === undefined) {
args[item] = ''
}
})
let str = resources
for (let key in args) {
let reg = new RegExp('{' + key + '}')
str = str.replace(reg, args[key])
}
return str
}
function isEmptyValue(value, type) {
if (value === undefined || value === null) {
return true;
}
if (typeof value === 'string' && !value) {
return true;
}
if (Array.isArray(value) && !value.length) {
return true;
}
if (type === 'object' && !Object.keys(value).length) {
return true;
}
return false;
}
const types = {
integer(value) {
return types.number(value) && parseInt(value, 10) === value;
},
string(value) {
return typeof value === 'string';
},
number(value) {
if (isNaN(value)) {
return false;
}
return typeof value === 'number';
},
"boolean": function(value) {
return typeof value === 'boolean';
},
"float": function(value) {
return types.number(value) && !types.integer(value);
},
array(value) {
return Array.isArray(value);
},
object(value) {
return typeof value === 'object' && !types.array(value);
},
date(value) {
return value instanceof Date;
},
timestamp(value) {
if (!this.integer(value) || Math.abs(value).toString().length > 16) {
return false
}
return true;
},
file(value) {
return typeof value.url === 'string';
},
email(value) {
return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255;
},
url(value) {
return typeof value === 'string' && !!value.match(pattern.url);
},
pattern(reg, value) {
try {
return new RegExp(reg).test(value);
} catch (e) {
return false;
}
},
method(value) {
return typeof value === 'function';
},
idcard(value) {
return typeof value === 'string' && !!value.match(pattern.idcard);
},
'url-https'(value) {
return this.url(value) && value.startsWith('https://');
},
'url-scheme'(value) {
return value.startsWith('://');
},
'url-web'(value) {
return false;
}
}
class RuleValidator {
constructor(message) {
this._message = message
}
async validateRule(fieldKey, fieldValue, value, data, allData) {
var result = null
let rules = fieldValue.rules
let hasRequired = rules.findIndex((item) => {
return item.required
})
if (hasRequired < 0) {
if (value === null || value === undefined) {
return result
}
if (typeof value === 'string' && !value.length) {
return result
}
}
var message = this._message
if (rules === undefined) {
return message['default']
}
for (var i = 0; i < rules.length; i++) {
let rule = rules[i]
let vt = this._getValidateType(rule)
Object.assign(rule, {
label: fieldValue.label || `["${fieldKey}"]`
})
if (RuleValidatorHelper[vt]) {
result = RuleValidatorHelper[vt](rule, value, message)
if (result != null) {
break
}
}
if (rule.validateExpr) {
let now = Date.now()
let resultExpr = rule.validateExpr(value, allData, now)
if (resultExpr === false) {
result = this._getMessage(rule, rule.errorMessage || this._message['default'])
break
}
}
if (rule.validateFunction) {
result = await this.validateFunction(rule, value, data, allData, vt)
if (result !== null) {
break
}
}
}
if (result !== null) {
result = message.TAG + result
}
return result
}
async validateFunction(rule, value, data, allData, vt) {
let result = null
try {
let callbackMessage = null
const res = await rule.validateFunction(rule, value, allData || data, (message) => {
callbackMessage = message
})
if (callbackMessage || (typeof res === 'string' && res) || res === false) {
result = this._getMessage(rule, callbackMessage || res, vt)
}
} catch (e) {
result = this._getMessage(rule, e.message, vt)
}
return result
}
_getMessage(rule, message, vt) {
return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default'])
}
_getValidateType(rule) {
var result = ''
if (rule.required) {
result = 'required'
} else if (rule.format) {
result = 'format'
} else if (rule.arrayType) {
result = 'arrayTypeFormat'
} else if (rule.range) {
result = 'range'
} else if (rule.maximum !== undefined || rule.minimum !== undefined) {
result = 'rangeNumber'
} else if (rule.maxLength !== undefined || rule.minLength !== undefined) {
result = 'rangeLength'
} else if (rule.pattern) {
result = 'pattern'
} else if (rule.validateFunction) {
result = 'validateFunction'
}
return result
}
}
const RuleValidatorHelper = {
required(rule, value, message) {
if (rule.required && isEmptyValue(value, rule.format || typeof value)) {
return formatMessage(rule, rule.errorMessage || message.required);
}
return null
},
range(rule, value, message) {
const {
range,
errorMessage
} = rule;
let list = new Array(range.length);
for (let i = 0; i < range.length; i++) {
const item = range[i];
if (types.object(item) && item.value !== undefined) {
list[i] = item.value;
} else {
list[i] = item;
}
}
let result = false
if (Array.isArray(value)) {
result = (new Set(value.concat(list)).size === list.length);
} else {
if (list.indexOf(value) > -1) {
result = true;
}
}
if (!result) {
return formatMessage(rule, errorMessage || message['enum']);
}
return null
},
rangeNumber(rule, value, message) {
if (!types.number(value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
let {
minimum,
maximum,
exclusiveMinimum,
exclusiveMaximum
} = rule;
let min = exclusiveMinimum ? value <= minimum : value < minimum;
let max = exclusiveMaximum ? value >= maximum : value > maximum;
if (minimum !== undefined && min) {
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ?
'exclusiveMinimum' : 'minimum'
])
} else if (maximum !== undefined && max) {
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ?
'exclusiveMaximum' : 'maximum'
])
} else if (minimum !== undefined && maximum !== undefined && (min || max)) {
return formatMessage(rule, rule.errorMessage || message['number'].range)
}
return null
},
rangeLength(rule, value, message) {
if (!types.string(value) && !types.array(value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
let min = rule.minLength;
let max = rule.maxLength;
let val = value.length;
if (min !== undefined && val < min) {
return formatMessage(rule, rule.errorMessage || message['length'].minLength)
} else if (max !== undefined && val > max) {
return formatMessage(rule, rule.errorMessage || message['length'].maxLength)
} else if (min !== undefined && max !== undefined && (val < min || val > max)) {
return formatMessage(rule, rule.errorMessage || message['length'].range)
}
return null
},
pattern(rule, value, message) {
if (!types['pattern'](rule.pattern, value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
return null
},
format(rule, value, message) {
var customTypes = Object.keys(types);
var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType);
if (customTypes.indexOf(format) > -1) {
if (!types[format](value)) {
return formatMessage(rule, rule.errorMessage || message.typeError);
}
}
return null
},
arrayTypeFormat(rule, value, message) {
if (!Array.isArray(value)) {
return formatMessage(rule, rule.errorMessage || message.typeError);
}
for (let i = 0; i < value.length; i++) {
const element = value[i];
let formatResult = this.format(rule, element, message)
if (formatResult !== null) {
return formatResult
}
}
return null
}
}
class SchemaValidator extends RuleValidator {
constructor(schema, options) {
super(SchemaValidator.message);
this._schema = schema
this._options = options || null
}
updateSchema(schema) {
this._schema = schema
}
async validate(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidate(data, false, allData)
}
return result.length ? result[0] : null
}
async validateAll(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidate(data, true, allData)
}
return result
}
async validateUpdate(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidateUpdate(data, false, allData)
}
return result.length ? result[0] : null
}
async invokeValidate(data, all, allData) {
let result = []
let schema = this._schema
for (let key in schema) {
let value = schema[key]
let errorMessage = await this.validateRule(key, value, data[key], data, allData)
if (errorMessage != null) {
result.push({
key,
errorMessage
})
if (!all) break
}
}
return result
}
async invokeValidateUpdate(data, all, allData) {
let result = []
for (let key in data) {
let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData)
if (errorMessage != null) {
result.push({
key,
errorMessage
})
if (!all) break
}
}
return result
}
_checkFieldInSchema(data) {
var keys = Object.keys(data)
var keys2 = Object.keys(this._schema)
if (new Set(keys.concat(keys2)).size === keys2.length) {
return ''
}
var noExistFields = keys.filter((key) => {
return keys2.indexOf(key) < 0;
})
var errorMessage = formatMessage({
field: JSON.stringify(noExistFields)
}, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid'])
return [{
key: 'invalid',
errorMessage
}]
}
}
function Message() {
return {
TAG: "",
default: '验证错误',
defaultInvalid: '提交的字段{field}在数据库中并不存在',
validateFunction: '验证无效',
required: '{label}必填',
'enum': '{label}超出范围',
timestamp: '{label}格式无效',
whitespace: '{label}不能为空',
typeError: '{label}类型无效',
date: {
format: '{label}日期{value}格式无效',
parse: '{label}日期无法解析,{value}无效',
invalid: '{label}日期{value}无效'
},
length: {
minLength: '{label}长度不能少于{minLength}',
maxLength: '{label}长度不能超过{maxLength}',
range: '{label}必须介于{minLength}和{maxLength}之间'
},
number: {
minimum: '{label}不能小于{minimum}',
maximum: '{label}不能大于{maximum}',
exclusiveMinimum: '{label}不能小于等于{minimum}',
exclusiveMaximum: '{label}不能大于等于{maximum}',
range: '{label}必须介于{minimum}and{maximum}之间'
},
pattern: {
mismatch: '{label}格式不匹配'
}
};
}
SchemaValidator.message = new Message();
export default SchemaValidator
+90 -90
View File
@@ -1,90 +1,90 @@
{
"id": "uni-forms",
"displayName": "uni-forms 表单",
"version": "1.3.2",
"description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据",
"keywords": [
"uni-ui",
"表单",
"校验",
"表单校验",
"表单验证"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
{
"id": "uni-forms",
"displayName": "uni-forms 表单",
"version": "1.3.2",
"description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据",
"keywords": [
"uni-ui",
"表单",
"校验",
"表单校验",
"表单验证"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+22 -22
View File
@@ -1,23 +1,23 @@
## Forms 表单
> **组件名:uni-forms**
> 代码块: `uForms`、`uni-forms-item`
> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。
uni-app的内置组件已经有了 `<form>`组件,用于提交表单内容。
然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 `<form>`组件封装了 `<uni-forms>`组件,内置了表单验证功能。
`<uni-forms>` 提供了 `rules`属性来描述校验规则、`<uni-forms-item>`子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。
每个要校验的表单项,不管input还是checkbox,都必须放在`<uni-forms-item>`组件中,且一个`<uni-forms-item>`组件只能放置一个表单项。
`<uni-forms-item>`组件内部预留了显示error message的区域,默认是在表单项的底部。
另外,`<uni-forms>`组件下面的各个表单项,可以通过`<uni-group>`包裹为不同的分组。同一`<uni-group>`下的不同表单项目将聚拢在一起,同其他group保持垂直间距。`<uni-group>`仅影响视觉效果。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-forms)
## Forms 表单
> **组件名:uni-forms**
> 代码块: `uForms`、`uni-forms-item`
> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。
uni-app的内置组件已经有了 `<form>`组件,用于提交表单内容。
然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 `<form>`组件封装了 `<uni-forms>`组件,内置了表单验证功能。
`<uni-forms>` 提供了 `rules`属性来描述校验规则、`<uni-forms-item>`子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。
每个要校验的表单项,不管input还是checkbox,都必须放在`<uni-forms-item>`组件中,且一个`<uni-forms-item>`组件只能放置一个表单项。
`<uni-forms-item>`组件内部预留了显示error message的区域,默认是在表单项的底部。
另外,`<uni-forms>`组件下面的各个表单项,可以通过`<uni-group>`包裹为不同的分组。同一`<uni-group>`下的不同表单项目将聚拢在一起,同其他group保持垂直间距。`<uni-group>`仅影响视觉效果。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-forms)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+18 -18
View File
@@ -1,18 +1,18 @@
## 1.2.1(2022-05-30)
- 新增 stat属性,是否开启uni统计功能
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-goods-nav](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
## 1.1.1(2021-08-24)
- 新增 支持国际化
## 1.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.7(2021-05-12)
- 新增 组件示例地址
## 1.0.6(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.5(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.4(2021-02-05)
- 调整为uni_modules目录规范
## 1.2.1(2022-05-30)
- 新增 stat属性,是否开启uni统计功能
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-goods-nav](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
## 1.1.1(2021-08-24)
- 新增 支持国际化
## 1.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.7(2021-05-12)
- 新增 组件示例地址
## 1.0.6(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.5(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.4(2021-02-05)
- 调整为uni_modules目录规范
@@ -1,6 +1,6 @@
{
"uni-goods-nav.options.shop": "shop",
"uni-goods-nav.options.cart": "cart",
"uni-goods-nav.buttonGroup.addToCart": "add to cart",
"uni-goods-nav.buttonGroup.buyNow": "buy now"
}
{
"uni-goods-nav.options.shop": "shop",
"uni-goods-nav.options.cart": "cart",
"uni-goods-nav.buttonGroup.addToCart": "add to cart",
"uni-goods-nav.buttonGroup.buyNow": "buy now"
}
@@ -1,8 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}
@@ -1,6 +1,6 @@
{
"uni-goods-nav.options.shop": "店铺",
"uni-goods-nav.options.cart": "购物车",
"uni-goods-nav.buttonGroup.addToCart": "加入购物车",
"uni-goods-nav.buttonGroup.buyNow": "立即购买"
}
{
"uni-goods-nav.options.shop": "店铺",
"uni-goods-nav.options.cart": "购物车",
"uni-goods-nav.buttonGroup.addToCart": "加入购物车",
"uni-goods-nav.buttonGroup.buyNow": "立即购买"
}
@@ -1,6 +1,6 @@
{
"uni-goods-nav.options.shop": "店鋪",
"uni-goods-nav.options.cart": "購物車",
"uni-goods-nav.buttonGroup.addToCart": "加入購物車",
"uni-goods-nav.buttonGroup.buyNow": "立即購買"
}
{
"uni-goods-nav.options.shop": "店鋪",
"uni-goods-nav.options.cart": "購物車",
"uni-goods-nav.buttonGroup.addToCart": "加入購物車",
"uni-goods-nav.buttonGroup.buyNow": "立即購買"
}
@@ -1,229 +1,229 @@
<template>
<view class="uni-goods-nav">
<!-- 底部占位 -->
<view class="uni-tab__seat" />
<view class="uni-tab__cart-box flex">
<view class="flex uni-tab__cart-sub-left">
<view v-for="(item,index) in options" :key="index" class="flex uni-tab__cart-button-left uni-tab__shop-cart" @click="onClick(index,item)">
<view class="uni-tab__icon">
<uni-icons :type="item.icon" size="20" color="#646566"></uni-icons>
<!-- <image class="image" :src="item.icon" mode="widthFix" /> -->
</view>
<text class="uni-tab__text">{{ item.text }}</text>
<view class="flex uni-tab__dot-box">
<text v-if="item.info" :class="{ 'uni-tab__dots': item.info > 9 }" class="uni-tab__dot " :style="{'backgroundColor':item.infoBackgroundColor?item.infoBackgroundColor:'#ff0000',
color:item.infoColor?item.infoColor:'#fff'
}">{{ item.info }}</text>
</view>
</view>
</view>
<view :class="{'uni-tab__right':fill}" class="flex uni-tab__cart-sub-right ">
<view v-for="(item,index) in buttonGroup" :key="index" :style="{background:item.backgroundColor,color:item.color}"
class="flex uni-tab__cart-button-right" @click="buttonClick(index,item)"><text :style="{color:item.color}" class="uni-tab__cart-button-right-text">{{ item.text }}</text></view>
</view>
</view>
</view>
</template>
<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const { t } = initVueI18n(messages)
/**
* GoodsNav 商品导航
* @description 商品加入购物车、立即购买等
* @tutorial https://ext.dcloud.net.cn/plugin?id=865
* @property {Array} options 组件参数
* @property {Array} buttonGroup 组件按钮组参数
* @property {Boolean} fill = [true | false] 组件按钮组参数
* @property {Boolean} stat 是否开启统计功能
* @event {Function} click 左侧点击事件
* @event {Function} buttonClick 右侧按钮组点击事件
* @example <uni-goods-nav :fill="true" options="" buttonGroup="buttonGroup" @click="" @buttonClick="" />
*/
export default {
name: 'UniGoodsNav',
emits:['click','buttonClick'],
props: {
options: {
type: Array,
default () {
return [{
icon: 'shop',
text: t("uni-goods-nav.options.shop"),
}, {
icon: 'cart',
text: t("uni-goods-nav.options.cart")
}]
}
},
buttonGroup: {
type: Array,
default () {
return [{
text: t("uni-goods-nav.buttonGroup.addToCart"),
backgroundColor: 'linear-gradient(90deg, #FFCD1E, #FF8A18)',
color: '#fff'
},
{
text: t("uni-goods-nav.buttonGroup.buyNow"),
backgroundColor: 'linear-gradient(90deg, #FE6035, #EF1224)',
color: '#fff'
}
]
}
},
fill: {
type: Boolean,
default: false
},
stat:{
type: Boolean,
default: false
}
},
methods: {
onClick(index, item) {
this.$emit('click', {
index,
content: item,
})
},
buttonClick(index, item) {
if (uni.report && this.stat) {
uni.report(item.text, item.text)
}
this.$emit('buttonClick', {
index,
content: item
})
}
}
}
</script>
<style lang="scss" >
.flex {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-goods-nav {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
}
.uni-tab__cart-box {
flex: 1;
height: 50px;
background-color: #fff;
z-index: 900;
}
.uni-tab__cart-sub-left {
padding: 0 5px;
}
.uni-tab__cart-sub-right {
flex: 1;
}
.uni-tab__right {
margin: 5px 0;
margin-right: 10px;
border-radius: 100px;
overflow: hidden;
}
.uni-tab__cart-button-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// flex: 1;
position: relative;
justify-content: center;
align-items: center;
flex-direction: column;
margin: 0 10px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-tab__icon {
width: 18px;
height: 18px;
}
.image {
width: 18px;
height: 18px;
}
.uni-tab__text {
margin-top: 3px;
font-size: 12px;
color: #646566;
}
.uni-tab__cart-button-right {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: column;
/* #endif */
flex: 1;
justify-content: center;
align-items: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-tab__cart-button-right-text {
font-size: 14px;
color: #fff;
}
.uni-tab__cart-button-right:active {
opacity: 0.7;
}
.uni-tab__dot-box {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: column;
/* #endif */
position: absolute;
right: -2px;
top: 2px;
justify-content: center;
align-items: center;
// width: 0;
// height: 0;
}
.uni-tab__dot {
// width: 30rpx;
// height: 30rpx;
padding: 0 4px;
line-height: 15px;
color: #ffffff;
text-align: center;
font-size: 12px;
background-color: #ff0000;
border-radius: 15px;
}
.uni-tab__dots {
padding: 0 4px;
// width: auto;
border-radius: 15px;
}
</style>
<template>
<view class="uni-goods-nav">
<!-- 底部占位 -->
<view class="uni-tab__seat" />
<view class="uni-tab__cart-box flex">
<view class="flex uni-tab__cart-sub-left">
<view v-for="(item,index) in options" :key="index" class="flex uni-tab__cart-button-left uni-tab__shop-cart" @click="onClick(index,item)">
<view class="uni-tab__icon">
<uni-icons :type="item.icon" size="20" color="#646566"></uni-icons>
<!-- <image class="image" :src="item.icon" mode="widthFix" /> -->
</view>
<text class="uni-tab__text">{{ item.text }}</text>
<view class="flex uni-tab__dot-box">
<text v-if="item.info" :class="{ 'uni-tab__dots': item.info > 9 }" class="uni-tab__dot " :style="{'backgroundColor':item.infoBackgroundColor?item.infoBackgroundColor:'#ff0000',
color:item.infoColor?item.infoColor:'#fff'
}">{{ item.info }}</text>
</view>
</view>
</view>
<view :class="{'uni-tab__right':fill}" class="flex uni-tab__cart-sub-right ">
<view v-for="(item,index) in buttonGroup" :key="index" :style="{background:item.backgroundColor,color:item.color}"
class="flex uni-tab__cart-button-right" @click="buttonClick(index,item)"><text :style="{color:item.color}" class="uni-tab__cart-button-right-text">{{ item.text }}</text></view>
</view>
</view>
</view>
</template>
<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const { t } = initVueI18n(messages)
/**
* GoodsNav 商品导航
* @description 商品加入购物车、立即购买等
* @tutorial https://ext.dcloud.net.cn/plugin?id=865
* @property {Array} options 组件参数
* @property {Array} buttonGroup 组件按钮组参数
* @property {Boolean} fill = [true | false] 组件按钮组参数
* @property {Boolean} stat 是否开启统计功能
* @event {Function} click 左侧点击事件
* @event {Function} buttonClick 右侧按钮组点击事件
* @example <uni-goods-nav :fill="true" options="" buttonGroup="buttonGroup" @click="" @buttonClick="" />
*/
export default {
name: 'UniGoodsNav',
emits:['click','buttonClick'],
props: {
options: {
type: Array,
default () {
return [{
icon: 'shop',
text: t("uni-goods-nav.options.shop"),
}, {
icon: 'cart',
text: t("uni-goods-nav.options.cart")
}]
}
},
buttonGroup: {
type: Array,
default () {
return [{
text: t("uni-goods-nav.buttonGroup.addToCart"),
backgroundColor: 'linear-gradient(90deg, #FFCD1E, #FF8A18)',
color: '#fff'
},
{
text: t("uni-goods-nav.buttonGroup.buyNow"),
backgroundColor: 'linear-gradient(90deg, #FE6035, #EF1224)',
color: '#fff'
}
]
}
},
fill: {
type: Boolean,
default: false
},
stat:{
type: Boolean,
default: false
}
},
methods: {
onClick(index, item) {
this.$emit('click', {
index,
content: item,
})
},
buttonClick(index, item) {
if (uni.report && this.stat) {
uni.report(item.text, item.text)
}
this.$emit('buttonClick', {
index,
content: item
})
}
}
}
</script>
<style lang="scss" >
.flex {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-goods-nav {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
}
.uni-tab__cart-box {
flex: 1;
height: 50px;
background-color: #fff;
z-index: 900;
}
.uni-tab__cart-sub-left {
padding: 0 5px;
}
.uni-tab__cart-sub-right {
flex: 1;
}
.uni-tab__right {
margin: 5px 0;
margin-right: 10px;
border-radius: 100px;
overflow: hidden;
}
.uni-tab__cart-button-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// flex: 1;
position: relative;
justify-content: center;
align-items: center;
flex-direction: column;
margin: 0 10px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-tab__icon {
width: 18px;
height: 18px;
}
.image {
width: 18px;
height: 18px;
}
.uni-tab__text {
margin-top: 3px;
font-size: 12px;
color: #646566;
}
.uni-tab__cart-button-right {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: column;
/* #endif */
flex: 1;
justify-content: center;
align-items: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-tab__cart-button-right-text {
font-size: 14px;
color: #fff;
}
.uni-tab__cart-button-right:active {
opacity: 0.7;
}
.uni-tab__dot-box {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: column;
/* #endif */
position: absolute;
right: -2px;
top: 2px;
justify-content: center;
align-items: center;
// width: 0;
// height: 0;
}
.uni-tab__dot {
// width: 30rpx;
// height: 30rpx;
padding: 0 4px;
line-height: 15px;
color: #ffffff;
text-align: center;
font-size: 12px;
background-color: #ff0000;
border-radius: 15px;
}
.uni-tab__dots {
padding: 0 4px;
// width: auto;
border-radius: 15px;
}
</style>
+88 -88
View File
@@ -1,88 +1,88 @@
{
"id": "uni-goods-nav",
"displayName": "uni-goods-nav 商品导航",
"version": "1.2.1",
"description": "商品导航组件主要用于电商类应用底部导航,可自定义加入购物车,购买等操作",
"keywords": [
"uni-ui",
"uniui",
"商品导航"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
{
"id": "uni-goods-nav",
"displayName": "uni-goods-nav 商品导航",
"version": "1.2.1",
"description": "商品导航组件主要用于电商类应用底部导航,可自定义加入购物车,购买等操作",
"keywords": [
"uni-ui",
"uniui",
"商品导航"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+9 -9
View File
@@ -1,10 +1,10 @@
## GoodsNav 商品导航
> **组件名:uni-goods-nav**
> 代码块: `uGoodsNav`
商品加入购物车,立即购买等。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
## GoodsNav 商品导航
> **组件名:uni-goods-nav**
> 代码块: `uGoodsNav`
商品加入购物车,立即购买等。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+13 -13
View File
@@ -1,13 +1,13 @@
## 1.4.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-grid](https://uniapp.dcloud.io/component/uniui/uni-grid)
## 1.3.2(2021-11-09)
- 新增 提供组件设计资源,组件样式调整
## 1.3.1(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.3.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.2.4(2021-05-12)
- 新增 组件示例地址
## 1.2.3(2021-02-05)
- 调整为uni_modules目录规范
## 1.4.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-grid](https://uniapp.dcloud.io/component/uniui/uni-grid)
## 1.3.2(2021-11-09)
- 新增 提供组件设计资源,组件样式调整
## 1.3.1(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.3.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.2.4(2021-05-12)
- 新增 组件示例地址
## 1.2.3(2021-02-05)
- 调整为uni_modules目录规范
@@ -1,140 +1,140 @@
<template>
<view
:style="'width:' + width + ';' + (square ? 'height:' + width : '')"
class="uni-grid-item grid-item"
>
<view
:class="{
'uni-grid-item--border': showBorder,
'uni-grid-item--border-top': showBorder && index < column,
'uni-highlight': highlight
}"
:style="{
'border-right-color': borderColor,
'border-bottom-color': borderColor,
'border-top-color': borderColor
}"
class="uni-grid-item__box"
@click="_onClick"
>
<slot />
</view>
</view>
</template>
<script>
/**
* GridItem 宫格
* @description 宫格组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=27
* @property {Number} index 子组件的唯一标识 ,点击gird会返回当前的标识
*/
export default {
name: 'UniGridItem',
inject: ['grid'],
props: {
index: {
type: Number,
default: 0
}
},
data() {
return {
column: 0,
showBorder: true,
square: true,
highlight: true,
left: 0,
top: 0,
openNum: 2,
width: 0,
borderColor: '#e5e5e5'
};
},
created() {
this.column = this.grid.column;
this.showBorder = this.grid.showBorder;
this.square = this.grid.square;
this.highlight = this.grid.highlight;
this.top = this.hor === 0 ? this.grid.hor : this.hor;
this.left = this.ver === 0 ? this.grid.ver : this.ver;
this.borderColor = this.grid.borderColor;
this.grid.children.push(this);
// this.grid.init()
this.width = this.grid.width;
},
beforeDestroy() {
this.grid.children.forEach((item, index) => {
if (item === this) {
this.grid.children.splice(index, 1);
}
});
},
methods: {
_onClick() {
this.grid.change({
detail: {
index: this.index
}
});
}
}
};
</script>
<style lang="scss" scoped>
.uni-grid-item {
/* #ifndef APP-NVUE */
height: 100%;
display: flex;
/* #endif */
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-grid-item__box {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
/* #endif */
position: relative;
flex: 1;
flex-direction: column;
// justify-content: center;
// align-items: center;
}
.uni-grid-item--border {
position: relative;
/* #ifdef APP-NVUE */
border-bottom-color: #d2d2d2;
border-bottom-style: solid;
border-bottom-width: 0.5px;
border-right-color: #d2d2d2;
border-right-style: solid;
border-right-width: 0.5px;
/* #endif */
/* #ifndef APP-NVUE */
z-index: 0;
border-bottom: 1px #d2d2d2 solid;
border-right: 1px #d2d2d2 solid;
/* #endif */
}
.uni-grid-item--border-top {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: #d2d2d2;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
/* #ifndef APP-NVUE */
border-top: 1px #d2d2d2 solid;
z-index: 0;
/* #endif */
}
.uni-highlight:active {
background-color: #f1f1f1;
}
</style>
<template>
<view
:style="'width:' + width + ';' + (square ? 'height:' + width : '')"
class="uni-grid-item grid-item"
>
<view
:class="{
'uni-grid-item--border': showBorder,
'uni-grid-item--border-top': showBorder && index < column,
'uni-highlight': highlight
}"
:style="{
'border-right-color': borderColor,
'border-bottom-color': borderColor,
'border-top-color': borderColor
}"
class="uni-grid-item__box"
@click="_onClick"
>
<slot />
</view>
</view>
</template>
<script>
/**
* GridItem 宫格
* @description 宫格组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=27
* @property {Number} index 子组件的唯一标识 ,点击gird会返回当前的标识
*/
export default {
name: 'UniGridItem',
inject: ['grid'],
props: {
index: {
type: Number,
default: 0
}
},
data() {
return {
column: 0,
showBorder: true,
square: true,
highlight: true,
left: 0,
top: 0,
openNum: 2,
width: 0,
borderColor: '#e5e5e5'
};
},
created() {
this.column = this.grid.column;
this.showBorder = this.grid.showBorder;
this.square = this.grid.square;
this.highlight = this.grid.highlight;
this.top = this.hor === 0 ? this.grid.hor : this.hor;
this.left = this.ver === 0 ? this.grid.ver : this.ver;
this.borderColor = this.grid.borderColor;
this.grid.children.push(this);
// this.grid.init()
this.width = this.grid.width;
},
beforeDestroy() {
this.grid.children.forEach((item, index) => {
if (item === this) {
this.grid.children.splice(index, 1);
}
});
},
methods: {
_onClick() {
this.grid.change({
detail: {
index: this.index
}
});
}
}
};
</script>
<style lang="scss" scoped>
.uni-grid-item {
/* #ifndef APP-NVUE */
height: 100%;
display: flex;
/* #endif */
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-grid-item__box {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
/* #endif */
position: relative;
flex: 1;
flex-direction: column;
// justify-content: center;
// align-items: center;
}
.uni-grid-item--border {
position: relative;
/* #ifdef APP-NVUE */
border-bottom-color: #d2d2d2;
border-bottom-style: solid;
border-bottom-width: 0.5px;
border-right-color: #d2d2d2;
border-right-style: solid;
border-right-width: 0.5px;
/* #endif */
/* #ifndef APP-NVUE */
z-index: 0;
border-bottom: 1px #d2d2d2 solid;
border-right: 1px #d2d2d2 solid;
/* #endif */
}
.uni-grid-item--border-top {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: #d2d2d2;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
/* #ifndef APP-NVUE */
border-top: 1px #d2d2d2 solid;
z-index: 0;
/* #endif */
}
.uni-highlight:active {
background-color: #f1f1f1;
}
</style>
@@ -1,142 +1,142 @@
<template>
<view class="uni-grid-wrap">
<view :id="elId" ref="uni-grid" class="uni-grid" :class="{ 'uni-grid--border': showBorder }" :style="{ 'border-left-color':borderColor}">
<slot />
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
/**
* Grid 宫格
* @description 宫格组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=27
* @property {Number} column 每列显示个数
* @property {String} borderColor 边框颜色
* @property {Boolean} showBorder 是否显示边框
* @property {Boolean} square 是否方形显示
* @property {Boolean} Boolean 点击背景是否高亮
* @event {Function} change 点击 grid 触发,e={detail:{index:0}},index 为当前点击 gird 下标
*/
export default {
name: 'UniGrid',
emits:['change'],
props: {
// 每列显示个数
column: {
type: Number,
default: 3
},
// 是否显示边框
showBorder: {
type: Boolean,
default: true
},
// 边框颜色
borderColor: {
type: String,
default: '#D2D2D2'
},
// 是否正方形显示,默认为 true
square: {
type: Boolean,
default: true
},
highlight: {
type: Boolean,
default: true
}
},
provide() {
return {
grid: this
}
},
data() {
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
elId,
width: 0
}
},
created() {
this.children = []
},
mounted() {
this.$nextTick(()=>{
this.init()
})
},
methods: {
init() {
setTimeout(() => {
this._getSize((width) => {
this.children.forEach((item, index) => {
item.width = width
})
})
}, 50)
},
change(e) {
this.$emit('change', e)
},
_getSize(fn) {
// #ifndef APP-NVUE
uni.createSelectorQuery()
.in(this)
.select(`#${this.elId}`)
.boundingClientRect()
.exec(ret => {
this.width = parseInt((ret[0].width - 1) / this.column) + 'px'
fn(this.width)
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['uni-grid'], (ret) => {
this.width = parseInt((ret.size.width - 1) / this.column) + 'px'
fn(this.width)
})
// #endif
}
}
}
</script>
<style lang="scss" scoped>
.uni-grid-wrap {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: column;
/* #ifdef H5 */
width: 100%;
/* #endif */
}
.uni-grid {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// flex: 1;
flex-direction: row;
flex-wrap: wrap;
}
.uni-grid--border {
position: relative;
/* #ifdef APP-NVUE */
border-left-color: #D2D2D2;
border-left-style: solid;
border-left-width: 0.5px;
/* #endif */
/* #ifndef APP-NVUE */
z-index: 1;
border-left: 1px #D2D2D2 solid;
/* #endif */
}
</style>
<template>
<view class="uni-grid-wrap">
<view :id="elId" ref="uni-grid" class="uni-grid" :class="{ 'uni-grid--border': showBorder }" :style="{ 'border-left-color':borderColor}">
<slot />
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
/**
* Grid 宫格
* @description 宫格组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=27
* @property {Number} column 每列显示个数
* @property {String} borderColor 边框颜色
* @property {Boolean} showBorder 是否显示边框
* @property {Boolean} square 是否方形显示
* @property {Boolean} Boolean 点击背景是否高亮
* @event {Function} change 点击 grid 触发,e={detail:{index:0}},index 为当前点击 gird 下标
*/
export default {
name: 'UniGrid',
emits:['change'],
props: {
// 每列显示个数
column: {
type: Number,
default: 3
},
// 是否显示边框
showBorder: {
type: Boolean,
default: true
},
// 边框颜色
borderColor: {
type: String,
default: '#D2D2D2'
},
// 是否正方形显示,默认为 true
square: {
type: Boolean,
default: true
},
highlight: {
type: Boolean,
default: true
}
},
provide() {
return {
grid: this
}
},
data() {
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
elId,
width: 0
}
},
created() {
this.children = []
},
mounted() {
this.$nextTick(()=>{
this.init()
})
},
methods: {
init() {
setTimeout(() => {
this._getSize((width) => {
this.children.forEach((item, index) => {
item.width = width
})
})
}, 50)
},
change(e) {
this.$emit('change', e)
},
_getSize(fn) {
// #ifndef APP-NVUE
uni.createSelectorQuery()
.in(this)
.select(`#${this.elId}`)
.boundingClientRect()
.exec(ret => {
this.width = parseInt((ret[0].width - 1) / this.column) + 'px'
fn(this.width)
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['uni-grid'], (ret) => {
this.width = parseInt((ret.size.width - 1) / this.column) + 'px'
fn(this.width)
})
// #endif
}
}
}
</script>
<style lang="scss" scoped>
.uni-grid-wrap {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: column;
/* #ifdef H5 */
width: 100%;
/* #endif */
}
.uni-grid {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// flex: 1;
flex-direction: row;
flex-wrap: wrap;
}
.uni-grid--border {
position: relative;
/* #ifdef APP-NVUE */
border-left-color: #D2D2D2;
border-left-style: solid;
border-left-width: 0.5px;
/* #endif */
/* #ifndef APP-NVUE */
z-index: 1;
border-left: 1px #D2D2D2 solid;
/* #endif */
}
</style>
+86 -86
View File
@@ -1,86 +1,86 @@
{
"id": "uni-grid",
"displayName": "uni-grid 宫格",
"version": "1.4.0",
"description": "Grid 宫格组件,提供移动端常见的宫格布局,如九宫格。",
"keywords": [
"uni-ui",
"uniui",
"九宫格",
"表格"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss","uni-icons"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
{
"id": "uni-grid",
"displayName": "uni-grid 宫格",
"version": "1.4.0",
"description": "Grid 宫格组件,提供移动端常见的宫格布局,如九宫格。",
"keywords": [
"uni-ui",
"uniui",
"九宫格",
"表格"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss","uni-icons"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+10 -10
View File
@@ -1,11 +1,11 @@
## Grid 宫格
> **组件名:uni-grid**
> 代码块: `uGrid`
宫格组件。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-grid)
## Grid 宫格
> **组件名:uni-grid**
> 代码块: `uGrid`
宫格组件。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-grid)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+16 -16
View File
@@ -1,16 +1,16 @@
## 1.2.2(2022-05-30)
- 新增 stat属性,是否开启uni统计功能
## 1.2.1(2021-11-22)
- 修复 vue3中某些scss变量无法找到的问题
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-group](https://uniapp.dcloud.io/component/uniui/uni-group)
## 1.1.7(2021-11-08)
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
- 优化 组件文档
## 1.0.3(2021-05-12)
- 新增 组件示例地址
## 1.0.2(2021-02-05)
- 调整为uni_modules目录规范
- 优化 兼容 nvue 页面
## 1.2.2(2022-05-30)
- 新增 stat属性,是否开启uni统计功能
## 1.2.1(2021-11-22)
- 修复 vue3中某些scss变量无法找到的问题
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-group](https://uniapp.dcloud.io/component/uniui/uni-group)
## 1.1.7(2021-11-08)
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
- 优化 组件文档
## 1.0.3(2021-05-12)
- 新增 组件示例地址
## 1.0.2(2021-02-05)
- 调整为uni_modules目录规范
- 优化 兼容 nvue 页面
@@ -1,134 +1,134 @@
<template>
<view class="uni-group" :class="['uni-group--'+mode ,margin?'group-margin':'']" :style="{marginTop: `${top}px` }">
<slot name="title">
<view v-if="title" class="uni-group__title" :style="{'padding-left':border?'30px':'15px'}">
<text class="uni-group__title-text">{{ title }}</text>
</view>
</slot>
<view class="uni-group__content" :class="{'group-conent-padding':border}">
<slot />
</view>
</view>
</template>
<script>
/**
* Group 分组
* @description 表单字段分组
* @tutorial https://ext.dcloud.net.cn/plugin?id=3281
* @property {String} title 主标题
* @property {Number} top 分组间隔
* @property {Number} mode 模式
*/
export default {
name: 'uniGroup',
emits:['click'],
props: {
title: {
type: String,
default: ''
},
top: {
type: [Number, String],
default: 10
},
mode: {
type: String,
default: 'default'
},
stat:{
type: Boolean,
default: false
}
},
data() {
return {
margin: false,
border: false
}
},
watch: {
title(newVal) {
if (uni.report && this.stat && newVal !== '') {
uni.report('title', newVal)
}
}
},
created() {
this.form = this.getForm()
if (this.form) {
this.margin = true
this.border = this.form.border
}
},
methods: {
/**
* 获取父元素实例
*/
getForm() {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== 'uniForms') {
parent = parent.$parent;
if (!parent) return false
parentName = parent.$options.name;
}
return parent;
},
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" >
.uni-group {
background: #fff;
margin-top: 10px;
// border: 1px red solid;
}
.group-margin {
// margin: 0 -15px;
}
.uni-group__title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding-left: 15px;
height: 40px;
background-color: #eee;
font-weight: normal;
color: #666;
}
.uni-group__content {
padding: 15px;
// padding-bottom: 5px;
// background-color: #FFF;
}
.group-conent-padding {
padding: 0 15px;
}
.uni-group__title-text {
font-size: 14px;
color: #666;
}
.distraction {
flex-direction: row;
align-items: center;
}
.uni-group--card {
margin: 10px;
border-radius: 5px;
overflow: hidden;
box-shadow: 0 0 5px 1px rgba($color: #000000, $alpha: 0.08);
}
</style>
<template>
<view class="uni-group" :class="['uni-group--'+mode ,margin?'group-margin':'']" :style="{marginTop: `${top}px` }">
<slot name="title">
<view v-if="title" class="uni-group__title" :style="{'padding-left':border?'30px':'15px'}">
<text class="uni-group__title-text">{{ title }}</text>
</view>
</slot>
<view class="uni-group__content" :class="{'group-conent-padding':border}">
<slot />
</view>
</view>
</template>
<script>
/**
* Group 分组
* @description 表单字段分组
* @tutorial https://ext.dcloud.net.cn/plugin?id=3281
* @property {String} title 主标题
* @property {Number} top 分组间隔
* @property {Number} mode 模式
*/
export default {
name: 'uniGroup',
emits:['click'],
props: {
title: {
type: String,
default: ''
},
top: {
type: [Number, String],
default: 10
},
mode: {
type: String,
default: 'default'
},
stat:{
type: Boolean,
default: false
}
},
data() {
return {
margin: false,
border: false
}
},
watch: {
title(newVal) {
if (uni.report && this.stat && newVal !== '') {
uni.report('title', newVal)
}
}
},
created() {
this.form = this.getForm()
if (this.form) {
this.margin = true
this.border = this.form.border
}
},
methods: {
/**
* 获取父元素实例
*/
getForm() {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== 'uniForms') {
parent = parent.$parent;
if (!parent) return false
parentName = parent.$options.name;
}
return parent;
},
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" >
.uni-group {
background: #fff;
margin-top: 10px;
// border: 1px red solid;
}
.group-margin {
// margin: 0 -15px;
}
.uni-group__title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding-left: 15px;
height: 40px;
background-color: #eee;
font-weight: normal;
color: #666;
}
.uni-group__content {
padding: 15px;
// padding-bottom: 5px;
// background-color: #FFF;
}
.group-conent-padding {
padding: 0 15px;
}
.uni-group__title-text {
font-size: 14px;
color: #666;
}
.distraction {
flex-direction: row;
align-items: center;
}
.uni-group--card {
margin: 10px;
border-radius: 5px;
overflow: hidden;
box-shadow: 0 0 5px 1px rgba($color: #000000, $alpha: 0.08);
}
</style>
+86 -86
View File
@@ -1,87 +1,87 @@
{
"id": "uni-group",
"displayName": "uni-group 分组",
"version": "1.2.2",
"description": "分组组件可用于将组件用于分组,添加间隔,以产生明显的区块",
"keywords": [
"uni-ui",
"uniui",
"group",
"分组",
""
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-group",
"displayName": "uni-group 分组",
"version": "1.2.2",
"description": "分组组件可用于将组件用于分组,添加间隔,以产生明显的区块",
"keywords": [
"uni-ui",
"uniui",
"group",
"分组",
""
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+8 -8
View File
@@ -1,9 +1,9 @@
## Group 分组
> **组件名:uni-group**
> 代码块: `uGroup`
分组组件可用于将组件分组,添加间隔,以产生明显的区块。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-group)
## Group 分组
> **组件名:uni-group**
> 代码块: `uGroup`
分组组件可用于将组件分组,添加间隔,以产生明显的区块。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-group)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+22 -22
View File
@@ -1,22 +1,22 @@
## 1.3.5(2022-01-24)
- 优化 size 属性可以传入不带单位的字符串数值
## 1.3.4(2022-01-24)
- 优化 size 支持其他单位
## 1.3.3(2022-01-17)
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
## 1.3.2(2021-12-01)
- 优化 示例可复制图标名称
## 1.3.1(2021-11-23)
- 优化 兼容旧组件 type 值
## 1.3.0(2021-11-19)
- 新增 更多图标
- 优化 自定义图标使用方式
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
## 1.1.7(2021-11-08)
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.5(2021-05-12)
- 新增 组件示例地址
## 1.1.4(2021-02-05)
- 调整为uni_modules目录规范
## 1.3.5(2022-01-24)
- 优化 size 属性可以传入不带单位的字符串数值
## 1.3.4(2022-01-24)
- 优化 size 支持其他单位
## 1.3.3(2022-01-17)
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
## 1.3.2(2021-12-01)
- 优化 示例可复制图标名称
## 1.3.1(2021-11-23)
- 优化 兼容旧组件 type 值
## 1.3.0(2021-11-19)
- 新增 更多图标
- 优化 自定义图标使用方式
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
## 1.1.7(2021-11-08)
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.5(2021-05-12)
- 新增 组件示例地址
## 1.1.4(2021-02-05)
- 调整为uni_modules目录规范
File diff suppressed because it is too large. Load diff
@@ -1,96 +1,96 @@
<template>
<!-- #ifdef APP-NVUE -->
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
<!-- #endif -->
</template>
<script>
import icons from './icons.js';
const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val) )? val + 'px' : val;
}
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './uniicons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('"+iconUrl+"')"
});
// #endif
/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'UniIcons',
emits:['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix:{
type: String,
default: ''
}
},
data() {
return {
icons: icons.glyphs
}
},
computed:{
unicode(){
let code = this.icons.find(v=>v.font_class === this.type)
if(code){
return unescape(`%u${code.unicode}`)
}
return ''
},
iconSize(){
return getVal(this.size)
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
@import './uniicons.css';
@font-face {
font-family: uniicons;
src: url('./uniicons.ttf') format('truetype');
}
/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>
<template>
<!-- #ifdef APP-NVUE -->
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
<!-- #endif -->
</template>
<script>
import icons from './icons.js';
const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val) )? val + 'px' : val;
}
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './uniicons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('"+iconUrl+"')"
});
// #endif
/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'UniIcons',
emits:['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix:{
type: String,
default: ''
}
},
data() {
return {
icons: icons.glyphs
}
},
computed:{
unicode(){
let code = this.icons.find(v=>v.font_class === this.type)
if(code){
return unescape(`%u${code.unicode}`)
}
return ''
},
iconSize(){
return getVal(this.size)
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
@import './uniicons.css';
@font-face {
font-family: uniicons;
src: url('./uniicons.ttf') format('truetype');
}
/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>
File diff suppressed because it is too large. Load diff
+85 -85
View File
@@ -1,86 +1,86 @@
{
"id": "uni-icons",
"displayName": "uni-icons 图标",
"version": "1.3.5",
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
"keywords": [
"uni-ui",
"uniui",
"icon",
"图标"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.2.14"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-icons",
"displayName": "uni-icons 图标",
"version": "1.3.5",
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
"keywords": [
"uni-ui",
"uniui",
"icon",
"图标"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.2.14"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+8 -8
View File
@@ -1,8 +1,8 @@
## Icons 图标
> **组件名:uni-icons**
> 代码块: `uIcons`
用于展示 icons 图标 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
## Icons 图标
> **组件名:uni-icons**
> 代码块: `uIcons`
用于展示 icons 图标 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+17 -17
View File
@@ -1,17 +1,17 @@
## 1.0.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-link](https://uniapp.dcloud.io/component/uniui/uni-link)
## 1.1.7(2021-11-08)
## 0.0.7(2021-09-03)
- 修复 在 nvue 下不显示的 bug
## 0.0.6(2021-07-30)
- 新增 支持自定义插槽
## 0.0.5(2021-06-21)
- 新增 download 属性,H5平台下载文件名
## 0.0.4(2021-05-12)
- 新增 组件示例地址
## 0.0.3(2021-03-09)
- 新增 href 属性支持 tel:|mailto:
## 0.0.2(2021-02-05)
- 调整为uni_modules目录规范
## 1.0.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-link](https://uniapp.dcloud.io/component/uniui/uni-link)
## 1.1.7(2021-11-08)
## 0.0.7(2021-09-03)
- 修复 在 nvue 下不显示的 bug
## 0.0.6(2021-07-30)
- 新增 支持自定义插槽
## 0.0.5(2021-06-21)
- 新增 download 属性,H5平台下载文件名
## 0.0.4(2021-05-12)
- 新增 组件示例地址
## 0.0.3(2021-03-09)
- 新增 href 属性支持 tel:|mailto:
## 0.0.2(2021-02-05)
- 调整为uni_modules目录规范
@@ -1,128 +1,128 @@
<template>
<a v-if="isShowA" class="uni-link" :href="href"
:class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" :download="download">
<slot>{{text}}</slot>
</a>
<!-- #ifndef APP-NVUE -->
<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" @click="openURL">
<slot>{{text}}</slot>
</text>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" @click="openURL">
{{text}}
</text>
<!-- #endif -->
</template>
<script>
/**
* Link 外部网页超链接组件
* @description uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页
* @tutorial https://ext.dcloud.net.cn/plugin?id=1182
* @property {String} href 点击后打开的外部网页url
* @property {String} text 显示的文字
* @property {String} downlaod H5平台下载文件名
* @property {Boolean} showUnderLine 是否显示下划线
* @property {String} copyTips 在小程序端复制链接时显示的提示语
* @property {String} color 链接文字颜色
* @property {String} fontSize 链接文字大小
* @example * <uni-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn"></uni-link>
*/
export default {
name: 'uniLink',
props: {
href: {
type: String,
default: ''
},
text: {
type: String,
default: ''
},
download: {
type: String,
default: ''
},
showUnderLine: {
type: [Boolean, String],
default: true
},
copyTips: {
type: String,
default: '已自动复制网址,请在手机浏览器里粘贴该网址'
},
color: {
type: String,
default: '#999999'
},
fontSize: {
type: [Number, String],
default: 14
}
},
computed: {
isShowA() {
// #ifdef H5
this._isH5 = true;
// #endif
if ((this.isMail() || this.isTel()) && this._isH5 === true) {
return true;
}
return false;
}
},
created() {
this._isH5 = null;
},
methods: {
isMail() {
return this.href.startsWith('mailto:');
},
isTel() {
return this.href.startsWith('tel:');
},
openURL() {
// #ifdef APP-PLUS
if (this.isTel()) {
this.makePhoneCall(this.href.replace('tel:', ''));
} else {
plus.runtime.openURL(this.href);
}
// #endif
// #ifdef H5
window.open(this.href)
// #endif
// #ifdef MP
uni.setClipboardData({
data: this.href
});
uni.showModal({
content: this.copyTips,
showCancel: false
});
// #endif
},
makePhoneCall(phoneNumber) {
uni.makePhoneCall({
phoneNumber
})
}
}
}
</script>
<style>
/* #ifndef APP-NVUE */
.uni-link {
cursor: pointer;
}
/* #endif */
.uni-link--withline {
text-decoration: underline;
}
</style>
<template>
<a v-if="isShowA" class="uni-link" :href="href"
:class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" :download="download">
<slot>{{text}}</slot>
</a>
<!-- #ifndef APP-NVUE -->
<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" @click="openURL">
<slot>{{text}}</slot>
</text>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
:style="{color,fontSize:fontSize+'px'}" @click="openURL">
{{text}}
</text>
<!-- #endif -->
</template>
<script>
/**
* Link 外部网页超链接组件
* @description uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页
* @tutorial https://ext.dcloud.net.cn/plugin?id=1182
* @property {String} href 点击后打开的外部网页url
* @property {String} text 显示的文字
* @property {String} downlaod H5平台下载文件名
* @property {Boolean} showUnderLine 是否显示下划线
* @property {String} copyTips 在小程序端复制链接时显示的提示语
* @property {String} color 链接文字颜色
* @property {String} fontSize 链接文字大小
* @example * <uni-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn"></uni-link>
*/
export default {
name: 'uniLink',
props: {
href: {
type: String,
default: ''
},
text: {
type: String,
default: ''
},
download: {
type: String,
default: ''
},
showUnderLine: {
type: [Boolean, String],
default: true
},
copyTips: {
type: String,
default: '已自动复制网址,请在手机浏览器里粘贴该网址'
},
color: {
type: String,
default: '#999999'
},
fontSize: {
type: [Number, String],
default: 14
}
},
computed: {
isShowA() {
// #ifdef H5
this._isH5 = true;
// #endif
if ((this.isMail() || this.isTel()) && this._isH5 === true) {
return true;
}
return false;
}
},
created() {
this._isH5 = null;
},
methods: {
isMail() {
return this.href.startsWith('mailto:');
},
isTel() {
return this.href.startsWith('tel:');
},
openURL() {
// #ifdef APP-PLUS
if (this.isTel()) {
this.makePhoneCall(this.href.replace('tel:', ''));
} else {
plus.runtime.openURL(this.href);
}
// #endif
// #ifdef H5
window.open(this.href)
// #endif
// #ifdef MP
uni.setClipboardData({
data: this.href
});
uni.showModal({
content: this.copyTips,
showCancel: false
});
// #endif
},
makePhoneCall(phoneNumber) {
uni.makePhoneCall({
phoneNumber
})
}
}
}
</script>
<style>
/* #ifndef APP-NVUE */
.uni-link {
cursor: pointer;
}
/* #endif */
.uni-link--withline {
text-decoration: underline;
}
</style>
+86 -86
View File
@@ -1,87 +1,87 @@
{
"id": "uni-link",
"displayName": "uni-link 超链接",
"version": "1.0.0",
"description": "uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打",
"keywords": [
"uni-ui",
"uniui",
"link",
"超链接",
""
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-link",
"displayName": "uni-link 超链接",
"version": "1.0.0",
"description": "uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打",
"keywords": [
"uni-ui",
"uniui",
"link",
"超链接",
""
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+10 -10
View File
@@ -1,11 +1,11 @@
## Link 链接
> **组件名:uni-link**
> 代码块: `uLink`
uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-link)
## Link 链接
> **组件名:uni-link**
> 代码块: `uLink`
uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-link)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+20 -20
View File
@@ -1,20 +1,20 @@
## 1.2.1(2022-03-30)
- 删除无用文件
## 1.2.0(2021-11-23)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-list](https://uniapp.dcloud.io/component/uniui/uni-list)
## 1.1.3(2021-08-30)
- 修复 在vue3中to属性在发行应用的时候报错的bug
## 1.1.2(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.1.1(2021-07-21)
- 修复 与其他组件嵌套使用时,点击失效的Bug
## 1.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.17(2021-05-12)
- 新增 组件示例地址
## 1.0.16(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.15(2021-02-05)
- 调整为uni_modules目录规范
- 修复 uni-list-chat 角标显示不正常的问题
## 1.2.1(2022-03-30)
- 删除无用文件
## 1.2.0(2021-11-23)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-list](https://uniapp.dcloud.io/component/uniui/uni-list)
## 1.1.3(2021-08-30)
- 修复 在vue3中to属性在发行应用的时候报错的bug
## 1.1.2(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.1.1(2021-07-21)
- 修复 与其他组件嵌套使用时,点击失效的Bug
## 1.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.17(2021-05-12)
- 新增 组件示例地址
## 1.0.16(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.15(2021-02-05)
- 调整为uni_modules目录规范
- 修复 uni-list-chat 角标显示不正常的问题
@@ -1,107 +1,107 @@
<template>
<!-- #ifdef APP-NVUE -->
<cell>
<!-- #endif -->
<view class="uni-list-ad">
<view v-if="borderShow" :class="{'uni-list--border':border,'uni-list-item--first':isFirstChild}"></view>
<ad style="width: 200px;height: 300px;border-width: 1px;border-color: red;border-style: solid;" adpid="1111111111"
unit-id="" appid="" apid="" type="feed" @error="aderror" @close="closeAd"></ad>
</view>
<!-- #ifdef APP-NVUE -->
</cell>
<!-- #endif -->
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
export default {
name: 'UniListAd',
props: {
title: {
type: String,
default: '',
}
},
// inject: ['list'],
data() {
return {
isFirstChild: false,
border: false,
borderShow: true,
}
},
mounted() {
this.list = this.getForm()
if (this.list) {
if (!this.list.firstChildAppend) {
this.list.firstChildAppend = true
this.isFirstChild = true
}
this.border = this.list.border
}
},
methods: {
/**
* 获取父元素实例
*/
getForm(name = 'uniList') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false
parentName = parent.$options.name;
}
return parent;
},
aderror(e) {
console.log("aderror: " + JSON.stringify(e.detail));
},
closeAd(e) {
this.borderShow = false
}
}
}
</script>
<style lang="scss" >
.uni-list-ad {
position: relative;
border: 1px red solid;
}
.uni-list--border {
position: relative;
padding-bottom: 1px;
/* #ifdef APP-PLUS */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
margin-left: $uni-spacing-row-lg;
}
/* #ifndef APP-NVUE */
.uni-list--border:after {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: $uni-border-color;
}
.uni-list-item--first:after {
height: 0px;
}
/* #endif */
</style>
<template>
<!-- #ifdef APP-NVUE -->
<cell>
<!-- #endif -->
<view class="uni-list-ad">
<view v-if="borderShow" :class="{'uni-list--border':border,'uni-list-item--first':isFirstChild}"></view>
<ad style="width: 200px;height: 300px;border-width: 1px;border-color: red;border-style: solid;" adpid="1111111111"
unit-id="" appid="" apid="" type="feed" @error="aderror" @close="closeAd"></ad>
</view>
<!-- #ifdef APP-NVUE -->
</cell>
<!-- #endif -->
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
export default {
name: 'UniListAd',
props: {
title: {
type: String,
default: '',
}
},
// inject: ['list'],
data() {
return {
isFirstChild: false,
border: false,
borderShow: true,
}
},
mounted() {
this.list = this.getForm()
if (this.list) {
if (!this.list.firstChildAppend) {
this.list.firstChildAppend = true
this.isFirstChild = true
}
this.border = this.list.border
}
},
methods: {
/**
* 获取父元素实例
*/
getForm(name = 'uniList') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false
parentName = parent.$options.name;
}
return parent;
},
aderror(e) {
console.log("aderror: " + JSON.stringify(e.detail));
},
closeAd(e) {
this.borderShow = false
}
}
}
</script>
<style lang="scss" >
.uni-list-ad {
position: relative;
border: 1px red solid;
}
.uni-list--border {
position: relative;
padding-bottom: 1px;
/* #ifdef APP-PLUS */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
margin-left: $uni-spacing-row-lg;
}
/* #ifndef APP-NVUE */
.uni-list--border:after {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: $uni-border-color;
}
.uni-list-item--first:after {
height: 0px;
}
/* #endif */
</style>
@@ -1,58 +1,58 @@
/**
* 这里是 uni-list 组件内置的常用样式变量
* 如果需要覆盖样式,这里提供了基本的组件样式变量,您可以尝试修改这里的变量,去完成样式替换,而不用去修改源码
*
*/
// 背景色
$background-color : #fff;
// 分割线颜色
$divide-line-color : #e5e5e5;
// 默认头像大小,如需要修改此值,注意同步修改 js 中的值 const avatarWidth = xx ,目前只支持方形头像
// nvue 页面不支持修改头像大小
$avatar-width : 45px ;
// 头像边框
$avatar-border-radius: 5px;
$avatar-border-color: #eee;
$avatar-border-width: 1px;
// 标题文字样式
$title-size : 16px;
$title-color : #3b4144;
$title-weight : normal;
// 描述文字样式
$note-size : 12px;
$note-color : #999;
$note-weight : normal;
// 右侧额外内容默认样式
$right-text-size : 12px;
$right-text-color : #999;
$right-text-weight : normal;
// 角标样式
// nvue 页面不支持修改圆点位置以及大小
// 角标在左侧时,角标的位置,默认为 0 ,负数左/下移动,正数右/上移动
$badge-left: 0px;
$badge-top: 0px;
// 显示圆点时,圆点大小
$dot-width: 10px;
$dot-height: 10px;
// 显示角标时,角标大小和字体大小
$badge-size : 18px;
$badge-font : 12px;
// 显示角标时,角标前景色
$badge-color : #fff;
// 显示角标时,角标背景色
$badge-background-color : #ff5a5f;
// 显示角标时,角标左右间距
$badge-space : 6px;
// 状态样式
// 选中颜色
$hover : #f5f5f5;
/**
* 这里是 uni-list 组件内置的常用样式变量
* 如果需要覆盖样式,这里提供了基本的组件样式变量,您可以尝试修改这里的变量,去完成样式替换,而不用去修改源码
*
*/
// 背景色
$background-color : #fff;
// 分割线颜色
$divide-line-color : #e5e5e5;
// 默认头像大小,如需要修改此值,注意同步修改 js 中的值 const avatarWidth = xx ,目前只支持方形头像
// nvue 页面不支持修改头像大小
$avatar-width : 45px ;
// 头像边框
$avatar-border-radius: 5px;
$avatar-border-color: #eee;
$avatar-border-width: 1px;
// 标题文字样式
$title-size : 16px;
$title-color : #3b4144;
$title-weight : normal;
// 描述文字样式
$note-size : 12px;
$note-color : #999;
$note-weight : normal;
// 右侧额外内容默认样式
$right-text-size : 12px;
$right-text-color : #999;
$right-text-weight : normal;
// 角标样式
// nvue 页面不支持修改圆点位置以及大小
// 角标在左侧时,角标的位置,默认为 0 ,负数左/下移动,正数右/上移动
$badge-left: 0px;
$badge-top: 0px;
// 显示圆点时,圆点大小
$dot-width: 10px;
$dot-height: 10px;
// 显示角标时,角标大小和字体大小
$badge-size : 18px;
$badge-font : 12px;
// 显示角标时,角标前景色
$badge-color : #fff;
// 显示角标时,角标背景色
$badge-background-color : #ff5a5f;
// 显示角标时,角标左右间距
$badge-space : 6px;
// 状态样式
// 选中颜色
$hover : #f5f5f5;
File diff suppressed because it is too large. Load diff
@@ -1,473 +1,473 @@
<template>
<!-- #ifdef APP-NVUE -->
<cell>
<!-- #endif -->
<view
:class="{ 'uni-list-item--disabled': disabled }"
:hover-class="(!clickable && !link) || disabled || showSwitch ? '' : 'uni-list-item--hover'"
class="uni-list-item"
@click="onClick"
>
<view v-if="!isFirstChild" class="border--left" :class="{ 'uni-list--border': border }"></view>
<view
class="uni-list-item__container"
:class="{ 'container--right': showArrow || link, 'flex--direction': direction === 'column' }"
>
<slot name="header">
<view class="uni-list-item__header">
<view v-if="thumb" class="uni-list-item__icon">
<image :src="thumb" class="uni-list-item__icon-img" :class="['uni-list--' + thumbSize]" />
</view>
<view v-else-if="showExtraIcon" class="uni-list-item__icon">
<uni-icons :color="extraIcon.color" :size="extraIcon.size" :type="extraIcon.type" />
</view>
</view>
</slot>
<slot name="body">
<view
class="uni-list-item__content"
:class="{ 'uni-list-item__content--center': thumb || showExtraIcon || showBadge || showSwitch }"
>
<text
v-if="title"
class="uni-list-item__content-title"
:class="[ellipsis !== 0 && ellipsis <= 2 ? 'uni-ellipsis-' + ellipsis : '']"
>
{{ title }}
</text>
<text v-if="note" class="uni-list-item__content-note">{{ note }}</text>
</view>
</slot>
<slot name="footer">
<view
v-if="rightText || showBadge || showSwitch"
class="uni-list-item__extra"
:class="{ 'flex--justify': direction === 'column' }"
>
<text v-if="rightText" class="uni-list-item__extra-text">{{ rightText }}</text>
<uni-badge v-if="showBadge" :type="badgeType" :text="badgeText" :custom-style="badgeStyle" />
<switch
v-if="showSwitch"
:disabled="disabled"
:checked="switchChecked"
@change="onSwitchChange"
/>
</view>
</slot>
</view>
<uni-icons v-if="showArrow || link" :size="16" class="uni-icon-wrapper" color="#bbb" type="arrowright" />
</view>
<!-- #ifdef APP-NVUE -->
</cell>
<!-- #endif -->
</template>
<script>
/**
* ListItem 列表子组件
* @description 列表子组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
* @property {String} title 标题
* @property {String} note 描述
* @property {String} thumb 左侧缩略图,若thumb有值,则不会显示扩展图标
* @property {String} thumbSize = [lg|base|sm] 略缩图大小
* @value lg 大图
* @value base 一般
* @value sm 小图
* @property {String} badgeText 数字角标内容
* @property {String} badgeType 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)
* @property {Object} badgeStyle 数字角标样式
* @property {String} rightText 右侧文字内容
* @property {Boolean} disabled = [true|false] 是否禁用
* @property {Boolean} clickable = [true|false] 是否开启点击反馈
* @property {String} link = [navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈
* @value navigateTo 同 uni.navigateTo()
* @value redirectTo 同 uni.redirectTo()
* @value reLaunch 同 uni.reLaunch()
* @value switchTab 同 uni.switchTab()
* @property {String | PageURIString} to 跳转目标页面
* @property {Boolean} showBadge = [true|false] 是否显示数字角标
* @property {Boolean} showSwitch = [true|false] 是否显示Switch
* @property {Boolean} switchChecked = [true|false] Switch是否被选中
* @property {Boolean} showExtraIcon = [true|false] 左侧是否显示扩展图标
* @property {Object} extraIcon 扩展图标参数,格式为 {color: '#4cd964',size: '22',type: 'spinner'}
* @property {String} direction = [row|column] 排版方向
* @value row 水平排列
* @value column 垂直排列
* @event {Function} click 点击 uniListItem 触发事件
* @event {Function} switchChange 点击切换 Switch 时触发
*/
export default {
name: 'UniListItem',
emits: ['click', 'switchChange'],
props: {
direction: {
type: String,
default: 'row'
},
title: {
type: String,
default: ''
},
note: {
type: String,
default: ''
},
ellipsis: {
type: [Number, String],
default: 0
},
disabled: {
type: [Boolean, String],
default: false
},
clickable: {
type: Boolean,
default: false
},
showArrow: {
type: [Boolean, String],
default: false
},
link: {
type: [Boolean, String],
default: false
},
to: {
type: String,
default: ''
},
showBadge: {
type: [Boolean, String],
default: false
},
showSwitch: {
type: [Boolean, String],
default: false
},
switchChecked: {
type: [Boolean, String],
default: false
},
badgeText: {
type: String,
default: ''
},
badgeType: {
type: String,
default: 'success'
},
badgeStyle: {
type: Object,
default() {
return {};
}
},
rightText: {
type: String,
default: ''
},
thumb: {
type: String,
default: ''
},
thumbSize: {
type: String,
default: 'base'
},
showExtraIcon: {
type: [Boolean, String],
default: false
},
extraIcon: {
type: Object,
default() {
return {
type: '',
color: '#000000',
size: 20
};
}
},
border: {
type: Boolean,
default: true
}
},
// inject: ['list'],
data() {
return {
isFirstChild: false
};
},
mounted() {
this.list = this.getForm();
// 判断是否存在 uni-list 组件
if (this.list) {
if (!this.list.firstChildAppend) {
this.list.firstChildAppend = true;
this.isFirstChild = true;
}
}
},
methods: {
/**
* 获取父元素实例
*/
getForm(name = 'uniList') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false;
parentName = parent.$options.name;
}
return parent;
},
onClick() {
if (this.to !== '') {
this.openPage();
return;
}
if (this.clickable || this.link) {
this.$emit('click', {
data: {}
});
}
},
onSwitchChange(e) {
this.$emit('switchChange', e.detail);
},
openPage() {
if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) {
this.pageApi(this.link);
} else {
this.pageApi('navigateTo');
}
},
pageApi(api) {
let callback = {
url: this.to,
success: res => {
this.$emit('click', {
data: res
});
},
fail: err => {
this.$emit('click', {
data: err
});
}
};
switch (api) {
case 'navigateTo':
uni.navigateTo(callback);
break;
case 'redirectTo':
uni.redirectTo(callback);
break;
case 'reLaunch':
uni.reLaunch(callback);
break;
case 'switchTab':
uni.switchTab(callback);
break;
default:
uni.navigateTo(callback);
}
}
}
};
</script>
<style lang="scss">
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16px;
$uni-spacing-col-lg: 12px;
$uni-spacing-row-lg: 15px;
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
$uni-border-color: #e5e5e5;
$uni-bg-color-hover: #f1f1f1;
$uni-text-color-grey: #999;
$list-item-pd: $uni-spacing-col-lg $uni-spacing-row-lg;
.uni-list-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
font-size: $uni-font-size-lg;
position: relative;
justify-content: space-between;
align-items: center;
// background-color: #fff;
flex-direction: row;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-list-item--disabled {
opacity: 0.3;
}
.uni-list-item--hover {
background-color: $uni-bg-color-hover;
}
.uni-list-item__container {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: $list-item-pd;
padding-left: $uni-spacing-row-lg;
flex: 1;
overflow: hidden;
// align-items: center;
}
.container--right {
padding-right: 0;
}
// .border--left {
// margin-left: $uni-spacing-row-lg;
// }
.uni-list--border {
position: absolute;
top: 0;
right: 0;
left: 0;
/* #ifdef APP-NVUE */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
}
/* #ifndef APP-NVUE */
.uni-list--border:after {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: $uni-border-color;
}
/* #endif */
.uni-list-item__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
padding-right: 8px;
flex: 1;
color: #3b4144;
// overflow: hidden;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
.uni-list-item__content--center {
justify-content: center;
}
.uni-list-item__content-title {
font-size: $uni-font-size-base;
color: #3b4144;
overflow: hidden;
}
.uni-list-item__content-note {
margin-top: 6rpx;
color: $uni-text-color-grey;
font-size: $uni-font-size-sm;
overflow: hidden;
}
.uni-list-item__extra {
// width: 25%;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.uni-list-item__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
}
.uni-list-item__icon {
margin-right: 18rpx;
flex-direction: row;
justify-content: center;
align-items: center;
}
.uni-list-item__icon-img {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
height: $uni-img-size-base;
width: $uni-img-size-base;
margin-right: 10px;
}
.uni-icon-wrapper {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
padding: 0 10px;
}
.flex--direction {
flex-direction: column;
/* #ifndef APP-NVUE */
align-items: initial;
/* #endif */
}
.flex--justify {
/* #ifndef APP-NVUE */
justify-content: initial;
/* #endif */
}
.uni-list--lg {
height: $uni-img-size-lg;
width: $uni-img-size-lg;
}
.uni-list--base {
height: $uni-img-size-base;
width: $uni-img-size-base;
}
.uni-list--sm {
height: $uni-img-size-sm;
width: $uni-img-size-sm;
}
.uni-list-item__extra-text {
color: $uni-text-color-grey;
font-size: $uni-font-size-sm;
}
.uni-ellipsis-1 {
/* #ifndef APP-NVUE */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
text-overflow: ellipsis;
/* #endif */
}
.uni-ellipsis-2 {
/* #ifndef APP-NVUE */
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
/* #endif */
/* #ifdef APP-NVUE */
lines: 2;
text-overflow: ellipsis;
/* #endif */
}
</style>
<template>
<!-- #ifdef APP-NVUE -->
<cell>
<!-- #endif -->
<view
:class="{ 'uni-list-item--disabled': disabled }"
:hover-class="(!clickable && !link) || disabled || showSwitch ? '' : 'uni-list-item--hover'"
class="uni-list-item"
@click="onClick"
>
<view v-if="!isFirstChild" class="border--left" :class="{ 'uni-list--border': border }"></view>
<view
class="uni-list-item__container"
:class="{ 'container--right': showArrow || link, 'flex--direction': direction === 'column' }"
>
<slot name="header">
<view class="uni-list-item__header">
<view v-if="thumb" class="uni-list-item__icon">
<image :src="thumb" class="uni-list-item__icon-img" :class="['uni-list--' + thumbSize]" />
</view>
<view v-else-if="showExtraIcon" class="uni-list-item__icon">
<uni-icons :color="extraIcon.color" :size="extraIcon.size" :type="extraIcon.type" />
</view>
</view>
</slot>
<slot name="body">
<view
class="uni-list-item__content"
:class="{ 'uni-list-item__content--center': thumb || showExtraIcon || showBadge || showSwitch }"
>
<text
v-if="title"
class="uni-list-item__content-title"
:class="[ellipsis !== 0 && ellipsis <= 2 ? 'uni-ellipsis-' + ellipsis : '']"
>
{{ title }}
</text>
<text v-if="note" class="uni-list-item__content-note">{{ note }}</text>
</view>
</slot>
<slot name="footer">
<view
v-if="rightText || showBadge || showSwitch"
class="uni-list-item__extra"
:class="{ 'flex--justify': direction === 'column' }"
>
<text v-if="rightText" class="uni-list-item__extra-text">{{ rightText }}</text>
<uni-badge v-if="showBadge" :type="badgeType" :text="badgeText" :custom-style="badgeStyle" />
<switch
v-if="showSwitch"
:disabled="disabled"
:checked="switchChecked"
@change="onSwitchChange"
/>
</view>
</slot>
</view>
<uni-icons v-if="showArrow || link" :size="16" class="uni-icon-wrapper" color="#bbb" type="arrowright" />
</view>
<!-- #ifdef APP-NVUE -->
</cell>
<!-- #endif -->
</template>
<script>
/**
* ListItem 列表子组件
* @description 列表子组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
* @property {String} title 标题
* @property {String} note 描述
* @property {String} thumb 左侧缩略图,若thumb有值,则不会显示扩展图标
* @property {String} thumbSize = [lg|base|sm] 略缩图大小
* @value lg 大图
* @value base 一般
* @value sm 小图
* @property {String} badgeText 数字角标内容
* @property {String} badgeType 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)
* @property {Object} badgeStyle 数字角标样式
* @property {String} rightText 右侧文字内容
* @property {Boolean} disabled = [true|false] 是否禁用
* @property {Boolean} clickable = [true|false] 是否开启点击反馈
* @property {String} link = [navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈
* @value navigateTo 同 uni.navigateTo()
* @value redirectTo 同 uni.redirectTo()
* @value reLaunch 同 uni.reLaunch()
* @value switchTab 同 uni.switchTab()
* @property {String | PageURIString} to 跳转目标页面
* @property {Boolean} showBadge = [true|false] 是否显示数字角标
* @property {Boolean} showSwitch = [true|false] 是否显示Switch
* @property {Boolean} switchChecked = [true|false] Switch是否被选中
* @property {Boolean} showExtraIcon = [true|false] 左侧是否显示扩展图标
* @property {Object} extraIcon 扩展图标参数,格式为 {color: '#4cd964',size: '22',type: 'spinner'}
* @property {String} direction = [row|column] 排版方向
* @value row 水平排列
* @value column 垂直排列
* @event {Function} click 点击 uniListItem 触发事件
* @event {Function} switchChange 点击切换 Switch 时触发
*/
export default {
name: 'UniListItem',
emits: ['click', 'switchChange'],
props: {
direction: {
type: String,
default: 'row'
},
title: {
type: String,
default: ''
},
note: {
type: String,
default: ''
},
ellipsis: {
type: [Number, String],
default: 0
},
disabled: {
type: [Boolean, String],
default: false
},
clickable: {
type: Boolean,
default: false
},
showArrow: {
type: [Boolean, String],
default: false
},
link: {
type: [Boolean, String],
default: false
},
to: {
type: String,
default: ''
},
showBadge: {
type: [Boolean, String],
default: false
},
showSwitch: {
type: [Boolean, String],
default: false
},
switchChecked: {
type: [Boolean, String],
default: false
},
badgeText: {
type: String,
default: ''
},
badgeType: {
type: String,
default: 'success'
},
badgeStyle: {
type: Object,
default() {
return {};
}
},
rightText: {
type: String,
default: ''
},
thumb: {
type: String,
default: ''
},
thumbSize: {
type: String,
default: 'base'
},
showExtraIcon: {
type: [Boolean, String],
default: false
},
extraIcon: {
type: Object,
default() {
return {
type: '',
color: '#000000',
size: 20
};
}
},
border: {
type: Boolean,
default: true
}
},
// inject: ['list'],
data() {
return {
isFirstChild: false
};
},
mounted() {
this.list = this.getForm();
// 判断是否存在 uni-list 组件
if (this.list) {
if (!this.list.firstChildAppend) {
this.list.firstChildAppend = true;
this.isFirstChild = true;
}
}
},
methods: {
/**
* 获取父元素实例
*/
getForm(name = 'uniList') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false;
parentName = parent.$options.name;
}
return parent;
},
onClick() {
if (this.to !== '') {
this.openPage();
return;
}
if (this.clickable || this.link) {
this.$emit('click', {
data: {}
});
}
},
onSwitchChange(e) {
this.$emit('switchChange', e.detail);
},
openPage() {
if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) {
this.pageApi(this.link);
} else {
this.pageApi('navigateTo');
}
},
pageApi(api) {
let callback = {
url: this.to,
success: res => {
this.$emit('click', {
data: res
});
},
fail: err => {
this.$emit('click', {
data: err
});
}
};
switch (api) {
case 'navigateTo':
uni.navigateTo(callback);
break;
case 'redirectTo':
uni.redirectTo(callback);
break;
case 'reLaunch':
uni.reLaunch(callback);
break;
case 'switchTab':
uni.switchTab(callback);
break;
default:
uni.navigateTo(callback);
}
}
}
};
</script>
<style lang="scss">
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16px;
$uni-spacing-col-lg: 12px;
$uni-spacing-row-lg: 15px;
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
$uni-border-color: #e5e5e5;
$uni-bg-color-hover: #f1f1f1;
$uni-text-color-grey: #999;
$list-item-pd: $uni-spacing-col-lg $uni-spacing-row-lg;
.uni-list-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
font-size: $uni-font-size-lg;
position: relative;
justify-content: space-between;
align-items: center;
// background-color: #fff;
flex-direction: row;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-list-item--disabled {
opacity: 0.3;
}
.uni-list-item--hover {
background-color: $uni-bg-color-hover;
}
.uni-list-item__container {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: $list-item-pd;
padding-left: $uni-spacing-row-lg;
flex: 1;
overflow: hidden;
// align-items: center;
}
.container--right {
padding-right: 0;
}
// .border--left {
// margin-left: $uni-spacing-row-lg;
// }
.uni-list--border {
position: absolute;
top: 0;
right: 0;
left: 0;
/* #ifdef APP-NVUE */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
}
/* #ifndef APP-NVUE */
.uni-list--border:after {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: $uni-border-color;
}
/* #endif */
.uni-list-item__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
padding-right: 8px;
flex: 1;
color: #3b4144;
// overflow: hidden;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
.uni-list-item__content--center {
justify-content: center;
}
.uni-list-item__content-title {
font-size: $uni-font-size-base;
color: #3b4144;
overflow: hidden;
}
.uni-list-item__content-note {
margin-top: 6rpx;
color: $uni-text-color-grey;
font-size: $uni-font-size-sm;
overflow: hidden;
}
.uni-list-item__extra {
// width: 25%;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.uni-list-item__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
}
.uni-list-item__icon {
margin-right: 18rpx;
flex-direction: row;
justify-content: center;
align-items: center;
}
.uni-list-item__icon-img {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
height: $uni-img-size-base;
width: $uni-img-size-base;
margin-right: 10px;
}
.uni-icon-wrapper {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
padding: 0 10px;
}
.flex--direction {
flex-direction: column;
/* #ifndef APP-NVUE */
align-items: initial;
/* #endif */
}
.flex--justify {
/* #ifndef APP-NVUE */
justify-content: initial;
/* #endif */
}
.uni-list--lg {
height: $uni-img-size-lg;
width: $uni-img-size-lg;
}
.uni-list--base {
height: $uni-img-size-base;
width: $uni-img-size-base;
}
.uni-list--sm {
height: $uni-img-size-sm;
width: $uni-img-size-sm;
}
.uni-list-item__extra-text {
color: $uni-text-color-grey;
font-size: $uni-font-size-sm;
}
.uni-ellipsis-1 {
/* #ifndef APP-NVUE */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
text-overflow: ellipsis;
/* #endif */
}
.uni-ellipsis-2 {
/* #ifndef APP-NVUE */
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
/* #endif */
/* #ifdef APP-NVUE */
lines: 2;
text-overflow: ellipsis;
/* #endif */
}
</style>
@@ -1,108 +1,108 @@
<template>
<!-- #ifndef APP-NVUE -->
<view class="uni-list uni-border-top-bottom">
<view v-if="border" class="uni-list--border-top"></view>
<slot />
<view v-if="border" class="uni-list--border-bottom"></view>
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<list class="uni-list" :class="{ 'uni-list--border': border }" :enableBackToTop="enableBackToTop" loadmoreoffset="15"><slot /></list>
<!-- #endif -->
</template>
<script>
/**
* List 列表
* @description 列表组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
* @property {String} border = [true|false] 标题
*/
export default {
name: 'uniList',
'mp-weixin': {
options: {
multipleSlots: false
}
},
props: {
enableBackToTop: {
type: [Boolean, String],
default: false
},
scrollY: {
type: [Boolean, String],
default: false
},
border: {
type: Boolean,
default: true
}
},
// provide() {
// return {
// list: this
// };
// },
created() {
this.firstChildAppend = false;
},
methods: {
loadMore(e) {
this.$emit('scrolltolower');
}
}
};
</script>
<style lang="scss" >
$uni-bg-color:#ffffff;
$uni-border-color:#e5e5e5;
.uni-list {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// background-color: $uni-bg-color;
position: relative;
flex-direction: column;
}
.uni-list--border {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 0.5px;
/* #endif */
z-index: -1;
}
/* #ifndef APP-NVUE */
.uni-list--border-top {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: $uni-border-color;
z-index: 1;
}
.uni-list--border-bottom {
position: absolute;
bottom: 0;
right: 0;
left: 0;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: $uni-border-color;
}
/* #endif */
</style>
<template>
<!-- #ifndef APP-NVUE -->
<view class="uni-list uni-border-top-bottom">
<view v-if="border" class="uni-list--border-top"></view>
<slot />
<view v-if="border" class="uni-list--border-bottom"></view>
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<list class="uni-list" :class="{ 'uni-list--border': border }" :enableBackToTop="enableBackToTop" loadmoreoffset="15"><slot /></list>
<!-- #endif -->
</template>
<script>
/**
* List 列表
* @description 列表组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
* @property {String} border = [true|false] 标题
*/
export default {
name: 'uniList',
'mp-weixin': {
options: {
multipleSlots: false
}
},
props: {
enableBackToTop: {
type: [Boolean, String],
default: false
},
scrollY: {
type: [Boolean, String],
default: false
},
border: {
type: Boolean,
default: true
}
},
// provide() {
// return {
// list: this
// };
// },
created() {
this.firstChildAppend = false;
},
methods: {
loadMore(e) {
this.$emit('scrolltolower');
}
}
};
</script>
<style lang="scss" >
$uni-bg-color:#ffffff;
$uni-border-color:#e5e5e5;
.uni-list {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// background-color: $uni-bg-color;
position: relative;
flex-direction: column;
}
.uni-list--border {
position: relative;
/* #ifdef APP-NVUE */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 0.5px;
/* #endif */
z-index: -1;
}
/* #ifndef APP-NVUE */
.uni-list--border-top {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: $uni-border-color;
z-index: 1;
}
.uni-list--border-bottom {
position: absolute;
bottom: 0;
right: 0;
left: 0;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: $uni-border-color;
}
/* #endif */
</style>
@@ -1,65 +1,65 @@
<template>
<!-- #ifdef APP-NVUE -->
<refresh :display="display" @refresh="onrefresh" @pullingdown="onpullingdown">
<slot />
</refresh>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view ref="uni-refresh" class="uni-refresh" v-show="isShow">
<slot />
</view>
<!-- #endif -->
</template>
<script>
export default {
name: 'UniRefresh',
props: {
display: {
type: [String],
default: "hide"
}
},
data() {
return {
pulling: false
}
},
computed: {
isShow() {
if (this.display === "show" || this.pulling === true) {
return true;
}
return false;
}
},
created() {},
methods: {
onchange(value) {
this.pulling = value;
},
onrefresh(e) {
this.$emit("refresh", e);
},
onpullingdown(e) {
// #ifdef APP-NVUE
this.$emit("pullingdown", e);
// #endif
// #ifndef APP-NVUE
var detail = {
viewHeight: 90,
pullingDistance: e.height
}
this.$emit("pullingdown", detail);
// #endif
}
}
}
</script>
<style>
.uni-refresh {
height: 0;
overflow: hidden;
}
</style>
<template>
<!-- #ifdef APP-NVUE -->
<refresh :display="display" @refresh="onrefresh" @pullingdown="onpullingdown">
<slot />
</refresh>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view ref="uni-refresh" class="uni-refresh" v-show="isShow">
<slot />
</view>
<!-- #endif -->
</template>
<script>
export default {
name: 'UniRefresh',
props: {
display: {
type: [String],
default: "hide"
}
},
data() {
return {
pulling: false
}
},
computed: {
isShow() {
if (this.display === "show" || this.pulling === true) {
return true;
}
return false;
}
},
created() {},
methods: {
onchange(value) {
this.pulling = value;
},
onrefresh(e) {
this.$emit("refresh", e);
},
onpullingdown(e) {
// #ifdef APP-NVUE
this.$emit("pullingdown", e);
// #endif
// #ifndef APP-NVUE
var detail = {
viewHeight: 90,
pullingDistance: e.height
}
this.$emit("pullingdown", detail);
// #endif
}
}
}
</script>
<style>
.uni-refresh {
height: 0;
overflow: hidden;
}
</style>
@@ -1,87 +1,87 @@
var pullDown = {
threshold: 95,
maxHeight: 200,
callRefresh: 'onrefresh',
callPullingDown: 'onpullingdown',
refreshSelector: '.uni-refresh'
};
function ready(newValue, oldValue, ownerInstance, instance) {
var state = instance.getState()
state.canPullDown = newValue;
// console.log(newValue);
}
function touchStart(e, instance) {
var state = instance.getState();
state.refreshInstance = instance.selectComponent(pullDown.refreshSelector);
state.canPullDown = (state.refreshInstance != null && state.refreshInstance != undefined);
if (!state.canPullDown) {
return
}
// console.log("touchStart");
state.height = 0;
state.touchStartY = e.touches[0].pageY || e.changedTouches[0].pageY;
state.refreshInstance.setStyle({
'height': 0
});
state.refreshInstance.callMethod("onchange", true);
}
function touchMove(e, ownerInstance) {
var instance = e.instance;
var state = instance.getState();
if (!state.canPullDown) {
return
}
var oldHeight = state.height;
var endY = e.touches[0].pageY || e.changedTouches[0].pageY;
var height = endY - state.touchStartY;
if (height > pullDown.maxHeight) {
return;
}
var refreshInstance = state.refreshInstance;
refreshInstance.setStyle({
'height': height + 'px'
});
height = height < pullDown.maxHeight ? height : pullDown.maxHeight;
state.height = height;
refreshInstance.callMethod(pullDown.callPullingDown, {
height: height
});
}
function touchEnd(e, ownerInstance) {
var state = e.instance.getState();
if (!state.canPullDown) {
return
}
state.refreshInstance.callMethod("onchange", false);
var refreshInstance = state.refreshInstance;
if (state.height > pullDown.threshold) {
refreshInstance.callMethod(pullDown.callRefresh);
return;
}
refreshInstance.setStyle({
'height': 0
});
}
function propObserver(newValue, oldValue, instance) {
pullDown = newValue;
}
module.exports = {
touchmove: touchMove,
touchstart: touchStart,
touchend: touchEnd,
propObserver: propObserver
}
var pullDown = {
threshold: 95,
maxHeight: 200,
callRefresh: 'onrefresh',
callPullingDown: 'onpullingdown',
refreshSelector: '.uni-refresh'
};
function ready(newValue, oldValue, ownerInstance, instance) {
var state = instance.getState()
state.canPullDown = newValue;
// console.log(newValue);
}
function touchStart(e, instance) {
var state = instance.getState();
state.refreshInstance = instance.selectComponent(pullDown.refreshSelector);
state.canPullDown = (state.refreshInstance != null && state.refreshInstance != undefined);
if (!state.canPullDown) {
return
}
// console.log("touchStart");
state.height = 0;
state.touchStartY = e.touches[0].pageY || e.changedTouches[0].pageY;
state.refreshInstance.setStyle({
'height': 0
});
state.refreshInstance.callMethod("onchange", true);
}
function touchMove(e, ownerInstance) {
var instance = e.instance;
var state = instance.getState();
if (!state.canPullDown) {
return
}
var oldHeight = state.height;
var endY = e.touches[0].pageY || e.changedTouches[0].pageY;
var height = endY - state.touchStartY;
if (height > pullDown.maxHeight) {
return;
}
var refreshInstance = state.refreshInstance;
refreshInstance.setStyle({
'height': height + 'px'
});
height = height < pullDown.maxHeight ? height : pullDown.maxHeight;
state.height = height;
refreshInstance.callMethod(pullDown.callPullingDown, {
height: height
});
}
function touchEnd(e, ownerInstance) {
var state = e.instance.getState();
if (!state.canPullDown) {
return
}
state.refreshInstance.callMethod("onchange", false);
var refreshInstance = state.refreshInstance;
if (state.height > pullDown.threshold) {
refreshInstance.callMethod(pullDown.callRefresh);
return;
}
refreshInstance.setStyle({
'height': 0
});
}
function propObserver(newValue, oldValue, instance) {
pullDown = newValue;
}
module.exports = {
touchmove: touchMove,
touchstart: touchStart,
touchend: touchEnd,
propObserver: propObserver
}
+90 -90
View File
@@ -1,91 +1,91 @@
{
"id": "uni-list",
"displayName": "uni-list 列表",
"version": "1.2.1",
"description": "List 组件 ,帮助使用者快速构建列表。",
"keywords": [
"",
"uni-ui",
"uniui",
"列表",
"",
"list"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-badge",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-list",
"displayName": "uni-list 列表",
"version": "1.2.1",
"description": "List 组件 ,帮助使用者快速构建列表。",
"keywords": [
"",
"uni-ui",
"uniui",
"列表",
"",
"list"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-badge",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+345 -345
View File
@@ -1,346 +1,346 @@
## List 列表
> **组件名:uni-list**
> 代码块: `uList`、`uListItem`
> 关联组件:`uni-list-item`、`uni-badge`、`uni-icons`、`uni-list-chat`、`uni-list-ad`
List 列表组件,包含基本列表样式、可扩展插槽机制、长列表性能优化、多端兼容。
在vue页面里,它默认使用页面级滚动。在app-nvue页面里,它默认使用原生list组件滚动。这样的长列表,在滚动出屏幕外后,系统会回收不可见区域的渲染内存资源,不会造成滚动越长手机越卡的问题。
uni-list组件是父容器,里面的核心是uni-list-item子组件,它代表列表中的一个可重复行,子组件可以无限循环。
uni-list-item有很多风格,uni-list-item组件通过内置的属性,满足一些常用的场景。当内置属性不满足需求时,可以通过扩展插槽来自定义列表内容。
内置属性可以覆盖的场景包括:导航列表、设置列表、小图标列表、通信录列表、聊天记录列表。
涉及很多大图或丰富内容的列表,比如类今日头条的新闻列表、类淘宝的电商列表,需要通过扩展插槽实现。
下文均有样例给出。
uni-list不包含下拉刷新和上拉翻页。上拉翻页另见组件:[uni-load-more](https://ext.dcloud.net.cn/plugin?id=29)
### 安装方式
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
> **注意事项**
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
> - 组件需要依赖 `sass` 插件 ,请自行手动安装
> - 组件内部依赖 `'uni-icons'` 、`uni-badge` 组件
> - `uni-list` 和 `uni-list-item` 需要配套使用,暂不支持单独使用 `uni-list-item`
> - 只有开启点击反馈后,会有点击选中效果
> - 使用插槽时,可以完全自定义内容
> - note 、rightText 属性暂时没做限制,不支持文字溢出隐藏,使用时应该控制长度显示或通过默认插槽自行扩展
> - 支付宝小程序平台需要在支付宝小程序开发者工具里开启 component2 编译模式,开启方式: 详情 --> 项目配置 --> 启用 component2 编译
> - 如果需要修改 `switch`、`badge` 样式,请使用插槽自定义
> - 在 `HBuilderX` 低版本中,可能会出现组件显示 `undefined` 的问题,请升级最新的 `HBuilderX` 或者 `cli`
> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
### 基本用法
- 设置 `title` 属性,可以显示列表标题
- 设置 `disabled` 属性,可以禁用当前项
```html
<uni-list>
<uni-list-item title="列表文字" ></uni-list-item>
<uni-list-item :disabled="true" title="列表禁用状态" ></uni-list-item>
</uni-list>
```
### 多行内容显示
- 设置 `note` 属性 ,可以在第二行显示描述文本信息
```html
<uni-list>
<uni-list-item title="列表文字" note="列表描述信息"></uni-list-item>
<uni-list-item :disabled="true" title="列表文字" note="列表禁用状态"></uni-list-item>
</uni-list>
```
### 右侧显示角标、switch
- 设置 `show-badge` 属性 ,可以显示角标内容
- 设置 `show-switch` 属性,可以显示 switch 开关
```html
<uni-list>
<uni-list-item title="列表右侧显示角标" :show-badge="true" badge-text="12" ></uni-list-item>
<uni-list-item title="列表右侧显示 switch" :show-switch="true" @switchChange="switchChange" ></uni-list-item>
</uni-list>
```
### 左侧显示略缩图、图标
- 设置 `thumb` 属性 ,可以在列表左侧显示略缩图
- 设置 `show-extra-icon` 属性,并指定 `extra-icon` 可以在左侧显示图标
```html
<uni-list>
<uni-list-item title="列表左侧带略缩图" note="列表描述信息" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"
thumb-size="lg" rightText="右侧文字"></uni-list-item>
<uni-list-item :show-extra-icon="true" :extra-icon="extraIcon1" title="列表左侧带扩展图标" ></uni-list-item>
</uni-list>
```
### 开启点击反馈和右侧箭头
- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件
- 设置 `link` 属性,会自动开启点击反馈,并给列表右侧添加一个箭头
- 设置 `to` 属性,可以跳转页面,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo`
```html
<uni-list>
<uni-list-item title="开启点击反馈" clickable @click="onClick" ></uni-list-item>
<uni-list-item title="默认 navigateTo 方式跳转页面" link to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
<uni-list-item title="reLaunch 方式跳转页面" link="reLaunch" to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
</uni-list>
```
### 聊天列表示例
- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件
- 设置 `link` 属性,会自动开启点击反馈,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo`
- 设置 `to` 属性,可以跳转页面
- `time` 属性,通常会设置成时间显示,但是这个属性不仅仅可以设置时间,你可以传入任何文本,注意文本长度可能会影响显示
- `avatar` 和 `avatarList` 属性同时只会有一个生效,同时设置的话,`avatarList` 属性的长度大于1 ,`avatar` 属性将失效
- 可以通过默认插槽自定义列表右侧内容
```html
<uni-list>
<uni-list :border="true">
<!-- 显示圆形头像 -->
<uni-list-chat :avatar-circle="true" title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" ></uni-list-chat>
<!-- 右侧带角标 -->
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-text="12" :badge-style="{backgroundColor:'#FF80AB'}"></uni-list-chat>
<!-- 头像显示圆点 -->
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
<!-- 头像显示角标 -->
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="99"></uni-list-chat>
<!-- 显示多头像 -->
<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
<!-- 自定义右侧内容 -->
<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot">
<view class="chat-custom-right">
<text class="chat-custom-text">刚刚</text>
<!-- 需要使用 uni-icons 请自行引入 -->
<uni-icons type="star-filled" color="#999" size="18"></uni-icons>
</view>
</uni-list-chat>
</uni-list>
</uni-list>
```
```javascript
export default {
components: {},
data() {
return {
avatarList: [{
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
}, {
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
}, {
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
}]
}
}
}
```
```css
.chat-custom-right {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
}
.chat-custom-text {
font-size: 12px;
color: #999;
}
```
## API
### List Props
属性名 |类型 |默认值 | 说明
:-: |:-: |:-: | :-:
border |Boolean |true | 是否显示边框
### ListItem Props
属性名 |类型 |默认值 | 说明
:-: |:-: |:-: | :-:
title |String |- | 标题
note |String |- | 描述
ellipsis |Number |0 | title 是否溢出隐藏,可选值,0:默认; 1:显示一行; 2:显示两行;【nvue 暂不支持】
thumb |String |- | 左侧缩略图,若thumb有值,则不会显示扩展图标
thumbSize |String |medium | 略缩图尺寸,可选值,lg:大图; medium:一般; sm:小图;
showBadge |Boolean |false | 是否显示数字角标
badgeText |String |- | 数字角标内容
badgeType |String |- | 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)
badgeStyle |Object |- | 数字角标样式,使用uni-badge的custom-style参数
rightText |String |- | 右侧文字内容
disabled |Boolean |false | 是否禁用
showArrow |Boolean |true | 是否显示箭头图标
link |String |navigateTo | 新页面跳转方式,可选值见下表
to |String |- | 新页面跳转地址,如填写此属性,click 会返回页面是否跳转成功
clickable |Boolean |false | 是否开启点击反馈
showSwitch |Boolean |false | 是否显示Switch
switchChecked |Boolean |false | Switch是否被选中
showExtraIcon |Boolean |false | 左侧是否显示扩展图标
extraIcon |Object |- | 扩展图标参数,格式为 ``{color: '#4cd964',size: '22',type: 'spinner'}``,参考 [uni-icons](https://ext.dcloud.net.cn/plugin?id=28)
direction | String |row | 排版方向,可选值,row:水平排列; column:垂直排列; 3个插槽是水平排还是垂直排,也受此属性控制
#### Link Options
属性名 | 说明
:-: | :-:
navigateTo | 同 uni.navigateTo()
redirectTo | 同 uni.reLaunch()
reLaunch | 同 uni.reLaunch()
switchTab | 同 uni.switchTab()
### ListItem Events
事件称名 |说明 |返回参数
:-: |:-: |:-:
click |点击 uniListItem 触发事件,需开启点击反馈 |-
switchChange |点击切换 Switch 时触发,需显示 switch |e={value:checked}
### ListItem Slots
名称 | 说明
:-: | :-:
header | 左/上内容插槽,可完全自定义默认显示
body | 中间内容插槽,可完全自定义中间内容
footer | 右/下内容插槽,可完全自定义右侧内容
> **通过插槽扩展**
> 需要注意的是当使用插槽时,内置样式将会失效,只保留排版样式,此时的样式需要开发者自己实现
> 如果 `uni-list-item` 组件内置属性样式无法满足需求,可以使用插槽来自定义uni-list-item里的内容。
> uni-list-item提供了3个可扩展的插槽:`header`、`body`、`footer`
> - 当 `direction` 属性为 `row` 时表示水平排列,此时 `header` 表示列表的左边部分,`body` 表示列表的中间部分,`footer` 表示列表的右边部分
> - 当 `direction` 属性为 `column` 时表示垂直排列,此时 `header` 表示列表的上边部分,`body` 表示列表的中间部分,`footer` 表示列表的下边部分
> 开发者可以只用1个插槽,也可以3个一起使用。在插槽中可自主编写view标签,实现自己所需的效果。
**示例**
```html
<uni-list>
<uni-list-item title="自定义右侧插槽" note="列表描述信息" link>
<template slot="header">
<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
</template>
</uni-list-item>
<uni-list-item>
<!-- 自定义 header -->
<view slot="header" class="slot-box"><image class="slot-image" src="/static/logo.png" mode="widthFix"></image></view>
<!-- 自定义 body -->
<text slot="body" class="slot-box slot-text">自定义插槽</text>
<!-- 自定义 footer-->
<template slot="footer">
<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
</template>
</uni-list-item>
</uni-list>
```
### ListItemChat Props
属性名 |类型 |默认值 | 说明
:-: |:-: |:-: | :-:
title |String |- | 标题
note |String |- | 描述
clickable |Boolean |false | 是否开启点击反馈
badgeText |String |- | 数字角标内容,设置为 `dot` 将显示圆点
badgePositon |String |right | 角标位置
link |String |navigateTo | 是否展示右侧箭头并开启点击反馈,可选值见下表
clickable |Boolean |false | 是否开启点击反馈
to |String |- | 跳转页面地址,如填写此属性,click 会返回页面是否跳转成功
time |String |- | 右侧时间显示
avatarCircle |Boolean |false | 是否显示圆形头像
avatar |String |- | 头像地址,avatarCircle 不填时生效
avatarList |Array |- | 头像组,格式为 [{url:''}]
#### Link Options
属性名 | 说明
:-: | :-:
navigateTo | 同 uni.navigateTo()
redirectTo | 同 uni.reLaunch()
reLaunch | 同 uni.reLaunch()
switchTab | 同 uni.switchTab()
### ListItemChat Slots
名称 | 说明
:- | :-
default | 自定义列表右侧内容(包括时间和角标显示)
### ListItemChat Events
事件称名 | 说明 | 返回参数
:-: | :-: | :-:
@click | 点击 uniListChat 触发事件 | {data:{}} ,如有 to 属性,会返回页面跳转信息
## 基于uni-list扩展的页面模板
通过扩展插槽,可实现多种常见样式的列表
**新闻列表类**
1. 云端一体混合布局:[https://ext.dcloud.net.cn/plugin?id=2546](https://ext.dcloud.net.cn/plugin?id=2546)
2. 云端一体垂直布局,大图模式:[https://ext.dcloud.net.cn/plugin?id=2583](https://ext.dcloud.net.cn/plugin?id=2583)
3. 云端一体垂直布局,多行图文混排:[https://ext.dcloud.net.cn/plugin?id=2584](https://ext.dcloud.net.cn/plugin?id=2584)
4. 云端一体垂直布局,多图模式:[https://ext.dcloud.net.cn/plugin?id=2585](https://ext.dcloud.net.cn/plugin?id=2585)
5. 云端一体水平布局,左图右文:[https://ext.dcloud.net.cn/plugin?id=2586](https://ext.dcloud.net.cn/plugin?id=2586)
6. 云端一体水平布局,左文右图:[https://ext.dcloud.net.cn/plugin?id=2587](https://ext.dcloud.net.cn/plugin?id=2587)
7. 云端一体垂直布局,无图模式,主标题+副标题:[https://ext.dcloud.net.cn/plugin?id=2588](https://ext.dcloud.net.cn/plugin?id=2588)
**商品列表类**
1. 云端一体列表/宫格视图互切:[https://ext.dcloud.net.cn/plugin?id=2651](https://ext.dcloud.net.cn/plugin?id=2651)
2. 云端一体列表(宫格模式):[https://ext.dcloud.net.cn/plugin?id=2671](https://ext.dcloud.net.cn/plugin?id=2671)
3. 云端一体列表(列表模式):[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672)
## 组件示例
## List 列表
> **组件名:uni-list**
> 代码块: `uList`、`uListItem`
> 关联组件:`uni-list-item`、`uni-badge`、`uni-icons`、`uni-list-chat`、`uni-list-ad`
List 列表组件,包含基本列表样式、可扩展插槽机制、长列表性能优化、多端兼容。
在vue页面里,它默认使用页面级滚动。在app-nvue页面里,它默认使用原生list组件滚动。这样的长列表,在滚动出屏幕外后,系统会回收不可见区域的渲染内存资源,不会造成滚动越长手机越卡的问题。
uni-list组件是父容器,里面的核心是uni-list-item子组件,它代表列表中的一个可重复行,子组件可以无限循环。
uni-list-item有很多风格,uni-list-item组件通过内置的属性,满足一些常用的场景。当内置属性不满足需求时,可以通过扩展插槽来自定义列表内容。
内置属性可以覆盖的场景包括:导航列表、设置列表、小图标列表、通信录列表、聊天记录列表。
涉及很多大图或丰富内容的列表,比如类今日头条的新闻列表、类淘宝的电商列表,需要通过扩展插槽实现。
下文均有样例给出。
uni-list不包含下拉刷新和上拉翻页。上拉翻页另见组件:[uni-load-more](https://ext.dcloud.net.cn/plugin?id=29)
### 安装方式
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
> **注意事项**
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
> - 组件需要依赖 `sass` 插件 ,请自行手动安装
> - 组件内部依赖 `'uni-icons'` 、`uni-badge` 组件
> - `uni-list` 和 `uni-list-item` 需要配套使用,暂不支持单独使用 `uni-list-item`
> - 只有开启点击反馈后,会有点击选中效果
> - 使用插槽时,可以完全自定义内容
> - note 、rightText 属性暂时没做限制,不支持文字溢出隐藏,使用时应该控制长度显示或通过默认插槽自行扩展
> - 支付宝小程序平台需要在支付宝小程序开发者工具里开启 component2 编译模式,开启方式: 详情 --> 项目配置 --> 启用 component2 编译
> - 如果需要修改 `switch`、`badge` 样式,请使用插槽自定义
> - 在 `HBuilderX` 低版本中,可能会出现组件显示 `undefined` 的问题,请升级最新的 `HBuilderX` 或者 `cli`
> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
### 基本用法
- 设置 `title` 属性,可以显示列表标题
- 设置 `disabled` 属性,可以禁用当前项
```html
<uni-list>
<uni-list-item title="列表文字" ></uni-list-item>
<uni-list-item :disabled="true" title="列表禁用状态" ></uni-list-item>
</uni-list>
```
### 多行内容显示
- 设置 `note` 属性 ,可以在第二行显示描述文本信息
```html
<uni-list>
<uni-list-item title="列表文字" note="列表描述信息"></uni-list-item>
<uni-list-item :disabled="true" title="列表文字" note="列表禁用状态"></uni-list-item>
</uni-list>
```
### 右侧显示角标、switch
- 设置 `show-badge` 属性 ,可以显示角标内容
- 设置 `show-switch` 属性,可以显示 switch 开关
```html
<uni-list>
<uni-list-item title="列表右侧显示角标" :show-badge="true" badge-text="12" ></uni-list-item>
<uni-list-item title="列表右侧显示 switch" :show-switch="true" @switchChange="switchChange" ></uni-list-item>
</uni-list>
```
### 左侧显示略缩图、图标
- 设置 `thumb` 属性 ,可以在列表左侧显示略缩图
- 设置 `show-extra-icon` 属性,并指定 `extra-icon` 可以在左侧显示图标
```html
<uni-list>
<uni-list-item title="列表左侧带略缩图" note="列表描述信息" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"
thumb-size="lg" rightText="右侧文字"></uni-list-item>
<uni-list-item :show-extra-icon="true" :extra-icon="extraIcon1" title="列表左侧带扩展图标" ></uni-list-item>
</uni-list>
```
### 开启点击反馈和右侧箭头
- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件
- 设置 `link` 属性,会自动开启点击反馈,并给列表右侧添加一个箭头
- 设置 `to` 属性,可以跳转页面,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo`
```html
<uni-list>
<uni-list-item title="开启点击反馈" clickable @click="onClick" ></uni-list-item>
<uni-list-item title="默认 navigateTo 方式跳转页面" link to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
<uni-list-item title="reLaunch 方式跳转页面" link="reLaunch" to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
</uni-list>
```
### 聊天列表示例
- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件
- 设置 `link` 属性,会自动开启点击反馈,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo`
- 设置 `to` 属性,可以跳转页面
- `time` 属性,通常会设置成时间显示,但是这个属性不仅仅可以设置时间,你可以传入任何文本,注意文本长度可能会影响显示
- `avatar` 和 `avatarList` 属性同时只会有一个生效,同时设置的话,`avatarList` 属性的长度大于1 ,`avatar` 属性将失效
- 可以通过默认插槽自定义列表右侧内容
```html
<uni-list>
<uni-list :border="true">
<!-- 显示圆形头像 -->
<uni-list-chat :avatar-circle="true" title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" ></uni-list-chat>
<!-- 右侧带角标 -->
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-text="12" :badge-style="{backgroundColor:'#FF80AB'}"></uni-list-chat>
<!-- 头像显示圆点 -->
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
<!-- 头像显示角标 -->
<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="99"></uni-list-chat>
<!-- 显示多头像 -->
<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
<!-- 自定义右侧内容 -->
<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot">
<view class="chat-custom-right">
<text class="chat-custom-text">刚刚</text>
<!-- 需要使用 uni-icons 请自行引入 -->
<uni-icons type="star-filled" color="#999" size="18"></uni-icons>
</view>
</uni-list-chat>
</uni-list>
</uni-list>
```
```javascript
export default {
components: {},
data() {
return {
avatarList: [{
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
}, {
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
}, {
url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
}]
}
}
}
```
```css
.chat-custom-right {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
}
.chat-custom-text {
font-size: 12px;
color: #999;
}
```
## API
### List Props
属性名 |类型 |默认值 | 说明
:-: |:-: |:-: | :-:
border |Boolean |true | 是否显示边框
### ListItem Props
属性名 |类型 |默认值 | 说明
:-: |:-: |:-: | :-:
title |String |- | 标题
note |String |- | 描述
ellipsis |Number |0 | title 是否溢出隐藏,可选值,0:默认; 1:显示一行; 2:显示两行;【nvue 暂不支持】
thumb |String |- | 左侧缩略图,若thumb有值,则不会显示扩展图标
thumbSize |String |medium | 略缩图尺寸,可选值,lg:大图; medium:一般; sm:小图;
showBadge |Boolean |false | 是否显示数字角标
badgeText |String |- | 数字角标内容
badgeType |String |- | 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)
badgeStyle |Object |- | 数字角标样式,使用uni-badge的custom-style参数
rightText |String |- | 右侧文字内容
disabled |Boolean |false | 是否禁用
showArrow |Boolean |true | 是否显示箭头图标
link |String |navigateTo | 新页面跳转方式,可选值见下表
to |String |- | 新页面跳转地址,如填写此属性,click 会返回页面是否跳转成功
clickable |Boolean |false | 是否开启点击反馈
showSwitch |Boolean |false | 是否显示Switch
switchChecked |Boolean |false | Switch是否被选中
showExtraIcon |Boolean |false | 左侧是否显示扩展图标
extraIcon |Object |- | 扩展图标参数,格式为 ``{color: '#4cd964',size: '22',type: 'spinner'}``,参考 [uni-icons](https://ext.dcloud.net.cn/plugin?id=28)
direction | String |row | 排版方向,可选值,row:水平排列; column:垂直排列; 3个插槽是水平排还是垂直排,也受此属性控制
#### Link Options
属性名 | 说明
:-: | :-:
navigateTo | 同 uni.navigateTo()
redirectTo | 同 uni.reLaunch()
reLaunch | 同 uni.reLaunch()
switchTab | 同 uni.switchTab()
### ListItem Events
事件称名 |说明 |返回参数
:-: |:-: |:-:
click |点击 uniListItem 触发事件,需开启点击反馈 |-
switchChange |点击切换 Switch 时触发,需显示 switch |e={value:checked}
### ListItem Slots
名称 | 说明
:-: | :-:
header | 左/上内容插槽,可完全自定义默认显示
body | 中间内容插槽,可完全自定义中间内容
footer | 右/下内容插槽,可完全自定义右侧内容
> **通过插槽扩展**
> 需要注意的是当使用插槽时,内置样式将会失效,只保留排版样式,此时的样式需要开发者自己实现
> 如果 `uni-list-item` 组件内置属性样式无法满足需求,可以使用插槽来自定义uni-list-item里的内容。
> uni-list-item提供了3个可扩展的插槽:`header`、`body`、`footer`
> - 当 `direction` 属性为 `row` 时表示水平排列,此时 `header` 表示列表的左边部分,`body` 表示列表的中间部分,`footer` 表示列表的右边部分
> - 当 `direction` 属性为 `column` 时表示垂直排列,此时 `header` 表示列表的上边部分,`body` 表示列表的中间部分,`footer` 表示列表的下边部分
> 开发者可以只用1个插槽,也可以3个一起使用。在插槽中可自主编写view标签,实现自己所需的效果。
**示例**
```html
<uni-list>
<uni-list-item title="自定义右侧插槽" note="列表描述信息" link>
<template slot="header">
<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
</template>
</uni-list-item>
<uni-list-item>
<!-- 自定义 header -->
<view slot="header" class="slot-box"><image class="slot-image" src="/static/logo.png" mode="widthFix"></image></view>
<!-- 自定义 body -->
<text slot="body" class="slot-box slot-text">自定义插槽</text>
<!-- 自定义 footer-->
<template slot="footer">
<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
</template>
</uni-list-item>
</uni-list>
```
### ListItemChat Props
属性名 |类型 |默认值 | 说明
:-: |:-: |:-: | :-:
title |String |- | 标题
note |String |- | 描述
clickable |Boolean |false | 是否开启点击反馈
badgeText |String |- | 数字角标内容,设置为 `dot` 将显示圆点
badgePositon |String |right | 角标位置
link |String |navigateTo | 是否展示右侧箭头并开启点击反馈,可选值见下表
clickable |Boolean |false | 是否开启点击反馈
to |String |- | 跳转页面地址,如填写此属性,click 会返回页面是否跳转成功
time |String |- | 右侧时间显示
avatarCircle |Boolean |false | 是否显示圆形头像
avatar |String |- | 头像地址,avatarCircle 不填时生效
avatarList |Array |- | 头像组,格式为 [{url:''}]
#### Link Options
属性名 | 说明
:-: | :-:
navigateTo | 同 uni.navigateTo()
redirectTo | 同 uni.reLaunch()
reLaunch | 同 uni.reLaunch()
switchTab | 同 uni.switchTab()
### ListItemChat Slots
名称 | 说明
:- | :-
default | 自定义列表右侧内容(包括时间和角标显示)
### ListItemChat Events
事件称名 | 说明 | 返回参数
:-: | :-: | :-:
@click | 点击 uniListChat 触发事件 | {data:{}} ,如有 to 属性,会返回页面跳转信息
## 基于uni-list扩展的页面模板
通过扩展插槽,可实现多种常见样式的列表
**新闻列表类**
1. 云端一体混合布局:[https://ext.dcloud.net.cn/plugin?id=2546](https://ext.dcloud.net.cn/plugin?id=2546)
2. 云端一体垂直布局,大图模式:[https://ext.dcloud.net.cn/plugin?id=2583](https://ext.dcloud.net.cn/plugin?id=2583)
3. 云端一体垂直布局,多行图文混排:[https://ext.dcloud.net.cn/plugin?id=2584](https://ext.dcloud.net.cn/plugin?id=2584)
4. 云端一体垂直布局,多图模式:[https://ext.dcloud.net.cn/plugin?id=2585](https://ext.dcloud.net.cn/plugin?id=2585)
5. 云端一体水平布局,左图右文:[https://ext.dcloud.net.cn/plugin?id=2586](https://ext.dcloud.net.cn/plugin?id=2586)
6. 云端一体水平布局,左文右图:[https://ext.dcloud.net.cn/plugin?id=2587](https://ext.dcloud.net.cn/plugin?id=2587)
7. 云端一体垂直布局,无图模式,主标题+副标题:[https://ext.dcloud.net.cn/plugin?id=2588](https://ext.dcloud.net.cn/plugin?id=2588)
**商品列表类**
1. 云端一体列表/宫格视图互切:[https://ext.dcloud.net.cn/plugin?id=2651](https://ext.dcloud.net.cn/plugin?id=2651)
2. 云端一体列表(宫格模式):[https://ext.dcloud.net.cn/plugin?id=2671](https://ext.dcloud.net.cn/plugin?id=2671)
3. 云端一体列表(列表模式):[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672)
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/list/list](https://hellouniapp.dcloud.net.cn/pages/extUI/list/list)
+19 -19
View File
@@ -1,19 +1,19 @@
## 1.3.3(2022-01-20)
- 新增 showText属性 ,是否显示文本
## 1.3.2(2022-01-19)
- 修复 nvue 平台下不显示文本的bug
## 1.3.1(2022-01-19)
- 修复 微信小程序平台样式选择器报警告的问题
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
## 1.2.1(2021-08-24)
- 新增 支持国际化
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.8(2021-05-12)
- 新增 组件示例地址
## 1.1.7(2021-03-30)
- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
## 1.1.6(2021-02-05)
- 调整为uni_modules目录规范
## 1.3.3(2022-01-20)
- 新增 showText属性 ,是否显示文本
## 1.3.2(2022-01-19)
- 修复 nvue 平台下不显示文本的bug
## 1.3.1(2022-01-19)
- 修复 微信小程序平台样式选择器报警告的问题
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
## 1.2.1(2021-08-24)
- 新增 支持国际化
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.8(2021-05-12)
- 新增 组件示例地址
## 1.1.7(2021-03-30)
- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
## 1.1.6(2021-02-05)
- 调整为uni_modules目录规范
@@ -1,5 +1,5 @@
{
"uni-load-more.contentdown": "Pull up to show more",
"uni-load-more.contentrefresh": "loading...",
"uni-load-more.contentnomore": "No more data"
}
{
"uni-load-more.contentdown": "Pull up to show more",
"uni-load-more.contentrefresh": "loading...",
"uni-load-more.contentnomore": "No more data"
}
@@ -1,8 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}
@@ -1,5 +1,5 @@
{
"uni-load-more.contentdown": "上拉显示更多",
"uni-load-more.contentrefresh": "正在加载...",
"uni-load-more.contentnomore": "没有更多数据了"
}
{
"uni-load-more.contentdown": "上拉显示更多",
"uni-load-more.contentrefresh": "正在加载...",
"uni-load-more.contentnomore": "没有更多数据了"
}
@@ -1,5 +1,5 @@
{
"uni-load-more.contentdown": "上拉顯示更多",
"uni-load-more.contentrefresh": "正在加載...",
"uni-load-more.contentnomore": "沒有更多數據了"
}
{
"uni-load-more.contentdown": "上拉顯示更多",
"uni-load-more.contentrefresh": "正在加載...",
"uni-load-more.contentnomore": "沒有更多數據了"
}
@@ -1,399 +1,399 @@
<template>
<view class="uni-load-more" @click="onClick">
<!-- #ifdef APP-NVUE -->
<loading-indicator v-if="!webviewHide && status === 'loading' && showIcon"
:style="{color: color,width:iconSize+'px',height:iconSize+'px'}" :animating="true"
class="uni-load-more__img uni-load-more__img--nvue"></loading-indicator>
<!-- #endif -->
<!-- #ifdef H5 -->
<svg width="24" height="24" viewBox="25 25 50 50"
v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
:style="{width:iconSize+'px',height:iconSize+'px'}"
class="uni-load-more__img uni-load-more__img--android-H5">
<circle cx="50" cy="50" r="20" fill="none" :style="{color:color}" :stroke-width="3"></circle>
</svg>
<!-- #endif -->
<!-- #ifndef APP-NVUE || H5 -->
<view
v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
:style="{width:iconSize+'px',height:iconSize+'px'}"
class="uni-load-more__img uni-load-more__img--android-MP">
<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view v-else-if="!webviewHide && status === 'loading' && showIcon"
:style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--ios-H5">
<image :src="imgBase64" mode="widthFix"></image>
</view>
<!-- #endif -->
<text v-if="showText" class="uni-load-more__text"
:style="{color: color}">{{ status === 'more' ? contentdownText : status === 'loading' ? contentrefreshText : contentnomoreText }}</text>
</view>
</template>
<script>
let platform
setTimeout(() => {
platform = uni.getSystemInfoSync().platform
}, 16)
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const {
t
} = initVueI18n(messages)
/**
* LoadMore 加载更多
* @description 用于列表中,做滚动加载使用,展示 loading 的各种状态
* @tutorial https://ext.dcloud.net.cn/plugin?id=29
* @property {String} status = [more|loading|noMore] loading 的状态
* @value more loading前
* @value loading loading中
* @value noMore 没有更多了
* @property {Number} iconSize 指定图标大小
* @property {Boolean} iconSize = [true|false] 是否显示 loading 图标
* @property {String} iconType = [snow|circle|auto] 指定图标样式
* @value snow ios雪花加载样式
* @value circle 安卓唤醒加载样式
* @value auto 根据平台自动选择加载样式
* @property {String} color 图标和文字颜色
* @property {Object} contentText 各状态文字说明,值为:{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}
* @event {Function} clickLoadMore 点击加载更多时触发
*/
export default {
name: 'UniLoadMore',
emits: ['clickLoadMore'],
props: {
status: {
// 上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
type: String,
default: 'more'
},
showIcon: {
type: Boolean,
default: true
},
iconType: {
type: String,
default: 'auto'
},
iconSize: {
type: Number,
default: 24
},
color: {
type: String,
default: '#777777'
},
contentText: {
type: Object,
default () {
return {
contentdown: '',
contentrefresh: '',
contentnomore: ''
}
}
},
showText: {
type: Boolean,
default: true
}
},
data() {
return {
webviewHide: false,
platform: platform,
imgBase64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZVHb98LM+F5bHL8khA1iSeiyQBCRM+YGqKUnnJTDLGI0BGZlKDIU2MMglUiDApEZvSsZnQtBRJtKwQNKQMFYeRDR10WOLd8ljYXdh+v8v5fR3Od+797t1dnOnO/Ofce77z+J//+b/P+ZqtXbs2sJ9MJhNUV1cHJ06cCJo3bx7EPc2aNcvpy7pWrVoF+/fvDyoqKoI2bdoE9fX1F7TjN8a+EXBn/fkfvw942Tf+wYMHg9mzZwfjxo0LDhw4EPa1x2MbFw/fOGfPng1qa2tzcCkILsLDydq2bRsunpOTMM7TD/W/tZDZhPdeKD+yGxHhdu3aBV27dg3OnDlzMVANMheLAO3btw8KCwuDmpoaX5OxbgUIMEq7K8IcPnw4KCsrC/r37x8cP378/4cAXAB3vqSkJMuiDhTkw+XcuXNhOWbMmKBly5YhUT8xArhyFvP0BfwRsAuwxJZJsm/nzp2DTp06he/OU+cZ64K6o0ePBkOHDg2GDx8e6gEbJ5Q/NHNuAJQ1hgBeHUDlR7nVTkY8rQAvAi4z34vR/mPs1FoRsaCgIJThI0eOBC1atEiFGGV+5MiRoS45efJkqFjJFXV1dQuA012m2WcwTw98fy6CqBdsaiIO4CScrGPHjvk4odhavPquRtFWXEC25VgkREKOCh/qDSq+vn37htzD/mZTOmOc5U7zKzBPEedygWshcDyWvs30igAbU+6oyMgJBCFhwQE0fccxN60Ay9iebbjoDh06hMowjQxT4fXq1SskArmHZpkArvixp/kWzHdMeArExSJEaiXIjjRjRJ4DaAGWpibLzXN3Fm1vA5teBgh3j1Rv3bp1YgKwPdmf2p9zcyNYYgPKMfY0T5f5nNYdw158nJ8QawW4CLKwiOBSEgO/hok2eBydR+3dYH+PLxA5J8Vv0KBBwenTp0P2JWAx6+yFEBfs8lMY+y0SWMBNI9E4ThKi58VKTg3FQZS1RQF1cz27eC0QHMu+3E0SkUowjhVt5VdaWhp07949ZHv2Qd1EjDXM2cla1M0nl3GxAs3J9yREzyTdFVKVFOaE9qRA8GM0WebRuo9JGZKA7Mv2SeS/Z8+eoQ9BArMfFrLGo6jvxbhHbJZnKX2Rzz1O7QhJJ9Cs2ZMaWIyq/zhdeqPNfIoHd58clIQD+JSXl4dKlyIAuBdVXZwFVWKspSSoxE++h8x4k3uCnEhE4I5KwRiFWGOU0QWKiCYLbdoRMRKAu2kQ9vkfLU6dOhX06NEjlH+yMRZSinnuyWnYosVcji8CEA/6Cg2JF+IIUBqnGKUTCNwtwBN4f89RiK1R96DEgO2o0NDmtEdvVFdVVYV+P3UAPUEs6GFwV3PHmXkD4vh74iDFJysVI/MlaQhwKeBNTLYX5VuA8T4/gZxA4MRGFxDB6R7OmYPfyykGRJbyie+XnGYnQIC/coH9+vULiYrxrkL9ZA9+0ykaHIfEpM7ge8TiJ2CsHYwyMfafAF1yCGBHYIbCVDjDjKt7BeB51D+LgQa6OkG7IDYEEtvQ7lnXLKLtLdLuJBpE4gPUXcW2+PkZwOex+4cGDhwYDBkyRL7/HFcEwUGPo/8uWRUpYnfxGHco8HkewLHLyYmAawAPuIFZxhOpDfJQ8gbUv41yORAptMWBNr6oqMhWird5+u+iHmBb2nhjDV7HWBNQTgK8y11l5NetWzc5ULscAtSj7nbNI0skhWeUZCc0W4nyH/jO4Vz0u1IeYhbk4AiwM6tjxIWByHsoZ9qcIBPJd/y+DwPfBESOmCa/QF3WiZHucLlEDpNxcNhmheEOPgdQNx6/VZFQzFZ5TN08AHXQt2Ii3EdyFuUsPtTcGPhW5iMiCNELvz+Gdn9huG4HUJaW/w3g0wxV0XaG7arG2WeKiUWYM4Y7GO5ezshTARbbWGw/DvXkpp/ivVvE0JVoMxN4rpGzJMhE5Pl+xlATsDIqikP9F9D2z3h9nOksEUFhK+qO4rcPkoalMQ/HqJLIyb3F3JdjrCcw1yZ8joyJLR5gCo54etlag7qIoeNh1N1BRYj3DTFJ0elotxPlVzkGuYAmL0VSJVGAJA41c4Z6A3BzTLfn0HYwYKEI6CUAMzZEWvLsIcQOo1AmmyyM72nHJCfYsogflGV6jEk9vyQZXSuq6w4c16NsGcGZbwOPr+H1RkOk2LEzjNepxQkihHSCQ4ynAYNRx2zMKV92CQMWqj8J0BRE8EShxRFN6YrfCRhC0x3r/Zm4IbQCcmJoV0kMamllccR6FjHqUC5F2R/wS2dcymOlfAKOS4KmzQb5cpNC2MC7JhVn5wjXoJ44rYhLh8n0eXOCorJxa7POjbSlCGVczr34/RsAmrcvo9s+wGp3tzVhntxiXiJ4nvEYb4FJkf0O8HocAePmLvCxnL0AORraVekJk6TYjDabRVXfRE2lCN1h6ZQRN1+InUbsCpKwoBZHh0dODN9JBCUffItXxEavTQkUtnfTVAplCWL3JISz29h4NjotnuSsQKJCk8dF+kJR6RARjrqFVmfPnj3ZbK8cIJ0msd6jgHPGtfVTQ8VLmlvh4mct9sobRmPic0DyDQQnx/NlfYUgyz59+oScsH379pAwXABD32nTpoUHIToESeI5mnbE/UqDdyLcafEBf2MCqgC7NwxIbMREJQ0g4D4sfJwnD+AmRrII05cfMWJE+L1169bQr+fip06dGp4oJ83lmYd5wj/EmMa4TaHivo4EeCguYZBnkB5g2aWA69OIEnUHOaGysjIYMGBAMGnSpODYsWPZwCpFmm4lNq+4gSLQA7jcX8DwtjEyRC8wjabnXEx9kfWnTJkSJkAo90xpJVV+FmcVNeYAF5zWngS4C4O91MBxmAv8blLEpbjI5sz9MTdAhcgkCT1RO8mZkAjfiYpTEvStAS53Uw1vAiUGgZ3GpuQEYvoiBqlIan7kSDHnTwJQFNiPu0+5VxCVYhcZIjNrdXUDdp+Eq5AZ3Gkg8QAyVZRZIk4Tl4QAbF9cXJxNYZMAtAokgs4BrNxEpCtteXg7DDTMDKYNSuQdKsnJBek7HxewvxaosWxLYXtw+cJp18217wql4aKCfBNoEu0O5VU+PhctJ0YeXD4C6JQpyrlpSLTojpGGGN5YwNziChdIZLk4lvLcFJ9jMX3QdiImY9bmGQU+TRUL5CHITTRlgF8D9ouD1MfmLoEPl5xokIumZ2cfgMpHt47IW9N64Hsh7wQYYjyIugWuF5fCqYncXRd5vPMWyizzvhi/32+nvG0dZc9vR6fZOu0md5e+uC408FvKSIOZwXlGvxPv95izA2Vtvg1xKFWARI+vMX66HUhpQQb643uW1bSjuTWyw2SBvDrBvjFic1eGGlz5esq3ko9uSIlBRqPuFcCv8F4WIcN12nVaBd0SaYwI6PDDImR11JkqgHcPmQssjxIn6bUshygDFJUTxPMpHk+jfjPgupgdnYV2R/g7xSjtpah8RJBewhwf0gGK6XI92u4wXFEU40afJ4DN4h5LcAd+40HI3JgJecuT0c062W0i2hQJUTcxan3/CMW1PF2K6bbA+Daz4xRs1D3Br1Cm0OihKCqizW78/nXAF/G5TXrEcVzaNMH6CyMswqsAHqDyDLEyou8lwOXnKF8DjI6KjV3KzMBiXkDH8ij/H214J5A596ekrZ3F0zXlWeL7+P5eUrNo3/QwC15uxthuzidy7DzKRwEDaAViiDgKbTbz7CJnzo0bN7pIfIiid8SuPwn25o3QCmpnyjlZkyxPP8EomCJzrGb7GJMx7tNsq4MT2Line truncated
}
},
computed: {
iconSnowWidth() {
return (Math.floor(this.iconSize / 24) || 1) * 2
},
contentdownText() {
return this.contentText.contentdown || t("uni-load-more.contentdown")
},
contentrefreshText() {
return this.contentText.contentrefresh || t("uni-load-more.contentrefresh")
},
contentnomoreText() {
return this.contentText.contentnomore || t("uni-load-more.contentnomore")
}
},
mounted() {
// #ifdef APP-PLUS
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page.$getAppWebview();
currentWebview.addEventListener('hide', () => {
this.webviewHide = true
})
currentWebview.addEventListener('show', () => {
this.webviewHide = false
})
// #endif
},
methods: {
onClick() {
this.$emit('clickLoadMore', {
detail: {
status: this.status,
}
})
}
}
}
</script>
<style lang="scss" >
.uni-load-more {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
height: 40px;
align-items: center;
justify-content: center;
}
.uni-load-more__text {
font-size: 14px;
margin-left: 8px;
}
.uni-load-more__img {
width: 24px;
height: 24px;
// margin-right: 8px;
}
.uni-load-more__img--nvue {
color: #666666;
}
.uni-load-more__img--android,
.uni-load-more__img--ios {
width: 24px;
height: 24px;
transform: rotate(0deg);
}
/* #ifndef APP-NVUE */
.uni-load-more__img--android {
animation: loading-ios 1s 0s linear infinite;
}
@keyframes loading-android {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.uni-load-more__img--ios-H5 {
position: relative;
animation: loading-ios-H5 1s 0s step-end infinite;
}
.uni-load-more__img--ios-H5 image {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}
@keyframes loading-ios-H5 {
0% {
transform: rotate(0deg);
}
8% {
transform: rotate(30deg);
}
16% {
transform: rotate(60deg);
}
24% {
transform: rotate(90deg);
}
32% {
transform: rotate(120deg);
}
40% {
transform: rotate(150deg);
}
48% {
transform: rotate(180deg);
}
56% {
transform: rotate(210deg);
}
64% {
transform: rotate(240deg);
}
73% {
transform: rotate(270deg);
}
82% {
transform: rotate(300deg);
}
91% {
transform: rotate(330deg);
}
100% {
transform: rotate(360deg);
}
}
/* #endif */
/* #ifdef H5 */
.uni-load-more__img--android-H5 {
animation: loading-android-H5-rotate 2s linear infinite;
transform-origin: center center;
}
.uni-load-more__img--android-H5 circle {
display: inline-block;
animation: loading-android-H5-dash 1.5s ease-in-out infinite;
stroke: currentColor;
stroke-linecap: round;
}
@keyframes loading-android-H5-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-H5-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -40;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -120;
}
}
/* #endif */
/* #ifndef APP-NVUE || H5 */
.uni-load-more__img--android-MP {
position: relative;
width: 24px;
height: 24px;
transform: rotate(0deg);
animation: loading-ios 1s 0s ease infinite;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon {
position: absolute;
box-sizing: border-box;
width: 100%;
height: 100%;
border-radius: 50%;
border: solid 2px transparent;
border-top: solid 2px #777777;
transform-origin: center;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(1) {
animation: loading-android-MP-1 1s 0s linear infinite;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(2) {
animation: loading-android-MP-2 1s 0s linear infinite;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(3) {
animation: loading-android-MP-3 1s 0s linear infinite;
}
@keyframes loading-android {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-MP-1 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(90deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-MP-2 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-MP-3 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(270deg);
}
100% {
transform: rotate(360deg);
}
}
/* #endif */
</style>
<template>
<view class="uni-load-more" @click="onClick">
<!-- #ifdef APP-NVUE -->
<loading-indicator v-if="!webviewHide && status === 'loading' && showIcon"
:style="{color: color,width:iconSize+'px',height:iconSize+'px'}" :animating="true"
class="uni-load-more__img uni-load-more__img--nvue"></loading-indicator>
<!-- #endif -->
<!-- #ifdef H5 -->
<svg width="24" height="24" viewBox="25 25 50 50"
v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
:style="{width:iconSize+'px',height:iconSize+'px'}"
class="uni-load-more__img uni-load-more__img--android-H5">
<circle cx="50" cy="50" r="20" fill="none" :style="{color:color}" :stroke-width="3"></circle>
</svg>
<!-- #endif -->
<!-- #ifndef APP-NVUE || H5 -->
<view
v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
:style="{width:iconSize+'px',height:iconSize+'px'}"
class="uni-load-more__img uni-load-more__img--android-MP">
<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view v-else-if="!webviewHide && status === 'loading' && showIcon"
:style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--ios-H5">
<image :src="imgBase64" mode="widthFix"></image>
</view>
<!-- #endif -->
<text v-if="showText" class="uni-load-more__text"
:style="{color: color}">{{ status === 'more' ? contentdownText : status === 'loading' ? contentrefreshText : contentnomoreText }}</text>
</view>
</template>
<script>
let platform
setTimeout(() => {
platform = uni.getSystemInfoSync().platform
}, 16)
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const {
t
} = initVueI18n(messages)
/**
* LoadMore 加载更多
* @description 用于列表中,做滚动加载使用,展示 loading 的各种状态
* @tutorial https://ext.dcloud.net.cn/plugin?id=29
* @property {String} status = [more|loading|noMore] loading 的状态
* @value more loading前
* @value loading loading中
* @value noMore 没有更多了
* @property {Number} iconSize 指定图标大小
* @property {Boolean} iconSize = [true|false] 是否显示 loading 图标
* @property {String} iconType = [snow|circle|auto] 指定图标样式
* @value snow ios雪花加载样式
* @value circle 安卓唤醒加载样式
* @value auto 根据平台自动选择加载样式
* @property {String} color 图标和文字颜色
* @property {Object} contentText 各状态文字说明,值为:{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}
* @event {Function} clickLoadMore 点击加载更多时触发
*/
export default {
name: 'UniLoadMore',
emits: ['clickLoadMore'],
props: {
status: {
// 上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
type: String,
default: 'more'
},
showIcon: {
type: Boolean,
default: true
},
iconType: {
type: String,
default: 'auto'
},
iconSize: {
type: Number,
default: 24
},
color: {
type: String,
default: '#777777'
},
contentText: {
type: Object,
default () {
return {
contentdown: '',
contentrefresh: '',
contentnomore: ''
}
}
},
showText: {
type: Boolean,
default: true
}
},
data() {
return {
webviewHide: false,
platform: platform,
imgBase64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZVHb98LM+F5bHL8khA1iSeiyQBCRM+YGqKUnnJTDLGI0BGZlKDIU2MMglUiDApEZvSsZnQtBRJtKwQNKQMFYeRDR10WOLd8ljYXdh+v8v5fR3Od+797t1dnOnO/Ofce77z+J//+b/P+ZqtXbs2sJ9MJhNUV1cHJ06cCJo3bx7EPc2aNcvpy7pWrVoF+/fvDyoqKoI2bdoE9fX1F7TjN8a+EXBn/fkfvw942Tf+wYMHg9mzZwfjxo0LDhw4EPa1x2MbFw/fOGfPng1qa2tzcCkILsLDydq2bRsunpOTMM7TD/W/tZDZhPdeKD+yGxHhdu3aBV27dg3OnDlzMVANMheLAO3btw8KCwuDmpoaX5OxbgUIMEq7K8IcPnw4KCsrC/r37x8cP378/4cAXAB3vqSkJMuiDhTkw+XcuXNhOWbMmKBly5YhUT8xArhyFvP0BfwRsAuwxJZJsm/nzp2DTp06he/OU+cZ64K6o0ePBkOHDg2GDx8e6gEbJ5Q/NHNuAJQ1hgBeHUDlR7nVTkY8rQAvAi4z34vR/mPs1FoRsaCgIJThI0eOBC1atEiFGGV+5MiRoS45efJkqFjJFXV1dQuA012m2WcwTw98fy6CqBdsaiIO4CScrGPHjvk4odhavPquRtFWXEC25VgkREKOCh/qDSq+vn37htzD/mZTOmOc5U7zKzBPEedygWshcDyWvs30igAbU+6oyMgJBCFhwQE0fccxN60Ay9iebbjoDh06hMowjQxT4fXq1SskArmHZpkArvixp/kWzHdMeArExSJEaiXIjjRjRJ4DaAGWpibLzXN3Fm1vA5teBgh3j1Rv3bp1YgKwPdmf2p9zcyNYYgPKMfY0T5f5nNYdw158nJ8QawW4CLKwiOBSEgO/hok2eBydR+3dYH+PLxA5J8Vv0KBBwenTp0P2JWAx6+yFEBfs8lMY+y0SWMBNI9E4ThKi58VKTg3FQZS1RQF1cz27eC0QHMu+3E0SkUowjhVt5VdaWhp07949ZHv2Qd1EjDXM2cla1M0nl3GxAs3J9yREzyTdFVKVFOaE9qRA8GM0WebRuo9JGZKA7Mv2SeS/Z8+eoQ9BArMfFrLGo6jvxbhHbJZnKX2Rzz1O7QhJJ9Cs2ZMaWIyq/zhdeqPNfIoHd58clIQD+JSXl4dKlyIAuBdVXZwFVWKspSSoxE++h8x4k3uCnEhE4I5KwRiFWGOU0QWKiCYLbdoRMRKAu2kQ9vkfLU6dOhX06NEjlH+yMRZSinnuyWnYosVcji8CEA/6Cg2JF+IIUBqnGKUTCNwtwBN4f89RiK1R96DEgO2o0NDmtEdvVFdVVYV+P3UAPUEs6GFwV3PHmXkD4vh74iDFJysVI/MlaQhwKeBNTLYX5VuA8T4/gZxA4MRGFxDB6R7OmYPfyykGRJbyie+XnGYnQIC/coH9+vULiYrxrkL9ZA9+0ykaHIfEpM7ge8TiJ2CsHYwyMfafAF1yCGBHYIbCVDjDjKt7BeB51D+LgQa6OkG7IDYEEtvQ7lnXLKLtLdLuJBpE4gPUXcW2+PkZwOex+4cGDhwYDBkyRL7/HFcEwUGPo/8uWRUpYnfxGHco8HkewLHLyYmAawAPuIFZxhOpDfJQ8gbUv41yORAptMWBNr6oqMhWird5+u+iHmBb2nhjDV7HWBNQTgK8y11l5NetWzc5ULscAtSj7nbNI0skhWeUZCc0W4nyH/jO4Vz0u1IeYhbk4AiwM6tjxIWByHsoZ9qcIBPJd/y+DwPfBESOmCa/QF3WiZHucLlEDpNxcNhmheEOPgdQNx6/VZFQzFZ5TN08AHXQt2Ii3EdyFuUsPtTcGPhW5iMiCNELvz+Gdn9huG4HUJaW/w3g0wxV0XaG7arG2WeKiUWYM4Y7GO5ezshTARbbWGw/DvXkpp/ivVvE0JVoMxN4rpGzJMhE5Pl+xlATsDIqikP9F9D2z3h9nOksEUFhK+qO4rcPkoalMQ/HqJLIyb3F3JdjrCcw1yZ8joyJLR5gCo54etlag7qIoeNh1N1BRYj3DTFJ0elotxPlVzkGuYAmL0VSJVGAJA41c4Z6A3BzTLfn0HYwYKEI6CUAMzZEWvLsIcQOo1AmmyyM72nHJCfYsogflGV6jEk9vyQZXSuq6w4c16NsGcGZbwOPr+H1RkOk2LEzjNepxQkihHSCQ4ynAYNRx2zMKV92CQMWqj8J0BRE8EShxRFN6YrfCRhC0x3r/Zm4IbQCcmJoV0kMamllccR6FjHqUC5F2R/wS2dcymOlfAKOS4KmzQb5cpNC2MC7JhVn5wjXoJ44rYhLh8n0eXOCorJxa7POjbSlCGVczr34/RsAmrcvo9s+wGp3tzVhntxiXiJ4nvEYb4FJkf0O8HocAePmLvCxnL0AORraVekJk6TYjDabRVXfRE2lCN1h6ZQRN1+InUbsCpKwoBZHh0dODN9JBCUffItXxEavTQkUtnfTVAplCWL3JISz29h4NjotnuSsQKJCk8dF+kJR6RARjrqFVmfPnj3ZbK8cIJ0msd6jgHPGtfVTQ8VLmlvh4mct9sobRmPic0DyDQQnx/NlfYUgyz59+oScsH379pAwXABD32nTpoUHIToESeI5mnbE/UqDdyLcafEBf2MCqgC7NwxIbMREJQ0g4D4sfJwnD+AmRrII05cfMWJE+L1169bQr+fip06dGp4oJ83lmYd5wj/EmMa4TaHivo4EeCguYZBnkB5g2aWA69OIEnUHOaGysjIYMGBAMGnSpODYsWPZwCpFmm4lNq+4gSLQA7jcX8DwtjEyRC8wjabnXEx9kfWnTJkSJkAo90xpJVV+FmcVNeYAF5zWngS4C4O91MBxmAv8blLEpbjI5sz9MTdAhcgkCT1RO8mZkAjfiYpTEvStAS53Uw1vAiUGgZ3GpuQEYvoiBqlIan7kSDHnTwJQFNiPu0+5VxCVYhcZIjNrdXUDdp+Eq5AZ3Gkg8QAyVZRZIk4Tl4QAbF9cXJxNYZMAtAokgs4BrNxEpCtteXg7DDTMDKYNSuQdKsnJBek7HxewvxaosWxLYXtw+cJp18217wql4aKCfBNoEu0O5VU+PhctJ0YeXD4C6JQpyrlpSLTojpGGGN5YwNziChdIZLk4lvLcFJ9jMX3QdiImY9bmGQU+TRUL5CHITTRlgF8D9ouD1MfmLoEPl5xokIumZ2cfgMpHt47IW9N64Hsh7wQYYjyIugWuF5fCqYncXRd5vPMWyizzvhi/32+nvG0dZc9vR6fZOu0md5e+uC408FvKSIOZwXlGvxPv95izA2Vtvg1xKFWARI+vMX66HUhpQQb643uW1bSjuTWyw2SBvDrBvjFic1eGGlz5esq3ko9uSIlBRqPuFcCv8F4WIcN12nVaBd0SaYwI6PDDImR11JkqgHcPmQssjxIn6bUshygDFJUTxPMpHk+jfjPgupgdnYV2R/g7xSjtpah8RJBewhwf0gGK6XI92u4wXFEU40afJ4DN4h5LcAd+40HI3JgJecuT0c062W0i2hQJUTcxan3/CMW1PF2K6bbA+Daz4xRs1D3Br1Cm0OihKCqizW78/nXAF/G5TXrEcVzaNMH6CyMswqsAHqDyDLEyou8lwOXnKF8DjI6KjV3KzMBiXkDH8ij/H214J5A596ekrZ3F0zXlWeL7+P5eUrNo3/QwC15uxthuzidy7DzKRwEDaAViiDgKbTbz7CJnzo0bN7pIfIiid8SuPwn25o3QCmpnyjlZkyxPP8EomCJzrGb7GJMx7tNsq4MT2Line truncated
}
},
computed: {
iconSnowWidth() {
return (Math.floor(this.iconSize / 24) || 1) * 2
},
contentdownText() {
return this.contentText.contentdown || t("uni-load-more.contentdown")
},
contentrefreshText() {
return this.contentText.contentrefresh || t("uni-load-more.contentrefresh")
},
contentnomoreText() {
return this.contentText.contentnomore || t("uni-load-more.contentnomore")
}
},
mounted() {
// #ifdef APP-PLUS
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page.$getAppWebview();
currentWebview.addEventListener('hide', () => {
this.webviewHide = true
})
currentWebview.addEventListener('show', () => {
this.webviewHide = false
})
// #endif
},
methods: {
onClick() {
this.$emit('clickLoadMore', {
detail: {
status: this.status,
}
})
}
}
}
</script>
<style lang="scss" >
.uni-load-more {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
height: 40px;
align-items: center;
justify-content: center;
}
.uni-load-more__text {
font-size: 14px;
margin-left: 8px;
}
.uni-load-more__img {
width: 24px;
height: 24px;
// margin-right: 8px;
}
.uni-load-more__img--nvue {
color: #666666;
}
.uni-load-more__img--android,
.uni-load-more__img--ios {
width: 24px;
height: 24px;
transform: rotate(0deg);
}
/* #ifndef APP-NVUE */
.uni-load-more__img--android {
animation: loading-ios 1s 0s linear infinite;
}
@keyframes loading-android {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.uni-load-more__img--ios-H5 {
position: relative;
animation: loading-ios-H5 1s 0s step-end infinite;
}
.uni-load-more__img--ios-H5 image {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}
@keyframes loading-ios-H5 {
0% {
transform: rotate(0deg);
}
8% {
transform: rotate(30deg);
}
16% {
transform: rotate(60deg);
}
24% {
transform: rotate(90deg);
}
32% {
transform: rotate(120deg);
}
40% {
transform: rotate(150deg);
}
48% {
transform: rotate(180deg);
}
56% {
transform: rotate(210deg);
}
64% {
transform: rotate(240deg);
}
73% {
transform: rotate(270deg);
}
82% {
transform: rotate(300deg);
}
91% {
transform: rotate(330deg);
}
100% {
transform: rotate(360deg);
}
}
/* #endif */
/* #ifdef H5 */
.uni-load-more__img--android-H5 {
animation: loading-android-H5-rotate 2s linear infinite;
transform-origin: center center;
}
.uni-load-more__img--android-H5 circle {
display: inline-block;
animation: loading-android-H5-dash 1.5s ease-in-out infinite;
stroke: currentColor;
stroke-linecap: round;
}
@keyframes loading-android-H5-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-H5-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -40;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -120;
}
}
/* #endif */
/* #ifndef APP-NVUE || H5 */
.uni-load-more__img--android-MP {
position: relative;
width: 24px;
height: 24px;
transform: rotate(0deg);
animation: loading-ios 1s 0s ease infinite;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon {
position: absolute;
box-sizing: border-box;
width: 100%;
height: 100%;
border-radius: 50%;
border: solid 2px transparent;
border-top: solid 2px #777777;
transform-origin: center;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(1) {
animation: loading-android-MP-1 1s 0s linear infinite;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(2) {
animation: loading-android-MP-2 1s 0s linear infinite;
}
.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(3) {
animation: loading-android-MP-3 1s 0s linear infinite;
}
@keyframes loading-android {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-MP-1 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(90deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-MP-2 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loading-android-MP-3 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(270deg);
}
100% {
transform: rotate(360deg);
}
}
/* #endif */
</style>
+85 -85
View File
@@ -1,86 +1,86 @@
{
"id": "uni-load-more",
"displayName": "uni-load-more 加载更多",
"version": "1.3.3",
"description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
"keywords": [
"uni-ui",
"uniui",
"加载更多",
"load-more"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-load-more",
"displayName": "uni-load-more 加载更多",
"version": "1.3.3",
"description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
"keywords": [
"uni-ui",
"uniui",
"加载更多",
"load-more"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+14 -14
View File
@@ -1,14 +1,14 @@
### LoadMore 加载更多
> **组件名:uni-load-more**
> 代码块: `uLoadMore`
用于列表中,做滚动加载使用,展示 loading 的各种状态。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
### LoadMore 加载更多
> **组件名:uni-load-more**
> 代码块: `uLoadMore`
用于列表中,做滚动加载使用,展示 loading 的各种状态。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+39 -39
View File
@@ -1,39 +1,39 @@
## 1.3.5(2022-05-24)
- 新增 stat 属性 ,可开启统计title 上报 ,仅使用了title 属性且项目开启了uni统计生效
## 1.3.4(2022-01-24)
- 更新 组件示例
## 1.3.3(2022-01-24)
- 新增 left-width/right-width属性 ,可修改左右两侧的宽度
## 1.3.2(2022-01-18)
- 修复 在vue下,标题不垂直居中的bug
## 1.3.1(2022-01-18)
- 修复 height 属性类型错误
## 1.3.0(2022-01-18)
- 新增 height 属性,可修改组件高度
- 新增 dark 属性可可开启暗黑模式
- 优化 标题字数过多显示省略号
- 优化 插槽,插入内容可完全覆盖
## 1.2.1(2022-01-10)
- 修复 color 属性不生效的bug
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-nav-bar](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.11(2021-05-12)
- 新增 组件示例地址
## 1.0.10(2021-04-30)
- 修复 在nvue下fixed为true,宽度不能撑满的Bug
## 1.0.9(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.8(2021-04-14)
- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
## 1.0.7(2021-02-25)
- 修复 easycom 下,找不到 uni-status-bar 的bug
## 1.0.6(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.5(2021-02-05)
- 调整为uni_modules目录规范
## 1.3.5(2022-05-24)
- 新增 stat 属性 ,可开启统计title 上报 ,仅使用了title 属性且项目开启了uni统计生效
## 1.3.4(2022-01-24)
- 更新 组件示例
## 1.3.3(2022-01-24)
- 新增 left-width/right-width属性 ,可修改左右两侧的宽度
## 1.3.2(2022-01-18)
- 修复 在vue下,标题不垂直居中的bug
## 1.3.1(2022-01-18)
- 修复 height 属性类型错误
## 1.3.0(2022-01-18)
- 新增 height 属性,可修改组件高度
- 新增 dark 属性可可开启暗黑模式
- 优化 标题字数过多显示省略号
- 优化 插槽,插入内容可完全覆盖
## 1.2.1(2022-01-10)
- 修复 color 属性不生效的bug
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-nav-bar](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.11(2021-05-12)
- 新增 组件示例地址
## 1.0.10(2021-04-30)
- 修复 在nvue下fixed为true,宽度不能撑满的Bug
## 1.0.9(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.8(2021-04-14)
- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
## 1.0.7(2021-02-25)
- 修复 easycom 下,找不到 uni-status-bar 的bug
## 1.0.6(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.5(2021-02-05)
- 调整为uni_modules目录规范
@@ -1,348 +1,348 @@
<template>
<view class="uni-navbar" :class="{'uni-dark':dark}">
<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }"
:style="{ 'background-color': themeBgColor }" class="uni-navbar__content">
<status-bar v-if="statusBar" />
<view :style="{ color: themeColor,backgroundColor: themeBgColor ,height:navbarHeight}"
class="uni-navbar__header">
<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left"
:style="{width:leftIconWidth}">
<slot name="left">
<view class="uni-navbar__content_view" v-if="leftIcon.length > 0">
<uni-icons :color="themeColor" :type="leftIcon" size="20" />
</view>
<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text"
v-if="leftText.length">
<text :style="{ color: themeColor, fontSize: '12px' }">{{ leftText }}</text>
</view>
</slot>
</view>
<view class="uni-navbar__header-container " @tap="onClickTitle">
<slot>
<view class="uni-navbar__header-container-inner" v-if="title.length>0">
<text class="uni-nav-bar-text uni-ellipsis-1"
:style="{color: themeColor }">{{ title }}</text>
</view>
</slot>
</view>
<view @click="onClickRight" class="uni-navbar__header-btns uni-navbar__header-btns-right"
:style="{width:rightIconWidth}">
<slot name="right">
<view v-if="rightIcon.length">
<uni-icons :color="themeColor" :type="rightIcon" size="22" />
</view>
<view class="uni-navbar-btn-text" v-if="rightText.length && !rightIcon.length">
<text class="uni-nav-bar-right-text" :style="{ color: themeColor}">{{ rightText }}</text>
</view>
</slot>
</view>
</view>
</view>
<view class="uni-navbar__placeholder" v-if="fixed">
<status-bar v-if="statusBar" />
<view class="uni-navbar__placeholder-view" :style="{ height:navbarHeight}" />
</view>
</view>
</template>
<script>
import statusBar from "./uni-status-bar.vue";
const getVal = (val) => typeof val === 'number' ? val + 'px' : val;
/**
* NavBar 自定义导航栏
* @description 导航栏组件,主要用于头部导航
* @tutorial https://ext.dcloud.net.cn/plugin?id=52
* @property {Boolean} dark 开启黑暗模式
* @property {String} title 标题文字
* @property {String} leftText 左侧按钮文本
* @property {String} rightText 右侧按钮文本
* @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
* @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
* @property {String} color 图标和文字颜色
* @property {String} backgroundColor 导航栏背景颜色
* @property {Boolean} fixed = [true|false] 是否固定顶部
* @property {Boolean} statusBar = [true|false] 是否包含状态栏
* @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
* @property {Boolean} stat 是否开启统计标题上报
* @event {Function} clickLeft 左侧按钮点击时触发
* @event {Function} clickRight 右侧按钮点击时触发
* @event {Function} clickTitle 中间标题点击时触发
*/
export default {
name: "UniNavBar",
components: {
statusBar
},
emits: ['clickLeft', 'clickRight', 'clickTitle'],
props: {
dark: {
type: Boolean,
default: false
},
title: {
type: String,
default: ""
},
leftText: {
type: String,
default: ""
},
rightText: {
type: String,
default: ""
},
leftIcon: {
type: String,
default: ""
},
rightIcon: {
type: String,
default: ""
},
fixed: {
type: [Boolean, String],
default: false
},
color: {
type: String,
default: ""
},
backgroundColor: {
type: String,
default: ""
},
statusBar: {
type: [Boolean, String],
default: false
},
shadow: {
type: [Boolean, String],
default: false
},
border: {
type: [Boolean, String],
default: true
},
height: {
type: [Number, String],
default: 44
},
leftWidth: {
type: [Number, String],
default: 60
},
rightWidth: {
type: [Number, String],
default: 60
},
stat: {
type: [Boolean, String],
default: ''
}
},
computed: {
themeBgColor() {
if (this.dark) {
// 默认值
if (this.backgroundColor) {
return this.backgroundColor
} else {
return this.dark ? '#333' : '#FFF'
}
}
return this.backgroundColor || '#FFF'
},
themeColor() {
if (this.dark) {
// 默认值
if (this.color) {
return this.color
} else {
return this.dark ? '#fff' : '#333'
}
}
return this.color || '#333'
},
navbarHeight() {
return getVal(this.height)
},
leftIconWidth() {
return getVal(this.leftWidth)
},
rightIconWidth() {
return getVal(this.rightWidth)
}
},
mounted() {
if (uni.report && this.stat && this.title !== '') {
uni.report('title', this.title)
}
},
methods: {
onClickLeft() {
this.$emit("clickLeft");
},
onClickRight() {
this.$emit("clickRight");
},
onClickTitle() {
this.$emit("clickTitle");
}
}
};
</script>
<style lang="scss" scoped>
$nav-height: 44px;
.uni-navbar {
// box-sizing: border-box;
}
.uni-nav-bar-text {
/* #ifdef APP-PLUS */
font-size: 34rpx;
/* #endif */
/* #ifndef APP-PLUS */
font-size: 14px;
/* #endif */
}
.uni-nav-bar-right-text {
font-size: 12px;
}
.uni-navbar__content {
position: relative;
// background-color: #fff;
// box-sizing: border-box;
background-color: transparent;
}
.uni-navbar__content_view {
// box-sizing: border-box;
}
.uni-navbar-btn-text {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: flex-start;
align-items: center;
line-height: 12px;
}
.uni-navbar__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
padding: 0 10px;
flex-direction: row;
height: $nav-height;
font-size: 12px;
}
.uni-navbar__header-btns {
/* #ifndef APP-NVUE */
overflow: hidden;
display: flex;
/* #endif */
flex-wrap: nowrap;
flex-direction: row;
width: 120rpx;
// padding: 0 6px;
justify-content: center;
align-items: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-navbar__header-btns-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
width: 120rpx;
justify-content: flex-start;
align-items: center;
}
.uni-navbar__header-btns-right {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
// width: 150rpx;
// padding-right: 30rpx;
justify-content: flex-end;
align-items: center;
}
.uni-navbar__header-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
padding: 0 10px;
overflow: hidden;
}
.uni-navbar__header-container-inner {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: 12px;
overflow: hidden;
// box-sizing: border-box;
}
.uni-navbar__placeholder-view {
height: $nav-height;
}
.uni-navbar--fixed {
position: fixed;
z-index: 998;
/* #ifdef H5 */
left: var(--window-left);
right: var(--window-right);
/* #endif */
/* #ifndef H5 */
left: 0;
right: 0;
/* #endif */
}
.uni-navbar--shadow {
box-shadow: 0 1px 6px #ccc;
}
.uni-navbar--border {
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #eee;
}
.uni-ellipsis-1 {
overflow: hidden;
/* #ifndef APP-NVUE */
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
text-overflow: ellipsis;
/* #endif */
}
// 暗主题配置
.uni-dark {}
</style>
<template>
<view class="uni-navbar" :class="{'uni-dark':dark}">
<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }"
:style="{ 'background-color': themeBgColor }" class="uni-navbar__content">
<status-bar v-if="statusBar" />
<view :style="{ color: themeColor,backgroundColor: themeBgColor ,height:navbarHeight}"
class="uni-navbar__header">
<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left"
:style="{width:leftIconWidth}">
<slot name="left">
<view class="uni-navbar__content_view" v-if="leftIcon.length > 0">
<uni-icons :color="themeColor" :type="leftIcon" size="20" />
</view>
<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text"
v-if="leftText.length">
<text :style="{ color: themeColor, fontSize: '12px' }">{{ leftText }}</text>
</view>
</slot>
</view>
<view class="uni-navbar__header-container " @tap="onClickTitle">
<slot>
<view class="uni-navbar__header-container-inner" v-if="title.length>0">
<text class="uni-nav-bar-text uni-ellipsis-1"
:style="{color: themeColor }">{{ title }}</text>
</view>
</slot>
</view>
<view @click="onClickRight" class="uni-navbar__header-btns uni-navbar__header-btns-right"
:style="{width:rightIconWidth}">
<slot name="right">
<view v-if="rightIcon.length">
<uni-icons :color="themeColor" :type="rightIcon" size="22" />
</view>
<view class="uni-navbar-btn-text" v-if="rightText.length && !rightIcon.length">
<text class="uni-nav-bar-right-text" :style="{ color: themeColor}">{{ rightText }}</text>
</view>
</slot>
</view>
</view>
</view>
<view class="uni-navbar__placeholder" v-if="fixed">
<status-bar v-if="statusBar" />
<view class="uni-navbar__placeholder-view" :style="{ height:navbarHeight}" />
</view>
</view>
</template>
<script>
import statusBar from "./uni-status-bar.vue";
const getVal = (val) => typeof val === 'number' ? val + 'px' : val;
/**
* NavBar 自定义导航栏
* @description 导航栏组件,主要用于头部导航
* @tutorial https://ext.dcloud.net.cn/plugin?id=52
* @property {Boolean} dark 开启黑暗模式
* @property {String} title 标题文字
* @property {String} leftText 左侧按钮文本
* @property {String} rightText 右侧按钮文本
* @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
* @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
* @property {String} color 图标和文字颜色
* @property {String} backgroundColor 导航栏背景颜色
* @property {Boolean} fixed = [true|false] 是否固定顶部
* @property {Boolean} statusBar = [true|false] 是否包含状态栏
* @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
* @property {Boolean} stat 是否开启统计标题上报
* @event {Function} clickLeft 左侧按钮点击时触发
* @event {Function} clickRight 右侧按钮点击时触发
* @event {Function} clickTitle 中间标题点击时触发
*/
export default {
name: "UniNavBar",
components: {
statusBar
},
emits: ['clickLeft', 'clickRight', 'clickTitle'],
props: {
dark: {
type: Boolean,
default: false
},
title: {
type: String,
default: ""
},
leftText: {
type: String,
default: ""
},
rightText: {
type: String,
default: ""
},
leftIcon: {
type: String,
default: ""
},
rightIcon: {
type: String,
default: ""
},
fixed: {
type: [Boolean, String],
default: false
},
color: {
type: String,
default: ""
},
backgroundColor: {
type: String,
default: ""
},
statusBar: {
type: [Boolean, String],
default: false
},
shadow: {
type: [Boolean, String],
default: false
},
border: {
type: [Boolean, String],
default: true
},
height: {
type: [Number, String],
default: 44
},
leftWidth: {
type: [Number, String],
default: 60
},
rightWidth: {
type: [Number, String],
default: 60
},
stat: {
type: [Boolean, String],
default: ''
}
},
computed: {
themeBgColor() {
if (this.dark) {
// 默认值
if (this.backgroundColor) {
return this.backgroundColor
} else {
return this.dark ? '#333' : '#FFF'
}
}
return this.backgroundColor || '#FFF'
},
themeColor() {
if (this.dark) {
// 默认值
if (this.color) {
return this.color
} else {
return this.dark ? '#fff' : '#333'
}
}
return this.color || '#333'
},
navbarHeight() {
return getVal(this.height)
},
leftIconWidth() {
return getVal(this.leftWidth)
},
rightIconWidth() {
return getVal(this.rightWidth)
}
},
mounted() {
if (uni.report && this.stat && this.title !== '') {
uni.report('title', this.title)
}
},
methods: {
onClickLeft() {
this.$emit("clickLeft");
},
onClickRight() {
this.$emit("clickRight");
},
onClickTitle() {
this.$emit("clickTitle");
}
}
};
</script>
<style lang="scss" scoped>
$nav-height: 44px;
.uni-navbar {
// box-sizing: border-box;
}
.uni-nav-bar-text {
/* #ifdef APP-PLUS */
font-size: 34rpx;
/* #endif */
/* #ifndef APP-PLUS */
font-size: 14px;
/* #endif */
}
.uni-nav-bar-right-text {
font-size: 12px;
}
.uni-navbar__content {
position: relative;
// background-color: #fff;
// box-sizing: border-box;
background-color: transparent;
}
.uni-navbar__content_view {
// box-sizing: border-box;
}
.uni-navbar-btn-text {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: flex-start;
align-items: center;
line-height: 12px;
}
.uni-navbar__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
padding: 0 10px;
flex-direction: row;
height: $nav-height;
font-size: 12px;
}
.uni-navbar__header-btns {
/* #ifndef APP-NVUE */
overflow: hidden;
display: flex;
/* #endif */
flex-wrap: nowrap;
flex-direction: row;
width: 120rpx;
// padding: 0 6px;
justify-content: center;
align-items: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-navbar__header-btns-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
width: 120rpx;
justify-content: flex-start;
align-items: center;
}
.uni-navbar__header-btns-right {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
// width: 150rpx;
// padding-right: 30rpx;
justify-content: flex-end;
align-items: center;
}
.uni-navbar__header-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
padding: 0 10px;
overflow: hidden;
}
.uni-navbar__header-container-inner {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: 12px;
overflow: hidden;
// box-sizing: border-box;
}
.uni-navbar__placeholder-view {
height: $nav-height;
}
.uni-navbar--fixed {
position: fixed;
z-index: 998;
/* #ifdef H5 */
left: var(--window-left);
right: var(--window-right);
/* #endif */
/* #ifndef H5 */
left: 0;
right: 0;
/* #endif */
}
.uni-navbar--shadow {
box-shadow: 0 1px 6px #ccc;
}
.uni-navbar--border {
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #eee;
}
.uni-ellipsis-1 {
overflow: hidden;
/* #ifndef APP-NVUE */
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
text-overflow: ellipsis;
/* #endif */
}
// 暗主题配置
.uni-dark {}
</style>
@@ -1,27 +1,27 @@
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar">
<slot />
</view>
</template>
<script>
export default {
name: 'UniStatusBar',
data() {
return {
statusBarHeight: 20
}
},
mounted() {
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
}
}
</script>
<style lang="scss" >
.uni-status-bar {
// width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
</style>
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar">
<slot />
</view>
</template>
<script>
export default {
name: 'UniStatusBar',
data() {
return {
statusBarHeight: 20
}
},
mounted() {
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
}
}
</script>
<style lang="scss" >
.uni-status-bar {
// width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
</style>
+88 -88
View File
@@ -1,89 +1,89 @@
{
"id": "uni-nav-bar",
"displayName": "uni-nav-bar 自定义导航栏",
"version": "1.3.5",
"description": "自定义导航栏组件,主要用于头部导航。",
"keywords": [
"uni-ui",
"导航",
"导航栏",
"自定义导航栏"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-nav-bar",
"displayName": "uni-nav-bar 自定义导航栏",
"version": "1.3.5",
"description": "自定义导航栏组件,主要用于头部导航。",
"keywords": [
"uni-ui",
"导航",
"导航栏",
"自定义导航栏"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+15 -15
View File
@@ -1,15 +1,15 @@
## NavBar 导航栏
> **组件名:uni-nav-bar**
> 代码块: `uNavBar`
导航栏组件,主要用于头部导航。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
## NavBar 导航栏
> **组件名:uni-nav-bar**
> 代码块: `uNavBar`
导航栏组件,主要用于头部导航。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+16 -16
View File
@@ -1,16 +1,16 @@
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-notice-bar](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
## 1.1.1(2021-11-09)
- 新增 提供组件设计资源,组件样式调整
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.9(2021-05-12)
- 新增 组件示例地址
## 1.0.8(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.7(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.6(2021-02-05)
- 调整为uni_modules目录规范
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-notice-bar](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
## 1.1.1(2021-11-09)
- 新增 提供组件设计资源,组件样式调整
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.9(2021-05-12)
- 新增 组件示例地址
## 1.0.8(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.7(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.6(2021-02-05)
- 调整为uni_modules目录规范
@@ -1,395 +1,395 @@
<template>
<view v-if="show" class="uni-noticebar" :style="{ backgroundColor: backgroundColor }" @click="onClick">
<uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound"
:color="color" size="22" />
<view ref="textBox" class="uni-noticebar__content-wrapper"
:class="{'uni-noticebar__content-wrapper--scrollable':scrollable, 'uni-noticebar__content-wrapper--single':!scrollable && (single || moreText)}">
<view :id="elIdBox" class="uni-noticebar__content"
:class="{'uni-noticebar__content--scrollable':scrollable, 'uni-noticebar__content--single':!scrollable && (single || moreText)}">
<text :id="elId" ref="animationEle" class="uni-noticebar__content-text"
:class="{'uni-noticebar__content-text--scrollable':scrollable,'uni-noticebar__content-text--single':!scrollable && (single || showGetMore)}"
:style="{color:color, width:wrapWidth+'px', 'animationDuration': animationDuration, '-webkit-animationDuration': animationDuration ,animationPlayState: webviewHide?'paused':animationPlayState,'-webkit-animationPlayState':webviewHide?'paused':animationPlayState, animationDelay: animationDelay, '-webkit-animationDelay':animationDelay}">{{text}}</text>
</view>
</view>
<view v-if="showGetMore === true || showGetMore === 'true'" class="uni-noticebar__more uni-cursor-point"
@click="clickMore">
<text v-if="moreText.length > 0" :style="{ color: moreColor }" class="uni-noticebar__more-text">{{ moreText }}</text>
<uni-icons v-else type="right" :color="moreColor" size="16" />
</view>
<view class="uni-noticebar-close uni-cursor-point" v-if="(showClose === true || showClose === 'true') && (showGetMore === false || showGetMore === 'false')">
<uni-icons
type="closeempty" :color="color" size="16" @click="close" />
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom');
const animation = weex.requireModule('animation');
// #endif
/**
* NoticeBar 自定义导航栏
* @description 通告栏组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=30
* @property {Number} speed 文字滚动的速度,默认100px/秒
* @property {String} text 显示文字
* @property {String} backgroundColor 背景颜色
* @property {String} color 文字颜色
* @property {String} moreColor 查看更多文字的颜色
* @property {String} moreText 设置“查看更多”的文本
* @property {Boolean} single = [true|false] 是否单行
* @property {Boolean} scrollable = [true|false] 是否滚动,为true时,NoticeBar为单行
* @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
* @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
* @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标,为true时,NoticeBar为单行
* @event {Function} click 点击 NoticeBar 触发事件
* @event {Function} close 关闭 NoticeBar 触发事件
* @event {Function} getmore 点击”查看更多“时触发事件
*/
export default {
name: 'UniNoticeBar',
emits: ['click', 'getmore', 'close'],
props: {
text: {
type: String,
default: ''
},
moreText: {
type: String,
default: ''
},
backgroundColor: {
type: String,
default: '#FFF9EA'
},
speed: {
// 默认1s滚动100px
type: Number,
default: 100
},
color: {
type: String,
default: '#FF9A43'
},
moreColor: {
type: String,
default: '#FF9A43'
},
single: {
// 是否单行
type: [Boolean, String],
default: false
},
scrollable: {
// 是否滚动,添加后控制单行效果取消
type: [Boolean, String],
default: false
},
showIcon: {
// 是否显示左侧icon
type: [Boolean, String],
default: false
},
showGetMore: {
// 是否显示右侧查看更多
type: [Boolean, String],
default: false
},
showClose: {
// 是否显示左侧关闭按钮
type: [Boolean, String],
default: false
}
},
data() {
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
textWidth: 0,
boxWidth: 0,
wrapWidth: '',
webviewHide: false,
// #ifdef APP-NVUE
stopAnimation: false,
// #endif
elId: elId,
elIdBox: elIdBox,
show: true,
animationDuration: 'none',
animationPlayState: 'paused',
animationDelay: '0s'
}
},
mounted() {
// #ifdef APP-PLUS
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page.$getAppWebview();
currentWebview.addEventListener('hide', () => {
this.webviewHide = true
})
currentWebview.addEventListener('show', () => {
this.webviewHide = false
})
// #endif
this.$nextTick(() => {
this.initSize()
})
},
// #ifdef APP-NVUE
beforeDestroy() {
this.stopAnimation = true
},
// #endif
methods: {
initSize() {
if (this.scrollable) {
// #ifndef APP-NVUE
let query = [],
boxWidth = 0,
textWidth = 0;
let textQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elId}`)
.boundingClientRect()
.exec(ret => {
this.textWidth = ret[0].width
resolve()
})
})
let boxQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elIdBox}`)
.boundingClientRect()
.exec(ret => {
this.boxWidth = ret[0].width
resolve()
})
})
query.push(textQuery)
query.push(boxQuery)
Promise.all(query).then(() => {
this.animationDuration = `${this.textWidth / this.speed}s`
this.animationDelay = `-${this.boxWidth / this.speed}s`
setTimeout(() => {
this.animationPlayState = 'running'
}, 1000)
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['animationEle'], (res) => {
let winWidth = uni.getSystemInfoSync().windowWidth
this.textWidth = res.size.width
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${winWidth}px)`
},
duration: 0,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${this.textWidth}px)`
},
timingFunction: 'linear',
duration: (this.textWidth - winWidth) / this.speed * 1000,
delay: 1000
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
})
// #endif
}
// #ifdef APP-NVUE
if (!this.scrollable && (this.single || this.moreText)) {
dom.getComponentRect(this.$refs['textBox'], (res) => {
this.wrapWidth = res.size.width
})
}
// #endif
},
loopAnimation() {
// #ifdef APP-NVUE
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(0px)`
},
duration: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${this.textWidth}px)`
},
duration: this.textWidth / this.speed * 1000,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
// #endif
},
clickMore() {
this.$emit('getmore')
},
close() {
this.show = false;
this.$emit('close')
},
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" scoped>
.uni-noticebar {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
padding: 10px 12px;
margin-bottom: 10px;
}
.uni-cursor-point {
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-noticebar-close {
margin-left: 8px;
margin-right: 5px;
}
.uni-noticebar-icon {
margin-right: 5px;
}
.uni-noticebar__content-wrapper {
flex: 1;
flex-direction: column;
overflow: hidden;
}
.uni-noticebar__content-wrapper--single {
/* #ifndef APP-NVUE */
line-height: 18px;
/* #endif */
}
.uni-noticebar__content-wrapper--single,
.uni-noticebar__content-wrapper--scrollable {
flex-direction: row;
}
/* #ifndef APP-NVUE */
.uni-noticebar__content-wrapper--scrollable {
position: relative;
height: 18px;
}
/* #endif */
.uni-noticebar__content--scrollable {
/* #ifdef APP-NVUE */
flex: 0;
/* #endif */
/* #ifndef APP-NVUE */
flex: 1;
display: block;
overflow: hidden;
/* #endif */
}
.uni-noticebar__content--single {
/* #ifndef APP-NVUE */
display: flex;
flex: none;
width: 100%;
justify-content: center;
/* #endif */
}
.uni-noticebar__content-text {
font-size: 14px;
line-height: 18px;
/* #ifndef APP-NVUE */
word-break: break-all;
/* #endif */
}
.uni-noticebar__content-text--single {
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
/* #ifndef APP-NVUE */
display: block;
width: 100%;
white-space: nowrap;
/* #endif */
overflow: hidden;
text-overflow: ellipsis;
}
.uni-noticebar__content-text--scrollable {
/* #ifdef APP-NVUE */
lines: 1;
padding-left: 750rpx;
/* #endif */
/* #ifndef APP-NVUE */
position: absolute;
display: block;
height: 18px;
line-height: 18px;
white-space: nowrap;
padding-left: 100%;
animation: notice 10s 0s linear infinite both;
animation-play-state: paused;
/* #endif */
}
.uni-noticebar__more {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding-left: 5px;
}
.uni-noticebar__more-text {
font-size: 14px;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
</style>
<template>
<view v-if="show" class="uni-noticebar" :style="{ backgroundColor: backgroundColor }" @click="onClick">
<uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound"
:color="color" size="22" />
<view ref="textBox" class="uni-noticebar__content-wrapper"
:class="{'uni-noticebar__content-wrapper--scrollable':scrollable, 'uni-noticebar__content-wrapper--single':!scrollable && (single || moreText)}">
<view :id="elIdBox" class="uni-noticebar__content"
:class="{'uni-noticebar__content--scrollable':scrollable, 'uni-noticebar__content--single':!scrollable && (single || moreText)}">
<text :id="elId" ref="animationEle" class="uni-noticebar__content-text"
:class="{'uni-noticebar__content-text--scrollable':scrollable,'uni-noticebar__content-text--single':!scrollable && (single || showGetMore)}"
:style="{color:color, width:wrapWidth+'px', 'animationDuration': animationDuration, '-webkit-animationDuration': animationDuration ,animationPlayState: webviewHide?'paused':animationPlayState,'-webkit-animationPlayState':webviewHide?'paused':animationPlayState, animationDelay: animationDelay, '-webkit-animationDelay':animationDelay}">{{text}}</text>
</view>
</view>
<view v-if="showGetMore === true || showGetMore === 'true'" class="uni-noticebar__more uni-cursor-point"
@click="clickMore">
<text v-if="moreText.length > 0" :style="{ color: moreColor }" class="uni-noticebar__more-text">{{ moreText }}</text>
<uni-icons v-else type="right" :color="moreColor" size="16" />
</view>
<view class="uni-noticebar-close uni-cursor-point" v-if="(showClose === true || showClose === 'true') && (showGetMore === false || showGetMore === 'false')">
<uni-icons
type="closeempty" :color="color" size="16" @click="close" />
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom');
const animation = weex.requireModule('animation');
// #endif
/**
* NoticeBar 自定义导航栏
* @description 通告栏组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=30
* @property {Number} speed 文字滚动的速度,默认100px/秒
* @property {String} text 显示文字
* @property {String} backgroundColor 背景颜色
* @property {String} color 文字颜色
* @property {String} moreColor 查看更多文字的颜色
* @property {String} moreText 设置“查看更多”的文本
* @property {Boolean} single = [true|false] 是否单行
* @property {Boolean} scrollable = [true|false] 是否滚动,为true时,NoticeBar为单行
* @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
* @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
* @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标,为true时,NoticeBar为单行
* @event {Function} click 点击 NoticeBar 触发事件
* @event {Function} close 关闭 NoticeBar 触发事件
* @event {Function} getmore 点击”查看更多“时触发事件
*/
export default {
name: 'UniNoticeBar',
emits: ['click', 'getmore', 'close'],
props: {
text: {
type: String,
default: ''
},
moreText: {
type: String,
default: ''
},
backgroundColor: {
type: String,
default: '#FFF9EA'
},
speed: {
// 默认1s滚动100px
type: Number,
default: 100
},
color: {
type: String,
default: '#FF9A43'
},
moreColor: {
type: String,
default: '#FF9A43'
},
single: {
// 是否单行
type: [Boolean, String],
default: false
},
scrollable: {
// 是否滚动,添加后控制单行效果取消
type: [Boolean, String],
default: false
},
showIcon: {
// 是否显示左侧icon
type: [Boolean, String],
default: false
},
showGetMore: {
// 是否显示右侧查看更多
type: [Boolean, String],
default: false
},
showClose: {
// 是否显示左侧关闭按钮
type: [Boolean, String],
default: false
}
},
data() {
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
textWidth: 0,
boxWidth: 0,
wrapWidth: '',
webviewHide: false,
// #ifdef APP-NVUE
stopAnimation: false,
// #endif
elId: elId,
elIdBox: elIdBox,
show: true,
animationDuration: 'none',
animationPlayState: 'paused',
animationDelay: '0s'
}
},
mounted() {
// #ifdef APP-PLUS
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page.$getAppWebview();
currentWebview.addEventListener('hide', () => {
this.webviewHide = true
})
currentWebview.addEventListener('show', () => {
this.webviewHide = false
})
// #endif
this.$nextTick(() => {
this.initSize()
})
},
// #ifdef APP-NVUE
beforeDestroy() {
this.stopAnimation = true
},
// #endif
methods: {
initSize() {
if (this.scrollable) {
// #ifndef APP-NVUE
let query = [],
boxWidth = 0,
textWidth = 0;
let textQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elId}`)
.boundingClientRect()
.exec(ret => {
this.textWidth = ret[0].width
resolve()
})
})
let boxQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elIdBox}`)
.boundingClientRect()
.exec(ret => {
this.boxWidth = ret[0].width
resolve()
})
})
query.push(textQuery)
query.push(boxQuery)
Promise.all(query).then(() => {
this.animationDuration = `${this.textWidth / this.speed}s`
this.animationDelay = `-${this.boxWidth / this.speed}s`
setTimeout(() => {
this.animationPlayState = 'running'
}, 1000)
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['animationEle'], (res) => {
let winWidth = uni.getSystemInfoSync().windowWidth
this.textWidth = res.size.width
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${winWidth}px)`
},
duration: 0,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${this.textWidth}px)`
},
timingFunction: 'linear',
duration: (this.textWidth - winWidth) / this.speed * 1000,
delay: 1000
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
})
// #endif
}
// #ifdef APP-NVUE
if (!this.scrollable && (this.single || this.moreText)) {
dom.getComponentRect(this.$refs['textBox'], (res) => {
this.wrapWidth = res.size.width
})
}
// #endif
},
loopAnimation() {
// #ifdef APP-NVUE
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(0px)`
},
duration: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${this.textWidth}px)`
},
duration: this.textWidth / this.speed * 1000,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
// #endif
},
clickMore() {
this.$emit('getmore')
},
close() {
this.show = false;
this.$emit('close')
},
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" scoped>
.uni-noticebar {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
padding: 10px 12px;
margin-bottom: 10px;
}
.uni-cursor-point {
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-noticebar-close {
margin-left: 8px;
margin-right: 5px;
}
.uni-noticebar-icon {
margin-right: 5px;
}
.uni-noticebar__content-wrapper {
flex: 1;
flex-direction: column;
overflow: hidden;
}
.uni-noticebar__content-wrapper--single {
/* #ifndef APP-NVUE */
line-height: 18px;
/* #endif */
}
.uni-noticebar__content-wrapper--single,
.uni-noticebar__content-wrapper--scrollable {
flex-direction: row;
}
/* #ifndef APP-NVUE */
.uni-noticebar__content-wrapper--scrollable {
position: relative;
height: 18px;
}
/* #endif */
.uni-noticebar__content--scrollable {
/* #ifdef APP-NVUE */
flex: 0;
/* #endif */
/* #ifndef APP-NVUE */
flex: 1;
display: block;
overflow: hidden;
/* #endif */
}
.uni-noticebar__content--single {
/* #ifndef APP-NVUE */
display: flex;
flex: none;
width: 100%;
justify-content: center;
/* #endif */
}
.uni-noticebar__content-text {
font-size: 14px;
line-height: 18px;
/* #ifndef APP-NVUE */
word-break: break-all;
/* #endif */
}
.uni-noticebar__content-text--single {
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
/* #ifndef APP-NVUE */
display: block;
width: 100%;
white-space: nowrap;
/* #endif */
overflow: hidden;
text-overflow: ellipsis;
}
.uni-noticebar__content-text--scrollable {
/* #ifdef APP-NVUE */
lines: 1;
padding-left: 750rpx;
/* #endif */
/* #ifndef APP-NVUE */
position: absolute;
display: block;
height: 18px;
line-height: 18px;
white-space: nowrap;
padding-left: 100%;
animation: notice 10s 0s linear infinite both;
animation-play-state: paused;
/* #endif */
}
.uni-noticebar__more {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding-left: 5px;
}
.uni-noticebar__more-text {
font-size: 14px;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
</style>
+90 -90
View File
@@ -1,90 +1,90 @@
{
"id": "uni-notice-bar",
"displayName": "uni-notice-bar 通告栏",
"version": "1.2.0",
"description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告",
"keywords": [
"uni-ui",
"uniui",
"通告栏",
"公告",
"跑马灯"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
{
"id": "uni-notice-bar",
"displayName": "uni-notice-bar 通告栏",
"version": "1.2.0",
"description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告",
"keywords": [
"uni-ui",
"uniui",
"通告栏",
"公告",
"跑马灯"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+13 -13
View File
@@ -1,13 +1,13 @@
## NoticeBar 通告栏
> **组件名:uni-notice-bar**
> 代码块: `uNoticeBar`
通告栏组件 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
## NoticeBar 通告栏
> **组件名:uni-notice-bar**
> 代码块: `uNoticeBar`
通告栏组件 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+25 -25
View File
@@ -1,25 +1,25 @@
## 1.2.1(2021-11-22)
- 修复 vue3中某些scss变量无法找到的问题
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box)
## 1.1.2(2021-11-09)
- 新增 提供组件设计资源,组件样式调整
## 1.1.1(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.7(2021-05-12)
- 新增 组件示例地址
## 1.0.6(2021-04-20)
- 修复 uni-number-box 浮点数运算不精确的 bug
- 修复 uni-number-box change 事件触发不正确的 bug
- 新增 uni-number-box v-model 双向绑定
## 1.0.5(2021-02-05)
- 调整为uni_modules目录规范
## 1.0.7(2021-02-05)
- 调整为uni_modules目录规范
- 新增 支持 v-model
- 新增 支持 focus、blur 事件
- 新增 支持 PC 端
## 1.2.1(2021-11-22)
- 修复 vue3中某些scss变量无法找到的问题
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box)
## 1.1.2(2021-11-09)
- 新增 提供组件设计资源,组件样式调整
## 1.1.1(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.7(2021-05-12)
- 新增 组件示例地址
## 1.0.6(2021-04-20)
- 修复 uni-number-box 浮点数运算不精确的 bug
- 修复 uni-number-box change 事件触发不正确的 bug
- 新增 uni-number-box v-model 双向绑定
## 1.0.5(2021-02-05)
- 调整为uni_modules目录规范
## 1.0.7(2021-02-05)
- 调整为uni_modules目录规范
- 新增 支持 v-model
- 新增 支持 focus、blur 事件
- 新增 支持 PC 端
@@ -1,220 +1,220 @@
<template>
<view class="uni-numbox">
<view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}">
<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }" :style="{color}">-</text>
</view>
<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value" type="number"
v-model="inputValue" :style="{background, color}" />
<view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}">
<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }" :style="{color}">+</text>
</view>
</view>
</template>
<script>
/**
* NumberBox 数字输入框
* @description 带加减按钮的数字输入框
* @tutorial https://ext.dcloud.net.cn/plugin?id=31
* @property {Number} value 输入框当前值
* @property {Number} min 最小值
* @property {Number} max 最大值
* @property {Number} step 每次点击改变的间隔大小
* @property {String} background 背景色
* @property {String} color 字体颜色(前景色)
* @property {Boolean} disabled = [true|false] 是否为禁用状态
* @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value
* @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象
* @event {Function} blur 输入框失焦时触发的事件,参数为 event 对象
*/
export default {
name: "UniNumberBox",
emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'],
props: {
value: {
type: [Number, String],
default: 1
},
modelValue: {
type: [Number, String],
default: 1
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
step: {
type: Number,
default: 1
},
background: {
type: String,
default: '#f5f5f5'
},
color: {
type: String,
default: '#333'
},
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
inputValue: 0
};
},
watch: {
value(val) {
this.inputValue = +val;
},
modelValue(val) {
this.inputValue = +val;
}
},
created() {
if (this.value === 1) {
this.inputValue = +this.modelValue;
}
if (this.modelValue === 1) {
this.inputValue = +this.value;
}
},
methods: {
_calcValue(type) {
if (this.disabled) {
return;
}
const scale = this._getDecimalScale();
let value = this.inputValue * scale;
let step = this.step * scale;
if (type === "minus") {
value -= step;
if (value < (this.min * scale)) {
return;
}
if (value > (this.max * scale)) {
value = this.max * scale
}
}
if (type === "plus") {
value += step;
if (value > (this.max * scale)) {
return;
}
if (value < (this.min * scale)) {
value = this.min * scale
}
}
this.inputValue = (value / scale).toFixed(String(scale).length - 1);
this.$emit("change", +this.inputValue);
// TODO vue2 兼容
this.$emit("input", +this.inputValue);
// TODO vue3 兼容
this.$emit("update:modelValue", +this.inputValue);
},
_getDecimalScale() {
let scale = 1;
// 浮点型
if (~~this.step !== this.step) {
scale = Math.pow(10, String(this.step).split(".")[1].length);
}
return scale;
},
_onBlur(event) {
this.$emit('blur', event)
let value = event.detail.value;
if (!value) {
// this.inputValue = 0;
return;
}
value = +value;
if (value > this.max) {
value = this.max;
} else if (value < this.min) {
value = this.min;
}
const scale = this._getDecimalScale();
this.inputValue = value.toFixed(String(scale).length - 1);
this.$emit("change", +this.inputValue);
this.$emit("input", +this.inputValue);
},
_onFocus(event) {
this.$emit('focus', event)
}
}
};
</script>
<style lang="scss" scoped>
$box-height: 26px;
$bg: #f5f5f5;
$br: 2px;
$color: #333;
.uni-numbox {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-numbox-btns {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
background-color: $bg;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-numbox__value {
margin: 0 2px;
background-color: $bg;
width: 40px;
height: $box-height;
text-align: center;
font-size: 14px;
border-left-width: 0;
border-right-width: 0;
color: $color;
}
.uni-numbox__minus {
border-top-left-radius: $br;
border-bottom-left-radius: $br;
}
.uni-numbox__plus {
border-top-right-radius: $br;
border-bottom-right-radius: $br;
}
.uni-numbox--text {
// fix nvue
line-height: 20px;
font-size: 20px;
font-weight: 300;
color: $color;
}
.uni-numbox .uni-numbox--disabled {
color: #c0c0c0 !important;
/* #ifdef H5 */
cursor: not-allowed;
/* #endif */
}
</style>
<template>
<view class="uni-numbox">
<view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}">
<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }" :style="{color}">-</text>
</view>
<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value" type="number"
v-model="inputValue" :style="{background, color}" />
<view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}">
<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }" :style="{color}">+</text>
</view>
</view>
</template>
<script>
/**
* NumberBox 数字输入框
* @description 带加减按钮的数字输入框
* @tutorial https://ext.dcloud.net.cn/plugin?id=31
* @property {Number} value 输入框当前值
* @property {Number} min 最小值
* @property {Number} max 最大值
* @property {Number} step 每次点击改变的间隔大小
* @property {String} background 背景色
* @property {String} color 字体颜色(前景色)
* @property {Boolean} disabled = [true|false] 是否为禁用状态
* @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value
* @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象
* @event {Function} blur 输入框失焦时触发的事件,参数为 event 对象
*/
export default {
name: "UniNumberBox",
emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'],
props: {
value: {
type: [Number, String],
default: 1
},
modelValue: {
type: [Number, String],
default: 1
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
step: {
type: Number,
default: 1
},
background: {
type: String,
default: '#f5f5f5'
},
color: {
type: String,
default: '#333'
},
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
inputValue: 0
};
},
watch: {
value(val) {
this.inputValue = +val;
},
modelValue(val) {
this.inputValue = +val;
}
},
created() {
if (this.value === 1) {
this.inputValue = +this.modelValue;
}
if (this.modelValue === 1) {
this.inputValue = +this.value;
}
},
methods: {
_calcValue(type) {
if (this.disabled) {
return;
}
const scale = this._getDecimalScale();
let value = this.inputValue * scale;
let step = this.step * scale;
if (type === "minus") {
value -= step;
if (value < (this.min * scale)) {
return;
}
if (value > (this.max * scale)) {
value = this.max * scale
}
}
if (type === "plus") {
value += step;
if (value > (this.max * scale)) {
return;
}
if (value < (this.min * scale)) {
value = this.min * scale
}
}
this.inputValue = (value / scale).toFixed(String(scale).length - 1);
this.$emit("change", +this.inputValue);
// TODO vue2 兼容
this.$emit("input", +this.inputValue);
// TODO vue3 兼容
this.$emit("update:modelValue", +this.inputValue);
},
_getDecimalScale() {
let scale = 1;
// 浮点型
if (~~this.step !== this.step) {
scale = Math.pow(10, String(this.step).split(".")[1].length);
}
return scale;
},
_onBlur(event) {
this.$emit('blur', event)
let value = event.detail.value;
if (!value) {
// this.inputValue = 0;
return;
}
value = +value;
if (value > this.max) {
value = this.max;
} else if (value < this.min) {
value = this.min;
}
const scale = this._getDecimalScale();
this.inputValue = value.toFixed(String(scale).length - 1);
this.$emit("change", +this.inputValue);
this.$emit("input", +this.inputValue);
},
_onFocus(event) {
this.$emit('focus', event)
}
}
};
</script>
<style lang="scss" scoped>
$box-height: 26px;
$bg: #f5f5f5;
$br: 2px;
$color: #333;
.uni-numbox {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-numbox-btns {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
background-color: $bg;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-numbox__value {
margin: 0 2px;
background-color: $bg;
width: 40px;
height: $box-height;
text-align: center;
font-size: 14px;
border-left-width: 0;
border-right-width: 0;
color: $color;
}
.uni-numbox__minus {
border-top-left-radius: $br;
border-bottom-left-radius: $br;
}
.uni-numbox__plus {
border-top-right-radius: $br;
border-bottom-right-radius: $br;
}
.uni-numbox--text {
// fix nvue
line-height: 20px;
font-size: 20px;
font-weight: 300;
color: $color;
}
.uni-numbox .uni-numbox--disabled {
color: #c0c0c0 !important;
/* #ifdef H5 */
cursor: not-allowed;
/* #endif */
}
</style>
+84 -84
View File
@@ -1,85 +1,85 @@
{
"id": "uni-number-box",
"displayName": "uni-number-box 数字输入框",
"version": "1.2.1",
"description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。",
"keywords": [
"uni-ui",
"uniui",
"数字输入框"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-number-box",
"displayName": "uni-number-box 数字输入框",
"version": "1.2.1",
"description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。",
"keywords": [
"uni-ui",
"uniui",
"数字输入框"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+13 -13
View File
@@ -1,13 +1,13 @@
## NumberBox 数字输入框
> **组件名:uni-number-box**
> 代码块: `uNumberBox`
带加减按钮的数字输入框。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
## NumberBox 数字输入框
> **组件名:uni-number-box**
> 代码块: `uNumberBox`
带加减按钮的数字输入框。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+25 -25
View File
@@ -1,25 +1,25 @@
## 1.3.1(2022-02-25)
- 修复 条件判断 `NaN` 错误的 bug
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-rate](https://uniapp.dcloud.io/component/uniui/uni-rate)
## 1.2.2(2021-09-10)
- 优化 默认值修改为 0 颗星
## 1.2.1(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.2.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.2(2021-05-12)
- 新增 组件示例地址
## 1.1.1(2021-04-21)
- 修复 布局变化后 uni-rate 星星计算不准确的 bug
- 优化 添加依赖 uni-icons, 导入 uni-rate 自动下载依赖
## 1.1.0(2021-04-16)
- 修复 uni-rate 属性 margin 值为 string 组件失效的 bug
## 1.0.9(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.8(2021-02-05)
- 调整为uni_modules目录规范
- 支持 pc 端
## 1.3.1(2022-02-25)
- 修复 条件判断 `NaN` 错误的 bug
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-rate](https://uniapp.dcloud.io/component/uniui/uni-rate)
## 1.2.2(2021-09-10)
- 优化 默认值修改为 0 颗星
## 1.2.1(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.2.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.2(2021-05-12)
- 新增 组件示例地址
## 1.1.1(2021-04-21)
- 修复 布局变化后 uni-rate 星星计算不准确的 bug
- 优化 添加依赖 uni-icons, 导入 uni-rate 自动下载依赖
## 1.1.0(2021-04-16)
- 修复 uni-rate 属性 margin 值为 string 组件失效的 bug
## 1.0.9(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.8(2021-02-05)
- 调整为uni_modules目录规范
- 支持 pc 端
@@ -1,361 +1,361 @@
<template>
<view>
<view ref="uni-rate" class="uni-rate">
<view class="uni-rate__icon" :class="{'uni-cursor-not-allowed': disabled}"
:style="{ 'margin-right': marginNumber + 'px' }" v-for="(star, index) in stars" :key="index"
@touchstart.stop="touchstart" @touchmove.stop="touchmove" @mousedown.stop="mousedown"
@mousemove.stop="mousemove" @mouseleave="mouseleave">
<uni-icons :color="color" :size="size" :type="isFill ? 'star-filled' : 'star'" />
<!-- #ifdef APP-NVUE -->
<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on">
<uni-icons style="text-align: left;" :color="disabled?'#ccc':activeColor" :size="size"
type="star-filled" />
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view :style="{ width: star.activeWitch}" class="uni-rate__icon-on">
<uni-icons :color="disabled?disabledColor:activeColor" :size="size" type="star-filled" />
</view>
<!-- #endif -->
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
/**
* Rate 评分
* @description 评分组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=33
* @property {Boolean} isFill = [true|false] 星星的类型,是否为实心类型, 默认为实心
* @property {String} color 未选中状态的星星颜色,默认为 "#ececec"
* @property {String} activeColor 选中状态的星星颜色,默认为 "#ffca3e"
* @property {String} disabledColor 禁用状态的星星颜色,默认为 "#c0c0c0"
* @property {Number} size 星星的大小
* @property {Number} value/v-model 当前评分
* @property {Number} max 最大评分评分数量,目前一分一颗星
* @property {Number} margin 星星的间距,单位 px
* @property {Boolean} disabled = [true|false] 是否为禁用状态,默认为 false
* @property {Boolean} readonly = [true|false] 是否为只读状态,默认为 false
* @property {Boolean} allowHalf = [true|false] 是否实现半星,默认为 false
* @property {Boolean} touchable = [true|false] 是否支持滑动手势,默认为 true
* @event {Function} change uniRate 的 value 改变时触发事件,e={value:Number}
*/
export default {
name: "UniRate",
props: {
isFill: {
// 星星的类型,是否镂空
type: [Boolean, String],
default: true
},
color: {
// 星星未选中的颜色
type: String,
default: "#ececec"
},
activeColor: {
// 星星选中状态颜色
type: String,
default: "#ffca3e"
},
disabledColor: {
// 星星禁用状态颜色
type: String,
default: "#c0c0c0"
},
size: {
// 星星的大小
type: [Number, String],
default: 24
},
value: {
// 当前评分
type: [Number, String],
default: 0
},
modelValue: {
// 当前评分
type: [Number, String],
default: 0
},
max: {
// 最大评分
type: [Number, String],
default: 5
},
margin: {
// 星星的间距
type: [Number, String],
default: 0
},
disabled: {
// 是否可点击
type: [Boolean, String],
default: false
},
readonly: {
// 是否只读
type: [Boolean, String],
default: false
},
allowHalf: {
// 是否显示半星
type: [Boolean, String],
default: false
},
touchable: {
// 是否支持滑动手势
type: [Boolean, String],
default: true
}
},
data() {
return {
valueSync: "",
userMouseFristMove: true,
userRated: false,
userLastRate: 1
};
},
watch: {
value(newVal) {
this.valueSync = Number(newVal);
},
modelValue(newVal) {
this.valueSync = Number(newVal);
},
},
computed: {
stars() {
const value = this.valueSync ? this.valueSync : 0;
const starList = [];
const floorValue = Math.floor(value);
const ceilValue = Math.ceil(value);
for (let i = 0; i < this.max; i++) {
if (floorValue > i) {
starList.push({
activeWitch: "100%"
});
} else if (ceilValue - 1 === i) {
starList.push({
activeWitch: (value - floorValue) * 100 + "%"
});
} else {
starList.push({
activeWitch: "0"
});
}
}
return starList;
},
marginNumber() {
return Number(this.margin)
}
},
created() {
this.valueSync = Number(this.value || this.modelValue);
this._rateBoxLeft = 0
this._oldValue = null
},
mounted() {
setTimeout(() => {
this._getSize()
}, 100)
// #ifdef H5
this.PC = this.IsPC()
// #endif
},
methods: {
touchstart(e) {
// #ifdef H5
if (this.IsPC()) return
// #endif
if (this.readonly || this.disabled) return
const {
clientX,
screenX
} = e.changedTouches[0]
// TODO 做一下兼容,只有 Nvue 下才有 screenX,其他平台式 clientX
this._getRateCount(clientX || screenX)
},
touchmove(e) {
// #ifdef H5
if (this.IsPC()) return
// #endif
if (this.readonly || this.disabled || !this.touchable) return
const {
clientX,
screenX
} = e.changedTouches[0]
this._getRateCount(clientX || screenX)
},
/**
* 兼容 PC @tian
*/
mousedown(e) {
// #ifdef H5
if (!this.IsPC()) return
if (this.readonly || this.disabled) return
const {
clientX,
} = e
this.userLastRate = this.valueSync
this._getRateCount(clientX)
this.userRated = true
// #endif
},
mousemove(e) {
// #ifdef H5
if (!this.IsPC()) return
if (this.userRated) return
if (this.userMouseFristMove) {
console.log('---mousemove----', this.valueSync);
this.userLastRate = this.valueSync
this.userMouseFristMove = false
}
if (this.readonly || this.disabled || !this.touchable) return
const {
clientX,
} = e
this._getRateCount(clientX)
// #endif
},
mouseleave(e) {
// #ifdef H5
if (!this.IsPC()) return
if (this.readonly || this.disabled || !this.touchable) return
if (this.userRated) {
this.userRated = false
return
}
this.valueSync = this.userLastRate
// #endif
},
// #ifdef H5
IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var flag = true;
for (let v = 0; v < Agents.length - 1; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
},
// #endif
/**
* 获取星星个数
*/
_getRateCount(clientX) {
this._getSize()
const size = Number(this.size)
if (isNaN(size)) {
return new Error('size 属性只能设置为数字')
}
const rateMoveRange = clientX - this._rateBoxLeft
let index = parseInt(rateMoveRange / (size + this.marginNumber))
index = index < 0 ? 0 : index;
index = index > this.max ? this.max : index;
const range = parseInt(rateMoveRange - (size + this.marginNumber) * index);
let value = 0;
if (this._oldValue === index && !this.PC) return;
this._oldValue = index;
if (this.allowHalf) {
if (range > (size / 2)) {
value = index + 1
} else {
value = index + 0.5
}
} else {
value = index + 1
}
value = Math.max(0.5, Math.min(value, this.max))
this.valueSync = value
this._onChange()
},
/**
* 触发动态修改
*/
_onChange() {
this.$emit("input", this.valueSync);
this.$emit("update:modelValue", this.valueSync);
this.$emit("change", {
value: this.valueSync
});
},
/**
* 获取星星距离屏幕左侧距离
*/
_getSize() {
// #ifndef APP-NVUE
uni.createSelectorQuery()
.in(this)
.select('.uni-rate')
.boundingClientRect()
.exec(ret => {
if (ret) {
this._rateBoxLeft = ret[0].left
}
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
const size = ret.size
if (size) {
this._rateBoxLeft = size.left
}
})
// #endif
}
}
};
</script>
<style lang="scss">
.uni-rate {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
line-height: 1;
font-size: 0;
flex-direction: row;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-rate__icon {
position: relative;
line-height: 1;
font-size: 0;
}
.uni-rate__icon-on {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
line-height: 1;
text-align: left;
}
.uni-cursor-not-allowed {
/* #ifdef H5 */
cursor: not-allowed !important;
/* #endif */
}
</style>
<template>
<view>
<view ref="uni-rate" class="uni-rate">
<view class="uni-rate__icon" :class="{'uni-cursor-not-allowed': disabled}"
:style="{ 'margin-right': marginNumber + 'px' }" v-for="(star, index) in stars" :key="index"
@touchstart.stop="touchstart" @touchmove.stop="touchmove" @mousedown.stop="mousedown"
@mousemove.stop="mousemove" @mouseleave="mouseleave">
<uni-icons :color="color" :size="size" :type="isFill ? 'star-filled' : 'star'" />
<!-- #ifdef APP-NVUE -->
<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on">
<uni-icons style="text-align: left;" :color="disabled?'#ccc':activeColor" :size="size"
type="star-filled" />
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view :style="{ width: star.activeWitch}" class="uni-rate__icon-on">
<uni-icons :color="disabled?disabledColor:activeColor" :size="size" type="star-filled" />
</view>
<!-- #endif -->
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
/**
* Rate 评分
* @description 评分组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=33
* @property {Boolean} isFill = [true|false] 星星的类型,是否为实心类型, 默认为实心
* @property {String} color 未选中状态的星星颜色,默认为 "#ececec"
* @property {String} activeColor 选中状态的星星颜色,默认为 "#ffca3e"
* @property {String} disabledColor 禁用状态的星星颜色,默认为 "#c0c0c0"
* @property {Number} size 星星的大小
* @property {Number} value/v-model 当前评分
* @property {Number} max 最大评分评分数量,目前一分一颗星
* @property {Number} margin 星星的间距,单位 px
* @property {Boolean} disabled = [true|false] 是否为禁用状态,默认为 false
* @property {Boolean} readonly = [true|false] 是否为只读状态,默认为 false
* @property {Boolean} allowHalf = [true|false] 是否实现半星,默认为 false
* @property {Boolean} touchable = [true|false] 是否支持滑动手势,默认为 true
* @event {Function} change uniRate 的 value 改变时触发事件,e={value:Number}
*/
export default {
name: "UniRate",
props: {
isFill: {
// 星星的类型,是否镂空
type: [Boolean, String],
default: true
},
color: {
// 星星未选中的颜色
type: String,
default: "#ececec"
},
activeColor: {
// 星星选中状态颜色
type: String,
default: "#ffca3e"
},
disabledColor: {
// 星星禁用状态颜色
type: String,
default: "#c0c0c0"
},
size: {
// 星星的大小
type: [Number, String],
default: 24
},
value: {
// 当前评分
type: [Number, String],
default: 0
},
modelValue: {
// 当前评分
type: [Number, String],
default: 0
},
max: {
// 最大评分
type: [Number, String],
default: 5
},
margin: {
// 星星的间距
type: [Number, String],
default: 0
},
disabled: {
// 是否可点击
type: [Boolean, String],
default: false
},
readonly: {
// 是否只读
type: [Boolean, String],
default: false
},
allowHalf: {
// 是否显示半星
type: [Boolean, String],
default: false
},
touchable: {
// 是否支持滑动手势
type: [Boolean, String],
default: true
}
},
data() {
return {
valueSync: "",
userMouseFristMove: true,
userRated: false,
userLastRate: 1
};
},
watch: {
value(newVal) {
this.valueSync = Number(newVal);
},
modelValue(newVal) {
this.valueSync = Number(newVal);
},
},
computed: {
stars() {
const value = this.valueSync ? this.valueSync : 0;
const starList = [];
const floorValue = Math.floor(value);
const ceilValue = Math.ceil(value);
for (let i = 0; i < this.max; i++) {
if (floorValue > i) {
starList.push({
activeWitch: "100%"
});
} else if (ceilValue - 1 === i) {
starList.push({
activeWitch: (value - floorValue) * 100 + "%"
});
} else {
starList.push({
activeWitch: "0"
});
}
}
return starList;
},
marginNumber() {
return Number(this.margin)
}
},
created() {
this.valueSync = Number(this.value || this.modelValue);
this._rateBoxLeft = 0
this._oldValue = null
},
mounted() {
setTimeout(() => {
this._getSize()
}, 100)
// #ifdef H5
this.PC = this.IsPC()
// #endif
},
methods: {
touchstart(e) {
// #ifdef H5
if (this.IsPC()) return
// #endif
if (this.readonly || this.disabled) return
const {
clientX,
screenX
} = e.changedTouches[0]
// TODO 做一下兼容,只有 Nvue 下才有 screenX,其他平台式 clientX
this._getRateCount(clientX || screenX)
},
touchmove(e) {
// #ifdef H5
if (this.IsPC()) return
// #endif
if (this.readonly || this.disabled || !this.touchable) return
const {
clientX,
screenX
} = e.changedTouches[0]
this._getRateCount(clientX || screenX)
},
/**
* 兼容 PC @tian
*/
mousedown(e) {
// #ifdef H5
if (!this.IsPC()) return
if (this.readonly || this.disabled) return
const {
clientX,
} = e
this.userLastRate = this.valueSync
this._getRateCount(clientX)
this.userRated = true
// #endif
},
mousemove(e) {
// #ifdef H5
if (!this.IsPC()) return
if (this.userRated) return
if (this.userMouseFristMove) {
console.log('---mousemove----', this.valueSync);
this.userLastRate = this.valueSync
this.userMouseFristMove = false
}
if (this.readonly || this.disabled || !this.touchable) return
const {
clientX,
} = e
this._getRateCount(clientX)
// #endif
},
mouseleave(e) {
// #ifdef H5
if (!this.IsPC()) return
if (this.readonly || this.disabled || !this.touchable) return
if (this.userRated) {
this.userRated = false
return
}
this.valueSync = this.userLastRate
// #endif
},
// #ifdef H5
IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var flag = true;
for (let v = 0; v < Agents.length - 1; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
},
// #endif
/**
* 获取星星个数
*/
_getRateCount(clientX) {
this._getSize()
const size = Number(this.size)
if (isNaN(size)) {
return new Error('size 属性只能设置为数字')
}
const rateMoveRange = clientX - this._rateBoxLeft
let index = parseInt(rateMoveRange / (size + this.marginNumber))
index = index < 0 ? 0 : index;
index = index > this.max ? this.max : index;
const range = parseInt(rateMoveRange - (size + this.marginNumber) * index);
let value = 0;
if (this._oldValue === index && !this.PC) return;
this._oldValue = index;
if (this.allowHalf) {
if (range > (size / 2)) {
value = index + 1
} else {
value = index + 0.5
}
} else {
value = index + 1
}
value = Math.max(0.5, Math.min(value, this.max))
this.valueSync = value
this._onChange()
},
/**
* 触发动态修改
*/
_onChange() {
this.$emit("input", this.valueSync);
this.$emit("update:modelValue", this.valueSync);
this.$emit("change", {
value: this.valueSync
});
},
/**
* 获取星星距离屏幕左侧距离
*/
_getSize() {
// #ifndef APP-NVUE
uni.createSelectorQuery()
.in(this)
.select('.uni-rate')
.boundingClientRect()
.exec(ret => {
if (ret) {
this._rateBoxLeft = ret[0].left
}
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
const size = ret.size
if (size) {
this._rateBoxLeft = size.left
}
})
// #endif
}
}
};
</script>
<style lang="scss">
.uni-rate {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
line-height: 1;
font-size: 0;
flex-direction: row;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-rate__icon {
position: relative;
line-height: 1;
font-size: 0;
}
.uni-rate__icon-on {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
line-height: 1;
text-align: left;
}
.uni-cursor-not-allowed {
/* #ifdef H5 */
cursor: not-allowed !important;
/* #endif */
}
</style>
+88 -88
View File
@@ -1,88 +1,88 @@
{
"id": "uni-rate",
"displayName": "uni-rate 评分",
"version": "1.3.1",
"description": "Rate 评分组件,可自定义评分星星图标的大小、间隔、评分数。",
"keywords": [
"uni-ui",
"uniui",
"评分"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
{
"id": "uni-rate",
"displayName": "uni-rate 评分",
"version": "1.3.1",
"description": "Rate 评分组件,可自定义评分星星图标的大小、间隔、评分数。",
"keywords": [
"uni-ui",
"uniui",
"评分"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+11 -11
View File
@@ -1,12 +1,12 @@
## Rate 评分
> **组件名:uni-rate**
> 代码块: `uRate`
> 关联组件:`uni-icons`
评分组件,多用于购买商品后,对商品进行评价等场景
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-rate)
## Rate 评分
> **组件名:uni-rate**
> 代码块: `uRate`
> 关联组件:`uni-icons`
评分组件,多用于购买商品后,对商品进行评价等场景
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-rate)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+10 -10
View File
@@ -1,10 +1,10 @@
## 1.0.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-row](https://uniapp.dcloud.io/component/uniui/uni-row)
## 0.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 0.0.4(2021-05-12)
- 新增 组件示例地址
## 0.0.3(2021-02-05)
- 调整为uni_modules目录规范
- 新增uni-row组件
## 1.0.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-row](https://uniapp.dcloud.io/component/uniui/uni-row)
## 0.1.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 0.0.4(2021-05-12)
- 新增 组件示例地址
## 0.0.3(2021-02-05)
- 调整为uni_modules目录规范
- 新增uni-row组件
+317 -317
View File
@@ -1,317 +1,317 @@
<template>
<!-- #ifndef APP-NVUE -->
<view :class="['uni-col', sizeClass, pointClassList]" :style="{
paddingLeft:`${Number(gutter)}rpx`,
paddingRight:`${Number(gutter)}rpx`,
}">
<slot></slot>
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<!-- 在nvue上,类名样式不生效,换为style -->
<!-- 设置right正值失效,设置 left 负值 -->
<view :class="['uni-col']" :style="{
paddingLeft:`${Number(gutter)}rpx`,
paddingRight:`${Number(gutter)}rpx`,
width:`${nvueWidth}rpx`,
position:'relative',
marginLeft:`${marginLeft}rpx`,
left:`${right === 0 ? left : -right}rpx`
}">
<slot></slot>
</view>
<!-- #endif -->
</template>
<script>
/**
* Col 布局-列
* @description 搭配uni-row使用,构建布局。
* @tutorial https://ext.dcloud.net.cn/plugin?id=3958
*
* @property {span} type = Number 栅格占据的列数
* 默认 24
* @property {offset} type = Number 栅格左侧的间隔格数
* @property {push} type = Number 栅格向右移动格数
* @property {pull} type = Number 栅格向左移动格数
* @property {xs} type = [Number, Object] <768px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {sm} type = [Number, Object] ≥768px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {md} type = [Number, Object] ≥992px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {lg} type = [Number, Object] ≥1200px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {xl} type = [Number, Object] ≥1920px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
*/
const ComponentClass = 'uni-col';
// -1 默认值,因为在微信小程序端只给Number会有默认值0
export default {
name: 'uniCol',
// #ifdef MP-WEIXIN
options: {
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现
},
// #endif
props: {
span: {
type: Number,
default: 24
},
offset: {
type: Number,
default: -1
},
pull: {
type: Number,
default: -1
},
push: {
type: Number,
default: -1
},
xs: [Number, Object],
sm: [Number, Object],
md: [Number, Object],
lg: [Number, Object],
xl: [Number, Object]
},
data() {
return {
gutter: 0,
sizeClass: '',
parentWidth: 0,
nvueWidth: 0,
marginLeft: 0,
right: 0,
left: 0
}
},
created() {
// 字节小程序中,在computed中读取$parent为undefined
let parent = this.$parent;
while (parent && parent.$options.componentName !== 'uniRow') {
parent = parent.$parent;
}
this.updateGutter(parent.gutter)
parent.$watch('gutter', (gutter) => {
this.updateGutter(gutter)
})
// #ifdef APP-NVUE
this.updateNvueWidth(parent.width)
parent.$watch('width', (width) => {
this.updateNvueWidth(width)
})
// #endif
},
computed: {
sizeList() {
let {
span,
offset,
pull,
push
} = this;
return {
span,
offset,
pull,
push
}
},
// #ifndef APP-NVUE
pointClassList() {
let classList = [];
['xs', 'sm', 'md', 'lg', 'xl'].forEach(point => {
const props = this[point];
if (typeof props === 'number') {
classList.push(`${ComponentClass}-${point}-${props}`)
} else if (typeof props === 'object' && props) {
Object.keys(props).forEach(pointProp => {
classList.push(
pointProp === 'span' ?
`${ComponentClass}-${point}-${props[pointProp]}` :
`${ComponentClass}-${point}-${pointProp}-${props[pointProp]}`
)
})
}
});
// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
return classList.join(' ');
}
// #endif
},
methods: {
updateGutter(parentGutter) {
parentGutter = Number(parentGutter);
if (!isNaN(parentGutter)) {
this.gutter = parentGutter / 2
}
},
// #ifdef APP-NVUE
updateNvueWidth(width) {
// 用于在nvue端,span,offset,pull,push的计算
this.parentWidth = width;
['span', 'offset', 'pull', 'push'].forEach(size => {
const curSize = this[size];
if ((curSize || curSize === 0) && curSize !== -1) {
let RPX = 1 / 24 * curSize * width
RPX = Number(RPX);
switch (size) {
case 'span':
this.nvueWidth = RPX
break;
case 'offset':
this.marginLeft = RPX
break;
case 'pull':
this.right = RPX
break;
case 'push':
this.left = RPX
break;
}
}
});
}
// #endif
},
watch: {
sizeList: {
immediate: true,
handler(newVal) {
// #ifndef APP-NVUE
let classList = [];
for (let size in newVal) {
const curSize = newVal[size];
if ((curSize || curSize === 0) && curSize !== -1) {
classList.push(
size === 'span' ?
`${ComponentClass}-${curSize}` :
`${ComponentClass}-${size}-${curSize}`
)
}
}
// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
this.sizeClass = classList.join(' ');
// #endif
// #ifdef APP-NVUE
this.updateNvueWidth(this.parentWidth);
// #endif
}
}
}
}
</script>
<style lang='scss' scoped>
/* breakpoints */
$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;
$breakpoints: ('xs' : (max-width: $--sm - 1),
'sm' : (min-width: $--sm),
'md' : (min-width: $--md),
'lg' : (min-width: $--lg),
'xl' : (min-width: $--xl));
$layout-namespace: ".uni-";
$col: $layout-namespace+"col";
@function getSize($size) {
/* TODO 1/24 * $size * 100 * 1%; 使用计算后的值,为了解决 vue3 控制台报错 */
@return 0.04166666666 * $size * 100 * 1%;
}
@mixin res($key, $map:$breakpoints) {
@if map-has-key($map, $key) {
@media screen and #{inspect(map-get($map,$key))} {
@content;
}
}
@else {
@warn "Undeinfed point: `#{$key}`";
}
}
/* #ifndef APP-NVUE */
#{$col} {
float: left;
box-sizing: border-box;
}
#{$col}-0 {
/* #ifdef APP-NVUE */
width: 0;
height: 0;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
/* #endif */
/* #ifndef APP-NVUE */
display: none;
/* #endif */
}
@for $i from 0 through 24 {
#{$col}-#{$i} {
width: getSize($i);
}
#{$col}-offset-#{$i} {
margin-left: getSize($i);
}
#{$col}-pull-#{$i} {
position: relative;
right: getSize($i);
}
#{$col}-push-#{$i} {
position: relative;
left: getSize($i);
}
}
@each $point in map-keys($breakpoints) {
@include res($point) {
#{$col}-#{$point}-0 {
display: none;
}
@for $i from 0 through 24 {
#{$col}-#{$point}-#{$i} {
width: getSize($i);
}
#{$col}-#{$point}-offset-#{$i} {
margin-left: getSize($i);
}
#{$col}-#{$point}-pull-#{$i} {
position: relative;
right: getSize($i);
}
#{$col}-#{$point}-push-#{$i} {
position: relative;
left: getSize($i);
}
}
}
}
/* #endif */
</style>
<template>
<!-- #ifndef APP-NVUE -->
<view :class="['uni-col', sizeClass, pointClassList]" :style="{
paddingLeft:`${Number(gutter)}rpx`,
paddingRight:`${Number(gutter)}rpx`,
}">
<slot></slot>
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<!-- 在nvue上,类名样式不生效,换为style -->
<!-- 设置right正值失效,设置 left 负值 -->
<view :class="['uni-col']" :style="{
paddingLeft:`${Number(gutter)}rpx`,
paddingRight:`${Number(gutter)}rpx`,
width:`${nvueWidth}rpx`,
position:'relative',
marginLeft:`${marginLeft}rpx`,
left:`${right === 0 ? left : -right}rpx`
}">
<slot></slot>
</view>
<!-- #endif -->
</template>
<script>
/**
* Col 布局-列
* @description 搭配uni-row使用,构建布局。
* @tutorial https://ext.dcloud.net.cn/plugin?id=3958
*
* @property {span} type = Number 栅格占据的列数
* 默认 24
* @property {offset} type = Number 栅格左侧的间隔格数
* @property {push} type = Number 栅格向右移动格数
* @property {pull} type = Number 栅格向左移动格数
* @property {xs} type = [Number, Object] <768px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {sm} type = [Number, Object] ≥768px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {md} type = [Number, Object] ≥992px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {lg} type = [Number, Object] ≥1200px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {xl} type = [Number, Object] ≥1920px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
*/
const ComponentClass = 'uni-col';
// -1 默认值,因为在微信小程序端只给Number会有默认值0
export default {
name: 'uniCol',
// #ifdef MP-WEIXIN
options: {
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现
},
// #endif
props: {
span: {
type: Number,
default: 24
},
offset: {
type: Number,
default: -1
},
pull: {
type: Number,
default: -1
},
push: {
type: Number,
default: -1
},
xs: [Number, Object],
sm: [Number, Object],
md: [Number, Object],
lg: [Number, Object],
xl: [Number, Object]
},
data() {
return {
gutter: 0,
sizeClass: '',
parentWidth: 0,
nvueWidth: 0,
marginLeft: 0,
right: 0,
left: 0
}
},
created() {
// 字节小程序中,在computed中读取$parent为undefined
let parent = this.$parent;
while (parent && parent.$options.componentName !== 'uniRow') {
parent = parent.$parent;
}
this.updateGutter(parent.gutter)
parent.$watch('gutter', (gutter) => {
this.updateGutter(gutter)
})
// #ifdef APP-NVUE
this.updateNvueWidth(parent.width)
parent.$watch('width', (width) => {
this.updateNvueWidth(width)
})
// #endif
},
computed: {
sizeList() {
let {
span,
offset,
pull,
push
} = this;
return {
span,
offset,
pull,
push
}
},
// #ifndef APP-NVUE
pointClassList() {
let classList = [];
['xs', 'sm', 'md', 'lg', 'xl'].forEach(point => {
const props = this[point];
if (typeof props === 'number') {
classList.push(`${ComponentClass}-${point}-${props}`)
} else if (typeof props === 'object' && props) {
Object.keys(props).forEach(pointProp => {
classList.push(
pointProp === 'span' ?
`${ComponentClass}-${point}-${props[pointProp]}` :
`${ComponentClass}-${point}-${pointProp}-${props[pointProp]}`
)
})
}
});
// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
return classList.join(' ');
}
// #endif
},
methods: {
updateGutter(parentGutter) {
parentGutter = Number(parentGutter);
if (!isNaN(parentGutter)) {
this.gutter = parentGutter / 2
}
},
// #ifdef APP-NVUE
updateNvueWidth(width) {
// 用于在nvue端,span,offset,pull,push的计算
this.parentWidth = width;
['span', 'offset', 'pull', 'push'].forEach(size => {
const curSize = this[size];
if ((curSize || curSize === 0) && curSize !== -1) {
let RPX = 1 / 24 * curSize * width
RPX = Number(RPX);
switch (size) {
case 'span':
this.nvueWidth = RPX
break;
case 'offset':
this.marginLeft = RPX
break;
case 'pull':
this.right = RPX
break;
case 'push':
this.left = RPX
break;
}
}
});
}
// #endif
},
watch: {
sizeList: {
immediate: true,
handler(newVal) {
// #ifndef APP-NVUE
let classList = [];
for (let size in newVal) {
const curSize = newVal[size];
if ((curSize || curSize === 0) && curSize !== -1) {
classList.push(
size === 'span' ?
`${ComponentClass}-${curSize}` :
`${ComponentClass}-${size}-${curSize}`
)
}
}
// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
this.sizeClass = classList.join(' ');
// #endif
// #ifdef APP-NVUE
this.updateNvueWidth(this.parentWidth);
// #endif
}
}
}
}
</script>
<style lang='scss' scoped>
/* breakpoints */
$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;
$breakpoints: ('xs' : (max-width: $--sm - 1),
'sm' : (min-width: $--sm),
'md' : (min-width: $--md),
'lg' : (min-width: $--lg),
'xl' : (min-width: $--xl));
$layout-namespace: ".uni-";
$col: $layout-namespace+"col";
@function getSize($size) {
/* TODO 1/24 * $size * 100 * 1%; 使用计算后的值,为了解决 vue3 控制台报错 */
@return 0.04166666666 * $size * 100 * 1%;
}
@mixin res($key, $map:$breakpoints) {
@if map-has-key($map, $key) {
@media screen and #{inspect(map-get($map,$key))} {
@content;
}
}
@else {
@warn "Undeinfed point: `#{$key}`";
}
}
/* #ifndef APP-NVUE */
#{$col} {
float: left;
box-sizing: border-box;
}
#{$col}-0 {
/* #ifdef APP-NVUE */
width: 0;
height: 0;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
/* #endif */
/* #ifndef APP-NVUE */
display: none;
/* #endif */
}
@for $i from 0 through 24 {
#{$col}-#{$i} {
width: getSize($i);
}
#{$col}-offset-#{$i} {
margin-left: getSize($i);
}
#{$col}-pull-#{$i} {
position: relative;
right: getSize($i);
}
#{$col}-push-#{$i} {
position: relative;
left: getSize($i);
}
}
@each $point in map-keys($breakpoints) {
@include res($point) {
#{$col}-#{$point}-0 {
display: none;
}
@for $i from 0 through 24 {
#{$col}-#{$point}-#{$i} {
width: getSize($i);
}
#{$col}-#{$point}-offset-#{$i} {
margin-left: getSize($i);
}
#{$col}-#{$point}-pull-#{$i} {
position: relative;
right: getSize($i);
}
#{$col}-#{$point}-push-#{$i} {
position: relative;
left: getSize($i);
}
}
}
}
/* #endif */
</style>
+190 -190
View File
@@ -1,190 +1,190 @@
<template>
<view :class="[ 'uni-row', typeClass , justifyClass, alignClass, ]" :style="{
marginLeft:`${Number(marginValue)}rpx`,
marginRight:`${Number(marginValue)}rpx`,
}">
<slot></slot>
</view>
</template>
<script>
const ComponentClass = 'uni-row';
const modifierSeparator = '--';
/**
* Row 布局-行
* @description 流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。
* @tutorial https://ext.dcloud.net.cn/plugin?id=3958
*
* @property {gutter} type = Number 栅格间隔
* @property {justify} type = String flex 布局下的水平排列方式
* 可选 start/end/center/space-around/space-between start
* 默认值 start
* @property {align} type = String flex 布局下的垂直排列方式
* 可选 top/middle/bottom
* 默认值 top
* @property {width} type = String|Number nvue下需要自行配置宽度用于计算
* 默认值 750
*/
export default {
name: 'uniRow',
componentName: 'uniRow',
// #ifdef MP-WEIXIN
options: {
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现,可使用flex布局
},
// #endif
props: {
type: String,
gutter: Number,
justify: {
type: String,
default: 'start'
},
align: {
type: String,
default: 'top'
},
// nvue如果使用span等属性,需要配置宽度
width: {
type: [String, Number],
default: 750
}
},
created() {
// #ifdef APP-NVUE
this.type = 'flex';
// #endif
},
computed: {
marginValue() {
// #ifndef APP-NVUE
if (this.gutter) {
return -(this.gutter / 2);
}
// #endif
return 0;
},
typeClass() {
return this.type === 'flex' ? `${ComponentClass + modifierSeparator}flex` : '';
},
justifyClass() {
return this.justify !== 'start' ? `${ComponentClass + modifierSeparator}flex-justify-${this.justify}` : ''
},
alignClass() {
return this.align !== 'top' ? `${ComponentClass + modifierSeparator}flex-align-${this.align}` : ''
}
}
};
</script>
<style lang="scss">
$layout-namespace: ".uni-";
$row:$layout-namespace+"row";
$modifier-separator: "--";
@mixin utils-clearfix {
$selector: &;
@at-root {
/* #ifndef APP-NVUE */
#{$selector}::before,
#{$selector}::after {
display: table;
content: "";
}
#{$selector}::after {
clear: both;
}
/* #endif */
}
}
@mixin utils-flex ($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
@mixin set-flex($state) {
@at-root &-#{$state} {
@content
}
}
#{$row} {
position: relative;
flex-direction: row;
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
// 非nvue使用float布局
@include utils-clearfix;
// 在QQ、字节、百度小程序平台,编译后使用shadow dom,不可使用flex布局,使用float
@at-root {
/* #ifndef MP-QQ || MP-TOUTIAO || MP-BAIDU */
&#{$modifier-separator}flex {
@include utils-flex;
flex-wrap: wrap;
flex: 1;
&:before,
&:after {
/* #ifndef APP-NVUE */
display: none;
/* #endif */
}
@include set-flex(justify-center) {
justify-content: center;
}
@include set-flex(justify-end) {
justify-content: flex-end;
}
@include set-flex(justify-space-between) {
justify-content: space-between;
}
@include set-flex(justify-space-around) {
justify-content: space-around;
}
@include set-flex(align-middle) {
align-items: center;
}
@include set-flex(align-bottom) {
align-items: flex-end;
}
}
/* #endif */
}
}
// 字节、QQ配置后不生效
// 此处用法无法使用scoped
/* #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ */
:host {
display: block;
}
/* #endif */
</style>
<template>
<view :class="[ 'uni-row', typeClass , justifyClass, alignClass, ]" :style="{
marginLeft:`${Number(marginValue)}rpx`,
marginRight:`${Number(marginValue)}rpx`,
}">
<slot></slot>
</view>
</template>
<script>
const ComponentClass = 'uni-row';
const modifierSeparator = '--';
/**
* Row 布局-行
* @description 流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。
* @tutorial https://ext.dcloud.net.cn/plugin?id=3958
*
* @property {gutter} type = Number 栅格间隔
* @property {justify} type = String flex 布局下的水平排列方式
* 可选 start/end/center/space-around/space-between start
* 默认值 start
* @property {align} type = String flex 布局下的垂直排列方式
* 可选 top/middle/bottom
* 默认值 top
* @property {width} type = String|Number nvue下需要自行配置宽度用于计算
* 默认值 750
*/
export default {
name: 'uniRow',
componentName: 'uniRow',
// #ifdef MP-WEIXIN
options: {
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现,可使用flex布局
},
// #endif
props: {
type: String,
gutter: Number,
justify: {
type: String,
default: 'start'
},
align: {
type: String,
default: 'top'
},
// nvue如果使用span等属性,需要配置宽度
width: {
type: [String, Number],
default: 750
}
},
created() {
// #ifdef APP-NVUE
this.type = 'flex';
// #endif
},
computed: {
marginValue() {
// #ifndef APP-NVUE
if (this.gutter) {
return -(this.gutter / 2);
}
// #endif
return 0;
},
typeClass() {
return this.type === 'flex' ? `${ComponentClass + modifierSeparator}flex` : '';
},
justifyClass() {
return this.justify !== 'start' ? `${ComponentClass + modifierSeparator}flex-justify-${this.justify}` : ''
},
alignClass() {
return this.align !== 'top' ? `${ComponentClass + modifierSeparator}flex-align-${this.align}` : ''
}
}
};
</script>
<style lang="scss">
$layout-namespace: ".uni-";
$row:$layout-namespace+"row";
$modifier-separator: "--";
@mixin utils-clearfix {
$selector: &;
@at-root {
/* #ifndef APP-NVUE */
#{$selector}::before,
#{$selector}::after {
display: table;
content: "";
}
#{$selector}::after {
clear: both;
}
/* #endif */
}
}
@mixin utils-flex ($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
@mixin set-flex($state) {
@at-root &-#{$state} {
@content
}
}
#{$row} {
position: relative;
flex-direction: row;
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
// 非nvue使用float布局
@include utils-clearfix;
// 在QQ、字节、百度小程序平台,编译后使用shadow dom,不可使用flex布局,使用float
@at-root {
/* #ifndef MP-QQ || MP-TOUTIAO || MP-BAIDU */
&#{$modifier-separator}flex {
@include utils-flex;
flex-wrap: wrap;
flex: 1;
&:before,
&:after {
/* #ifndef APP-NVUE */
display: none;
/* #endif */
}
@include set-flex(justify-center) {
justify-content: center;
}
@include set-flex(justify-end) {
justify-content: flex-end;
}
@include set-flex(justify-space-between) {
justify-content: space-between;
}
@include set-flex(justify-space-around) {
justify-content: space-around;
}
@include set-flex(align-middle) {
align-items: center;
}
@include set-flex(align-bottom) {
align-items: flex-end;
}
}
/* #endif */
}
}
// 字节、QQ配置后不生效
// 此处用法无法使用scoped
/* #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ */
:host {
display: block;
}
/* #endif */
</style>
+86 -86
View File
@@ -1,87 +1,87 @@
{
"id": "uni-row",
"displayName": "uni-row 布局-行",
"version": "1.0.0",
"description": "流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。",
"keywords": [
"uni-ui",
"uniui",
"栅格",
"布局",
"layout"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "u"
}
}
}
}
{
"id": "uni-row",
"displayName": "uni-row 布局-行",
"version": "1.0.0",
"description": "流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。",
"keywords": [
"uni-ui",
"uniui",
"栅格",
"布局",
"layout"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "u"
}
}
}
}
}
+9 -9
View File
@@ -1,10 +1,10 @@
## Layout 布局
> **组件名 uni-row、uni-col**
> 代码块: `uRow`、`uCol`
流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-row)
## Layout 布局
> **组件名 uni-row、uni-col**
> 代码块: `uRow`、`uCol`
流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-row)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+8 -8
View File
@@ -1,8 +1,8 @@
## 1.0.3(2022-01-21)
- 优化 组件示例
## 1.0.2(2021-11-22)
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
## 1.0.1(2021-11-22)
- 修复 vue3中scss语法兼容问题
## 1.0.0(2021-11-18)
- init
## 1.0.3(2022-01-21)
- 优化 组件示例
## 1.0.2(2021-11-22)
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
## 1.0.1(2021-11-22)
- 修复 vue3中scss语法兼容问题
## 1.0.0(2021-11-18)
- init
+1 -1
View File
@@ -1 +1 @@
@import './styles/index.scss';
@import './styles/index.scss';
+95 -95
View File
@@ -1,95 +1,95 @@
{
"name" : "",
"appid" : "",
"description": "应用描述",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
/* 5+App特有相关 */
"app-plus": {
"usingComponents": true,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": {
"OAuth": {},
"Payment": {},
"Push": {},
"Share": {},
"Speech": {},
"VideoPlayer": {}
},
/* 应用发布信息 */
"distribute": {
/* android打包配置 */
"android": {
"permissions": [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
]
},
/* ios打包配置 */
"ios": {
"UIBackgroundModes": ["audio"]
},
/* SDK配置 */
"sdkConfigs": {
"speech": {
"ifly": {}
}
},
"orientation": ["portrait-primary"]
}
},
/* 快应用特有相关 */
"quickapp": {},
/* 小程序特有相关 */
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false
},
"usingComponents": true
},
"h5": {
"template": "template.h5.html",
"router": {
"mode": "history",
"base": "/h5/"
}
}
}
{
"name" : "",
"appid" : "",
"description": "应用描述",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
/* 5+App特有相关 */
"app-plus": {
"usingComponents": true,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": {
"OAuth": {},
"Payment": {},
"Push": {},
"Share": {},
"Speech": {},
"VideoPlayer": {}
},
/* 应用发布信息 */
"distribute": {
/* android打包配置 */
"android": {
"permissions": [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
]
},
/* ios打包配置 */
"ios": {
"UIBackgroundModes": ["audio"]
},
/* SDK配置 */
"sdkConfigs": {
"speech": {
"ifly": {}
}
},
"orientation": ["portrait-primary"]
}
},
/* 快应用特有相关 */
"quickapp": {},
/* 小程序特有相关 */
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false
},
"usingComponents": true
},
"h5": {
"template": "template.h5.html",
"router": {
"mode": "history",
"base": "/h5/"
}
}
}
+82 -82
View File
@@ -1,82 +1,82 @@
{
"id": "uni-scss",
"displayName": "uni-scss 辅助样式",
"version": "1.0.3",
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
"keywords": [
"uni-scss",
"uni-ui",
"辅助样式"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"JS SDK",
"通用 SDK"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
{
"id": "uni-scss",
"displayName": "uni-scss 辅助样式",
"version": "1.0.3",
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
"keywords": [
"uni-scss",
"uni-ui",
"辅助样式"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"JS SDK",
"通用 SDK"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+7 -7
View File
@@ -1,7 +1,7 @@
@import './setting/_variables.scss';
@import './setting/_border.scss';
@import './setting/_color.scss';
@import './setting/_space.scss';
@import './setting/_radius.scss';
@import './setting/_text.scss';
@import './setting/_styles.scss';
@import './setting/_variables.scss';
@import './setting/_border.scss';
@import './setting/_color.scss';
@import './setting/_space.scss';
@import './setting/_radius.scss';
@import './setting/_text.scss';
@import './setting/_styles.scss';
@@ -1,3 +1,3 @@
.uni-border {
border: 1px $uni-border-1 solid;
.uni-border {
border: 1px $uni-border-1 solid;
}
+66 -66
View File
@@ -1,66 +1,66 @@
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
// @mixin get-styles($k,$c) {
// @if $k == size or $k == weight{
// font-#{$k}:#{$c}
// }@else{
// #{$k}:#{$c}
// }
// }
$uni-ui-color:(
// 主色
primary: $uni-primary,
primary-disable: $uni-primary-disable,
primary-light: $uni-primary-light,
// 辅助色
success: $uni-success,
success-disable: $uni-success-disable,
success-light: $uni-success-light,
warning: $uni-warning,
warning-disable: $uni-warning-disable,
warning-light: $uni-warning-light,
error: $uni-error,
error-disable: $uni-error-disable,
error-light: $uni-error-light,
info: $uni-info,
info-disable: $uni-info-disable,
info-light: $uni-info-light,
// 中性色
main-color: $uni-main-color,
base-color: $uni-base-color,
secondary-color: $uni-secondary-color,
extra-color: $uni-extra-color,
// 背景色
bg-color: $uni-bg-color,
// 边框颜色
border-1: $uni-border-1,
border-2: $uni-border-2,
border-3: $uni-border-3,
border-4: $uni-border-4,
// 黑色
black:$uni-black,
// 白色
white:$uni-white,
// 透明
transparent:$uni-transparent
) !default;
@each $key, $child in $uni-ui-color {
.uni-#{"" + $key} {
color: $child;
}
.uni-#{"" + $key}-bg {
background-color: $child;
}
}
.uni-shadow-sm {
box-shadow: $uni-shadow-sm;
}
.uni-shadow-base {
box-shadow: $uni-shadow-base;
}
.uni-shadow-lg {
box-shadow: $uni-shadow-lg;
}
.uni-mask {
background-color:$uni-mask;
}
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
// @mixin get-styles($k,$c) {
// @if $k == size or $k == weight{
// font-#{$k}:#{$c}
// }@else{
// #{$k}:#{$c}
// }
// }
$uni-ui-color:(
// 主色
primary: $uni-primary,
primary-disable: $uni-primary-disable,
primary-light: $uni-primary-light,
// 辅助色
success: $uni-success,
success-disable: $uni-success-disable,
success-light: $uni-success-light,
warning: $uni-warning,
warning-disable: $uni-warning-disable,
warning-light: $uni-warning-light,
error: $uni-error,
error-disable: $uni-error-disable,
error-light: $uni-error-light,
info: $uni-info,
info-disable: $uni-info-disable,
info-light: $uni-info-light,
// 中性色
main-color: $uni-main-color,
base-color: $uni-base-color,
secondary-color: $uni-secondary-color,
extra-color: $uni-extra-color,
// 背景色
bg-color: $uni-bg-color,
// 边框颜色
border-1: $uni-border-1,
border-2: $uni-border-2,
border-3: $uni-border-3,
border-4: $uni-border-4,
// 黑色
black:$uni-black,
// 白色
white:$uni-white,
// 透明
transparent:$uni-transparent
) !default;
@each $key, $child in $uni-ui-color {
.uni-#{"" + $key} {
color: $child;
}
.uni-#{"" + $key}-bg {
background-color: $child;
}
}
.uni-shadow-sm {
box-shadow: $uni-shadow-sm;
}
.uni-shadow-base {
box-shadow: $uni-shadow-base;
}
.uni-shadow-lg {
box-shadow: $uni-shadow-lg;
}
.uni-mask {
background-color:$uni-mask;
}
@@ -1,55 +1,55 @@
@mixin radius($r,$d:null ,$important: false){
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
// Key exists within the $uni-radius variable
@if (map-has-key($uni-radius, $r) and $d){
@if $d == t {
border-top-left-radius:$radius-value;
border-top-right-radius:$radius-value;
}@else if $d == r {
border-top-right-radius:$radius-value;
border-bottom-right-radius:$radius-value;
}@else if $d == b {
border-bottom-left-radius:$radius-value;
border-bottom-right-radius:$radius-value;
}@else if $d == l {
border-top-left-radius:$radius-value;
border-bottom-left-radius:$radius-value;
}@else if $d == tl {
border-top-left-radius:$radius-value;
}@else if $d == tr {
border-top-right-radius:$radius-value;
}@else if $d == br {
border-bottom-right-radius:$radius-value;
}@else if $d == bl {
border-bottom-left-radius:$radius-value;
}
}@else{
border-radius:$radius-value;
}
}
@each $key, $child in $uni-radius {
@if($key){
.uni-radius-#{"" + $key} {
@include radius($key)
}
}@else{
.uni-radius {
@include radius($key)
}
}
}
@each $direction in t, r, b, l,tl, tr, br, bl {
@each $key, $child in $uni-radius {
@if($key){
.uni-radius-#{"" + $direction}-#{"" + $key} {
@include radius($key,$direction,false)
}
}@else{
.uni-radius-#{$direction} {
@include radius($key,$direction,false)
}
}
}
}
@mixin radius($r,$d:null ,$important: false){
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
// Key exists within the $uni-radius variable
@if (map-has-key($uni-radius, $r) and $d){
@if $d == t {
border-top-left-radius:$radius-value;
border-top-right-radius:$radius-value;
}@else if $d == r {
border-top-right-radius:$radius-value;
border-bottom-right-radius:$radius-value;
}@else if $d == b {
border-bottom-left-radius:$radius-value;
border-bottom-right-radius:$radius-value;
}@else if $d == l {
border-top-left-radius:$radius-value;
border-bottom-left-radius:$radius-value;
}@else if $d == tl {
border-top-left-radius:$radius-value;
}@else if $d == tr {
border-top-right-radius:$radius-value;
}@else if $d == br {
border-bottom-right-radius:$radius-value;
}@else if $d == bl {
border-bottom-left-radius:$radius-value;
}
}@else{
border-radius:$radius-value;
}
}
@each $key, $child in $uni-radius {
@if($key){
.uni-radius-#{"" + $key} {
@include radius($key)
}
}@else{
.uni-radius {
@include radius($key)
}
}
}
@each $direction in t, r, b, l,tl, tr, br, bl {
@each $key, $child in $uni-radius {
@if($key){
.uni-radius-#{"" + $direction}-#{"" + $key} {
@include radius($key,$direction,false)
}
}@else{
.uni-radius-#{$direction} {
@include radius($key,$direction,false)
}
}
}
}
+55 -55
View File
@@ -1,56 +1,56 @@
@mixin fn($space,$direction,$size,$n) {
@if $n {
#{$space}-#{$direction}: #{$size*$uni-space-root}px
} @else {
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
}
}
@mixin get-styles($direction,$i,$space,$n){
@if $direction == t {
@include fn($space, top,$i,$n);
}
@if $direction == r {
@include fn($space, right,$i,$n);
}
@if $direction == b {
@include fn($space, bottom,$i,$n);
}
@if $direction == l {
@include fn($space, left,$i,$n);
}
@if $direction == x {
@include fn($space, left,$i,$n);
@include fn($space, right,$i,$n);
}
@if $direction == y {
@include fn($space, top,$i,$n);
@include fn($space, bottom,$i,$n);
}
@if $direction == a {
@if $n {
#{$space}:#{$i*$uni-space-root}px;
} @else {
#{$space}:#{-$i*$uni-space-root}px;
}
}
}
@each $orientation in m,p {
$space: margin;
@if $orientation == m {
$space: margin;
} @else {
$space: padding;
}
@for $i from 0 through 16 {
@each $direction in t, r, b, l, x, y, a {
.uni-#{$orientation}#{$direction}-#{$i} {
@include get-styles($direction,$i,$space,true);
}
.uni-#{$orientation}#{$direction}-n#{$i} {
@include get-styles($direction,$i,$space,false);
}
}
}
@mixin fn($space,$direction,$size,$n) {
@if $n {
#{$space}-#{$direction}: #{$size*$uni-space-root}px
} @else {
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
}
}
@mixin get-styles($direction,$i,$space,$n){
@if $direction == t {
@include fn($space, top,$i,$n);
}
@if $direction == r {
@include fn($space, right,$i,$n);
}
@if $direction == b {
@include fn($space, bottom,$i,$n);
}
@if $direction == l {
@include fn($space, left,$i,$n);
}
@if $direction == x {
@include fn($space, left,$i,$n);
@include fn($space, right,$i,$n);
}
@if $direction == y {
@include fn($space, top,$i,$n);
@include fn($space, bottom,$i,$n);
}
@if $direction == a {
@if $n {
#{$space}:#{$i*$uni-space-root}px;
} @else {
#{$space}:#{-$i*$uni-space-root}px;
}
}
}
@each $orientation in m,p {
$space: margin;
@if $orientation == m {
$space: margin;
} @else {
$space: padding;
}
@for $i from 0 through 16 {
@each $direction in t, r, b, l, x, y, a {
.uni-#{$orientation}#{$direction}-#{$i} {
@include get-styles($direction,$i,$space,true);
}
.uni-#{$orientation}#{$direction}-n#{$i} {
@include get-styles($direction,$i,$space,false);
}
}
}
}
+167 -167
View File
@@ -1,167 +1,167 @@
/* #ifndef APP-NVUE */
$-color-white:#fff;
$-color-black:#000;
@mixin base-style($color) {
color: #fff;
background-color: $color;
border-color: mix($-color-black, $color, 8%);
&:not([hover-class]):active {
background: mix($-color-black, $color, 10%);
border-color: mix($-color-black, $color, 20%);
color: $-color-white;
outline: none;
}
}
@mixin is-color($color) {
@include base-style($color);
&[loading] {
@include base-style($color);
&::before {
margin-right:5px;
}
}
&[disabled] {
&,
&[loading],
&:not([hover-class]):active {
color: $-color-white;
border-color: mix(darken($color,10%), $-color-white);
background-color: mix($color, $-color-white);
}
}
}
@mixin base-plain-style($color) {
color:$color;
background-color: mix($-color-white, $color, 90%);
border-color: mix($-color-white, $color, 70%);
&:not([hover-class]):active {
background: mix($-color-white, $color, 80%);
color: $color;
outline: none;
border-color: mix($-color-white, $color, 50%);
}
}
@mixin is-plain($color){
&[plain] {
@include base-plain-style($color);
&[loading] {
@include base-plain-style($color);
&::before {
margin-right:5px;
}
}
&[disabled] {
&,
&:active {
color: mix($-color-white, $color, 40%);
background-color: mix($-color-white, $color, 90%);
border-color: mix($-color-white, $color, 80%);
}
}
}
}
.uni-btn {
margin: 5px;
color: #393939;
border:1px solid #ccc;
font-size: 16px;
font-weight: 200;
background-color: #F9F9F9;
// TODO 暂时处理边框隐藏一边的问题
overflow: visible;
&::after{
border: none;
}
&:not([type]),&[type=default] {
color: #999;
&[loading] {
background: none;
&::before {
margin-right:5px;
}
}
&[disabled]{
color: mix($-color-white, #999, 60%);
&,
&[loading],
&:active {
color: mix($-color-white, #999, 60%);
background-color: mix($-color-white,$-color-black , 98%);
border-color: mix($-color-white, #999, 85%);
}
}
&[plain] {
color: #999;
background: none;
border-color: $uni-border-1;
&:not([hover-class]):active {
background: none;
color: mix($-color-white, $-color-black, 80%);
border-color: mix($-color-white, $-color-black, 90%);
outline: none;
}
&[disabled]{
&,
&[loading],
&:active {
background: none;
color: mix($-color-white, #999, 60%);
border-color: mix($-color-white, #999, 85%);
}
}
}
}
&:not([hover-class]):active {
color: mix($-color-white, $-color-black, 50%);
}
&[size=mini] {
font-size: 16px;
font-weight: 200;
border-radius: 8px;
}
&.uni-btn-small {
font-size: 14px;
}
&.uni-btn-mini {
font-size: 12px;
}
&.uni-btn-radius {
border-radius: 999px;
}
&[type=primary] {
@include is-color($uni-primary);
@include is-plain($uni-primary)
}
&[type=success] {
@include is-color($uni-success);
@include is-plain($uni-success)
}
&[type=error] {
@include is-color($uni-error);
@include is-plain($uni-error)
}
&[type=warning] {
@include is-color($uni-warning);
@include is-plain($uni-warning)
}
&[type=info] {
@include is-color($uni-info);
@include is-plain($uni-info)
}
}
/* #endif */
/* #ifndef APP-NVUE */
$-color-white:#fff;
$-color-black:#000;
@mixin base-style($color) {
color: #fff;
background-color: $color;
border-color: mix($-color-black, $color, 8%);
&:not([hover-class]):active {
background: mix($-color-black, $color, 10%);
border-color: mix($-color-black, $color, 20%);
color: $-color-white;
outline: none;
}
}
@mixin is-color($color) {
@include base-style($color);
&[loading] {
@include base-style($color);
&::before {
margin-right:5px;
}
}
&[disabled] {
&,
&[loading],
&:not([hover-class]):active {
color: $-color-white;
border-color: mix(darken($color,10%), $-color-white);
background-color: mix($color, $-color-white);
}
}
}
@mixin base-plain-style($color) {
color:$color;
background-color: mix($-color-white, $color, 90%);
border-color: mix($-color-white, $color, 70%);
&:not([hover-class]):active {
background: mix($-color-white, $color, 80%);
color: $color;
outline: none;
border-color: mix($-color-white, $color, 50%);
}
}
@mixin is-plain($color){
&[plain] {
@include base-plain-style($color);
&[loading] {
@include base-plain-style($color);
&::before {
margin-right:5px;
}
}
&[disabled] {
&,
&:active {
color: mix($-color-white, $color, 40%);
background-color: mix($-color-white, $color, 90%);
border-color: mix($-color-white, $color, 80%);
}
}
}
}
.uni-btn {
margin: 5px;
color: #393939;
border:1px solid #ccc;
font-size: 16px;
font-weight: 200;
background-color: #F9F9F9;
// TODO 暂时处理边框隐藏一边的问题
overflow: visible;
&::after{
border: none;
}
&:not([type]),&[type=default] {
color: #999;
&[loading] {
background: none;
&::before {
margin-right:5px;
}
}
&[disabled]{
color: mix($-color-white, #999, 60%);
&,
&[loading],
&:active {
color: mix($-color-white, #999, 60%);
background-color: mix($-color-white,$-color-black , 98%);
border-color: mix($-color-white, #999, 85%);
}
}
&[plain] {
color: #999;
background: none;
border-color: $uni-border-1;
&:not([hover-class]):active {
background: none;
color: mix($-color-white, $-color-black, 80%);
border-color: mix($-color-white, $-color-black, 90%);
outline: none;
}
&[disabled]{
&,
&[loading],
&:active {
background: none;
color: mix($-color-white, #999, 60%);
border-color: mix($-color-white, #999, 85%);
}
}
}
}
&:not([hover-class]):active {
color: mix($-color-white, $-color-black, 50%);
}
&[size=mini] {
font-size: 16px;
font-weight: 200;
border-radius: 8px;
}
&.uni-btn-small {
font-size: 14px;
}
&.uni-btn-mini {
font-size: 12px;
}
&.uni-btn-radius {
border-radius: 999px;
}
&[type=primary] {
@include is-color($uni-primary);
@include is-plain($uni-primary)
}
&[type=success] {
@include is-color($uni-success);
@include is-plain($uni-success)
}
&[type=error] {
@include is-color($uni-error);
@include is-plain($uni-error)
}
&[type=warning] {
@include is-color($uni-warning);
@include is-plain($uni-warning)
}
&[type=info] {
@include is-color($uni-info);
@include is-plain($uni-info)
}
}
/* #endif */
+24 -24
View File
@@ -1,24 +1,24 @@
@mixin get-styles($k,$c) {
@if $k == size or $k == weight{
font-#{$k}:#{$c}
}@else{
#{$k}:#{$c}
}
}
@each $key, $child in $uni-headings {
/* #ifndef APP-NVUE */
.uni-#{$key} {
@each $k, $c in $child {
@include get-styles($k,$c)
}
}
/* #endif */
/* #ifdef APP-NVUE */
.container .uni-#{$key} {
@each $k, $c in $child {
@include get-styles($k,$c)
}
}
/* #endif */
}
@mixin get-styles($k,$c) {
@if $k == size or $k == weight{
font-#{$k}:#{$c}
}@else{
#{$k}:#{$c}
}
}
@each $key, $child in $uni-headings {
/* #ifndef APP-NVUE */
.uni-#{$key} {
@each $k, $c in $child {
@include get-styles($k,$c)
}
}
/* #endif */
/* #ifdef APP-NVUE */
.container .uni-#{$key} {
@each $k, $c in $child {
@include get-styles($k,$c)
}
}
/* #endif */
}
@@ -1,146 +1,146 @@
// @use "sass:math";
@import '../tools/functions.scss';
// 间距基础倍数
$uni-space-root: 2 !default;
// 边框半径默认值
$uni-radius-root:5px !default;
$uni-radius: () !default;
// 边框半径断点
$uni-radius: map-deep-merge(
(
0: 0,
// TODO 当前版本暂时不支持 sm 属性
// 'sm': math.div($uni-radius-root, 2),
null: $uni-radius-root,
'lg': $uni-radius-root * 2,
'xl': $uni-radius-root * 6,
'pill': 9999px,
'circle': 50%
),
$uni-radius
);
// 字体家族
$body-font-family: 'Roboto', sans-serif !default;
// 文本
$heading-font-family: $body-font-family !default;
$uni-headings: () !default;
$letterSpacing: -0.01562em;
$uni-headings: map-deep-merge(
(
'h1': (
size: 32px,
weight: 300,
line-height: 50px,
// letter-spacing:-0.01562em
),
'h2': (
size: 28px,
weight: 300,
line-height: 40px,
// letter-spacing: -0.00833em
),
'h3': (
size: 24px,
weight: 400,
line-height: 32px,
// letter-spacing: normal
),
'h4': (
size: 20px,
weight: 400,
line-height: 30px,
// letter-spacing: 0.00735em
),
'h5': (
size: 16px,
weight: 400,
line-height: 24px,
// letter-spacing: normal
),
'h6': (
size: 14px,
weight: 500,
line-height: 18px,
// letter-spacing: 0.0125em
),
'subtitle': (
size: 12px,
weight: 400,
line-height: 20px,
// letter-spacing: 0.00937em
),
'body': (
font-size: 14px,
font-weight: 400,
line-height: 22px,
// letter-spacing: 0.03125em
),
'caption': (
'size': 12px,
'weight': 400,
'line-height': 20px,
// 'letter-spacing': 0.03333em,
// 'text-transform': false
)
),
$uni-headings
);
// 主色
$uni-primary: #2979ff !default;
$uni-primary-disable:lighten($uni-primary,20%) !default;
$uni-primary-light: lighten($uni-primary,25%) !default;
// 辅助色
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
$uni-success: #18bc37 !default;
$uni-success-disable:lighten($uni-success,20%) !default;
$uni-success-light: lighten($uni-success,25%) !default;
$uni-warning: #f3a73f !default;
$uni-warning-disable:lighten($uni-warning,20%) !default;
$uni-warning-light: lighten($uni-warning,25%) !default;
$uni-error: #e43d33 !default;
$uni-error-disable:lighten($uni-error,20%) !default;
$uni-error-light: lighten($uni-error,25%) !default;
$uni-info: #8f939c !default;
$uni-info-disable:lighten($uni-info,20%) !default;
$uni-info-light: lighten($uni-info,25%) !default;
// 中性色
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
$uni-main-color: #3a3a3a !default; // 主要文字
$uni-base-color: #6a6a6a !default; // 常规文字
$uni-secondary-color: #909399 !default; // 次要文字
$uni-extra-color: #c7c7c7 !default; // 辅助说明
// 边框颜色
$uni-border-1: #F0F0F0 !default;
$uni-border-2: #EDEDED !default;
$uni-border-3: #DCDCDC !default;
$uni-border-4: #B9B9B9 !default;
// 常规色
$uni-black: #000000 !default;
$uni-white: #ffffff !default;
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
// 背景色
$uni-bg-color: #f7f7f7 !default;
/* 水平间距 */
$uni-spacing-sm: 8px !default;
$uni-spacing-base: 15px !default;
$uni-spacing-lg: 30px !default;
// 阴影
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
// 蒙版
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
// @use "sass:math";
@import '../tools/functions.scss';
// 间距基础倍数
$uni-space-root: 2 !default;
// 边框半径默认值
$uni-radius-root:5px !default;
$uni-radius: () !default;
// 边框半径断点
$uni-radius: map-deep-merge(
(
0: 0,
// TODO 当前版本暂时不支持 sm 属性
// 'sm': math.div($uni-radius-root, 2),
null: $uni-radius-root,
'lg': $uni-radius-root * 2,
'xl': $uni-radius-root * 6,
'pill': 9999px,
'circle': 50%
),
$uni-radius
);
// 字体家族
$body-font-family: 'Roboto', sans-serif !default;
// 文本
$heading-font-family: $body-font-family !default;
$uni-headings: () !default;
$letterSpacing: -0.01562em;
$uni-headings: map-deep-merge(
(
'h1': (
size: 32px,
weight: 300,
line-height: 50px,
// letter-spacing:-0.01562em
),
'h2': (
size: 28px,
weight: 300,
line-height: 40px,
// letter-spacing: -0.00833em
),
'h3': (
size: 24px,
weight: 400,
line-height: 32px,
// letter-spacing: normal
),
'h4': (
size: 20px,
weight: 400,
line-height: 30px,
// letter-spacing: 0.00735em
),
'h5': (
size: 16px,
weight: 400,
line-height: 24px,
// letter-spacing: normal
),
'h6': (
size: 14px,
weight: 500,
line-height: 18px,
// letter-spacing: 0.0125em
),
'subtitle': (
size: 12px,
weight: 400,
line-height: 20px,
// letter-spacing: 0.00937em
),
'body': (
font-size: 14px,
font-weight: 400,
line-height: 22px,
// letter-spacing: 0.03125em
),
'caption': (
'size': 12px,
'weight': 400,
'line-height': 20px,
// 'letter-spacing': 0.03333em,
// 'text-transform': false
)
),
$uni-headings
);
// 主色
$uni-primary: #2979ff !default;
$uni-primary-disable:lighten($uni-primary,20%) !default;
$uni-primary-light: lighten($uni-primary,25%) !default;
// 辅助色
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
$uni-success: #18bc37 !default;
$uni-success-disable:lighten($uni-success,20%) !default;
$uni-success-light: lighten($uni-success,25%) !default;
$uni-warning: #f3a73f !default;
$uni-warning-disable:lighten($uni-warning,20%) !default;
$uni-warning-light: lighten($uni-warning,25%) !default;
$uni-error: #e43d33 !default;
$uni-error-disable:lighten($uni-error,20%) !default;
$uni-error-light: lighten($uni-error,25%) !default;
$uni-info: #8f939c !default;
$uni-info-disable:lighten($uni-info,20%) !default;
$uni-info-light: lighten($uni-info,25%) !default;
// 中性色
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
$uni-main-color: #3a3a3a !default; // 主要文字
$uni-base-color: #6a6a6a !default; // 常规文字
$uni-secondary-color: #909399 !default; // 次要文字
$uni-extra-color: #c7c7c7 !default; // 辅助说明
// 边框颜色
$uni-border-1: #F0F0F0 !default;
$uni-border-2: #EDEDED !default;
$uni-border-3: #DCDCDC !default;
$uni-border-4: #B9B9B9 !default;
// 常规色
$uni-black: #000000 !default;
$uni-white: #ffffff !default;
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
// 背景色
$uni-bg-color: #f7f7f7 !default;
/* 水平间距 */
$uni-spacing-sm: 8px !default;
$uni-spacing-base: 15px !default;
$uni-spacing-lg: 30px !default;
// 阴影
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
// 蒙版
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
@@ -1,19 +1,19 @@
// 合并 map
@function map-deep-merge($parent-map, $child-map){
$result: $parent-map;
@each $key, $child in $child-map {
$parent-has-key: map-has-key($result, $key);
$parent-value: map-get($result, $key);
$parent-type: type-of($parent-value);
$child-type: type-of($child);
$parent-is-map: $parent-type == map;
$child-is-map: $child-type == map;
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
$result: map-merge($result, ( $key: $child ));
}@else {
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
}
}
@return $result;
};
// 合并 map
@function map-deep-merge($parent-map, $child-map){
$result: $parent-map;
@each $key, $child in $child-map {
$parent-has-key: map-has-key($result, $key);
$parent-value: map-get($result, $key);
$parent-type: type-of($parent-value);
$child-type: type-of($child);
$parent-is-map: $parent-type == map;
$child-is-map: $child-type == map;
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
$result: map-merge($result, ( $key: $child ));
}@else {
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
}
}
@return $result;
};
+31 -31
View File
@@ -1,31 +1,31 @@
// 间距基础倍数
$uni-space-root: 2;
// 边框半径默认值
$uni-radius-root:5px;
// 主色
$uni-primary: #2979ff;
// 辅助色
$uni-success: #4cd964;
// 警告色
$uni-warning: #f0ad4e;
// 错误色
$uni-error: #dd524d;
// 描述色
$uni-info: #909399;
// 中性色
$uni-main-color: #303133;
$uni-base-color: #606266;
$uni-secondary-color: #909399;
$uni-extra-color: #C0C4CC;
// 背景色
$uni-bg-color: #f5f5f5;
// 边框颜色
$uni-border-1: #DCDFE6;
$uni-border-2: #E4E7ED;
$uni-border-3: #EBEEF5;
$uni-border-4: #F2F6FC;
// 常规色
$uni-black: #000000;
$uni-white: #ffffff;
$uni-transparent: rgba($color: #000000, $alpha: 0);
// 间距基础倍数
$uni-space-root: 2;
// 边框半径默认值
$uni-radius-root:5px;
// 主色
$uni-primary: #2979ff;
// 辅助色
$uni-success: #4cd964;
// 警告色
$uni-warning: #f0ad4e;
// 错误色
$uni-error: #dd524d;
// 描述色
$uni-info: #909399;
// 中性色
$uni-main-color: #303133;
$uni-base-color: #606266;
$uni-secondary-color: #909399;
$uni-extra-color: #C0C4CC;
// 背景色
$uni-bg-color: #f5f5f5;
// 边框颜色
$uni-border-1: #DCDFE6;
$uni-border-2: #E4E7ED;
$uni-border-3: #EBEEF5;
$uni-border-4: #F2F6FC;
// 常规色
$uni-black: #000000;
$uni-white: #ffffff;
$uni-transparent: rgba($color: #000000, $alpha: 0);
+62 -62
View File
@@ -1,62 +1,62 @@
@import './styles/setting/_variables.scss';
// 间距基础倍数
$uni-space-root: 2;
// 边框半径默认值
$uni-radius-root:5px;
// 主色
$uni-primary: #2979ff;
$uni-primary-disable:mix(#fff,$uni-primary,50%);
$uni-primary-light: mix(#fff,$uni-primary,80%);
// 辅助色
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
$uni-success: #18bc37;
$uni-success-disable:mix(#fff,$uni-success,50%);
$uni-success-light: mix(#fff,$uni-success,80%);
$uni-warning: #f3a73f;
$uni-warning-disable:mix(#fff,$uni-warning,50%);
$uni-warning-light: mix(#fff,$uni-warning,80%);
$uni-error: #e43d33;
$uni-error-disable:mix(#fff,$uni-error,50%);
$uni-error-light: mix(#fff,$uni-error,80%);
$uni-info: #8f939c;
$uni-info-disable:mix(#fff,$uni-info,50%);
$uni-info-light: mix(#fff,$uni-info,80%);
// 中性色
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
$uni-main-color: #3a3a3a; // 主要文字
$uni-base-color: #6a6a6a; // 常规文字
$uni-secondary-color: #909399; // 次要文字
$uni-extra-color: #c7c7c7; // 辅助说明
// 边框颜色
$uni-border-1: #F0F0F0;
$uni-border-2: #EDEDED;
$uni-border-3: #DCDCDC;
$uni-border-4: #B9B9B9;
// 常规色
$uni-black: #000000;
$uni-white: #ffffff;
$uni-transparent: rgba($color: #000000, $alpha: 0);
// 背景色
$uni-bg-color: #f7f7f7;
/* 水平间距 */
$uni-spacing-sm: 8px;
$uni-spacing-base: 15px;
$uni-spacing-lg: 30px;
// 阴影
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
// 蒙版
$uni-mask: rgba($color: #000000, $alpha: 0.4);
@import './styles/setting/_variables.scss';
// 间距基础倍数
$uni-space-root: 2;
// 边框半径默认值
$uni-radius-root:5px;
// 主色
$uni-primary: #2979ff;
$uni-primary-disable:mix(#fff,$uni-primary,50%);
$uni-primary-light: mix(#fff,$uni-primary,80%);
// 辅助色
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
$uni-success: #18bc37;
$uni-success-disable:mix(#fff,$uni-success,50%);
$uni-success-light: mix(#fff,$uni-success,80%);
$uni-warning: #f3a73f;
$uni-warning-disable:mix(#fff,$uni-warning,50%);
$uni-warning-light: mix(#fff,$uni-warning,80%);
$uni-error: #e43d33;
$uni-error-disable:mix(#fff,$uni-error,50%);
$uni-error-light: mix(#fff,$uni-error,80%);
$uni-info: #8f939c;
$uni-info-disable:mix(#fff,$uni-info,50%);
$uni-info-light: mix(#fff,$uni-info,80%);
// 中性色
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
$uni-main-color: #3a3a3a; // 主要文字
$uni-base-color: #6a6a6a; // 常规文字
$uni-secondary-color: #909399; // 次要文字
$uni-extra-color: #c7c7c7; // 辅助说明
// 边框颜色
$uni-border-1: #F0F0F0;
$uni-border-2: #EDEDED;
$uni-border-3: #DCDCDC;
$uni-border-4: #B9B9B9;
// 常规色
$uni-black: #000000;
$uni-white: #ffffff;
$uni-transparent: rgba($color: #000000, $alpha: 0);
// 背景色
$uni-bg-color: #f7f7f7;
/* 水平间距 */
$uni-spacing-sm: 8px;
$uni-spacing-base: 15px;
$uni-spacing-lg: 30px;
// 阴影
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
// 蒙版
$uni-mask: rgba($color: #000000, $alpha: 0.4);
+33 -33
View File
@@ -1,33 +1,33 @@
## 1.2.3(2022-05-24)
- 新增 readonly 属性,组件只读
## 1.2.2(2022-05-06)
- 修复 vue3 input 事件不生效的bug
## 1.2.1(2022-05-06)
- 修复 多余代码导致的bug
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-search-bar](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
## 1.1.2(2021-08-30)
- 修复 value 属性与 modelValue 属性不兼容的Bug
## 1.1.1(2021-08-24)
- 新增 支持国际化
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.9(2021-05-12)
- 新增 项目示例地址
## 1.0.8(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.7(2021-04-15)
- uni-ui 新增 uni-search-bar 的 focus 事件
## 1.0.6(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.5(2021-02-05)
- 调整为uni_modules目录规范
- 新增 支持双向绑定
- 更改 input 事件的返回值,e={value:Number} --> e=value
- 新增 支持图标插槽
- 新增 支持 clear、blur 事件
- 新增 支持 focus 属性
- 去掉组件背景色
## 1.2.3(2022-05-24)
- 新增 readonly 属性,组件只读
## 1.2.2(2022-05-06)
- 修复 vue3 input 事件不生效的bug
## 1.2.1(2022-05-06)
- 修复 多余代码导致的bug
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-search-bar](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
## 1.1.2(2021-08-30)
- 修复 value 属性与 modelValue 属性不兼容的Bug
## 1.1.1(2021-08-24)
- 新增 支持国际化
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.9(2021-05-12)
- 新增 项目示例地址
## 1.0.8(2021-04-21)
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.7(2021-04-15)
- uni-ui 新增 uni-search-bar 的 focus 事件
## 1.0.6(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.0.5(2021-02-05)
- 调整为uni_modules目录规范
- 新增 支持双向绑定
- 更改 input 事件的返回值,e={value:Number} --> e=value
- 新增 支持图标插槽
- 新增 支持 clear、blur 事件
- 新增 支持 focus 属性
- 去掉组件背景色
@@ -1,4 +1,4 @@
{
"uni-search-bar.cancel": "cancel",
"uni-search-bar.placeholder": "Search enter content"
{
"uni-search-bar.cancel": "cancel",
"uni-search-bar.placeholder": "Search enter content"
}
@@ -1,8 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}
@@ -1,4 +1,4 @@
{
"uni-search-bar.cancel": "cancel",
"uni-search-bar.placeholder": "请输入搜索内容"
}
{
"uni-search-bar.cancel": "cancel",
"uni-search-bar.placeholder": "请输入搜索内容"
}
@@ -1,4 +1,4 @@
{
"uni-search-bar.cancel": "cancel",
"uni-search-bar.placeholder": "請輸入搜索內容"
}
{
"uni-search-bar.cancel": "cancel",
"uni-search-bar.placeholder": "請輸入搜索內容"
}
@@ -1,298 +1,298 @@
<template>
<view class="uni-searchbar">
<view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box"
@click="searchClick">
<view class="uni-searchbar__box-icon-search">
<slot name="searchIcon">
<uni-icons color="#c0c4cc" size="18" type="search" />
</slot>
</view>
<input v-if="show || searchVal" :focus="showSync" :disabled="readonly" :placeholder="placeholderText" :maxlength="maxlength"
class="uni-searchbar__box-search-input" confirm-type="search" type="text" v-model="searchVal"
@confirm="confirm" @blur="blur" @focus="emitFocus" />
<text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
<view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='') &&!readonly"
class="uni-searchbar__box-icon-clear" @click="clear">
<slot name="clearIcon">
<uni-icons color="#c0c4cc" size="20" type="clear" />
</slot>
</view>
</view>
<text @click="cancel" class="uni-searchbar__cancel"
v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelTextI18n}}</text>
</view>
</template>
<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const {
t
} = initVueI18n(messages)
/**
* SearchBar 搜索栏
* @description 搜索栏组件,通常用于搜索商品、文章等
* @tutorial https://ext.dcloud.net.cn/plugin?id=866
* @property {Number} radius 搜索栏圆角
* @property {Number} maxlength 输入最大长度
* @property {String} placeholder 搜索栏Placeholder
* @property {String} clearButton = [always|auto|none] 是否显示清除按钮
* @value always 一直显示
* @value auto 输入框不为空时显示
* @value none 一直不显示
* @property {String} cancelButton = [always|auto|none] 是否显示取消按钮
* @value always 一直显示
* @value auto 输入框不为空时显示
* @value none 一直不显示
* @property {String} cancelText 取消按钮的文字
* @property {String} bgColor 输入框背景颜色
* @property {Boolean} focus 是否自动聚焦
* @property {Boolean} readonly 组件只读,不能有任何操作,只做展示
* @event {Function} confirm uniSearchBar 的输入框 confirm 事件,返回参数为uniSearchBar的value,e={value:Number}
* @event {Function} input uniSearchBar 的 value 改变时触发事件,返回参数为uniSearchBar的value,e=value
* @event {Function} cancel 点击取消按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
* @event {Function} clear 点击清除按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
* @event {Function} blur input失去焦点时触发事件,返回参数为uniSearchBar的value,e={value:Number}
*/
export default {
name: "UniSearchBar",
emits: ['input', 'update:modelValue', 'clear', 'cancel', 'confirm', 'blur', 'focus'],
props: {
placeholder: {
type: String,
default: ""
},
radius: {
type: [Number, String],
default: 5
},
clearButton: {
type: String,
default: "auto"
},
cancelButton: {
type: String,
default: "auto"
},
cancelText: {
type: String,
default: '取消'
},
bgColor: {
type: String,
default: "#F8F8F8"
},
maxlength: {
type: [Number, String],
default: 100
},
value: {
type: [Number, String],
default: ""
},
modelValue: {
type: [Number, String],
default: ""
},
focus: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
}
},
data() {
return {
show: false,
showSync: false,
searchVal: ''
}
},
computed: {
cancelTextI18n() {
return this.cancelText || t("uni-search-bar.cancel")
},
placeholderText() {
return this.placeholder || t("uni-search-bar.placeholder")
}
},
watch: {
// #ifndef VUE3
value: {
immediate: true,
handler(newVal) {
this.searchVal = newVal
if (newVal) {
this.show = true
}
}
},
// #endif
// #ifdef VUE3
modelValue: {
immediate: true,
handler(newVal) {
this.searchVal = newVal
if (newVal) {
this.show = true
}
}
},
// #endif
focus: {
immediate: true,
handler(newVal) {
if (newVal) {
if(this.readonly) return
this.show = true;
this.$nextTick(() => {
this.showSync = true
})
}
}
},
searchVal(newVal, oldVal) {
this.$emit("input", newVal)
// #ifdef VUE3
this.$emit("update:modelValue", newVal)
// #endif
}
},
methods: {
searchClick() {
if(this.readonly) return
if (this.show) {
return
}
this.show = true;
this.$nextTick(() => {
this.showSync = true
})
},
clear() {
this.$emit("clear", {
value: this.searchVal
})
this.searchVal = ""
},
cancel() {
if(this.readonly) return
this.$emit("cancel", {
value: this.searchVal
});
this.searchVal = ""
this.show = false
this.showSync = false
// #ifndef APP-PLUS
uni.hideKeyboard()
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
},
confirm() {
// #ifndef APP-PLUS
uni.hideKeyboard();
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
this.$emit("confirm", {
value: this.searchVal
})
},
blur() {
// #ifndef APP-PLUS
uni.hideKeyboard();
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
this.$emit("blur", {
value: this.searchVal
})
},
emitFocus(e) {
this.$emit("focus", e.detail)
}
}
};
</script>
<style lang="scss">
$uni-searchbar-height: 36px;
.uni-searchbar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
position: relative;
padding: 5px;
// background-color: #fff;
}
.uni-searchbar__box {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
overflow: hidden;
position: relative;
flex: 1;
// justify-content: center;
flex-direction: row;
align-items: center;
height: $uni-searchbar-height;
padding: 5px 8px 5px 0px;
}
.uni-searchbar__box-icon-search {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
// width: 32px;
padding: 0 8px;
justify-content: center;
align-items: center;
color: #B3B3B3;
}
.uni-searchbar__box-search-input {
flex: 1;
font-size: 14px;
color: #333;
}
.uni-searchbar__box-icon-clear {
align-items: center;
line-height: 24px;
padding-left: 8px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-searchbar__text-placeholder {
font-size: 14px;
color: #B3B3B3;
margin-left: 5px;
}
.uni-searchbar__cancel {
padding-left: 10px;
line-height: $uni-searchbar-height;
font-size: 14px;
color: #333333;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
</style>
<template>
<view class="uni-searchbar">
<view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box"
@click="searchClick">
<view class="uni-searchbar__box-icon-search">
<slot name="searchIcon">
<uni-icons color="#c0c4cc" size="18" type="search" />
</slot>
</view>
<input v-if="show || searchVal" :focus="showSync" :disabled="readonly" :placeholder="placeholderText" :maxlength="maxlength"
class="uni-searchbar__box-search-input" confirm-type="search" type="text" v-model="searchVal"
@confirm="confirm" @blur="blur" @focus="emitFocus" />
<text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
<view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='') &&!readonly"
class="uni-searchbar__box-icon-clear" @click="clear">
<slot name="clearIcon">
<uni-icons color="#c0c4cc" size="20" type="clear" />
</slot>
</view>
</view>
<text @click="cancel" class="uni-searchbar__cancel"
v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelTextI18n}}</text>
</view>
</template>
<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const {
t
} = initVueI18n(messages)
/**
* SearchBar 搜索栏
* @description 搜索栏组件,通常用于搜索商品、文章等
* @tutorial https://ext.dcloud.net.cn/plugin?id=866
* @property {Number} radius 搜索栏圆角
* @property {Number} maxlength 输入最大长度
* @property {String} placeholder 搜索栏Placeholder
* @property {String} clearButton = [always|auto|none] 是否显示清除按钮
* @value always 一直显示
* @value auto 输入框不为空时显示
* @value none 一直不显示
* @property {String} cancelButton = [always|auto|none] 是否显示取消按钮
* @value always 一直显示
* @value auto 输入框不为空时显示
* @value none 一直不显示
* @property {String} cancelText 取消按钮的文字
* @property {String} bgColor 输入框背景颜色
* @property {Boolean} focus 是否自动聚焦
* @property {Boolean} readonly 组件只读,不能有任何操作,只做展示
* @event {Function} confirm uniSearchBar 的输入框 confirm 事件,返回参数为uniSearchBar的value,e={value:Number}
* @event {Function} input uniSearchBar 的 value 改变时触发事件,返回参数为uniSearchBar的value,e=value
* @event {Function} cancel 点击取消按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
* @event {Function} clear 点击清除按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
* @event {Function} blur input失去焦点时触发事件,返回参数为uniSearchBar的value,e={value:Number}
*/
export default {
name: "UniSearchBar",
emits: ['input', 'update:modelValue', 'clear', 'cancel', 'confirm', 'blur', 'focus'],
props: {
placeholder: {
type: String,
default: ""
},
radius: {
type: [Number, String],
default: 5
},
clearButton: {
type: String,
default: "auto"
},
cancelButton: {
type: String,
default: "auto"
},
cancelText: {
type: String,
default: '取消'
},
bgColor: {
type: String,
default: "#F8F8F8"
},
maxlength: {
type: [Number, String],
default: 100
},
value: {
type: [Number, String],
default: ""
},
modelValue: {
type: [Number, String],
default: ""
},
focus: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
}
},
data() {
return {
show: false,
showSync: false,
searchVal: ''
}
},
computed: {
cancelTextI18n() {
return this.cancelText || t("uni-search-bar.cancel")
},
placeholderText() {
return this.placeholder || t("uni-search-bar.placeholder")
}
},
watch: {
// #ifndef VUE3
value: {
immediate: true,
handler(newVal) {
this.searchVal = newVal
if (newVal) {
this.show = true
}
}
},
// #endif
// #ifdef VUE3
modelValue: {
immediate: true,
handler(newVal) {
this.searchVal = newVal
if (newVal) {
this.show = true
}
}
},
// #endif
focus: {
immediate: true,
handler(newVal) {
if (newVal) {
if(this.readonly) return
this.show = true;
this.$nextTick(() => {
this.showSync = true
})
}
}
},
searchVal(newVal, oldVal) {
this.$emit("input", newVal)
// #ifdef VUE3
this.$emit("update:modelValue", newVal)
// #endif
}
},
methods: {
searchClick() {
if(this.readonly) return
if (this.show) {
return
}
this.show = true;
this.$nextTick(() => {
this.showSync = true
})
},
clear() {
this.$emit("clear", {
value: this.searchVal
})
this.searchVal = ""
},
cancel() {
if(this.readonly) return
this.$emit("cancel", {
value: this.searchVal
});
this.searchVal = ""
this.show = false
this.showSync = false
// #ifndef APP-PLUS
uni.hideKeyboard()
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
},
confirm() {
// #ifndef APP-PLUS
uni.hideKeyboard();
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
this.$emit("confirm", {
value: this.searchVal
})
},
blur() {
// #ifndef APP-PLUS
uni.hideKeyboard();
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
this.$emit("blur", {
value: this.searchVal
})
},
emitFocus(e) {
this.$emit("focus", e.detail)
}
}
};
</script>
<style lang="scss">
$uni-searchbar-height: 36px;
.uni-searchbar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
position: relative;
padding: 5px;
// background-color: #fff;
}
.uni-searchbar__box {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
overflow: hidden;
position: relative;
flex: 1;
// justify-content: center;
flex-direction: row;
align-items: center;
height: $uni-searchbar-height;
padding: 5px 8px 5px 0px;
}
.uni-searchbar__box-icon-search {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
// width: 32px;
padding: 0 8px;
justify-content: center;
align-items: center;
color: #B3B3B3;
}
.uni-searchbar__box-search-input {
flex: 1;
font-size: 14px;
color: #333;
}
.uni-searchbar__box-icon-clear {
align-items: center;
line-height: 24px;
padding-left: 8px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-searchbar__text-placeholder {
font-size: 14px;
color: #B3B3B3;
margin-left: 5px;
}
.uni-searchbar__cancel {
padding-left: 10px;
line-height: $uni-searchbar-height;
font-size: 14px;
color: #333333;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
</style>
+88 -88
View File
@@ -1,89 +1,89 @@
{
"id": "uni-search-bar",
"displayName": "uni-search-bar 搜索栏",
"version": "1.2.3",
"description": "搜索栏组件,通常用于搜索商品、文章等",
"keywords": [
"uni-ui",
"uniui",
"搜索框",
"搜索栏"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-search-bar",
"displayName": "uni-search-bar 搜索栏",
"version": "1.2.3",
"description": "搜索栏组件,通常用于搜索商品、文章等",
"keywords": [
"uni-ui",
"uniui",
"搜索框",
"搜索栏"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+14 -14
View File
@@ -1,14 +1,14 @@
## SearchBar 搜索栏
> **组件名:uni-search-bar**
> 代码块: `uSearchBar`
搜索栏组件
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
## SearchBar 搜索栏
> **组件名:uni-search-bar**
> 代码块: `uSearchBar`
搜索栏组件
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
@@ -1,9 +1,9 @@
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-segmented-control](https://uniapp.dcloud.io/component/uniui/uni-segmented-control)
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.5(2021-05-12)
- 新增 项目示例地址
## 1.0.4(2021-02-05)
- 调整为uni_modules目录规范
## 1.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-segmented-control](https://uniapp.dcloud.io/component/uniui/uni-segmented-control)
## 1.1.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.5(2021-05-12)
- 新增 项目示例地址
## 1.0.4(2021-02-05)
- 调整为uni_modules目录规范
@@ -1,145 +1,145 @@
<template>
<view :class="[styleType === 'text'?'segmented-control--text' : 'segmented-control--button' ]"
:style="{ borderColor: styleType === 'text' ? '' : activeColor }" class="segmented-control">
<view v-for="(item, index) in values" :class="[ styleType === 'text' ? '': 'segmented-control__item--button',
index === currentIndex&&styleType === 'button' ? 'segmented-control__item--button--active': '',
index === 0&&styleType === 'button' ? 'segmented-control__item--button--first': '',
index === values.length - 1&&styleType === 'button' ? 'segmented-control__item--button--last': '' ]" :key="index"
:style="{ backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : '',borderColor: index === currentIndex&&styleType === 'text'||styleType === 'button'?activeColor:'transparent' }"
class="segmented-control__item" @click="_onClick(index)">
<view>
<text :style="{color:
index === currentIndex
? styleType === 'text'
? activeColor
: '#fff'
: styleType === 'text'
? '#000'
: activeColor}" class="segmented-control__text" :class="styleType === 'text' && index === currentIndex ? 'segmented-control__item--text': ''">{{ item }}</text>
</view>
</view>
</view>
</template>
<script>
/**
* SegmentedControl 分段器
* @description 用作不同视图的显示
* @tutorial https://ext.dcloud.net.cn/plugin?id=54
* @property {Number} current 当前选中的tab索引值,从0计数
* @property {String} styleType = [button|text] 分段器样式类型
* @value button 按钮类型
* @value text 文字类型
* @property {String} activeColor 选中的标签背景色与边框颜色
* @property {Array} values 选项数组
* @event {Function} clickItem 组件触发点击事件时触发,e={currentIndex}
*/
export default {
name: 'UniSegmentedControl',
emits: ['clickItem'],
props: {
current: {
type: Number,
default: 0
},
values: {
type: Array,
default () {
return []
}
},
activeColor: {
type: String,
default: '#2979FF'
},
styleType: {
type: String,
default: 'button'
}
},
data() {
return {
currentIndex: 0
}
},
watch: {
current(val) {
if (val !== this.currentIndex) {
this.currentIndex = val
}
}
},
created() {
this.currentIndex = this.current
},
methods: {
_onClick(index) {
if (this.currentIndex !== index) {
this.currentIndex = index
this.$emit('clickItem', {
currentIndex: index
})
}
}
}
}
</script>
<style lang="scss" scoped>
.segmented-control {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
flex-direction: row;
height: 36px;
overflow: hidden;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.segmented-control__item {
/* #ifndef APP-NVUE */
display: inline-flex;
box-sizing: border-box;
/* #endif */
position: relative;
flex: 1;
justify-content: center;
align-items: center;
}
.segmented-control__item--button {
border-style: solid;
border-top-width: 1px;
border-bottom-width: 1px;
border-right-width: 1px;
border-left-width: 0;
}
.segmented-control__item--button--first {
border-left-width: 1px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.segmented-control__item--button--last {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.segmented-control__item--text {
border-bottom-style: solid;
border-bottom-width: 2px;
padding: 6px 0;
}
.segmented-control__text {
font-size: 14px;
line-height: 20px;
text-align: center;
}
</style>
<template>
<view :class="[styleType === 'text'?'segmented-control--text' : 'segmented-control--button' ]"
:style="{ borderColor: styleType === 'text' ? '' : activeColor }" class="segmented-control">
<view v-for="(item, index) in values" :class="[ styleType === 'text' ? '': 'segmented-control__item--button',
index === currentIndex&&styleType === 'button' ? 'segmented-control__item--button--active': '',
index === 0&&styleType === 'button' ? 'segmented-control__item--button--first': '',
index === values.length - 1&&styleType === 'button' ? 'segmented-control__item--button--last': '' ]" :key="index"
:style="{ backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : '',borderColor: index === currentIndex&&styleType === 'text'||styleType === 'button'?activeColor:'transparent' }"
class="segmented-control__item" @click="_onClick(index)">
<view>
<text :style="{color:
index === currentIndex
? styleType === 'text'
? activeColor
: '#fff'
: styleType === 'text'
? '#000'
: activeColor}" class="segmented-control__text" :class="styleType === 'text' && index === currentIndex ? 'segmented-control__item--text': ''">{{ item }}</text>
</view>
</view>
</view>
</template>
<script>
/**
* SegmentedControl 分段器
* @description 用作不同视图的显示
* @tutorial https://ext.dcloud.net.cn/plugin?id=54
* @property {Number} current 当前选中的tab索引值,从0计数
* @property {String} styleType = [button|text] 分段器样式类型
* @value button 按钮类型
* @value text 文字类型
* @property {String} activeColor 选中的标签背景色与边框颜色
* @property {Array} values 选项数组
* @event {Function} clickItem 组件触发点击事件时触发,e={currentIndex}
*/
export default {
name: 'UniSegmentedControl',
emits: ['clickItem'],
props: {
current: {
type: Number,
default: 0
},
values: {
type: Array,
default () {
return []
}
},
activeColor: {
type: String,
default: '#2979FF'
},
styleType: {
type: String,
default: 'button'
}
},
data() {
return {
currentIndex: 0
}
},
watch: {
current(val) {
if (val !== this.currentIndex) {
this.currentIndex = val
}
}
},
created() {
this.currentIndex = this.current
},
methods: {
_onClick(index) {
if (this.currentIndex !== index) {
this.currentIndex = index
this.$emit('clickItem', {
currentIndex: index
})
}
}
}
}
</script>
<style lang="scss" scoped>
.segmented-control {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
flex-direction: row;
height: 36px;
overflow: hidden;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.segmented-control__item {
/* #ifndef APP-NVUE */
display: inline-flex;
box-sizing: border-box;
/* #endif */
position: relative;
flex: 1;
justify-content: center;
align-items: center;
}
.segmented-control__item--button {
border-style: solid;
border-top-width: 1px;
border-bottom-width: 1px;
border-right-width: 1px;
border-left-width: 0;
}
.segmented-control__item--button--first {
border-left-width: 1px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.segmented-control__item--button--last {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.segmented-control__item--text {
border-bottom-style: solid;
border-bottom-width: 2px;
padding: 6px 0;
}
.segmented-control__text {
font-size: 14px;
line-height: 20px;
text-align: center;
}
</style>
+86 -86
View File
@@ -1,87 +1,87 @@
{
"id": "uni-segmented-control",
"displayName": "uni-segmented-control 分段器",
"version": "1.2.0",
"description": "分段器由至少 2 个分段控件组成,用作不同视图的显示",
"keywords": [
"uni-ui",
"uniui",
"分段器",
"segement",
"顶部选择"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "uni-segmented-control",
"displayName": "uni-segmented-control 分段器",
"version": "1.2.0",
"description": "分段器由至少 2 个分段控件组成,用作不同视图的显示",
"keywords": [
"uni-ui",
"uniui",
"分段器",
"segement",
"顶部选择"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
Loaded 100 of 169 files, more files were not shown because too many files have changed in this diff. Show more