搜索
约 700 字大约 2 分钟
2025-2-5
搜索变量
`search`变量为搜索的表单对象
<template>
{{ search }}
<tvue-crud :option="option"
v-model:search="search"
:data="data">
</tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const search = ref({ name: 'small' });
const data = ref([{ name: '张三' }]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
search: true
}
]
});
</script>搜索按钮文字和图标配置
`searchBtnText`和`emptyBtnText`为搜索和清空的文字`searchBtnIcon`和`emptyBtnIcon`为搜索和清空的图标
<template>
<tvue-crud :option="option"
:data="data" />
</template>
<script setup>
import { ref } from 'vue';
const data = ref([{ name: '张三' }]);
const option = ref({
searchBtnText: '查询',
searchBtnIcon: 'el-icon-user',
emptyBtnText: '重置',
emptyBtnIcon: 'el-icon-close',
column: [
{
label: '姓名',
prop: 'name',
search: true,
}
]
});
</script>搜索方法
`search-change`为点击搜索后执行方法,`done`方法为关闭等待框,`search-reset`点击清空的执行方法
<template>
<tvue-crud :option="option"
:data="data"
@search-change="searchChange"
@search-reset="resetChange">
</tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const data = ref([{ name: '张三' }]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
search: true,
}
]
});
function resetChange (item) {
ElMessage.success('清空回调');
}
function searchChange (params, done) {
ElMessage.success('2s后关闭锁定');
setTimeout(() => {
done();
ElMessage.success(JSON.stringify(params));
}, 2000);
}
</script>搜索字段标题宽度
`searchLabelWidth`为标题的宽度,默认为`110`,可以配置到`option`下作用于全部,也可以单独配置每一项
<template>
<tvue-crud :data="data"
:option="option"></tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ name: '张三', sex: '男' },
{ name: '李四', sex: '女' }
]);
const option = ref({
searchLabelWidth: 150,
column: [
{
label: '姓名',
prop: 'name',
searchLabelWidth: 30,
search: true
},
{
label: '性别',
prop: 'sex',
search: true
}
]
});
</script>搜索字段排序
`searchOrder`为排序字段,不写默认为`0`搜索字段排序不影响表格顺序
<template>
<tvue-crud :data="data"
:option="option"></tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ name: '张三', sex: '男' },
{ name: '李四', sex: '女' }
]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
search: true
},
{
label: '性别',
prop: 'sex',
search: true,
searchOrder: 1
}
]
});
</script>搜索过滤
{ "cascader": [ 0, 1 ], "tree": 0 }
<template>
<el-button type="danger"
@click="filterDic">过滤数据字典</el-button>
<el-button type="success"
@click="filterNull">过滤空数据</el-button>
<el-button type="primary"
@click="filter">不过滤</el-button>
<p>{{ search }}</p>
<tvue-crud :key="reload"
:data="data"
v-model:search="search"
:option="option"></tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
// 初始化响应式数据
const search = ref({
cascader: [0, 1],
tree: 0
});
const reload = ref(Math.random());
const data = ref([
{
cascader: [0, 1],
tree: 0
}
]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
search: true
},
{
label: '级别',
prop: 'cascader',
type: 'cascader',
search: true,
dicData: [
{
label: '一级',
value: 0,
children: [
{
label: '一级1',
value: 1
},
{
label: '一级2',
value: 2
}
]
}
]
},
{
label: '树型',
prop: 'tree',
type: 'tree',
search: true,
dicData: [
{
label: '一级',
value: 0,
children: [
{
label: '一级1',
value: 1
},
{
label: '一级2',
value: 2
}
]
}
]
}
]
});
// 方法定义
const refresh = () => {
reload.value = Math.random();
};
const filter = () => {
option.value.searchFilterDic = false;
option.value.searchFilterNull = false;
refresh();
};
const filterDic = () => {
option.value.searchFilterDic = true;
refresh();
};
const filterNull = () => {
option.value.searchFilterNull = true;
refresh();
};
</script>搜索验证规则
提示
具体参考async-validator
配置验证字段的`searchRules`的数据对象即可
<template>
<tvue-crud :option="option"
:data="data">
</tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([{ name: '张三' }]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
search: true,
searchRules: [
{
required: true,
message: "请输入姓名",
trigger: "blur"
}
]
},
{
label: '日期',
prop: 'date',
type: 'datetime'
}
]
});
</script>搜索范围和宽度
`searchSpan`搜索框的宽度,`searchRange`配置后可以开启范围搜索
<template>
<tvue-crud :option="option"
:data="data" />
</template>
<script setup>
import { ref } from 'vue';
const data = ref([{ name: '张三', date: '' }]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
search: true,
},
{
label: '日期',
prop: 'date',
type: 'datetime',
search: true,
searchSpan: 18,
searchRange: true,
}
]
});
</script>搜索默认值
`searchValue`为搜索的默认值
<template>
<tvue-crud :option="option"
:data="data"></tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ name: '张三' }
]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
searchValue: 'small',
search: true
}
]
});
</script>局部展开收缩
`searchIcon`是否启用功能按钮, `searchIndex`配置收缩展示的个数,默认为`2`个
<template>
<tvue-crud :option="option"
:data="data"></tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ text1: '文本1', text2: '文本2' }
]);
const option = ref({
searchIndex: 3,
searchIcon: true,
column: [
{
label: '内容1',
prop: 'text1',
search: true
},
{
label: '内容2',
prop: 'text2',
search: true
},
{
label: '内容3',
prop: 'text3',
search: true
},
{
label: '内容4',
prop: 'text4',
search: true
}
]
});
</script>辅助提示语
`searchTip`为提示的内容,`searchTipPlacement`为提示语的方向,默认为`bottom`
<template>
<tvue-crud :option="option"
:data="data" />
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ text1: '文本1', text2: '文本2' }
]);
const option = ref({
column: [
{
label: '内容1',
prop: 'text1',
search: true,
searchTip: '我是一个默认提示语',
},
{
label: '内容2',
prop: 'text2',
search: true,
searchTip: '我是一个左边提示语',
searchTipPlacement: 'left',
}
]
});
</script>隐藏搜索折叠按钮
`searchShowBtn`设置为:`false`
<template>
<tvue-crud :option="option"
:data="data" />
</template>
<script setup>
import { ref } from 'vue';
const data = ref([{ name: '张三' }]);
const option = ref({
searchShowBtn: false,
column: [
{
label: '姓名',
prop: 'name',
search: true,
},
{
label: '日期',
prop: 'date',
type: 'datetime',
search: true,
}
]
});
</script>按钮是否单独成行
前提的`searchMenuSpan`可以控制搜索按钮的长度
<template>
<tvue-crud :option="option"
:data="data"></tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([
{ text1: '文本1', text2: '文本2' }
]);
const option = ref({
searchMenuSpan: 8,
column: [
{
label: '内容1',
prop: 'text1',
search: true
},
{
label: '内容2',
prop: 'text2',
search: true
}
]
});
</script>定义类型
`searchType`属性可以重新定义搜索框的类型
<template>
<tvue-crud :option="option"
:data="data" />
</template>
<script setup>
import { ref } from 'vue';
const dic = [
{ label: '选项1', value: 1 },
{ label: '选项2', value: 2 }
];
const data = ref([{
selects: [1, 2],
select: 1
}]);
const option = ref({
column: [
{
label: '多选框',
prop: 'selects',
type: 'select',
multiple: true,
search: true,
searchType: 'checkbox',
searchSpan: 24,
dicData: dic
},
{
label: '单选框',
prop: 'select',
type: 'select',
search: true,
searchType: 'radio',
searchSpan: 24,
dicData: dic
}
]
});
</script>自定义搜索卡槽
`search`和`searchMenu`卡槽可以自定义搜索内容,不需要单独设置列`search`:`true`
<template>
<tvue-crud :option="option"
v-model:search="search"
:data="data">
<template #search-menu="{ row, size }">
<el-button :size="size"
@click="searchSubmit(row)">自定义提交</el-button>
</template>
<template #search="{ size }">
<el-tag>标题</el-tag>
<el-input placeholder="自定义输入框"
:size="size"
style="width: 200px"
v-model:value="search.slot"></el-input>
</template>
</tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const search = ref({});
const data = ref([{ name: '张三' }]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name'
},
{
label: '日期',
prop: 'date',
type: 'datetime'
}
]
});
function searchSubmit (row) {
console.log(row)
}
</script>自定义列搜索
列的`prop`加`-search`作为卡槽的名称即可开启自定义
<template>
<tvue-crud :option="option"
:data="data"
v-model:search="search">
<template #age-search="{ disabled, size }">
<el-slider :disabled="disabled"
:size="size"
v-model:value="search.age" />
</template>
</tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
const search = ref({});
const data = ref([{ name: '张三', age: 18 }]);
const option = ref({
column: [
{
label: '姓名',
prop: 'name',
search: true,
},
{
label: '年龄',
prop: 'age',
search: true
}
]
});
</script>多级联动
`cascader`为需要联动的子选择框`prop`值,可以写多个,形成一对多的关系,需要手动调用内部的`dicInit`方法去初始化表格联动数据
<template>
<tvue-crud ref="crud"
:option="option"
:data="data"></tvue-crud>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue';
const baseUrl = 'https://cli.avuejs.com/api/area';
const data = ref([]);
const option = ref({
excelBtn: true,
column: [
{
label: '省份',
prop: 'province',
type: 'select',
props: { label: 'name', value: 'code' },
cascader: ['city'],
search: true,
dicUrl: `${baseUrl}/getProvince`,
rules: [
{ required: true, message: '请选择省份', trigger: 'blur' }
]
},
{
label: '城市',
prop: 'city',
type: 'select',
cascader: ['area'],
props: { label: 'name', value: 'code' },
search: true,
dicUrl: `${baseUrl}/getCity/{{key}}`,
rules: [
{ required: true, message: '请选择城市', trigger: 'blur' }
]
},
{
label: '地区',
prop: 'area',
type: 'select',
props: { label: 'name', value: 'code' },
search: true,
dicUrl: `${baseUrl}/getArea/{{key}}`,
rules: [
{ required: true, message: '请选择地区', trigger: 'blur' }
]
}
]
});
const crud = ref(null);
onMounted(() => {
data.value = [
{ id: 1, name: '张三', province: '110000', city: '110100', area: '110101' },
{ id: 2, name: '李四', province: '140000', city: '140600', area: '140623' }
]
//加载完数据后调用
nextTick(() => {
crud.value.dicInit('cascader');
});
});
</script>单独日期搜索
配置`dateBtn`为`true`即可激活,搜索后回调`date-change`方法
<template>
<tvue-crud ref="crud"
@date-change="dateChange"
:option="option"
:data="data"></tvue-crud>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const data = ref([
{ text1: '内容1-1', text2: '内容1-2' },
{ text1: '内容2-1', text2: '内容2-2' },
{ text1: '内容3-1', text2: '内容3-2' }
]);
const option = ref({
dateBtn: true,
column: [
{ label: '列内容1', prop: 'text1' },
{ label: '列内容2', prop: 'text2' }
]
});
const dateChange = (date) => {
ElMessage.success(JSON.stringify(date));
};
</script>