Merge pull request 'qiaopengfei' (#8) from qiaopengfei into master

Reviewed-on: #8
This commit is contained in:
qiaopengfei 2024-07-15 10:32:54 +08:00
commit 6eff4461ca
12 changed files with 639 additions and 221 deletions

View File

@ -3,7 +3,7 @@ import App from '../src/App.vue'
//基于element组件封装引入element组件库
import { Input, Select, Option, OptionGroup, DatePicker, Tabs, TabPane, Pagination, Dialog, Button } from 'element-ui';
import { Input, Select, Option, OptionGroup, DatePicker, Tabs, TabPane, Pagination, Dialog, Button, Form, FormItem, Popover } from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import '../src/styles/element-variables.scss'//element 组件样式文件
@ -17,6 +17,9 @@ Vue.use(TabPane);
Vue.use(Pagination)
Vue.use(Dialog)
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Popover)
// 导入组件库
import erp_element_ui from '../packages'

View File

@ -1,9 +0,0 @@
// import pedestal from './src'
// // 为组件提供 install 安装方法,供按需引入
// pedestal.install = function (Vue) {
// Vue.component(pedestal.name, pedestal)
// }
// // 导出组件
// export default pedestal

View File

@ -1,18 +0,0 @@
<template>
<div>
<h1>主组件</h1>
</div>
</template>
<script>
export default {
components: {},
data() {
return {};
},
methods: {},
};
</script>
<style scoped lang='scss'>
</style>

View File

@ -0,0 +1,9 @@
import agCascadeOptional from './src'
// 为组件提供 install 安装方法,供按需引入
agCascadeOptional.install = function (Vue) {
Vue.component(agCascadeOptional.name, agCascadeOptional)
}
// 导出组件
export default agCascadeOptional

View File

@ -0,0 +1,163 @@
<template>
<div class="ag-CascadeOptional">
<ag-input
class="ag_input_group"
placeholder="请输入内容"
:value="value[1]"
v-bind="config.input"
v-on="Listeners.input"
>
<ag-select
slot="prepend"
:clearable="false"
placeholder="请选择"
:value="value[0]"
v-bind="config.select"
v-on="Listeners.select"
class="ag_select_group"
>
<template slot="prefix">
{{
(config.select.options.find((e) => e.value == value[0]) || {}).label
}}
</template>
</ag-select>
</ag-input>
</div>
</template>
<script>
import agSelect from "../../agSelect/src/index.vue";
import agInput from "../../agInput/src/index.vue";
export default {
name: "agCascadeOptional",
components: {
agSelect,
agInput,
},
props: {
value: {
type: Array,
default: () => {
return [null, null];
},
},
},
data() {
return {
values: [null, null],
};
},
computed: {
config() {
const input_config = this.getAfterAgo(this.$attrs, "after_");
const input = {
...this.$attrs,
...input_config,
};
const select_configs = this.getAfterAgo(this.$attrs, "ago_");
const select = {
...this.$attrs,
...select_configs,
};
console.log(input, select);
return {
input,
select,
};
},
Listeners() {
const new_listeners = Object.assign({}, this.$listeners, {
after_input: (value) => {
this.$emit("input", [value, this.value[1] ? this.value[1] : ""]);
},
ago_input: (value) => {
this.$emit("input", [this.value[0] ? this.value[0] : "", value]);
},
});
const select = this.getAfterAgo(new_listeners, "after_");
const input = this.getAfterAgo(new_listeners, "ago_");
return {
select,
input,
};
},
},
watch: {
value: {
handler(newVal) {
if (!Array.isArray(newVal)) {
throw new Error("agDatePicker data请传入数组");
}
},
immediate: true,
},
},
methods: {
getAfterAgo(attr, prefix) {
const config = {};
for (const key in attr) {
if (attr.hasOwnProperty(key) && key.startsWith(prefix)) {
const newKey = key.substring(prefix.length);
config[newKey] = attr[key];
}
}
return config;
},
},
};
</script>
<style scoped lang='scss'>
::v-deep {
.el-input-group__prepend {
background-color: #fff;
border: none !important;
}
.el-input__suffix {
z-index: 99;
transition: none !important;
}
.el-input__inner {
position: relative;
left: 0;
border: 1px solid #dcdfe6 !important;
padding: 0 5px 0 15px !important;
&:hover {
position: relative;
z-index: 20 !important;
border: 1px solid #c0c4cc !important;
}
&:focus {
position: relative;
z-index: 20 !important;
border: 1px solid #1890ff !important;
}
}
}
::v-deep .ag_select_group {
min-width: 90px;
max-width: 140px;
color: #606266;
text-align: start;
.el-input__prefix {
position: relative;
left: 0;
padding: 0 5px 0 15px;
box-sizing: border-box;
color: #606266;
visibility: hidden;
}
.el-input__inner {
border-radius: 4px 0 0 4px;
z-index: 1;
}
}
::v-deep .el-select {
margin: 0 -21px !important;
box-sizing: border-box;
}
</style>

