feat[create]: 完成单选置底多选排它
- choice 新增 handleChange 函数,处理多选排它项 - option-action 新增 isPreview 传参,处理 置底和排它的顺序功能
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="option-action">
|
||||
<draggable
|
||||
:is-preview="isPreview"
|
||||
:data="element"
|
||||
item-key="option_index"
|
||||
item-key="optison_index"
|
||||
:handle="handle"
|
||||
chosenClass="chosen"
|
||||
animation="300"
|
||||
@@ -41,6 +42,7 @@
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
@change="handleLastOption"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
@@ -84,6 +86,10 @@ import CheckboxAction from './components/OptionItemAction/CheckboxAction.vue';
|
||||
import { ref } from 'vue';
|
||||
import { showConfirmDialog } from 'vant';
|
||||
import Draggable from '@/views/Design/components/Draggable.vue';
|
||||
|
||||
// 是否是预览模式
|
||||
const isPreview = defineModel('isPreview', { default: false, type: Boolean });
|
||||
|
||||
defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
@@ -100,11 +106,11 @@ defineProps({
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
const element = defineModel('data', {
|
||||
type: Array,
|
||||
default: () => []
|
||||
});
|
||||
|
||||
const actions = [
|
||||
{ name: '上移选项', action: 'up' },
|
||||
{ name: '下移选项', action: 'down' }
|
||||
@@ -119,6 +125,21 @@ const updateData = (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');
|
||||
/**
|
||||
* @name 打开model弹窗
|
||||
@@ -159,7 +180,6 @@ const optionMove = (action) => {
|
||||
};
|
||||
|
||||
// 删除当前选项
|
||||
|
||||
const deleteOption = (index) => {
|
||||
showConfirmDialog({
|
||||
title: '提示',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div ref="draggable" class="draggable">
|
||||
<div
|
||||
v-for="(element, index) in data"
|
||||
v-for="(element, index) in sortedData"
|
||||
:key="element.id || element.pageId"
|
||||
:data_id="element[itemKey] || index"
|
||||
:data_index="index"
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<script setup>
|
||||
import Sortable from 'sortablejs';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
itemKey: {
|
||||
@@ -52,12 +52,36 @@ const props = defineProps({
|
||||
}
|
||||
}
|
||||
});
|
||||
// 是否是预览状态,非预览状态不进行排序
|
||||
let isPreview = defineModel('isPreview', { default: false, type: Boolean });
|
||||
|
||||
const data = defineModel('data', {
|
||||
type: Array,
|
||||
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 sortable = ref(null);
|
||||
@@ -97,5 +121,3 @@ onMounted(() => {
|
||||
sortable.value = Sortable.create(draggable.value, options);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<option-action
|
||||
:data="isPreview ? item.options : item"
|
||||
:active="active"
|
||||
:is-preview="isPreview"
|
||||
:question="element"
|
||||
handle=".moverQues"
|
||||
>
|
||||
@@ -60,11 +61,17 @@
|
||||
</option-action>
|
||||
</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
|
||||
:data="isPreview ? item.options : item"
|
||||
handle=".moverQues"
|
||||
:active="active"
|
||||
:is-preview="isPreview"
|
||||
:question="element"
|
||||
>
|
||||
<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 emitValue = () => {
|
||||
emit('update:element', element.value);
|
||||
|
||||
Reference in New Issue
Block a user