同学你好,通过你提供的代码分析,主要的问题在于
一般情况下,组件的显示隐藏,不需要将 用于显示状态的变量 传入组件内部,
即你代码的这个位置
可以改为下图
组件的显示与隐藏,由使用者决定
----------------
同理,在这个功能中,要删除元素的下标,也不需要传入组件,而是在点击的时候自行用变量记录即可,组件内部只决定,是“确定”还是取消
即改为下图所示
-----------
经过上面的操作后,组件内部,将不需要通过状态再来重置 某些变量的初始值,
即:组件内部下图框选部分全部删除
即:最终组件内部代码如下
修改完成后
最后只需处理,“调用者 ”接受 组件 提交的 “del”事件
上方的函数的 index 去除,因为内部不在提交 index,而是 “调用者”自行保存的 “indexOfTodo”
即:最终确认删除的 数组成员下标 就是 “indexOfTodo.value”
最终修改后,“调用者”控制组件部分的代码如下
--------------------------
最后,在一般情况下,数组成员的删除,不应是给该数组成员 标记某个属性,如你这里的
而是真实从该数组内删除
所以可以通过 JS 原生的 Array.prototype.splice 函数 进行删除
splice 函数 使用方法如下
两个参数,
参数1:要删除的数组成员 起始下标,(假设为 S),
参数2:要删除的长度(假设为 C)
即语义化理解为,从数组的 第 S 个成员开始,删除 C个成员。
所以,修改后的代码如下图所示:
从 indexOfTodo.value 的下标开始,删除 1个,即删除指定下标的成员
-----------------------------------------------------
经过上方的修改后,即可将下方用于 标记“已删除”状态的部分去除
-------------------------------------------------------------------------------
最终修改后,
todoList.vue 完整代码
<script setup>
import {ref} from "vue";
const color = ref("#000000");
const day = ref();
const todo = ref();
const list = ref([
{
color: "#55b74c",
day: "今天",
todo: "要上班",
complete: true,
del: false,
},
{
color: "#3a48fa",
day: "明天",
todo: "要上班",
complete: false,
del: false,
},
{
color: "#9b3ec0",
day: "后天",
todo: "还是要上班",
complete: false,
del: false,
},
]);
const addTodo = function () {
list.value.push({
color: color.value,
day: day.value,
todo: todo.value,
complete: false,
del: false,
});
color.value = "#000000";
day.value = "";
todo.value = "";
};
const completeTodo = function (index) {
console.log("completeTodo");
list.value[index].complete = true;
};
import ConFrame from "@/components/ConFrame.vue";
import MyInput from "@/components/input.vue";
import MyDelete from "@/components/delete.vue";
const ConFrameShow = ref(false);
const ConFrameCallback = function (msg) {
ConFrameShow.value = false;
console.log(msg);
};
const ConFrameToShow = function () {
ConFrameShow.value = true;
};
const MydeleteShow = ref(false);
const indexOfTodo = ref();
const deleteTodo = function (index) {
indexOfTodo.value = index;
MydeleteShow.value = true;
};
const deleteTodoConfirm = function () {
MydeleteShow.value = false;
list.value.splice(indexOfTodo.value, 1)
};
const deleteTodoCancel = function () {
MydeleteShow.value = false;
};
</script>
<template>
<div class="container">
<h1>代办事项 {{ day }}</h1>
<button @click="ConFrameToShow">添加代办事项</button>
<div class="option"></div>
<ul class="list">
<!--Vue3中v-if权限比v-for高-->
<template v-for="(item, index) in list">
<li
:style="item.complete === true ? 'text-decoration: line-through;' : ''"
@click="completeTodo(index)"
>
<div class="color" :style="'background-color:' + item.color"></div>
<span>{{ item.day }}</span>
<span>{{ item.todo }}</span>
<div class="del" @click.stop="deleteTodo(index)">*</div>
</li>
</template>
</ul>
</div>
<ConFrame
:isShow="ConFrameShow"
title="新增代办事项"
@close="ConFrameCallback"
>
<MyInput class="color" label="颜色" type="color" v-model="color"/>
<MyInput class="day" label="哪天" placeholder="请输入哪天" v-model="day"/>
<MyInput
class="todo"
label="要做什么"
placeholder="请输入要做什么"
v-model="todo"
/>
<button class="addTodo" @click="addTodo">添加事项</button>
</ConFrame>
<MyDelete
v-if="MydeleteShow"
@del="deleteTodoConfirm"
@cancel="deleteTodoCancel"
/>
</template>
<style scoped>
.container {
box-sizing: border-box;
width: 100%;
padding: 10px;
}
.list {
li {
display: flex;
margin: 20px;
cursor: pointer;
&:hover {
background-color: antiquewhite;
}
.color {
width: 20px;
height: 20px;
margin-right: 20px;
}
.del {
margin-left: auto;
}
}
}
.option {
display: flex;
.color {
width: 30px;
height: 30px;
}
.day,
.todo,
.addTodo {
padding: 5px 10px;
}
}
.option input:focus {
outline: none;
}
.option .addTodo {
cursor: pointer;
}
</style>
delete.vue (删除组件)完整代码
<script setup>
import {defineProps, defineEmits, ref, watch} from "vue";
const count = ref(10);
const updateCount = function () {
count.value--;
if (count.value === 0) {
clearInterval(timer);
cancel();
}
};
let timer = setInterval(updateCount, 1000);
const emits = defineEmits(["del", "cancel"]);
const del = function () {
emits("del");
};
const cancel = function () {
emits("cancel");
};
</script>
<template>
<div class="masking"></div>
<div class="popover">
<div class="popover-con">
<div class="popover-info">
<div class="content">
<p>警告({{ count }}秒后自动取消)</p>
<p>是否要删除当前选项?</p>
</div>
<div class="operateBar">
<button @click="cancel">取消</button>
<button @click="del">确认</button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.masking {
width: 100%;
height: 100vh;
position: fixed;
left: 0;
top: 0;
z-index: 100;
background-color: rgba(0, 0, 0, 0.3);
}
.popover {
left: 0;
top: 0;
width: 100%;
height: 100vh;
z-index: 999;
position: fixed;
display: table;
.popover-con {
position: relative;
z-index: 9999;
display: table-cell;
vertical-align: middle;
text-align: center;
.popover-info {
border-radius: 5px;
text-align: left;
display: inline-block;
width: 300px;
height: 100px;
background: #fff;
.operateBar {
padding: 0 10px;
height: 38px;
line-height: 38px;
border-bottom: 1px solid #ebeef5;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
background-color: #379aff;
button {
color: #ffffff;
width: 150px;
height: 30px;
background-color: #379aff;
border: none;
}
}
}
.content {
width: 100%;
margin: 10px 20px;
p {
font-size: 14px;
}
}
}
}
</style>