View File

@ -5,7 +5,7 @@
clear-icon="ag-icon-clear"
v-model="dateArr"
v-bind="attrs"
v-on="inputListeners"
v-on="Listeners"
@mouseenter.native="mousetrue = true"
@mouseleave.native="mousetrue = false"
/>
@ -21,29 +21,25 @@ export default {
name: "agDatePicker",
props: {
value: {
type: Array,
default: () => [null, null],
default: "",
},
},
data() {
return {
width: "160px",
dateArr: [null, null],
dateArr: "",
date_picker: false,
mousetrue: true,
};
},
computed: {
attrs() {
return {
size: "small",
type: "daterange",
format: "yyyy/MM/dd",
"value-format": "yyyy-MM-dd",
let config = {};
if (this.$attrs.type === "daterange" || !this.$attrs.type) {
config = {
"start-placeholder": "开始日期",
"end-placeholder": "结束日期",
"range-separator": "-",
"picker-options": {
disabledDate(time) {
return (
@ -108,21 +104,85 @@ export default {
},
],
}, //
};
} else {
config = {
align: "right",
placeholder: "选择日期",
"picker-options": {
disabledDate(time) {
return time.getTime() > Date.now();
},
shortcuts: [
{
text: "近一周",
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 7 * 24 * 60 * 60 * 1000);
picker.$emit("pick", date);
},
},
{
text: "近一个月",
onClick(picker) {
const date = new Date();
date.setMonth(date.getMonth() - 1);
picker.$emit("pick", date);
},
},
{
text: "近三个月",
onClick(picker) {
const date = new Date();
date.setMonth(date.getMonth() - 3);
picker.$emit("pick", date);
},
},
{
text: "近六个月",
onClick(picker) {
const date = new Date();
date.setMonth(date.getMonth() - 6);
picker.$emit("pick", date);
},
},
{
text: "近一年",
onClick(picker) {
const date = new Date();
date.setFullYear(date.getFullYear() - 1);
picker.$emit("pick", date);
},
},
],
},
};
}
return {
size: "small",
type: "daterange",
format: "yyyy-MM-dd",
"value-format": "yyyy-MM-dd",
...config,
...this.$attrs,
};
},
//
inputListeners() {
Listeners() {
return Object.assign({}, this.$listeners, {
input: (value) => {
let date1 = "";
let date2 = "";
if (this.attrs.type === "daterange") {
if (!isEmpty(value) && value.length === 2 && value[0] && value[1]) {
date1 = `${value[0]} 00:00:00`;
date2 = `${value[1]} 23:59:59`;
this.$emit("input", [
`${value[0]} 00:00:00`,
`${value[1]} 23:59:59`,
]);
} else {
this.$emit("input", []);
}
} else {
this.$emit("input", value);
}
this.$emit("input", [date1, date2]);
},
});
},
@ -135,34 +195,35 @@ export default {
watch: {
value: {
handler(newVal) {
if (this.attrs.type === "daterange") {
if (!Array.isArray(newVal)) {
throw new Error("agDatePicker date请传入数组");
}
let [date1, date2] = newVal;
if (!this.dateArr) {
const [date1, date2] = newVal.slice(0, 2);
this.dateArr = [date1 || "", date2 || ""];
return;
} else {
this.dateArr = newVal;
}
this.$set(this.dateArr, 0, date1 || "");
this.$set(this.dateArr, 1, date2 || "");
},
immediate: true,
deep: true,
},
dateArr: {
handler(newVal) {
if (
let defaultWidth = this.attrs.type === "daterange" ? "170px" : "140px";
if (this.attrs.type === "daterange") {
this.date_picker =
newVal &&
newVal.length > 0 &&
newVal.some(
(item) => item !== null && item !== undefined && item !== ""
)
) {
this.width = "190px";
this.date_picker = true;
newVal.some((item) => item != null && item !== "");
this.width =
newVal &&
newVal.length > 0 &&
newVal.some((item) => item != null && item !== "")
? "205px"
: defaultWidth;
} else {
this.width = "160px";
this.date_picker = false;
this.width = defaultWidth;
this.date_picker = !!newVal; // 使newVal
}
},
immediate: true,
@ -188,31 +249,29 @@ export default {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.el-input__icon.el-range__close-icon {
.el-input__icon,
.ag-icon-prefix-show,
.ag-iconfont,
.ag-icon-clear {
position: absolute;
width: 16px;
width: 16px !important;
font-size: 16px;
margin-left: -5px;
line-height: 30px;
right: 8px;
top: 0;
line-height: 1 !important;
right: 6px;
top: 1px;
z-index: 1;
}
.el-input__prefix {
position: absolute;
left: 98%;
}
.ag-icon-clear {
&:before {
content: "\e6db";
}
}
.ag-icon-prefix-show {
width: 16px;
font-size: 16px;
margin-left: -5px;
line-height: 38px;
position: absolute;
right: 8px;
top: 1px;
&:before {
content: "\e78e";
}

View File

@ -2,7 +2,7 @@
<el-input
class="ag_input"
:style="{ width }"
v-on="inputListeners"
v-on="Listeners"
v-bind="attrs"
>
<slot name="append" slot="append" />
@ -26,7 +26,7 @@ export default {
},
toUpperCase: {
type: Boolean,
default: true,
default: false,
},
},
computed: {
@ -38,7 +38,7 @@ export default {
};
},
//
inputListeners() {
Listeners() {
return Object.assign(
{},
//
@ -70,23 +70,8 @@ export default {
<style lang="scss" scoped>
::v-deep {
.el-input__suffix {
// @include sjf;
.el-input__suffix-inner {
.el-input__icon {
font-size: 12px;
width: 14px;
height: 14px;
line-height: 14px;
// @include cj1;
right: 5px;
&:hover {
border-radius: 50%;
color: #c0c4cc;
background: #ecedee;
}
}
}
font-size: 16px !important;
}
.el-icon-circle-close:before {
content: "\e6db";

View File

@ -0,0 +1,9 @@
import agMultifunctionSearch from './src'
// 为组件提供 install 安装方法,供按需引入
agMultifunctionSearch.install = function (Vue) {
Vue.component(agMultifunctionSearch.name, agMultifunctionSearch)
}
// 导出组件
export default agMultifunctionSearch

View File

@ -0,0 +1,117 @@
<template>
<div class="ag-MultifunctionSearch">
<ag-select
slot="prepend"
:clearable="false"
placeholder="请选择"
:value="value[0]"
v-bind="config.select"
v-on="Listeners.select"
class="ag_select_group"
>
<template slot="prefix">
{{
(config.select.options.find((e) => e.value == value[0]) || {}).label
}}
</template>
</ag-select>
<ag-input
class="ag_input_group"
placeholder="请输入内容"
:value="value[1]"
v-bind="config.input"
v-on="Listeners.input"
>
</ag-input>
</div>
</template>
<script>
import agSelect from "../../agSelect/src/index.vue";
import agInput from "../../agInput/src/index.vue";
export default {
name: "agMultifunctionSearch",
components: {
agSelect,
agInput,
},
props: {
value: {
type: Array,
default: () => {
return [null, null];
},
},
},
data() {
return {
values: [null, null],
};
},
computed: {
config() {
const input_config = this.getAfterAgo(this.$attrs, "after_");
const input = {
...this.$attrs,
...input_config,
};
const select_configs = this.getAfterAgo(this.$attrs, "ago_");
const select = {
...this.$attrs,
...select_configs,
};
console.log(input, select);
return {
input,
select,
};
},
Listeners() {
const new_listeners = Object.assign({}, this.$listeners, {
after_input: (value) => {
this.$emit("input", [value, this.value[1] ? this.value[1] : ""]);
},
ago_input: (value) => {
this.$emit("input", [this.value[0] ? this.value[0] : "", value]);
},
});
const select = this.getAfterAgo(new_listeners, "after_");
const input = this.getAfterAgo(new_listeners, "ago_");
return {
select,
input,
};
},
},
watch: {
value: {
handler(newVal) {
if (!Array.isArray(newVal)) {
throw new Error("agDatePicker data请传入数组");
}
},
immediate: true,
},
},
methods: {
getAfterAgo(attr, prefix) {
const config = {};
for (const key in attr) {
if (attr.hasOwnProperty(key) && key.startsWith(prefix)) {
const newKey = key.substring(prefix.length);
config[newKey] = attr[key];
}
}
return config;
},
},
};
</script>
<style scoped lang='scss'>
.ag-MultifunctionSearch {
display: flex;
align-items: center;
}
</style>

View File

@ -49,7 +49,7 @@ export default {
//
width: {
type: [Number, String],
default: "50",
default: "60",
},
size: {
type: String,
@ -63,9 +63,6 @@ export default {
//
endValue: "",
};
},
comments: {
},
watch: {
value(newValue) {
@ -115,4 +112,8 @@ export default {
</script>
<style scoped>
.separator {
margin: 0 5px;
color: #c0c4cc;
}
</style>

View File

@ -3,7 +3,7 @@
class="ag_select"
:style="{ width }"
v-bind="attrs"
v-on="inputListeners"
v-on="$listeners"
>
<slot />
<slot name="prefix" slot="prefix" />
@ -39,37 +39,11 @@ export default {
attrs() {
return {
size: "small",
remote: true,
clearable: true,
filterable: true,
...this.$attrs,
};
},
//
inputListeners() {
return Object.assign(
{},
//
this.$listeners,
//
//
{
// `v-model`
input: (value) => {
this.$emit("input", this.toUpperCase ? value.toUpperCase() : value);
},
blur: (e) => {
let value = e.target.value
.trim()
.replace(/\s/g, (match) =>
match.charCodeAt(0) === 12288 ? String.fromCharCode(32) : match
);
//
this.$emit("input", value);
},
}
);
},
},
methods: {},
};
@ -77,24 +51,8 @@ export default {
<style lang="scss" scoped>
::v-deep {
.el-date-editor--daterange.el-input__inner {
width: none;
}
.el-input__suffix {
.el-input__suffix-inner {
.el-input__icon {
font-size: 12px;
width: 14px;
height: 14px;
line-height: 14px;
right: 5px;
&:hover {
border-radius: 50%;
color: #c0c4cc;
background: #ecedee;
}
}
}
font-size: 16px !important;
}
.el-icon-circle-close:before {
content: "\e6db";

View File

@ -2,10 +2,56 @@
<div>
<el-button type="success" @click="abb = true">点击打开 Dialog</el-button>
<ag-dialog :visible.sync="abb"> </ag-dialog>
<ag-datePicker :value="values"> </ag-datePicker>
<ag-input :visible.sync="abb"> </ag-input>
<ag-select :visible.sync="abb" :options="a_options" v-model="value">
<ag-datePicker v-model="value" type="date" @change="change">
</ag-datePicker>
<ag-input value="value"> </ag-input>
<ag-select :options="a_options" v-model="value">
<!-- <template slot="prefix">
{{
(a_options.find((e) => e.value == value) || {}).label
}}
</template> -->
</ag-select>
<ag-NumberRange v-model="values"> </ag-NumberRange>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
class="demo-ruleForm"
>
<el-form-item prop="pass">
<ag-CascadeOptional
size="small"
ref="ttt"
v-model="ruleForm.pass"
:after_clearable="true"
:ago_options="a_options"
>
</ag-CascadeOptional>
</el-form-item>
</el-form>
<ag-MultifunctionSearch
size="small"
ref="ttt"
v-model="values"
:after_clearable="true"
:ago_options="a_options"
>
</ag-MultifunctionSearch>
<!-- <el-input
size="small"
placeholder="请输入内容"
v-model="value"
class="input-with-select"
>
<el-select v-model="a_value" slot="prepend" size="small" placeholder="请选择">
<el-option label="餐厅名" value="1"></el-option>
<el-option label="订单号" value="2"></el-option>
<el-option label="用户电话" value="3"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input> -->
</div>
</template>
@ -14,12 +60,46 @@ import agDialog from "../packages/agDialog/src/index.vue";
import agDatePicker from "../packages/agDatePicker/src/index.vue";
import agInput from "../packages/agInput/src/index.vue";
import agSelect from "../packages/agSelect/src/index.vue";
import agNumberRange from "../packages/agNumberRange/src/index.vue";
import agCascadeOptional from "../packages/agCascadeOptional/src/index.vue";
import agMultifunctionSearch from "../packages/agMultifunctionSearch/src/index.vue";
export default {
components: { agDialog, agDatePicker, agInput, agSelect },
components: {
agDialog,
agDatePicker,
agInput,
agSelect,
agNumberRange,
agCascadeOptional,
agMultifunctionSearch,
},
data() {
var validatePass = (rule, value, callback) => {
for (const key in value) {
if (!value[key]) {
alert("错误");
callback();
}
}
// if (value === "") {
// callback(new Error(""));
// } else {
// if (this.ruleForm.checkPass !== "") {
// this.$refs.ruleForm.validateField("checkPass");
// }
// }
};
return {
value: "",
values: [],
ruleForm: {
pass: [],
},
rules: {
pass: [{ validator: validatePass, trigger: "blur" }],
},
value: "选项1",
a_value: "59584",
values: ["选项1", 999],
options: [
{
label: "热门城市",
@ -146,14 +226,75 @@ export default {
},
{
value: "选项5",
label: "北京烤鸭",
label: "IMEI/机器编号",
},
],
select: "",
input: "",
queryTerm: [
{
label: "IMEI/机器编号",
type: "ag-MultifunctionSearch",
value: "imei",
input: "",
placeholder: "请输入imei",
size: "small ",
clearable: true,
show: true,
change: () => {},
options: [],
},
{
label: "质检码",
type: "ag-MultifunctionSearch",
value: "business_id",
placeholder: "请输入imei",
size: "small ",
clearable: true,
show: true,
options: [],
},
{
lable: "入库时间",
type: "el-date-picker",
enName: "time",
TimeType: "daterange",
clearable: true,
startplaceholder: "开始日期",
endplaceholder: "结束日期",
rangeseparator: "至",
format: "timestamp",
placeholder: "请选择日期",
filterable: true,
display: false,
show: true,
size: "small",
focus: () => {},
blur: () => {},
handleChange: () => {},
},
],
};
},
watch: {
values: {
handler(val) {
console.log(val, 238);
},
deep: true,
immediate: true,
},
},
methods: {
handleClick() {
console.log(1111);
change() {
console.log(this.values, "48484");
},
submit() {
this.$refs.ttt.values;
},
changes(val) {
console.log(val);
console.log(999);
},
handleSizeChange() {},
handleCurrentChange() {},