feat[create]: 完成单选置底多选排它

- choice 新增 handleChange 函数,处理多选排它项
- option-action 新增 isPreview 传参,处理 置底和排它的顺序功能
This commit is contained in:
Huangzhe
2025-03-23 16:46:25 +08:00
parent 5ae09ce20e
commit 35f33e7f22
3 changed files with 75 additions and 8 deletions

View File

@@ -1,8 +1,9 @@
<template> <template>
<div class="option-action"> <div class="option-action">
<draggable <draggable
:is-preview="isPreview"
:data="element" :data="element"
item-key="option_index" item-key="optison_index"
:handle="handle" :handle="handle"
chosenClass="chosen" chosenClass="chosen"
animation="300" animation="300"
@@ -41,6 +42,7 @@
class="option-action-sheet-switch" class="option-action-sheet-switch"
size="0.5rem" size="0.5rem"
:active-value="1" :active-value="1"
@change="handleLastOption"
:inactive-value="0" :inactive-value="0"
></van-switch> ></van-switch>
</template> </template>
@@ -84,6 +86,10 @@ import CheckboxAction from './components/OptionItemAction/CheckboxAction.vue';
import { ref } from 'vue'; import { ref } from 'vue';
import { showConfirmDialog } from 'vant'; import { showConfirmDialog } from 'vant';
import Draggable from '@/views/Design/components/Draggable.vue'; import Draggable from '@/views/Design/components/Draggable.vue';
// 是否是预览模式
const isPreview = defineModel('isPreview', { default: false, type: Boolean });
defineProps({ defineProps({
active: { active: {
type: Boolean, type: Boolean,
@@ -100,11 +106,11 @@ defineProps({
default: '' default: ''
} }
}); });
const element = defineModel('data', { const element = defineModel('data', {
type: Array, type: Array,
default: () => [] default: () => []
}); });
const actions = [ const actions = [
{ name: '上移选项', action: 'up' }, { name: '上移选项', action: 'up' },
{ name: '下移选项', action: 'down' } { name: '下移选项', action: 'down' }
@@ -119,6 +125,21 @@ const updateData = (newValue) => {
element.value = newValue; element.value = newValue;
}; };
/**
* 将当前激活的选项置底
*/
function handleLastOption(value) {
// 检查是否有有效的选项被激活
if (value === 0) return;
if (!activeIndex.value >= 0) return;
// 寻找当前激活的选项
const activeOption = element.value[activeIndex.value];
activeOption.is_fixed = value;
// // 触发数据更新
// updateData([...element.value]);
}
// emit('update:data'); // emit('update:data');
/** /**
* @name 打开model弹窗 * @name 打开model弹窗
@@ -159,7 +180,6 @@ const optionMove = (action) => {
}; };
// 删除当前选项 // 删除当前选项
const deleteOption = (index) => { const deleteOption = (index) => {
showConfirmDialog({ showConfirmDialog({
title: '提示', title: '提示',

View File

@@ -1,7 +1,7 @@
<template> <template>
<div ref="draggable" class="draggable"> <div ref="draggable" class="draggable">
<div <div
v-for="(element, index) in data" v-for="(element, index) in sortedData"
:key="element.id || element.pageId" :key="element.id || element.pageId"
:data_id="element[itemKey] || index" :data_id="element[itemKey] || index"
:data_index="index" :data_index="index"
@@ -14,7 +14,7 @@
<script setup> <script setup>
import Sortable from 'sortablejs'; import Sortable from 'sortablejs';
import { onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
const props = defineProps({ const props = defineProps({
itemKey: { itemKey: {
@@ -52,12 +52,36 @@ const props = defineProps({
} }
} }
}); });
// 是否是预览状态,非预览状态不进行排序
let isPreview = defineModel('isPreview', { default: false, type: Boolean });
const data = defineModel('data', { const data = defineModel('data', {
type: Array, type: Array,
default: () => [] default: () => []
}); });
// 排序之后的数组
const sortedData = computed(() => {
// 如果不是预览状态,不进行排序
if (!isPreview.value) return data.value;
// 置底选项数组
const lastOptions = data.value.filter((item) => {
return item.is_fixed === 1;
});
// 排他选项数组
const remoteOtherOptions = data.value.filter((item) => {
return item.is_remove_other === 1;
});
// 剩余的 options
const otherOptions = data.value.filter((item) => {
return !item.is_fixed && !item.is_remove_other;
});
console.log([...otherOptions, ...lastOptions, ...remoteOtherOptions]);
// 顺序 剩余选项 + 置底选项 + 排他选项
return [...otherOptions, ...lastOptions, ...remoteOtherOptions];
});
const emit = defineEmits(['update:data', 'end']); const emit = defineEmits(['update:data', 'end']);
const sortable = ref(null); const sortable = ref(null);
@@ -97,5 +121,3 @@ onMounted(() => {
sortable.value = Sortable.create(draggable.value, options); sortable.value = Sortable.create(draggable.value, options);
}); });
</script> </script>
<style lang="scss" scoped></style>

View File

@@ -23,6 +23,7 @@
<option-action <option-action
:data="isPreview ? item.options : item" :data="isPreview ? item.options : item"
:active="active" :active="active"
:is-preview="isPreview"
:question="element" :question="element"
handle=".moverQues" handle=".moverQues"
> >
@@ -60,11 +61,17 @@
</option-action> </option-action>
</van-radio-group> </van-radio-group>
<van-checkbox-group v-if="element.question_type === 2" v-model="value" shape="square"> <van-checkbox-group
v-if="element.question_type === 2"
v-model="value"
shape="square"
@change="handleChange"
>
<option-action <option-action
:data="isPreview ? item.options : item" :data="isPreview ? item.options : item"
handle=".moverQues" handle=".moverQues"
:active="active" :active="active"
:is-preview="isPreview"
:question="element" :question="element"
> >
<template #item="{ element: it, index: itIndex }"> <template #item="{ element: it, index: itIndex }">
@@ -140,6 +147,24 @@ const element = defineModel('element', {
}; };
} }
}); });
/**
* 控制选项,如果新增排它项, 那么就直接重新取值
* 按理说是不是 watch 更加合理
* @param names {number[]} 选中的项
*/
function handleChange(names) {
const newOption = names[names.length - 1];
// 如果names 长度小于1直接返回不处理
if (names.length < 1) return;
const options = element.value.options[0] ?? element.value.list[0];
// 如果新增的结果是排它项, 对结果进行处理
if (options[newOption - 1].is_remove_other === 1) {
value.value = [newOption];
}
}
const emit = defineEmits(['update:element']); const emit = defineEmits(['update:element']);
const emitValue = () => { const emitValue = () => {
emit('update:element', element.value); emit('update:element', element.value);