根据已有的文件让vue文件跑起来怎么做?
1.根据已有的 package.json 下依赖包 yarn install / yarn(可以省略 install)
完成
todo案例
完整效果演示
todo案例-创建工程和组件
目标: 新建工程, 准备好所需的一切
- 需求1: 创建新工程
- 需求2: 分组件创建 – 准备标签和样式
分析:
①:初始化todo工程
②:创建3个组件和里面代码
③:把styles的样式文件准备好
④: App.vue引入注册使用, 最外层容器类名todoapp
预先准备: 把styles的样式文件准备好(从预习资料复制), 在App.vue引入使用
// 1.0 样式引入
import "./styles/base.css"
import "./styles/index.css"
根据需求: 我们定义3个组件准备复用
components/TodoHeader.vue - 复制标签和类名
<template>
<header class="header">
<h1>todos</h1>
<input id="toggle-all" class="toggle-all" type="checkbox" >
<label for="toggle-all"></label>
<input
class="new-todo"
placeholder="输入任务名称-回车确认"
autofocus
/>
</header>
</template>
<script>
export default {
}
</script>
components/TodoMain.vue - 复制标签和类名
<template>
<ul class="todo-list">
<!-- completed: 完成的类名 -->
<li class="completed" >
<div class="view">
<input class="toggle" type="checkbox" />
<label>任务名</label>
<button class="destroy"></button>
</div>
</li>
</ul>
</template>
<script>
export default {
}
</script>
components/TodoFooter.vue - 复制标签和类名
<template>
<footer class="footer">
<span class="todo-count">剩余<strong>数量值</strong></span>
<ul class="filters">
<li>
<a class="selected" href="javascript:;" >全部</a>
</li>
<li>
<a href="javascript:;">未完成</a>
</li>
<li>
<a href="javascript:;" >已完成</a>
</li>
</ul>
<button class="clear-completed" >清除已完成</button>
</footer>
</template>
<script>
export default {
}
</script>
App.vue中引入和使用
<template>
<section class="todoapp">
<!-- 除了驼峰, 还可以使用-转换链接 -->
<TodoHeader></TodoHeader>
<TodoMain></TodoMain>
<TodoFooter></TodoFooter>
</section>
</template>
<script>
// 1.0 样式引入
import "./styles/base.css"
import "./styles/index.css"
import TodoHeader from "./components/TodoHeader";
import TodoMain from "./components/TodoMain";
import TodoFooter from "./components/TodoFooter";
export default {
components: {
TodoHeader,
TodoMain,
TodoFooter,
},
};
</script>
todo案例-铺设待办任务
目的: 把待办任务, 展示到页面TodoMain.vue组件上
- 需求1: 把待办任务, 展示到页面TodoMain.vue组件上
- 需求2: 关联选中状态, 设置相关样式
分析:
①: App.vue – 准备数组传入TodoMain.vue内
②: v-for循环展示数据
③: v-model绑定复选框选中状态
④: 根据选中状态, 设置完成划线样式
App.vue
<TodoMain :arr="showArr"></TodoMain>
export default {
data() {
return {
list: [
{ id: 100, name: "吃饭", isDone: true },
{ id: 201, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
};
}
};
TodoMain.vue
<template>
<ul class="todo-list">
<!-- 2.2 循环任务-关联选中状态-铺设数据 -->
<!-- completed: 完成的类名 -->
<li :class="{completed: obj.isDone}" v-for="(obj, index) in arr" :key='obj.id'>
<div class="view">
<input class="toggle" type="checkbox" v-model="obj.isDone"/>
<label>{{ obj.name }}</label>
<!-- 4.0 注册点击事件 -->
<button @click="delFn(index)" class="destroy"></button>
</div>
</li>
</ul>
</template>
<script>
export default {
props: ["list"]
};
</script>
<style>
</style>
todo案例-添加任务
目标: 在顶部输入框输入要完成的任务名, 敲击回车, 完成新增功能
- 需求: 输入任务敲击回车, 新增待办任务
分析:
①: TodoHeader.vue – 输入框 – 键盘事件 – 回车按键
②: 子传父, 把待办任务 – App.vue中 – 加入数组list里
③: 原数组改变, 所有用到的地方都会更新
④: 输入框为空, 提示用户必须输入内容
子组件:TodoHeader.vue
<template>
<header class="header">
<h1>todos</h1>
<input id="toggle-all" class="toggle-all" type="checkbox" />
<label for="toggle-all"></label>
<!-- 3.0 v-model 双向绑定获取输入框的值 -->
<!-- 3.1 @keyup.enter 监听用户按下回车 -->
<input
class="new-todo"
placeholder="输入任务名称-回车确认"
autofocus
v-model.trim="task"
@keyup.enter="downFn"
/>
</header>
</template>
<script>
export default {
data() {
return {
task: "",
};
},
methods: {
downFn() {
if (this.task === "") {
return alert("请输入用户名称");
}
// console.log("用户按下了回车键", this.task);
// 3.2(重要) - 当前任务名字要加到list数组里
this.$emit("create", this.task);
// 为了更好地用户体验,清空输入框
this.task = "";
},
},
};
</script>
父组件:综合案例_Todo.vue
<template>
<!-- 1.3 在根标签添加 todoapp 类名 -->
<div class="todoapp">
<!-- 3.2 注册自定义事件 让子组件触发 -->
<TodoHender @create="createFn"></TodoHender>
<TodoMain :arr="list"></TodoMain>
<TodoFooter></TodoFooter>
</div>
</template>
<script>
// 1.1 使用组件的四个步骤: 新建组件( vue 文件) 2.引入组件 import 3.注册组件 components 4.使用组件
import TodoFooter from "./components/TodoFooter.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoHender from "./components/TodoHender.vue";
// 1.2 样式引入
import "./styles/base.css";
import "./styles/index.css";
export default {
// components:定义组件的结构
components: {
TodoFooter,
TodoMain,
TodoHender,
},
// data:定义数据的结构
data() {
return {
list: [
{ id: 100, name: "吃饭", isDone: true },
{ id: 101, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
};
},
//methods:定义函数/方法的结构
methods: {
createFn(theTesk) {
// 3.3 push 到数组里
this.list.push({
// id 准备
id: this.list.length ? this.list[this.list.length - 1].id + 1 : 10,
// 任务是子组件触发自定义事件的时候传过来的
name: theTesk,
// 新建的任务默认都是未完成
isDone: false,
});
},
},
};
</script>
<style>
</style>
todo案例-删除任务
目标: 实现点x, 删除任务功能
- 需求: 点击任务后的x, 删除当前这条任务
分析:
①: x标签 – 点击事件 – 传入id区分
②: 子传父, 把id传回– App.vue中 – 删除数组list里某个对应的对象
③: 原数组改变, 所有用到的地方都会更新
App.vue - 传入自定义事件等待接收要被删除的序号
父组件:综合案例_Todo.vue
<template>
<!-- 1.3 在根标签添加 todoapp 类名 -->
<div class="todoapp">
<!-- 3.2 注册自定义事件 让子组件触发 -->
<TodoHender @create="createFn"></TodoHender>
<TodoMain @del="deleteFn" :arr="list"></TodoMain>
<TodoFooter></TodoFooter>
</div>
</template>
<script>
// 1.1 使用组件的四个步骤: 新建组件( vue 文件) 2.引入组件 import 3.注册组件 components 4.使用组件
import TodoFooter from "./components/TodoFooter.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoHender from "./components/TodoHender.vue";
// 1.2 样式引入
import "./styles/base.css";
import "./styles/index.css";
export default {
// components:定义组件的结构
components: {
TodoFooter,
TodoMain,
TodoHender,
},
// data:定义数据的结构
data() {
return {
list: [
{ id: 100, name: "吃饭", isDone: true },
{ id: 101, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
};
},
//methods:定义函数/方法的结构
methods: {
// 创建任务
createFn(theTesk) {
// 3.3 push 到数组里
this.list.push({
// id 准备
id: this.list.length ? this.list[this.list.length - 1].id + 1 : 10,
// 任务是子组件触发自定义事件的时候传过来的
name: theTesk,
// 新建的任务默认都是未完成
isDone: false,
});
},
// 删除任务
deleteFn(theId) {
// 注意:filter 不改变原数组,需要重新赋值
this.list = this.list.filter((item) => item.id !== theId);
},
},
};
</script>
<style>
</style>
子组件:TodoMain.vue
<template>
<ul class="todo-list">
<!-- completed: 完成的类名 -->
<li v-for="item in arr" :key="item.id" :class="{ completed: item.isDone }">
<div class="view">
<input v-model="item.isDone" class="toggle" type="checkbox" />
<label>{{ item.name }}</label>
<button class="destroy" @click="destroyBtn(item.id)"></button>
</div>
</li>
</ul>
</template>
<script>
export default {
// 接收父组件的数据
props: ["arr"],
methods: {
destroyBtn(id) {
// console.log("点击了删除按钮", id);
this.$emit("del", id);
},
},
};
</script>
todo案例-底部统计
目的: 显示现在任务的总数
- 需求: 统计当前任务的条数
分析:
①: App.vue中 – 数组list – 传给TodoFooter.vue
②: 直接在标签上显示 / 定义计算属性用于显示都可以
③: 原数组只要改变, 所有用到此数组的地方都会更新
TodoFooter.vue - 接收list统计直接显示
子组件:TodoFooter.vue
<template>
<footer class="footer">
<span class="todo-count"
>剩余<strong>{{ count }}</strong></span
>
<ul class="filters">
<li>
<a class="selected" href="javascript:;">全部</a>
</li>
<li>
<a href="javascript:;">未完成</a>
</li>
<li>
<a href="javascript:;">已完成</a>
</li>
</ul>
<button class="clear-completed">清除已完成</button>
</footer>
</template>
<script>
export default {
props: ["farr"],
// 通过 computed 计算结构
computed: {
count() {
return this.farr.length;
},
},
};
</script>
父组件:综合案例_Todo.vue
<template>
<!-- 1.3 在根标签添加 todoapp 类名 -->
<div class="todoapp">
<!-- 3.2 注册自定义事件 让子组件触发 -->
<TodoHender @create="createFn"></TodoHender>
<TodoMain @del="deleteFn" :arr="list"></TodoMain>
<TodoFooter :farr="list"></TodoFooter>
</div>
</template>
<script>
// 1.1 使用组件的四个步骤: 新建组件( vue 文件) 2.引入组件 import 3.注册组件 components 4.使用组件
import TodoFooter from "./components/TodoFooter.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoHender from "./components/TodoHender.vue";
// 1.2 样式引入
import "./styles/base.css";
import "./styles/index.css";
export default {
// components:定义组件的结构
components: {
TodoFooter,
TodoMain,
TodoHender,
},
// data:定义数据的结构
data() {
return {
list: [
{ id: 100, name: "吃饭", isDone: true },
{ id: 101, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
};
},
//methods:定义函数/方法的结构
methods: {
// 创建任务
createFn(theTesk) {
// 3.3 push 到数组里
this.list.push({
// id 准备
id: this.list.length ? this.list[this.list.length - 1].id + 1 : 10,
// 任务是子组件触发自定义事件的时候传过来的
name: theTesk,
// 新建的任务默认都是未完成
isDone: false,
});
},
// 删除任务
deleteFn(theId) {
// 注意:filter 不改变原数组,需要重新赋值
this.list = this.list.filter((item) => item.id !== theId);
},
},
};
</script>
<style>
</style>
todo案例-数据切换
目的: 点击底部切换数据
- 需求1: 点击底部切换 – 点谁谁有边框
- 需求2: 对应切换不同数据显示
分析:
①: TodoFooter.vue – 定义isSel – 值为all, yes, no其中一种
②: 多个class分别判断谁应该有类名selected
③: 点击修改isSel的值
④: 子传父, 把类型isSel传到 综合案例_Todo.vue
⑤: 定义计算属性showArr, 决定从list里显示哪些数据给TodoMain.vue和TodoFooter.vue
父组件:综合案例_Todo.vue
<template>
<!-- 1.3 在根标签添加 todoapp 类名 -->
<div class="todoapp">
<!-- 3.2 注册自定义事件 让子组件触发 -->
<TodoHender @create="createFn"></TodoHender>
<TodoMain @del="deleteFn" :arr="showArr"></TodoMain>
<TodoFooter @changeType="typeFn" :farr="showArr"></TodoFooter>
</div>
</template>
<script>
// 1.1 使用组件的四个步骤: 新建组件( vue 文件) 2.引入组件 import 3.注册组件 components 4.使用组件
import TodoFooter from "./components/TodoFooter.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoHender from "./components/TodoHender.vue";
// 1.2 样式引入
import "./styles/base.css";
import "./styles/index.css";
export default {
// components:定义组件的结构
components: {
TodoFooter,
TodoMain,
TodoHender,
},
// data:定义数据的结构
data() {
return {
list: [
{ id: 100, name: "吃饭", isDone: true },
{ id: 101, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
getSel:'all',
};
},
//methods:定义函数/方法的结构
methods: {
// 创建任务
createFn(theTesk) {
// 3.3 push 到数组里
this.list.push({
// id 准备
id: this.list.length ? this.list[this.list.length - 1].id + 1 : 10,
// 任务是子组件触发自定义事件的时候传过来的
name: theTesk,
// 新建的任务默认都是未完成
isDone: false,
});
},
// 删除任务
deleteFn(theId) {
// 注意:filter 不改变原数组,需要重新赋值
this.list = this.list.filter((item) => item.id !== theId);
},
// 切换任务
typeFn(theSel){
this.getSel = theSel
}
},
// computed 写计算属性的结构(算出来新的变量)
computed: {
showArr(){
if( this.getSel === 'yes'){
return this.list.filter(item => item.isDone === true)
}else if(this.getSel === 'no'){
return this.list.filter(item => item.isDone === false)
}else{
return this.list
}
}
}
};
</script>
<style>
</style>
子组件:TodoFooter.vue
<template>
<footer class="footer">
<span class="todo-count"
>剩余<strong>{{ count }}</strong></span
>
<ul class="filters">
<li>
<a :class="{selected : isSel === 'all'}" href="javascript:;" @click="changeSel('all')" >全部</a>
</li>
<li>
<a :class="{selected : isSel === 'no'}" href="javascript:;" @click="changeSel('no')" >未完成</a>
</li>
<li>
<a :class="{selected : isSel === 'yes'}" href="javascript:;" @click="changeSel('yes')">已完成</a>
</li>
</ul>
<button class="clear-completed">清除已完成</button>
</footer>
</template>
<script>
export default {
props: ["farr"],
data () {
return {
// all 全部, no 未完成, yes 已完成
isSel:"all"
}
},
methods: {
changeSel(sel){
// 点击时按钮添加边框
this.isSel = sel
// 触发父子间上的自定义事件,把 选中的类型 传到父组件中
this.$emit('changeType', sel)
}
},
// 通过 computed 计算结构
computed: {
count() {
return this.farr.length;
},
},
};
</script>
todo案例-清空已完成
目的: 点击右下角按钮- 把已经完成的任务清空了
- 需求: 点击右下角链接标签, 清除已完成任务
分析:
①: 清空标签 – 点击事件
②: 子传父 – App.vue – 一个清空方法
③: 过滤未完成的覆盖list数组 (不考虑恢复)
综合案例_Todo.vue - 先传入一个自定义事件-因为得接收TodoFooter.vue里的点击事件
父组件:综合案例_Todo.vue
<template>
<!-- 1.3 在根标签添加 todoapp 类名 -->
<div class="todoapp">
<!-- 3.2 注册自定义事件 让子组件触发 -->
<TodoHender @create="createFn"></TodoHender>
<!-- 换成计算出来的 showArr 数组 -->
<TodoMain @del="deleteFn" :arr="showArr"></TodoMain>
<TodoFooter @changeType="typeFn" @clear="clearFn" :farr="showArr"></TodoFooter>
</div>
</template>
<script>
// 1.1 使用组件的四个步骤: 新建组件( vue 文件) 2.引入组件 import 3.注册组件 components 4.使用组件
import TodoFooter from "./components/TodoFooter.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoHender from "./components/TodoHender.vue";
// 1.2 样式引入
import "./styles/base.css";
import "./styles/index.css";
export default {
// components:定义组件的结构
components: {
TodoFooter,
TodoMain,
TodoHender,
},
// data:定义数据的结构
data() {
return {
list: [
{ id: 100, name: "吃饭", isDone: true },
{ id: 101, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
getSel:'all',
};
},
//methods:定义函数/方法的结构
methods: {
// 创建任务
createFn(theTesk) {
// 3.3 push 到数组里
this.list.push({
// id 准备
id: this.list.length ? this.list[this.list.length - 1].id + 1 : 10,
// 任务是子组件触发自定义事件的时候传过来的
name: theTesk,
// 新建的任务默认都是未完成
isDone: false,
});
},
// 删除任务
deleteFn(theId) {
// 注意:filter 不改变原数组,需要重新赋值
this.list = this.list.filter((item) => item.id !== theId);
},
// 切换任务
typeFn(theSel){
this.getSel = theSel
},
// 清除已完成
clearFn(){
// 真是修改了 list
this.list = this.list.filter(item => item.isDone !== true)
}
},
// computed 写计算属性的结构(算出来新的变量)
computed: {
showArr(){
if( this.getSel === 'yes'){
return this.list.filter(item => item.isDone === true)
}else if(this.getSel === 'no'){
return this.list.filter(item => item.isDone === false)
}else{
return this.list
}
}
}
};
</script>
<style>
</style>
子组件:TodoFooter.vue
<template>
<footer class="footer">
<span class="todo-count"
>剩余<strong>{{ count }}</strong></span
>
<ul class="filters">
<li>
<a :class="{selected : isSel === 'all'}" href="javascript:;" @click="changeSel('all')" >全部</a>
</li>
<li>
<a :class="{selected : isSel === 'no'}" href="javascript:;" @click="changeSel('no')" >未完成</a>
</li>
<li>
<a :class="{selected : isSel === 'yes'}" href="javascript:;" @click="changeSel('yes')">已完成</a>
</li>
</ul>
<button class="clear-completed" @click="clearBtn">清除已完成</button>
</footer>
</template>
<script>
export default {
props: ["farr"],
data () {
return {
// all 全部, no 未完成, yes 已完成
isSel:"all"
}
},
methods: {
changeSel(sel){
// 点击时按钮添加边框
this.isSel = sel
// 触发父子间上的自定义事件,把 选中的类型 传到父组件中
this.$emit('changeType', sel)
},
clearBtn(){
this.$emit('clear')
}
},
// 通过 computed 计算结构
computed: {
count() {
return this.farr.length;
},
},
};
</script>
todo案例-数据缓存
目的: 新增/修改状态/删除 后, 马上把数据同步到浏览器本地存储
- 需求: 无论如何变化 – 都保证刷新后数据还在
分析:
①:~Todo.vue – 侦听list数组改变 – 深度
②: 覆盖式存入到本地 – 注意本地只能存入JSON字符串
③: 刷新页面 – list应该默认从本地取值 – 要考虑
父组件:Todo.vue
<template>
<!-- 1.3 在根标签添加 todoapp 类名 -->
<div class="todoapp">
<!-- 3.2 注册自定义事件 让子组件触发 -->
<TodoHender @create="createFn"></TodoHender>
<!-- 换成计算出来的 showArr 数组 -->
<TodoMain @del="deleteFn" :arr="showArr"></TodoMain>
<TodoFooter @changeType="typeFn" @clear="clearFn" :farr="showArr"></TodoFooter>
</div>
</template>
<script>
// 1.1 使用组件的四个步骤: 新建组件( vue 文件) 2.引入组件 import 3.注册组件 components 4.使用组件
import TodoFooter from "./components/TodoFooter.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoHender from "./components/TodoHender.vue";
// 1.2 样式引入
import "./styles/base.css";
import "./styles/index.css";
export default {
// components:定义组件的结构
components: {
TodoFooter,
TodoMain,
TodoHender,
},
// data:定义数据的结构
data() {
return {
list:JSON.parse(localStorage.getItem('todoList')) || [
{ id: 100, name: "吃饭", isDone: true },
{ id: 101, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
getSel:'all',
};
},
//methods:定义函数/方法的结构
methods: {
// 创建任务
createFn(theTesk) {
// 3.3 push 到数组里
this.list.push({
// id 准备
id: this.list.length ? this.list[this.list.length - 1].id + 1 : 10,
// 任务是子组件触发自定义事件的时候传过来的
name: theTesk,
// 新建的任务默认都是未完成
isDone: false,
});
},
// 删除任务
deleteFn(theId) {
// 注意:filter 不改变原数组,需要重新赋值
this.list = this.list.filter((item) => item.id !== theId);
},
// 切换任务
typeFn(theSel){
this.getSel = theSel
},
// 清除已完成
clearFn(){
// 真是修改了 list
this.list = this.list.filter(item => item.isDone !== true)
}
},
// computed 写计算属性的结构(算出来新的变量)
computed: {
showArr(){
if( this.getSel === 'yes'){
return this.list.filter(item => item.isDone === true)
}else if(this.getSel === 'no'){
return this.list.filter(item => item.isDone === false)
}else{
return this.list
}
}
},
watch: {
list:{
deep:true,
handler(){
localStorage.setItem('todoList',JSON.stringify(this.list))
}
}
}
};
</script>
<style>
</style>
todo案例-全选功能
目标: 点击左上角v号, 可以设置一键完成, 再点一次取消全选
- 需求1: 点击全选 – 小选框受到影响
- 需求2: 小选框都选中(手选) – 全选自动选中状态
分析:
①: TodoHeader.vue – 计算属性 - isAll
②: App.vue – 传入数组list – 在isAll的set里影响小选框
③: isAll的get里统计小选框最后状态, 影响isAll – 影响全选状态
④: 考虑无数据情况空数组 – 全选不应该勾选
提示: 就是遍历所有的对象, 修改他们的完成状态属性的值
子组件:TodoHender.vue
<template>
<header class="header">
<h1>todos</h1>
<input id="toggle-all" class="toggle-all" type="checkbox" v-model="isAll" />
<label for="toggle-all"></label>
<!-- 3.0 v-model 双向绑定获取输入框的值 -->
<!-- 3.1 @keyup.enter 监听用户按下回车 -->
<input
class="new-todo"
placeholder="输入任务名称-回车确认"
autofocus
v-model.trim="task"
@keyup.enter="downFn"
/>
</header>
</template>
<script>
export default {
props:['arr'],
data() {
return {
task: "",
};
},
methods: {
downFn() {
if (this.task === "") {
return alert("请输入用户名称");
}
// console.log("用户按下了回车键", this.task);
// 3.2(重要) - 当前任务名字要加到list数组里
this.$emit("create", this.task);
// 为了更好地用户体验,清空输入框
this.task = "";
},
},
computed: {
isAll:{
get(){
return this.arr.every(item => item.isDone === true)
},
set(val){
this.arr.forEach(item => item.isDone = val)
}
}
}
};
</script>
父组件:综合案例_Todo.vue
<template>
<!-- 1.3 在根标签添加 todoapp 类名 -->
<div class="todoapp">
<!-- 3.2 注册自定义事件 让子组件触发 -->
<TodoHender :arr="list" @create="createFn"></TodoHender>
<!-- 换成计算出来的 showArr 数组 -->
<TodoMain @del="deleteFn" :arr="showArr"></TodoMain>
<TodoFooter @changeType="typeFn" @clear="clearFn" :farr="showArr"></TodoFooter>
</div>
</template>
<script>
// 1.1 使用组件的四个步骤: 新建组件( vue 文件) 2.引入组件 import 3.注册组件 components 4.使用组件
import TodoFooter from "./components/TodoFooter.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoHender from "./components/TodoHender.vue";
// 1.2 样式引入
import "./styles/base.css";
import "./styles/index.css";
export default {
// components:定义组件的结构
components: {
TodoFooter,
TodoMain,
TodoHender,
},
// data:定义数据的结构
data() {
return {
list:JSON.parse(localStorage.getItem('todoList')) || [
{ id: 100, name: "吃饭", isDone: true },
{ id: 101, name: "睡觉", isDone: false },
{ id: 103, name: "打豆豆", isDone: true },
],
getSel:'all',
};
},
//methods:定义函数/方法的结构
methods: {
// 创建任务
createFn(theTesk) {
// 3.3 push 到数组里
this.list.push({
// id 准备
id: this.list.length ? this.list[this.list.length - 1].id + 1 : 10,
// 任务是子组件触发自定义事件的时候传过来的
name: theTesk,
// 新建的任务默认都是未完成
isDone: false,
});
},
// 删除任务
deleteFn(theId) {
// 注意:filter 不改变原数组,需要重新赋值
this.list = this.list.filter((item) => item.id !== theId);
},
// 切换任务
typeFn(theSel){
this.getSel = theSel
},
// 清除已完成
clearFn(){
// 真是修改了 list
this.list = this.list.filter(item => item.isDone !== true)
}
},
// computed 写计算属性的结构(算出来新的变量)
computed: {
showArr(){
if( this.getSel === 'yes'){
return this.list.filter(item => item.isDone === true)
}else if(this.getSel === 'no'){
return this.list.filter(item => item.isDone === false)
}else{
return this.list
}
}
},
watch: {
list:{
deep:true,
handler(){
localStorage.setItem('todoList',JSON.stringify(this.list))
}
}
}
};
</script>
<style>
</style>