Merge pull request 'liunan' (#9) from liunan into master

Reviewed-on: #9
This commit is contained in:
liunan 2024-08-23 17:21:13 +08:00
commit 297e10d70c
15 changed files with 6431 additions and 7990 deletions

7855
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
:value="value[1]"
v-bind="config.input"
v-on="Listeners.input"
>
<ag-select
slot="prepend"
@ -16,12 +17,11 @@
v-on="Listeners.select"
class="ag_select_group"
>
<template slot="prefix">
{{
(config.select.options.find((e) => e.value == value[0]) || {}).label
}}
</template>
</ag-select>
<template slot="suffix">
<el-button>提交</el-button>
</template>
</ag-input>
</div>
</template>
@ -70,10 +70,10 @@ export default {
Listeners() {
const new_listeners = Object.assign({}, this.$listeners, {
after_input: (value) => {
this.$emit("input", [value, this.value[1] ? this.value[1] : ""]);
this.$emit("change", [value, this.value[1] ? this.value[1] : ""]);
},
ago_input: (value) => {
this.$emit("input", [this.value[0] ? this.value[0] : "", value]);
this.$emit("change", [this.value[0] ? this.value[0] : "", value]);
},
});
const select = this.getAfterAgo(new_listeners, "after_");
@ -138,8 +138,8 @@ export default {
}
::v-deep .ag_select_group {
min-width: 90px;
max-width: 140px;
min-width: 45px;
max-width: 165px;
color: #606266;
text-align: start;
.el-input__prefix {

9
packages/agCol/index.js Normal file
View File

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

View File

@ -0,0 +1,33 @@
<template>
<div class="agColbox" :style="{flex:`0 0 ${Number(span)/24*100}%`,marginLeft:`${Number(offset)/24*100}%`}">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'AgCol',
props: {
span:{
type:Number|String,
default:24
},
offset:{
type:Number|String,
default:0
}
},
data() {
return {};
},
}
</script>
<style lang="scss" scoped>
.agColbox{
flex:0 0 100%;
padding-left: 10px;
padding-right: 10px;
box-sizing: border-box;
}
</style>

View File

@ -6,6 +6,7 @@
v-model="dateArr"
v-bind="attrs"
v-on="Listeners"
:type="datetype"
@mouseenter.native="mousetrue = true"
@mouseleave.native="mousetrue = false"
/>
@ -20,22 +21,43 @@ import isEmpty from "../../../src/utils/isEmpty";
export default {
name: "agDatePicker",
props: {
range:false,
showTime:false,
type: {
type: String,
default: "date",
},
value: {
default: "",
default: null||[],
},
},
data() {
return {
width: "160px",
dateArr: "",
dateArr: null||[],
date_picker: false,
mousetrue: true,
mousetrue: false,
};
},
computed: {
datetype(){
if(this.range){
if(this.showTime){
return "datetimerange"
}else{
return "daterange";
}
}else{
if(this.showTime){
return "datetime";
}else{
return "date";
}
}
},
attrs() {
let config = {};
if (this.$attrs.type === "daterange" || !this.$attrs.type) {
if (this.range) {
config = {
"start-placeholder": "开始日期",
"end-placeholder": "结束日期",
@ -115,45 +137,29 @@ export default {
},
shortcuts: [
{
text: "近一周",
text: "今天",
onClick(picker) {
const date = new Date();
date.setTime(date.getTime());
picker.$emit("pick", date);
},
},
{
text: "昨天",
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 1* 24 * 60 * 60 * 1000);
picker.$emit("pick", date);
},
},
{
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);
},
},
},
],
},
};
@ -161,8 +167,8 @@ export default {
return {
size: "small",
type: "daterange",
format: "yyyy-MM-dd",
"value-format": "yyyy-MM-dd",
format: this.showTime?"yyyy-MM-dd hh:mm:ss":"yyyy-MM-dd",
"value-format":this.showTime?"yyyy-MM-dd hh:mm:ss": "yyyy-MM-dd",
...config,
...this.$attrs,
};
@ -171,34 +177,33 @@ export default {
Listeners() {
return Object.assign({}, this.$listeners, {
input: (value) => {
if (this.attrs.type === "daterange") {
if (this.range) {
if (!isEmpty(value) && value.length === 2 && value[0] && value[1]) {
this.$emit("input", [
this.$emit("change", [
`${value[0]} 00:00:00`,
`${value[1]} 23:59:59`,
]);
} else {
this.$emit("input", []);
this.$emit("change", []);
}
} else {
this.$emit("input", value);
this.$emit("change", value);
}
},
});
},
iconClass() {
return this.date_picker && this.mousetrue
return this.mousetrue
? "ag-icon-prefix-hide"
: "ag-icon-prefix-show";
},
},
watch: {
watch: {
value: {
handler(newVal) {
if (this.attrs.type === "daterange") {
if (!Array.isArray(newVal)) {
throw new Error("agDatePicker date请传入数组");
}
if (Array.isArray(newVal)&&this.range){
const [date1, date2] = newVal.slice(0, 2);
this.dateArr = [date1 || "", date2 || ""];
} else {
@ -209,22 +214,11 @@ export default {
},
dateArr: {
handler(newVal) {
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 !== "");
this.width =
newVal &&
newVal.length > 0 &&
newVal.some((item) => item != null && item !== "")
? "205px"
: defaultWidth;
} else {
this.width = defaultWidth;
this.date_picker = !!newVal; // 使newVal
if(!newVal){
return
}
let defaultWidth = this.range ?this.showTime?"330px":"170px" : this.showTime?"190px":"140px";
this.width = defaultWidth;
},
immediate: true,
deep: true,
@ -266,7 +260,7 @@ export default {
position: absolute;
left: 98%;
}
.ag-icon-clear {
.ag-icon-clear {
&:before {
content: "\e6db";
}

View File

@ -1,6 +1,7 @@
<template>
<el-input
class="ag_input"
size="small"
:style="{ width }"
v-on="Listeners"
v-bind="attrs"
@ -48,7 +49,7 @@ export default {
{
// `v-model`
input: (value) => {
this.$emit("input", this.toUpperCase ? value.toUpperCase() : value);
this.$emit("change", this.toUpperCase ? value.toUpperCase() : value);
},
blur: (e) => {
let value = e.target.value
@ -58,7 +59,7 @@ export default {
);
//
this.$emit("input", value);
this.$emit("change", value);
},
}
);

View File

@ -6,35 +6,93 @@
placeholder="请选择"
:value="value[0]"
v-bind="config.select"
v-on="Listeners.select"
@change="onSelect"
class="ag_select_group"
>
<template slot="prefix">
{{
(config.select.options.find((e) => e.value == value[0]) || {}).label
}}
</template>
</ag-select>
:style="{ width: `${swidth}px` }"
>
</ag-select>
<ag-input
v-if="!showExtra"
class="ag_input_group"
placeholder="请输入内容"
:value="value[1]"
:disabled="config.input.disabled||imeipopover"
v-bind="config.input"
v-on="Listeners.input"
>
@change="onInputChange"
>
</ag-input>
<el-popover
v-if="showExtra"
placement="bottom"
trigger="manual"
ref="popover"
popper-class="popperOptions"
v-model="imeipopover"
>
<template slot="reference">
<ag-input
class="ag_input_group"
placeholder="请输入内容"
:value="value[1]"
:disabled="config.input.disabled||imeipopover"
v-bind="config.input"
@change="onInputChange"
>
<template slot="suffix" v-if="showExtra">
<i
class="iconfont icon-icon-piliangcaozuo imeiicondefault"
:class="imeipopover && 'imeiiconActive'"
style="font-size: 12px;"
@click.prevent="imeiiconClick"
></i>
</template>
</ag-input>
</template>
<el-input
v-model="value[1]"
type="textarea"
:rows="12"
placeholder="一行一项最多支持200行"
resize="none"
border="none"
class="textareainput"
@input="onInputChange"
/>
<divider class="divider"></divider>
<div class="btnbox">
<div>
<el-button size="mini" @click="imeiclose"
>关闭</el-button
>
</div>
<div>
<el-button size="mini" @click="cleartext"
>清空</el-button
>
<el-button
size="mini"
type="primary"
plain
@click="search"
>查询</el-button
>
</div>
</div>
</el-popover>
</div>
</template>
<script>
import agSelect from "../../agSelect/src/index.vue";
import agInput from "../../agInput/src/index.vue";
import {Divider} from "element-ui";
export default {
name: "agMultifunctionSearch",
components: {
agSelect,
agInput,
Divider
},
props: {
value: {
@ -43,58 +101,96 @@ export default {
return [null, null];
},
},
options: {
type: Array,
default: () => {
return [];
},
},
showExtra: {
type: Boolean,
default: false,
},
},
data() {
return {
values: [null, null],
swidth:90,
selectvalue:"",
imeipopover:false
};
},
computed: {
config() {
const input_config = this.getAfterAgo(this.$attrs, "after_");
config() {
const input = {
...this.$attrs,
...input_config,
};
const select_configs = this.getAfterAgo(this.$attrs, "ago_");
...this.$attrs
};
const select = {
...this.$attrs,
...select_configs,
};
console.log(input, select);
options:this.options
};
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) {
handler(newVal) {
if (!Array.isArray(newVal)) {
throw new Error("agDatePicker data请传入数组");
throw new Error("请传入数组");
}
let newselectValue=newVal[0];
const find=this.options.find((f)=>f.value==newselectValue);
if(find){
let fontwidth=this.getStringWidth(find?.label);
this.swidth=fontwidth>165?165:fontwidth;
}
},
immediate: true,
},
},
methods: {
onSelect(value){
this.$emit("change", [value, this.value[1]||""]);
},
onInputChange(value){
this.$emit("change", [ this.value[0] ||"",value]);
},
getStringWidth(text) {
let font = "13px";
//
let element = document.createElement('span');
element.style.visibility = 'hidden';
element.style.whiteSpace = 'nowrap';
element.style.font = font; //
element.textContent = text;
//
document.body.appendChild(element);
//
let width = element.offsetWidth;
//
document.body.removeChild(element);
return width+50;
},
imeiiconClick(){
this.imeipopover=!this.imeipopover;
},
imeiclose(){
this.imeipopover=false;
},
cleartext(){
this.value[1]="";
this.$set(this.value,1,"");
},
search(){
this.imeipopover=false;
this.$emit("onSrarch", this.value);
},
getAfterAgo(attr, prefix) {
const config = {};
for (const key in attr) {
@ -108,10 +204,49 @@ export default {
},
};
</script>
<style lang="scss">
.popperOptions {
min-width: 200px !important;
padding: 0px !important;
}
</style>
<style scoped lang='scss'>
.ag-MultifunctionSearch {
display: flex;
align-items: center;
}
align-items: center;
}
.imeiicondefault {
padding: 5px;
border-radius: 4px;
background: #f0f2f5;
cursor: pointer;
}
.imeiiconActive {
cursor: pointer;
color: #409eff;
background: #e9f1fc;
}
.divider {
margin: 0;
}
.btnbox {
padding: 5px;
display: flex;
justify-content: space-between;
}
::v-deep{
.el-textarea__inner{
border:none;
}
.el-input__suffix-inner{
height:100%;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

View File

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

View File

@ -0,0 +1,132 @@
<template>
<div class="ag-querybox">
<el-popover
placement="bottom"
:width="width"
v-model="popState"
trigger="click">
<ag-input slot="reference" size="small" class="queryplacetext" :style="{width:labelWidth}" :clearable="false" :value="placeholderValue" :placeholder="placeholder"></ag-input>
<el-form label-position="left" size="small" :model="values" :inline="false" v-if="inputs.length>0" ref="queryformref">
<ag-row>
<ag-col :span="12" v-for="(item,index) in inputs" :key="index">
<el-form-item :label="item.label" :rules="item.rules" :prop="item.name">
<ag-input :placeholder="item.placeholder" :value="item.value||''" closeable v-if="item.elem=='el-input'" @change="onSelect($event,item,index)"/>
<ag-select :placeholder="item.placeholder" :value="item.value||''" closeable v-if="item.elem=='el-select'" :options="item.options" style="width:100%" @change="onSelect($event,item,index)"/>
</el-form-item>
</ag-col>
<ag-col :offset="16" :span="8">
<el-form-item >
<el-button size="small" @click="onCancel">取消</el-button>
<el-button size="small" type="primary" @click="onQuery">查询</el-button>
</el-form-item>
</ag-col>
</ag-row>
</el-form>
</el-popover>
</div>
</template>
<script>
import agSelect from "../../agSelect/src/index.vue";
import agInput from "../../agInput/src/index.vue";
import agRow from "./../../agRow/src/index.vue";
import AgCol from "./../../agCol/src/index.vue";
export default {
name: "agQuery",
components: {
agSelect,
agInput,
AgCol,
agRow
},
props: {
width:{
type: Number,
default: 450,
},
labelWidth:{
type: Number,
default: 200,
},
inputs:{
type: Array,
default: () => {
return [];
},
},
},
mounted(){
let newinput=this.inputs.map((g)=>g.label);
this.placeholder="请选择"+newinput.join("/");
},
data() {
return {
values: {},
placeholderValue:"",
placeholder:"请选择",
popState:false,
}
},
methods: {
onSelect(value,item,index){
item.value=value;
this.$set(this.inputs,index,item);
let newvalues={};
let newplaceholderValue=[];
this.inputs.map((g)=>{
if(g.value&&g.name){
newvalues[g.name]=g.value;
g.options.find((f)=>f.value==g.value).label&&(newplaceholderValue.push(g.options.find((f)=>f.value==g.value).label));
}
});
this.$emit('change',newvalues);
this.values=newvalues;
this.placeholderValue=newplaceholderValue.join("/")
},
onCancel(){
this.popState=false;
this.$emit('cancel');
},
onQuery(){
console.log(this.$refs.queryformref,'this.$refs.queryformref');
if(this.$refs.queryformref){
this.$refs.queryformref.validate((valid) => {
console.log(valid,"valid");
if (valid) {
this.$emit('onSearch',this.values);
this.popState=false;
} else {
console.log('error submit!!');
return false;
}
});
}
}
},
};
</script>
<style scoped lang='scss'>
.ag-querybox {
display: flex;
align-items: center;
.queryplacetext{
color:#333;
max-width:200px;
box-sizing: border-box;
cursor: pointer;
caret-color: transparent; /* 隐藏光标 */
}
}
::v-deep {
.el-form-item--small .el-form-item__label{
line-height: 40px;
}
.el-form-item--small.el-form-item{
margin-bottom:5px;
}
}
</style>

9
packages/agRow/index.js Normal file
View File

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

View File

@ -0,0 +1,26 @@
<template>
<div class="agRowbox">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'agRow',
data(){
return {
}
},
props:{
},
}
</script>
<style lang="scss" scoped>
.agRowbox{
display: flex;
flex-wrap: wrap;
}
</style>

View File

@ -1,9 +1,11 @@
<template>
<el-select
<div>
<el-select
class="ag_select"
:style="{ width }"
:style="{ width: `100%` }"
:value="selectValue"
v-bind="attrs"
v-on="$listeners"
v-on="$listeners"
>
<slot />
<slot name="prefix" slot="prefix" />
@ -14,7 +16,8 @@
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-select>
</div>
</template>
<script>
@ -22,18 +25,37 @@ export default {
name: "agSelect",
props: {
width: {
type: String,
default: "",
type: Number,
default:0,
},
options: {
type: Array,
default: () => {
return [];
},
},
},
},
value:{
default: () =>'',
}
},
data() {
return {};
return {
selectValue:""
};
},
watch: {
value: {
handler(newVal) {
let newselectValue=newVal;
const find=this.options.find((f)=>f.value==newselectValue);
if(find){
this.selectValue=newselectValue;
}else{
this.selectValue="";
}
},
immediate: true,
},
},
computed: {
attrs() {
@ -45,12 +67,16 @@ export default {
};
},
},
methods: {},
methods: {
},
};
</script>
<style lang="scss" scoped>
::v-deep {
.ag_select{
min-width: 90px;
}
.el-input__icon {
font-size: 16px !important;
}

View File

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<link rel="stylesheet" href="https://at.alicdn.com/t/c/font_4285161_67f087o652k.css"/>
</head>
<body>
<noscript>

View File

@ -2,7 +2,7 @@
<div>
<el-button type="success" @click="abb = true">点击打开 Dialog</el-button>
<ag-dialog :visible.sync="abb"> </ag-dialog>
<ag-datePicker v-model="value" type="date" @change="change">
<ag-datePicker v-model="date_value" :showTime="true" :range="true" @change="onPicker">
</ag-datePicker>
<ag-input value="value"> </ag-input>
<ag-select :options="a_options" v-model="value">
@ -35,10 +35,15 @@
size="small"
ref="ttt"
v-model="values"
:after_clearable="true"
:ago_options="a_options"
:showExtra="true"
:clearable="true"
:options="a_options"
@change="onInputinput"
>
</ag-MultifunctionSearch>
<agQuery :inputs="inputs" @onSearch="onSearch"/>
<!-- <el-input
size="small"
placeholder="请输入内容"
@ -63,6 +68,8 @@ 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";
import agQuery from "../packages/agQuery/src/index.vue";
export default {
components: {
agDialog,
@ -72,6 +79,7 @@ export default {
agNumberRange,
agCascadeOptional,
agMultifunctionSearch,
agQuery
},
data() {
var validatePass = (rule, value, callback) => {
@ -97,9 +105,10 @@ export default {
rules: {
pass: [{ validator: validatePass, trigger: "blur" }],
},
date_value:null,
value: "选项1",
a_value: "59584",
values: ["选项1", 999],
values: ["4",""],
options: [
{
label: "热门城市",
@ -136,6 +145,56 @@ export default {
],
},
],
inputs:[
{
label:"分类",
elem:'el-select',
name:"class",
options:[
{
value: "Chengdu",
label: "成都",
},
{
value: "Shenzhen",
label: "深圳",
},
{
value: "Guangzhou",
label: "广州",
},
{
value: "Dalian",
label: "大连",
},
]
},
{
label:"品牌",
elem:'el-select',
name:"brand",
placeholder:"请输入品牌",
options:[]
},
{
label:"型号",
elem:'el-select',
name:"model",
options: []
},
{
label:"颜色",
elem:'el-select',
name:"color",
options:[]
},
{
label:"容量",
elem:'el-select',
name:"capacity",
options:[]
}
],
pickerOptions: {
shortcuts: [
{
@ -209,23 +268,23 @@ export default {
innerVisible: false,
a_options: [
{
value: "选项1",
value: "1",
label: "黄金糕",
},
{
value: "选项2",
value: "2",
label: "双皮奶",
},
{
value: "选项3",
value: "3",
label: "蚵仔煎",
},
{
value: "选项4",
value: "4",
label: "龙须面",
},
{
value: "选项5",
value: "5",
label: "IMEI/机器编号",
},
],
@ -286,6 +345,16 @@ export default {
},
},
methods: {
onPicker(value){
this.date_value=value;
},
onSearch(values){
console.log(values,"onSearch");
},
onInputinput(value){
console.log(value,"oninput");
this.values=value;
},
change() {
console.log(this.values, "48484");
},

5852
yarn.lock Normal file

File diff suppressed because it is too large Load Diff