VUE入门:组件化开发shopping_todos(2)
前言
在上一篇章的学习中我们得知了组件化的实现方式,明白了组件化思想,熟练运用了v-on
和 index
实现了页面跳转;认识了表格标签<table
>和他的同族标签,并使用他们绘制了表格;利用v-for
和响应式拓展表格,使用 index
实现arr中item的属性的变化,巧妙的利用 v-bind
和:disabled
实现按钮禁用功能......今天,在本篇文章里你将完成shopping_todos的后半部分,学会如何在vue中开发一个计划笔记todos
Todos
分析需求
先分析我们需要实现什么功能。观察目标效果,首先我们需要一个响应式的todo栏。在固定的输入框中输入我们我们的代办事项, 这个栏框可以接收到我们的代办事项并动态的生成一栏新的todo栏。其次,当我们使用鼠标点击固定栏下面的动态栏中的字体时,会变换字体的样式
实用开发工具:npmjs.com
在这里为大家介绍一个相当好用的网站,这个网站是node的官方网站,在这个网站中,你可以使用任何一个别人封装好的库。 npm | Home (npmjs.com)
请大家在这个网站中搜索todomvc-app-css,你会惊奇的发现,这不就是我们今天要实现的小demo吗
没错,这就是一个包,一个库,别人已经为我们封装好了css部分,接下来的开发我们只要引入这个包就行,安装第三方库,无需反复造轮子,直接使用他们为我们打造好了的css样式。
- 在node中输入如下指令
npm i todomvc-app-css
这个安装包是否成功安装可以检查我们vue架构的package.json
文件,在这个文件说明书中我们可以发现在 "dependencies" 依赖中多增加一个依赖"todomvc-app-css": "^2.4.3"
。
还记得 devDependencies
和dependencies
是什么吗?
dev————
代表的是在开发环境中的依赖dependencies
代表的是项目完成后以确保项目能够正常运行保留的依赖
- 最后将他引入在main.js中。在以后你独自开发项目时,不同的库引入的方法可能会有不同,你需要查看他的git库在寻找引入方法。
import 'todomvc-app-css/index.css'
在将他这个包安装完成之后我们只需要在开发中和他使用一样类名就能使用他的css,极大的节省我们编程时的开发时间,使我们不用再写Css样式
构建基本骨架
接下来我们正式开发这个页面,经过我们前面的分析我们已经大概了解这个表单的结构构成,结合作者在npmjs使用文档中的对比,总结html架构主要分为固定栏,全选按钮,动态栏3部分。
1.固定栏
首先我们来开发固定栏,作为最轻松的固定样式,我们能很轻松写出他的结构。
我们使用 header
来表示这个结构,给他添加类名 header
,接着在他里面写好我们的头部名称————todos,这使得在这个页面的头部生成红色的大字标识。使用 input
框,在里面使用他写好的类名,所有类名都有对应的样式,所以在应用第三方库时建议采用复制类名的方法,在开发过程中应该尽量避免手敲。
<header class="header">
<h1>todos</h1>
<input type="text" class="new-todo" placeholder="What needs to be done?">
</header>
正确展示结果如下
2.全选按钮
我们使用 section
标签添加类名 mian
,使用 input
框,写定他给好的类名,使用,写好 label
标签后页面会多出一个向下的箭头标识全选,当代办事项变多时可以看到全选的效果
<section class="main">
<input type="checkbox" class="toggle-all" id="toggle-all">
<label for="toggle-all">mark all as complete</label>
</section>
正确展示结果如下
3.动态栏
动态栏和全选按钮处于同级,都在 <section class="main"></section>
中。 在动态栏中,整体是ul
,里面放了一个li
.在li
中的div
并列内置了输入框,标签和按钮。我们的目的是实现 li
的响应式生成和点击字体实现选中和取消效果。
<ul class="todo-list">
<li class="todo">
<div class="view">
<input type="checkbox" class="toggle">
<label>学习</label>
<button class="destroy"></button>
</div>
</li>
</ul>
正确展示结果如下
最后将这3部分都放进 <section class="todoapp" />
中,取代 div
。至此项目的基本骨架被构建完成
实现响应式交互
- 首先我们需要定义响应式的数据,定义一份后端假数据, 通过import引入将我们定义的假数据响应化;
import { reactive } from 'vue'
const state = reactive({
todos: [
{
id: 1,
title: '学习',
completed: false
},
{
id: 2,
title: '吃饭',
completed: true
}
]
})
-
在
li
标签中通过v-for="todo in state.todos"
循环遍历数组中的对象 -
checkbox
复选框为true时默认打勾,使用v-model="todo.completed"
双向绑定input框和数据中的值。当我们将复选框的v-model
绑定到todo.completed
时,Vue会自动处理用户点击复选框时的数据更新。当用户点击复选框时,todo.completed
的值会在true
和false
之间切换,从而实现代办事项的状态转换。
全篇精华————逻辑思路分析
在这里我们需要再次整理我们的思路,我们要如何实现在固定框中输入代办事项时会生成一个新的todolist条?毫无疑问的是我们首先需要为这个input框进行双向绑定。进行双向绑定的目的是什么?是为了将用户输入的数据传入我们的假数据库state中,然后通过在li
中v-for
循环遍历这份假数据,实现新增加数据的导入,新的li的生成。
所以第一步我们需要干什么?我们是不是需要定义一份空数组,当用户输入时,通过双向绑定我们拿到了这份数据,我们需要将这份数据放进一个空数组中。
// 空数组:
const newTodo = reactive(
{
id: 1,
title: ' ',
completed: false
})
接着,我们需要将这个空数组放进原先的数据库中,这样才能让v-for遍历到他。所以我们无疑要打造一个添加函数,实现:当用户点击enter键时,将这个空数组push进数据库中。所以我会给用户绑定键盘事件,给添加函数打造一个功能:将用户数据push进数据库的列表中。
// 实现点击enter键将用户输入的数组添加进数据库
const addTodo = () => {
newTodo.id = state.todos.length + 1
state.todos.push(newTodo)
}
接下来我要实现当点击代办事项中的字体时,会出现字体变灰色被横干掉的效果。我们不用思考实现这个样式,因为字体的变化效果时css部分内容,在前面的步骤中我们已经引入过css包。所以我们要考虑的是实现点击时产生变化的逻辑。为什么鼠标一点击就会产生变化呢?是因为当点击事件发生时,对应数组的completed会发生改变,是ture就会变成false,是false就会变成ture。所以这里涉及到1.绑定点击事件2.点击事件绑定了一个函数:当点击事件触发时布尔值变更。在这里,很多人无法想到第三点,这个函数是如何追踪到你点击的数据执行职能的。在数组中,数组天生具有的下标index可以快速的解决这个问题。我们使用数组state来接收了用户输入的数据,这使得每一条数据(数组中的每一个对象)都带上了一个下标index。所以,第3点,也是核心的一点就是:我会将数组的下标当作参数传入函数中,这样当函数触发时就能精确的执行到对应的数据;同时,我也必须为v-for循环中传入参数index,这样我才能把数组的下标当作实参index而不是形参index传入绑定的事件中。所以在这里我们可以把绑定的点击事件写为 @click="toggle(index)
// 点击代办事项代办事项被"消除"
const toggle = (index) => {
state.todos[index].completed = !state.todos[index].completed
}
同样的思想,通过传入数组的下标和使用数组中的splice()方法可以轻松的定位到需要删除的对象。还记得splice()怎么使用吗,他接收两个参数,一个是修改的开始位置,一个是需要移除的个数。所以我们传入index和1,绑定点击事件 @click="subTodo(index)
// 点击按钮删除对应栏
const subTodo = (index) => {
state.todos.splice(index, 1)
}
同样的思想,我们通过绑定 @click="toggleAll"
打造第一次点击时全选,再次点击时全不选按钮,本质就是将所有数组中的completed
全部赋值为 ture or false
,在每一次点击时将其布尔值取反。所以我们先绑定 @click="toggleAll"
,造一个 is_all,通过控制第3方的值来控制所有列表的值。要拿到所有列表我们需要对数据库中的数据,数组中的对象进行遍历。所以使用forEach()
来遍历todos,在遍历时将todo(用户输入值,数据库中的对象身上的属性)统一为is_all的布尔值,在更改完成后将is_all的布尔值取反。这样在每次点击时is_all的值都会改变,所有todo的值都会被统一,最终功能实现。
let is_all = true
const toggleAll = () => {
state.todos.forEach((todo) => {
todo.completed = is_all
})
is_all = !is_all
}
转载自:https://juejin.cn/post/7389913889331101748