feat[create]: 完成单选置底多选排它
- choice 新增 handleChange 函数,处理多选排它项 - option-action 新增 isPreview 传参,处理 置底和排它的顺序功能
This commit is contained in:
@@ -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: '提示',
|
||||||
|
|||||||
@@ -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>
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user