使用 useModel 绑定

This commit is contained in:
icssoa 2024-01-30 01:37:35 +08:00
parent b7114ca82b
commit 8381fe5e0b
14 changed files with 140 additions and 140 deletions

View File

@ -6,6 +6,10 @@
<cl-row> <cl-row>
<cl-add-btn /> <cl-add-btn />
<cl-adv-btn /> <cl-adv-btn />
<cl-flex1 />
<cl-search-key v-model="v1" @change="onChange" refreshOnInput></cl-search-key>
</cl-row> </cl-row>
<cl-row> <cl-row>
@ -20,10 +24,6 @@
<cl-upsert ref="Upsert"></cl-upsert> <cl-upsert ref="Upsert"></cl-upsert>
<cl-adv-search ref="AdvSearch"></cl-adv-search> <cl-adv-search ref="AdvSearch"></cl-adv-search>
</cl-crud> </cl-crud>
<cl-dialog v-model="visible" height="20vh">
<div style="height: 50px" v-for="d in 100" :key="d">{{ d }}</div>
</cl-dialog>
</div> </div>
</template> </template>
@ -38,7 +38,11 @@ interface Data {
[key: string]: any; [key: string]: any;
} }
const visible = ref(true); const v1 = ref();
function onChange() {
console.log(1111);
}
const Upsert = useUpsert<Data>({ const Upsert = useUpsert<Data>({
items: [ items: [
@ -152,15 +156,6 @@ const Crud = useCrud(
); );
const Form = useForm<Data>(); const Form = useForm<Data>();
Form.value?.open({
items: [
{
type: "tabs",
prop: "age"
}
]
});
</script> </script>
<style scoped> <style scoped>

View File

@ -1,6 +1,7 @@
import { defineComponent, ref, watch, computed, PropType } from "vue"; import { defineComponent, ref, computed, type PropType, useModel } from "vue";
import { useConfig, useCore } from "../../hooks"; import { useConfig, useCore } from "../../hooks";
import { parsePx } from "../../utils"; import { parsePx } from "../../utils";
import { debounce } from "lodash-es";
export default defineComponent({ export default defineComponent({
name: "cl-search-key", name: "cl-search-key",
@ -26,7 +27,9 @@ export default defineComponent({
width: { width: {
type: [String, Number], type: [String, Number],
default: 300 default: 300
} },
// 是否实时刷新
refreshOnInput: Boolean
}, },
emits: ["update:modelValue", "change", "field-change"], emits: ["update:modelValue", "change", "field-change"],
@ -57,17 +60,7 @@ export default defineComponent({
}); });
// 搜索内容 // 搜索内容
const value = ref(""); const value = useModel(props, "modelValue");
watch(
() => props.modelValue,
(val) => {
value.value = val || "";
},
{
immediate: true
}
);
// 锁 // 锁
let lock = false; let lock = false;
@ -109,27 +102,33 @@ export default defineComponent({
} }
} }
// 监听输入
function onInput(val: string) {
emit("update:modelValue", val);
emit("change", val);
}
// 监听变化 // 监听变化
function onChange() { function onChange(val: string) {
search(); if (!props.refreshOnInput) {
lock = true; search();
lock = true;
setTimeout(() => { setTimeout(() => {
lock = false; lock = false;
}, 300); }, 300);
emit("change", val);
}
} }
// 监听输入
const onInput = debounce((val: string) => {
emit("change", val);
if (props.refreshOnInput) {
search();
}
}, 300);
// 监听字段选择 // 监听字段选择
function onFieldChange() { function onFieldChange() {
emit("field-change", selectField.value); emit("field-change", selectField.value);
onInput(""); value.value = undefined;
value.value = "";
} }
expose({ expose({
@ -157,8 +156,8 @@ export default defineComponent({
size={style.size} size={style.size}
placeholder={placeholder.value} placeholder={placeholder.value}
onKeydown={onKeydown} onKeydown={onKeydown}
onInput={onInput}
onChange={onChange} onChange={onChange}
onInput={onInput}
clearable clearable
/> />

View File

@ -21,7 +21,7 @@
<script lang="ts" name="cl-dept-select" setup> <script lang="ts" name="cl-dept-select" setup>
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { onMounted, ref, watch } from "vue"; import { onMounted, ref, useModel } from "vue";
import { useCool } from "/@/cool"; import { useCool } from "/@/cool";
import { deepTree } from "/@/cool/utils"; import { deepTree } from "/@/cool/utils";
@ -38,7 +38,7 @@ const emit = defineEmits(["update:modelValue", "change"]);
const { service } = useCool(); const { service } = useCool();
const value = ref(); const value = useModel(props, "modelValue");
const list = ref(); const list = ref();
@ -69,16 +69,6 @@ function refresh() {
}); });
} }
watch(
() => props.modelValue,
(val) => {
value.value = val;
},
{
immediate: true
}
);
onMounted(() => { onMounted(() => {
refresh(); refresh();
}); });

View File

@ -1,5 +1,5 @@
<template> <template>
<el-select filterable v-model="name" fit-input-width @change="onChange"> <el-select filterable v-model="value" fit-input-width>
<div class="cl-menu-icon"> <div class="cl-menu-icon">
<el-option :value="item" v-for="item in list" :key="item"> <el-option :value="item" v-for="item in list" :key="item">
<cl-svg :name="item" /> <cl-svg :name="item" />
@ -9,7 +9,7 @@
</template> </template>
<script lang="ts" name="cl-menu-icon" setup> <script lang="ts" name="cl-menu-icon" setup>
import { ref, watch } from "vue"; import { ref, useModel } from "vue";
import { basename } from "/@/cool/utils"; import { basename } from "/@/cool/utils";
// svg // svg
@ -42,22 +42,7 @@ function iconList() {
const list = ref(iconList()); const list = ref(iconList());
// //
const name = ref<string>(); const value = useModel(props, "modelValue");
//
function onChange(val: string) {
emit("update:modelValue", val);
}
watch(
() => props.modelValue,
(val) => {
name.value = val;
},
{
immediate: true
}
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -15,15 +15,14 @@
filterable filterable
:size="size" :size="size"
:placeholder="placeholder" :placeholder="placeholder"
@change="onChange" />
></el-tree-select>
</div> </div>
</template> </template>
<script lang="ts" name="cl-menu-select" setup> <script lang="ts" name="cl-menu-select" setup>
import { useForm } from "@cool-vue/crud"; import { useForm, useUpsert } from "@cool-vue/crud";
import { cloneDeep } from "lodash-es"; import { cloneDeep } from "lodash-es";
import { computed, onMounted, ref, watch } from "vue"; import { computed, ref, useModel } from "vue";
import { useCool } from "/@/cool"; import { useCool } from "/@/cool";
import { deepTree } from "/@/cool/utils"; import { deepTree } from "/@/cool/utils";
@ -43,42 +42,36 @@ const { service } = useCool();
const Form = useForm(); const Form = useForm();
// //
const value = ref(); const value = useModel(props, "modelValue", {
get(val) {
return val ? Number(val) : val;
}
});
// //
const list = ref<any[]>([]); const list = ref<any[]>([]);
// //
const tree = computed(() => { const tree = computed(() => {
return deepTree( return deepTree(cloneDeep(list.value)).filter((e) => !e.parentId);
cloneDeep(list.value).filter((e) => (props.type === 0 ? e.type == 0 : props.type > e.type))
);
}); });
// //
function refresh() { async function refresh() {
service.base.sys.menu.list().then((res) => { return service.base.sys.menu.list().then((res) => {
list.value = res.filter((e) => e.id != Form.value?.form.id); //
list.value = res.filter(
(e) =>
e.id != Form.value?.form.id &&
(props.type === 0 ? e.type == 0 : props.type > e.type!)
);
}); });
} }
// useUpsert({
function onChange(id: number) { onOpened() {
emit("update:modelValue", id); refresh();
}
watch(
() => props.modelValue,
(val) => {
value.value = val ? Number(val) : val;
},
{
immediate: true
} }
);
onMounted(function () {
refresh();
}); });
</script> </script>

View File

@ -30,9 +30,12 @@
<!-- 字典 --> <!-- 字典 -->
<cl-filter label="工作(字典)"> <cl-filter label="工作(字典)">
<cl-select <cl-select
tree
:options="dict.get('occupation')" :options="dict.get('occupation')"
prop="occupation" prop="occupation"
:width="120" :width="140"
check-strictly
@change="onChange"
/> />
</cl-filter> </cl-filter>
@ -124,6 +127,8 @@ import { reactive, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { useCool } from "/@/cool"; import { useCool } from "/@/cool";
const v = ref();
// //
const { service, refs, setRefs } = useCool(); const { service, refs, setRefs } = useCool();
@ -575,4 +580,8 @@ const visible = ref(false);
function open() { function open() {
visible.value = true; visible.value = true;
} }
function onChange(val: any) {
console.log(val);
}
</script> </script>

View File

@ -12,7 +12,8 @@
'form/component/index.vue', 'form/component/index.vue',
'form/component/select-labels.vue', 'form/component/select-labels.vue',
'form/component/select-status.vue', 'form/component/select-status.vue',
'form/component/select-work.vue' 'form/component/select-work.vue',
'form/component/select-work2.vue'
]" ]"
/> />
@ -35,7 +36,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useForm } from "@cool-vue/crud"; import { useForm } from "@cool-vue/crud";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import SelectWork from "./select-work.vue"; import SelectWork from "./select-work2.vue";
import SelectLabels from "./select-labels.vue"; import SelectLabels from "./select-labels.vue";
import SelectStatus from "./select-status.vue"; import SelectStatus from "./select-status.vue";
@ -48,8 +49,9 @@ function open() {
items: [ items: [
{ {
label: "昵称", label: "昵称",
prop: "nickname", prop: "name",
// 1便 // 1便
value: "神仙",
component: { component: {
// element-plus el-inputel-date-picker // element-plus el-inputel-date-picker
name: "el-input" name: "el-input"
@ -59,6 +61,7 @@ function open() {
label: "年龄", label: "年龄",
prop: "age", prop: "age",
// 2 // 2
value: 18,
component: { component: {
// "slot-" // "slot-"
name: "slot-age" name: "slot-age"
@ -68,6 +71,7 @@ function open() {
{ {
label: "工作", label: "工作",
prop: "work", prop: "work",
value: "设计",
component: { component: {
// //
vm: SelectWork vm: SelectWork
@ -76,7 +80,7 @@ function open() {
{ {
label: "标签", label: "标签",
prop: "labels", prop: "labels",
value: [], value: ["多金", "深情"],
component: { component: {
// scope[prop] // scope[prop]
vm: SelectLabels vm: SelectLabels

View File

@ -23,16 +23,16 @@ const props = defineProps({
// //
const list = ref<{ label: string; value: string }[]>([ const list = ref<{ label: string; value: string }[]>([
{ {
label: "倒茶", label: "帅气",
value: "倒茶" // 使label1234id value: "帅气" // 使label1234id
}, },
{ {
label: "设计", label: "多金",
value: "设计" value: "多金"
}, },
{ {
label: "开发", label: "深情",
value: "开发" value: "深情"
} }
]); ]);
</script> </script>

View File

@ -14,7 +14,7 @@
import { ref, watch } from "vue"; import { ref, watch } from "vue";
const props = defineProps({ const props = defineProps({
modelValue: Number modelValue: String
}); });
const emit = defineEmits(["update:modelValue", "change"]); const emit = defineEmits(["update:modelValue", "change"]);

View File

@ -0,0 +1,38 @@
<template>
<el-select v-model="active">
<el-option
v-for="(item, index) in list"
:key="index"
:label="item.label"
:value="item.label"
/>
</el-select>
</template>
<!-- 很重要必须要有name避免注册后和其他冲突 -->
<script setup lang="ts" name="select-work2">
import { ref, useModel } from "vue";
const props = defineProps({
modelValue: String
});
//使 useModel
const active = useModel(props, "modelValue");
//
const list = ref<{ label: string; value: string }[]>([
{
label: "倒茶",
value: "倒茶" // 使label1234id
},
{
label: "设计",
value: "设计"
},
{
label: "开发",
value: "开发"
}
]);
</script>

View File

@ -24,7 +24,7 @@
</template> </template>
<script lang="ts" setup name="demo-crud"> <script lang="ts" setup name="demo-crud">
import { ref, onActivated } from "vue"; import { ref, onActivated, getCurrentScope, toValue } from "vue";
import CrudBase from "./components/crud/base.vue"; import CrudBase from "./components/crud/base.vue";
import CrudAll from "./components/crud/all.vue"; import CrudAll from "./components/crud/all.vue";

View File

@ -50,6 +50,10 @@ const list = [ContextMenu, ClForm, Crud, Upload, Editor, Svg, Copy, File, Design
height: 50px; height: 50px;
box-sizing: border-box; box-sizing: border-box;
a {
font-size: 12px;
}
&._svg { &._svg {
.cl-svg { .cl-svg {
margin-right: 15px; margin-right: 15px;

View File

@ -22,10 +22,10 @@
<script lang="ts" setup name="cl-date-picker"> <script lang="ts" setup name="cl-date-picker">
import { useCrud } from "@cool-vue/crud"; import { useCrud } from "@cool-vue/crud";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { type PropType, computed, ref, watch } from "vue"; import { type PropType, computed, ref, useModel } from "vue";
const props = defineProps({ const props = defineProps({
modelValue: Array, modelValue: null,
// //
type: { type: {
type: String as PropType< type: String as PropType<
@ -72,7 +72,7 @@ const defaultTime = ref<any>(
); );
// //
const date = ref(); const date = useModel(props, "modelValue");
// //
const quickType = ref(props.defaultQuickType); const quickType = ref(props.defaultQuickType);
@ -157,16 +157,6 @@ function init() {
onQuickTypeChange(); onQuickTypeChange();
} }
watch(
() => props.modelValue,
(val) => {
date.value = val;
},
{
immediate: true
}
);
defineExpose({ defineExpose({
init init
}); });

View File

@ -1,8 +1,8 @@
import { useCrud } from "@cool-vue/crud"; import { useCrud } from "@cool-vue/crud";
import { isEmpty, isString } from "lodash-es"; import { isEmpty, isString } from "lodash-es";
import { computed, defineComponent, isRef, type PropType, type Ref, ref, watch } from "vue"; import { computed, defineComponent, type PropType, type Ref, toValue, useModel } from "vue";
import { parsePx } from "/@/cool/utils"; import { parsePx } from "/@/cool/utils";
import { Dict } from "/$/dict/types"; import type { Dict } from "/$/dict/types";
export default defineComponent({ export default defineComponent({
name: "cl-select", name: "cl-select",
@ -27,7 +27,9 @@ export default defineComponent({
// 是否树形 // 是否树形
tree: Boolean, tree: Boolean,
// 是否返回选中层级下的所有值 // 是否返回选中层级下的所有值
allLevelsId: Boolean allLevelsId: Boolean,
// 是否父子不互相关联
checkStrictly: Boolean
}, },
emits: ["update:modelValue", "change"], emits: ["update:modelValue", "change"],
@ -37,11 +39,11 @@ export default defineComponent({
const Crud = useCrud(); const Crud = useCrud();
// 选中值 // 选中值
const value = ref(); const value = useModel(props, "modelValue");
// 列表 // 列表
const list = computed(() => { const list = computed(() => {
return (isRef(props.options) ? props.options.value : props.options) || []; return toValue(props.options) || [];
}); });
// 获取值 // 获取值
@ -84,16 +86,6 @@ export default defineComponent({
} }
} }
watch(
() => props.modelValue,
(val) => {
value.value = val;
},
{
immediate: true
}
);
return () => { return () => {
// 样式 // 样式
const style = { const style = {
@ -111,6 +103,7 @@ export default defineComponent({
filterable filterable
placeholder={placeholder} placeholder={placeholder}
data={list.value} data={list.value}
checkStrictly={props.allLevelsId || props.checkStrictly}
props={{ props={{
label: props.labelKey, label: props.labelKey,
value: props.valueKey value: props.valueKey