构建|我用React和Vue构建了同款应用,来看看哪里不一样(2020版)( 二 )
实际上,React 和 Vue 在这里做的是同样的事情,也就是创建可以更新的数据。Vue 本质上会在每次更新一条包装在 ref() 函数内的数据时默认结合它自己的 name 和 setName 版本。React 要求你使用内部值调用 setName() 来更新状态,而如果你曾尝试更新数据对象内部的值,Vue 就会假设你要这么做。那么为什么 React 会费劲地将值与函数分开,还要使用 useState() 呢?这是因为当状态改变时,React 希望重新运行某些生命周期 Hooks。在我们的例子中,当你调用 setName() 时,React 会知道有些状态已更改,所以可以运行它们的生命周期 Hooks。如果你直接改变状态,React 将不得不做更多的工作来跟踪更改以及要运行的生命周期 Hooks 等。
现在我们已经搞明白了数据突变,接下来看看在两个 To Do 应用中添加新项目的方法。
我们如何创建新的待办事项?
React:
在 React 里是怎么做的?
在 React 中,我们的输入字段有一个名为value的属性。每次通过onChange 事件侦听器更改它的值时,都会自动更新此值。JSX(基本上是 HTML 的变体)如下所示:
每次更改值时,它都会更新状态。handleInput 函数如下所示:
现在,每当用户按下页面上的+按钮添加新项目时,都会触发createNewToDoItem函数。我们再来看一下这个函数,搞清楚具体发生了什么:
本质上,newId 函数是在创建一个新 ID,该 ID 将提供给我们的新 toDo 项目。newToDo 变量是一个对象,有一个 id 键,其值由 newID 确定。它还有一个 text 键,其值由 toDo 确定。这个 toDo 就是输入值更改时要更新的那个 toDo。
setList 函数到此为止,然后我们传入一个包含整个 list 以及新创建的 newToDo 的数组。
你可能觉得…list 看起来很奇怪:开头的三个点称为 spread 运算符,负责将 list 中的所有值作为单独的项目传递,而不是简单地把所有项目打包在一起作为数组传递。感觉有些糊涂吗?那我强烈建议你仔细阅读 spread 运算符的相关介绍,因为它很有用!
最后我们运行 setToDo() 并传入一个空字符串。这样我们的输入值为空,可以输入新的 toDo 了。
Vue:
在 Vue 里是怎么做的?
在 Vue 中,我们的input字段有一个称为v-model的句柄。这使我们能够执行称为双向绑定的操作。下面来看一下 input 字段,搞清楚到底发生了什么:
V-Model 将这个字段的输入与我们在 setup() 函数上创建的一个变量相关联,然后公开为一个返回对象内的键。到目前为止我们还没有介绍对象返回的内容,所以先说一下,这是我们从ToDo.vue内部的 setup() 函数返回的内容:
这里,list、todo 和 showError 是我们的有状态值,而其他所有内容都是我们希望能在应用其他位置调用的函数。在页面加载时,我们必须将 todo 设置为一个空字符串,例如:const todo = ref("")。如果其中已经有一些数据,例如 const todo = ref("add some text here"):我们的输入字段将在内部已有 add some text here 的情况下加载。不管怎样,回到空字符串的状态,无论我们在输入字段中键入什么文本都必须绑定到 todo.value。这实际上就是双向绑定——输入字段可以更新 ref() 值,反过来后者也可以更新输入字段。
回顾一下前面的createNewToDoItem ()代码块,可以看到,我们将 todo.value 的内容推送到 list 数组中,然后将前者更新为一个空字符串。
我们还使用了与 React 示例中相同的 newId() 函数。
如何从列表中删除项目?
React:
在 React 里是怎么做的?
因为 deleteItem() 函数位于ToDo.js内,我可以很容易地在ToDoItem.js里引用它,首先将deleteItem ()函数作为一个 prop,如下所示:
这里首先将该函数传递下去,使其能被子级访问。然后在ToDoItem组件内执行以下操作:
我要引用位于父组件内的函数,只需引用props.deleteItem。你可能发现在代码示例中,我们只写了 deleteItem,而不是 props.deleteItem。这是因为我们使用了一种称为解构的技术,该技术允许我们获取props对象的一部分并将其分配给变量。因此在我们的ToDoItem.js文件中有以下内容:
这为我们创建了两个变量,其中一个称为 item,它被赋予与 props.item 相同的值,而 deleteItem 则根据 props.deleteItem 赋值。我们也可以简单地使用 props.item 和 props.deleteItem 来避免解构的操作,但我认为这里值得单独介绍一下!
Vue:
在 Vue 里是怎么做的?
Vue 需要的方法稍微有一些不同。这里我们必须做三件事:
首先,在我们要调用函数元素上:
然后我们必须在子组件(在本例中为ToDoItem.vue)中创建一个 emit 函数作为方法,如下所示:
与此同时你会发现,当我们在ToDo.vue中添加ToDoItem.vue时,我们实际上引用了一个函数:
这就是所谓的自定义事件侦听器 event-listener。它会侦听使用字符串“delete”触发 emit 的所有情况。如果听到此消息,它将触发一个名为onDeleteItem的函数。此函数位于ToDo.vue内部,而不是在ToDoItem.vue中。如前所述,此函数仅过滤来自 list.value 数组内的 id。
推荐阅读
- 联合实验室|腾讯携手虎牙成立安全联合实验室 “AI审核+安全攻防”构建更健康直播生态
- 技术升级|F5G+IPv6打破连接障碍,共同构建智能联接新世界
- 扶贫|数字乡村|德生科技助力各县构建电商扶贫生态!
- 高等教育|废除学历教育中“职业教育”概念构建适合中国国情的中、高等教育新体系
- 家政|构建家政工匠培养的中国模式
- 研究生|两部门:鼓励构建专业学位研究生双导师制
- 马路|爱奇艺随刻跨界联动美食马路边边 构建"快乐搞哈"线下娱乐消费
- 真会玩|被称为“国宝级”的洗发水,却因价格太低,没人在乎,袁咏仪:我用3年了
- 运去|“运去哪”与PSA达成战略合作 合力构建全球服务网络
- 苏宁|家乐福加入苏宁周年日:构建SaaS平台 全方位加速生意成长