qiaopengfei #12
|
@ -2,10 +2,13 @@ import Vue from 'vue'
|
||||||
import App from '../src/App.vue'
|
import App from '../src/App.vue'
|
||||||
|
|
||||||
//基于element组件封装,引入element组件库
|
//基于element组件封装,引入element组件库
|
||||||
import { Input, Select } from 'element-ui';
|
import { Input, Select, Option, OptionGroup, DatePicker } from 'element-ui';
|
||||||
import 'element-ui/lib/theme-chalk/index.css';
|
import 'element-ui/lib/theme-chalk/index.css';
|
||||||
Vue.use(Input);
|
Vue.use(Input);
|
||||||
Vue.use(Select);
|
Vue.use(Select);
|
||||||
|
Vue.use(OptionGroup);
|
||||||
|
Vue.use(Option);
|
||||||
|
Vue.use(DatePicker);
|
||||||
|
|
||||||
// 导入组件库
|
// 导入组件库
|
||||||
import erp_element_ui from '../packages'
|
import erp_element_ui from '../packages'
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import agDatePicker from './src'
|
||||||
|
|
||||||
|
// 为组件提供 install 安装方法,供按需引入
|
||||||
|
agDatePicker.install = function (Vue) {
|
||||||
|
Vue.component(agDatePicker.name, agDatePicker)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出组件
|
||||||
|
export default agDatePicker
|
|
@ -0,0 +1,141 @@
|
||||||
|
<template>
|
||||||
|
<el-date-picker
|
||||||
|
class="ag-date-picker"
|
||||||
|
v-model="dateArr"
|
||||||
|
v-bind="attrs"
|
||||||
|
@change="dataChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* agDatePicker 时间选择器
|
||||||
|
*/
|
||||||
|
import isEmpty from "../../../src/utils/isEmpty";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "agDatePicker",
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dateArr: ["", ""],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
attrs() {
|
||||||
|
return {
|
||||||
|
size: "small",
|
||||||
|
type: "daterange",
|
||||||
|
format: "yyyy/MM/dd",
|
||||||
|
"value-format": "yyyy-MM-dd",
|
||||||
|
"start-placeholder": "开始日期",
|
||||||
|
"end-placeholder": "结束日期",
|
||||||
|
"range-separator": "-",
|
||||||
|
"picker-options": {
|
||||||
|
disabledDate(time) {
|
||||||
|
return (
|
||||||
|
time.getTime() >
|
||||||
|
new Date(new Date().toLocaleDateString()).getTime() +
|
||||||
|
24 * 60 * 60 * 1000 -
|
||||||
|
1
|
||||||
|
);
|
||||||
|
},
|
||||||
|
shortcuts: [
|
||||||
|
{
|
||||||
|
text: "本月",
|
||||||
|
onClick(picker) {
|
||||||
|
const end =
|
||||||
|
new Date(new Date().toLocaleDateString()).getTime() +
|
||||||
|
24 * 60 * 60 * 1000 -
|
||||||
|
1;
|
||||||
|
const time = new Date();
|
||||||
|
time.setDate(1);
|
||||||
|
time.setHours(0);
|
||||||
|
time.setSeconds(0);
|
||||||
|
time.setMinutes(0);
|
||||||
|
var start = time.getTime();
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "近一个月",
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "近三个月",
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "近六个月",
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 180);
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "最近一年",
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 360);
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}, //多选日期
|
||||||
|
...this.$attrs,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value: {
|
||||||
|
handler(newVal) {
|
||||||
|
if (!Array.isArray(newVal)) {
|
||||||
|
throw new Error("agDatePicker date请传入数组");
|
||||||
|
}
|
||||||
|
|
||||||
|
let [date1, date2] = newVal;
|
||||||
|
if (!this.dateArr) {
|
||||||
|
this.dateArr = [date1 || "", date2 || ""];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$set(this.dateArr, 0, date1 || "");
|
||||||
|
this.$set(this.dateArr, 1, date2 || "");
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
dataChange(val) {
|
||||||
|
let date1 = "";
|
||||||
|
let date2 = "";
|
||||||
|
|
||||||
|
if (!isEmpty(val) && val.length === 2 && val[0] && val[1]) {
|
||||||
|
date1 = `${val[0]} 00:00:00`;
|
||||||
|
date2 = `${val[1]} 23:59:59`;
|
||||||
|
}
|
||||||
|
this.$emit("input", [date1, date2]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,9 @@
|
||||||
|
import agNumberRange from './src'
|
||||||
|
|
||||||
|
// 为组件提供 install 安装方法,供按需引入
|
||||||
|
agNumberRange.install = function (Vue) {
|
||||||
|
Vue.component(agNumberRange.name, agNumberRange)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出组件
|
||||||
|
export default agNumberRange
|
|
@ -0,0 +1,118 @@
|
||||||
|
<template>
|
||||||
|
<div class="ag-number-range">
|
||||||
|
<el-input
|
||||||
|
:style="{ width: width + 'px' }"
|
||||||
|
:size="size"
|
||||||
|
v-model="startValue"
|
||||||
|
@input="handleStartInput"
|
||||||
|
@blur="handleInputBlur"
|
||||||
|
></el-input>
|
||||||
|
<span class="separator">{{ rangeSeparator }}</span>
|
||||||
|
<el-input
|
||||||
|
:style="{ width: width + 'px' }"
|
||||||
|
:size="size"
|
||||||
|
v-model="endValue"
|
||||||
|
@input="handleEndInput"
|
||||||
|
@blur="handleInputBlur"
|
||||||
|
></el-input>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* NumberRange
|
||||||
|
* 数值范围
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "agNumberRange",
|
||||||
|
|
||||||
|
model: {
|
||||||
|
prop: "value",
|
||||||
|
event: "change",
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
// 绑定的value
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default: function () {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// 分隔符
|
||||||
|
rangeSeparator: {
|
||||||
|
type: String,
|
||||||
|
default: "-",
|
||||||
|
},
|
||||||
|
|
||||||
|
// 输入框宽度
|
||||||
|
width: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: "50",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: "small",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 开始数值
|
||||||
|
startValue: "",
|
||||||
|
// 结束数值
|
||||||
|
endValue: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(newValue) {
|
||||||
|
if (Array.isArray(newValue)) {
|
||||||
|
this.startValue = newValue[0];
|
||||||
|
this.endValue = newValue[1];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 输入框失去焦点
|
||||||
|
* @emit change
|
||||||
|
*/
|
||||||
|
handleInputBlur() {
|
||||||
|
this.$emit("change", [this.startValue, this.endValue]);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听start值
|
||||||
|
* @param e 当前值
|
||||||
|
*/
|
||||||
|
handleStartInput(e) {
|
||||||
|
this.startValue = this.formatValue(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听end值
|
||||||
|
* @param e 当前值
|
||||||
|
*/
|
||||||
|
handleEndInput(e) {
|
||||||
|
this.endValue = this.formatValue(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化输入, 只能输入数字 和 .
|
||||||
|
* @param v
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
formatValue(v) {
|
||||||
|
const reg = /[^\d|.]/g;
|
||||||
|
return v.replace(reg, "");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -2,23 +2,22 @@
|
||||||
<el-select
|
<el-select
|
||||||
class="ag_select"
|
class="ag_select"
|
||||||
:style="{ width }"
|
:style="{ width }"
|
||||||
:value="value"
|
|
||||||
:size="size"
|
|
||||||
v-on="inputListeners"
|
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
|
v-on="inputListeners"
|
||||||
>
|
>
|
||||||
|
<slot />
|
||||||
|
<slot name="prefix" slot="prefix" />
|
||||||
|
<slot name="empty" slot="empty" />
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, index) in options"
|
v-for="item in options"
|
||||||
:key="index"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
></el-option>
|
></el-option>
|
||||||
<!-- <slot name="options" slot="options" /> -->
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import cloneDeep from "../../../src/utils/cloneDeep";
|
|
||||||
export default {
|
export default {
|
||||||
name: "agSelect",
|
name: "agSelect",
|
||||||
props: {
|
props: {
|
||||||
|
@ -26,29 +25,25 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
value: {
|
options: {
|
||||||
type: String,
|
type: Array,
|
||||||
default: "",
|
default: () => {
|
||||||
},
|
return [];
|
||||||
size: {
|
},
|
||||||
type: String,
|
|
||||||
default: "small",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {};
|
||||||
model: "",
|
|
||||||
options: [],
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
attrs() {
|
attrs() {
|
||||||
if (this.$attrs["remote-method"]) {
|
return {
|
||||||
let obj = cloneDeep(this.$attrs);
|
size: "small",
|
||||||
Reflect.deleteProperty(obj, "remote-method");
|
remote: true,
|
||||||
return { ...obj, clearable: true, filterable: true, remote: true };
|
clearable: true,
|
||||||
}
|
filterable: true,
|
||||||
return false;
|
...this.$attrs,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
// 所有父级事件
|
// 所有父级事件
|
||||||
inputListeners() {
|
inputListeners() {
|
||||||
|
@ -76,26 +71,7 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
methods: {},
|
||||||
value: {
|
|
||||||
immediate: true,
|
|
||||||
handler(newVal) {
|
|
||||||
this.removeMethod(newVal);
|
|
||||||
this.model = newVal;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async removeMethod(keywords) {
|
|
||||||
if (this.$attrs["remote-method"]) {
|
|
||||||
let opts = await this.$attrs["remote-method"](keywords);
|
|
||||||
this.options = opts;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleChange(value) {
|
|
||||||
this.$emit("input", value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import agTabs from './src'
|
||||||
|
|
||||||
|
// 为组件提供 install 安装方法,供按需引入
|
||||||
|
agTabs.install = function (Vue) {
|
||||||
|
Vue.component(agTabs.name, agTabs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出组件
|
||||||
|
export default agTabs
|
|
@ -0,0 +1,23 @@
|
||||||
|
<template>
|
||||||
|
<el-tabs class="ag-tabs" v-on="$listeners" v-bind="attrs"> </el-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "agTabs",
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
attrs() {
|
||||||
|
return {
|
||||||
|
...this.$attrs,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
</style>
|
115
src/App.vue
115
src/App.vue
|
@ -1,33 +1,106 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<agSelect ref="ref_Pedestal" :value="value" @input="changeInput">
|
<agDatePicker ref="ref_Pedestal" v-model="value" @blur="changeInput" >
|
||||||
</agSelect>
|
</agDatePicker>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import agSelect from "../packages/agSelect/src/index";
|
import agDatePicker from "../packages/agDatePicker/src/index.vue";
|
||||||
export default {
|
export default {
|
||||||
components: { agSelect },
|
components: { agDatePicker },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
value: "",
|
value: [],
|
||||||
options: [{
|
options: [
|
||||||
value: '选项1',
|
{
|
||||||
label: '黄金糕'
|
label: "热门城市",
|
||||||
}, {
|
options: [
|
||||||
value: '选项2',
|
{
|
||||||
label: '双皮奶'
|
value: "Shanghai",
|
||||||
}, {
|
label: "上海",
|
||||||
value: '选项3',
|
},
|
||||||
label: '蚵仔煎'
|
{
|
||||||
}, {
|
value: "Beijing",
|
||||||
value: '选项4',
|
label: "北京",
|
||||||
label: '龙须面'
|
},
|
||||||
}, {
|
],
|
||||||
value: '选项5',
|
},
|
||||||
label: '北京烤鸭'
|
{
|
||||||
}],
|
label: "城市名",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: "Chengdu",
|
||||||
|
label: "成都",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "Shenzhen",
|
||||||
|
label: "深圳",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "Guangzhou",
|
||||||
|
label: "广州",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "Dalian",
|
||||||
|
label: "大连",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pickerOptions: {
|
||||||
|
shortcuts: [
|
||||||
|
{
|
||||||
|
text: "最近一周",
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "最近一个月",
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "最近三个月",
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||||||
|
picker.$emit("pick", [start, end]);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// options: [
|
||||||
|
// {
|
||||||
|
// value: "选项1",
|
||||||
|
// label: "黄金糕",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: "选项2",
|
||||||
|
// label: "双皮奶",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: "选项3",
|
||||||
|
// label: "蚵仔煎",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: "选项4",
|
||||||
|
// label: "龙须面",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: "选项5",
|
||||||
|
// label: "北京烤鸭",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
export default function isEmpty(value) {
|
||||||
|
// 首先,检查null和undefined
|
||||||
|
if (value == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查数字、字符串和布尔值(非空字符串、非零数字和非false值被视为非空)
|
||||||
|
if (typeof value === 'number' || typeof value === 'string' || typeof value === 'boolean') {
|
||||||
|
return !value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查对象、数组和函数
|
||||||
|
if (typeof value === 'object' || typeof value === 'function') {
|
||||||
|
// 使用Object.keys()来获取对象自身的所有属性键组成的数组
|
||||||
|
// 然后检查这个数组的长度是否为0
|
||||||
|
// 注意:对于数组和函数,这同样适用,因为它们在JavaScript中也是对象
|
||||||
|
return Object.keys(value).length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果以上条件都不满足,那么可能是一个特殊的对象(如RegExp, Date等)
|
||||||
|
// 在这里,我们假设这些都不是“空”的,除非你有特定的需求来处理它们
|
||||||
|
// 但按照lodash的`_.isEmpty`的逻辑,这些通常被视为非空
|
||||||
|
return false;
|
||||||
|
}
|
Loading…
Reference in New Issue