代码拉取完成,页面将自动刷新
同步操作将从 awjf/Vue课件 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/main.css" />
<script src="./js/vue.js"></script>
</head>
<body>
<div id="root">
<div>
<header class="header">
<h1>待办清单</h1>
<input
v-model="newTask"
@keyup.enter="send"
type="text"
class="new-todo"
placeholder="type something here"
/>
</header>
<section class="main">
<input type="checkbox" class="toggle-all" />
<ul class="todo-list">
<!--该li有三种状态
class=""的时候为未完成状态
class="completed"的时候为已完成状态
class="editing"的时候为编辑任务状态
-->
<my-li
@my-save="fatherSave"
@my-edit="fatherEdit"
@my-del="fatherDel"
v-for="(ele,i) in filterArr"
:key="ele.id"
:item="ele"
></my-li>
</ul>
</section>
<my-footer
@my-clear="fatherClear"
:left-num="leftNum"
@my-change="fatherChange"
:state="state"
></my-footer>
</div>
</div>
</body>
<script>
//全局注册一个 组件
Vue.component("my-li", {
template: `<li :class="{'completed':item.isComplete,'editing':item.isEdit}">
<div class="view">
<input type="checkbox" class="toggle" v-model="item.isComplete" />
<label ref="label" @dblclick="childEdit($event)">{{item.task}}</label>
<button @click="childdel" class="destroy"></button>
</div>
<input @blur="childSave" type="text" class="edit" v-model="item.task" />
</li>`,
props: ["item"],
methods: {
childdel() {
console.log(this.item);
this.$emit("my-del", this.item.id);
},
childEdit(ev) {
//子组件双击编辑
console.log(ev.target.parentElement.nextElementSibling); //通过原生方法获取当前的编辑输入框
let editInput = ev.target.parentElement.nextElementSibling;
setTimeout(() => {
editInput.focus(); //获取焦点,要在元素显示之后执行
}, 100);
//进入编辑状态 -- isEdit控制
this.$emit("my-edit", this.item.id);
},
childSave() {
//取消编辑状态
this.$emit("my-save", this.item.id);
},
},
});
Vue.component("my-footer", {
template: `<footer class="footer">
<span class="todo-count">
<strong> {{leftNum}} </strong>
<span>item left</span>
</span>
<ul class="filters">
<li @click="childChange('all')">
<a :class="{'selected':state=='all'}">All</a>
</li>
<li @click="childChange('active')">
<a :class="{'selected':state=='active'}">Active</a>
</li>
<li @click="childChange('completed')">
<a :class="{'selected':state=='completed'}">Completed</a>
</li>
</ul>
<button class="clear-completed" @click="childClear">
clear all completed
</button>
</footer>`,
props: ["leftNum", "state"],
methods: {
childChange(str) {
//触发父组件函数,修改任务展示的状态
this.$emit("my-change", str);
},
childClear() {
//子组件触发父组件的 清空所有已完成
this.$emit("my-clear");
},
},
});
new Vue({
el: "#root",
data: {
state: "all", //记录当前展示任务的类型 all--全部 active--进行中 completed--已完成
newTask: "", //记录新的发布的任务内容
list: [
{
//记录全部的任务信息
id: 1001,
task: "吃饭",
isComplete: false,
isEdit: false,
},
{
id: 1002,
task: "学习",
isComplete: true,
isEdit: false,
},
],
},
computed: {
leftNum() {
//找到所有isComplete字段为false的数量
//filter -- 过滤数据包,并且将过滤的结果返回出来
let arr = this.list.filter((ele) => !ele.isComplete);
return arr.length;
},
filterArr() {
let arr = [];
switch (this.state) {
case "all":
arr = this.list;
break;
case "active":
arr = this.list.filter((ele) => !ele.isComplete);
break;
case "completed":
arr = this.list.filter((ele) => ele.isComplete);
break;
}
return arr;
},
},
methods: {
send() {
//发布新任务
if (this.newTask.trim().length == 0) {
return false;
}
let obj = {
id: new Date().getTime(),
task: this.newTask,
isComplete: false,
isEdit: false,
};
this.list.unshift(obj);
this.newTask = "";
},
fatherDel(idx) {
//真正的删除一条任务
for (let n in this.list) {
if (this.list[n].id == idx) {
this.list.splice(n, 1);
}
}
},
fatherEdit(idx) {
//真正的编辑一条任务
console.log(idx);
for (let n in this.list) {
this.list[n].isEdit = false; //保证永远只有一个进入编辑状态
if (this.list[n].id == idx) {
this.list[n].isEdit = true;
}
}
},
fatherSave() {
//真正的保存
for (let n in this.list) {
this.list[n].isEdit = false;
}
},
fatherChange(s) {
//切换展示状态
console.log(s);
this.state = s;
},
fatherClear() {
//清空已完成
let cmf = confirm("删除不能恢复!!!");
if (cmf) {
//逐条删除,建议使用 id作为判断条件,防止删除后下标产生位移,删除错误!!!
//使用filter直接过滤需要保留的内容
this.list = this.list.filter((ele) => !ele.isComplete);
}
},
},
});
</script>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。