- Vue 3.0 性能提升主要是通过哪几方面体现的?
- 更小的打包体积
- 采用CompositionApi
- Vue 3.0 所采用的 Composition Api 与 Vue 2.x使用的Options Api 有什么区别?
- 使得代码可以以业务逻辑为模块组织,方便了复用
- Proxy 相对于 Object.defineProperty 有哪些优点?
- 实现了数组用length和用下标修改不能响应式变化的缺陷
- 代理了对象,而不是属性
- 本身的实现过程更加简洁
- Vue 3.0 在编译方面有哪些优化?
- 使用浏览器支持模块化加载的特性直接加载文件,使用服务端贬编译为js文件,再返回给浏览器解释执行,不需要提前打包项目
- 加速了热更新响应速度,得到了更好的开发体验
- Vue.js 3.0 响应式系统的实现原理?
- weakMap, Map, Set
- reactive, ref, effect,
数组也可以用 in 遍历
在todo list 案例中,我觉得有收获的点:
根据hash名称创建函数,完美避开if else 语句
<ul class="filters"><li><a href="#/all">All</a></li><li><a href="#/active">Active</a></li><li><a href="#/completed">Completed</a></li></ul>
```javascript const filter = { all: list => list, active: list => list.filter(todo => !todo.completed), completed: list => list.filter(todo => todo.completed) } // 处理路由变化逻辑
const onHashChange = () => { const hash = window.location.hash.replace(‘#/‘, ‘’) if (filter[hash]) {
// 正确的路由跳转只有3个type.value = hash
} else {
// 不正确的路由跳转有 路由输入错误 初始状态下没有hash 都直接转到 all hash 处理type.value = 'all'window.location.hash = ''
} }
// 监听hashchange事件(我不熟悉这个事件) onMounted(() => { window.addEventListener(‘hashchange’, onHashChange) onHashChange() })
onUnmounted(() => { window.removeEventListener(‘hashchange’, onHashChange) })
疑惑的点:<br />todo === editingTodo 这都是对象,怎么可以用来判断是否相等<br />我觉得还需要听一遍,这里面的逻辑对我来说很有条理,功能各司其职,需要学习它如何拆分,又如何分类这些功能的。```vue<template><section id="app" class="todoapp"><header class="header"><h1>todos</h1><inputclass="new-todo"placeholder="What needs to be done?"autocomplete="off"autofocusv-model="input"@keyup.enter="addTodo"></header><section class="main" v-show="count"><input id="toggle-all" class="toggle-all" v-model="allDone" type="checkbox"><label for="toggle-all">Mark all as complete</label><ul class="todo-list"><liv-for="todo in filteredTodos":key="todo":class="{ editing: todo === editingTodo, completed: todo.completed }"><div class="view"><input class="toggle" type="checkbox" v-model="todo.completed"><label @dblclick="editTodo(todo)">{{ todo.text }}</label><button class="destroy" @click="remove(todo)"></button></div><inputclass="edit"type="text"v-editing-focus="todo === editingTodo"v-model="todo.text"@keyup.enter="doneEdit(todo)"@blur="doneEdit(todo)"@keyup.esc="cancelEdit(todo)"></li></ul></section><footer class="footer" v-show="count"><span class="todo-count"><strong>{{ remainingCount }}</strong> {{ remainingCount > 1 ? 'items' : 'item' }} left</span><ul class="filters"><li><a href="#/all">All</a></li><li><a href="#/active">Active</a></li><li><a href="#/completed">Completed</a></li></ul><button class="clear-completed" @click="removeCompleted" v-show="count > remainingCount">Clear completed</button></footer></section><footer class="info"><p>Double-click to edit a todo</p><!-- Remove the below line ↓ --><p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p><!-- Change this out with your name and url ↓ --><p>Created by <a href="https://www.lagou.com">教瘦</a></p><p>Part of <a href="http://todomvc.com">TodoMVC</a></p></footer></template><script>import './assets/index.css'import useLocalStorage from './utils/useLocalStorage'import { ref, computed, onMounted, onUnmounted, watchEffect } from 'vue'const storage = useLocalStorage()// 1. 添加待办事项const useAdd = todos => {const input = ref('')const addTodo = () => {const text = input.value && input.value.trim()if (text.length === 0) returntodos.value.unshift({text,completed: false})input.value = ''}return {input,addTodo}}// 2. 删除待办事项const useRemove = todos => {const remove = todo => {const index = todos.value.indexOf(todo)todos.value.splice(index, 1)}const removeCompleted = () => {todos.value = todos.value.filter(todo => !todo.completed)}return {remove,removeCompleted}}// 3. 编辑待办项const useEdit = remove => {let beforeEditingText = ''const editingTodo = ref(null)const editTodo = todo => {beforeEditingText = todo.texteditingTodo.value = todo}const doneEdit = todo => {if (!editingTodo.value) returntodo.text = todo.text.trim()todo.text || remove(todo)editingTodo.value = null}const cancelEdit = todo => {editingTodo.value = nulltodo.text = beforeEditingText}return {editingTodo,editTodo,doneEdit,cancelEdit}}// 4. 切换待办项完成状态const useFilter = todos => {const allDone = computed({get () {return !todos.value.filter(todo => !todo.completed).length},set (value) {todos.value.forEach(todo => {todo.completed = value})}})const filter = {all: list => list,active: list => list.filter(todo => !todo.completed),completed: list => list.filter(todo => todo.completed)}const type = ref('all')const filteredTodos = computed(() => filter[type.value](todos.value))const remainingCount = computed(() => filter.active(todos.value).length)const count = computed(() => todos.value.length)const onHashChange = () => {const hash = window.location.hash.replace('#/', '')if (filter[hash]) {type.value = hash} else {type.value = 'all'window.location.hash = ''}}onMounted(() => {window.addEventListener('hashchange', onHashChange)onHashChange()})onUnmounted(() => {window.removeEventListener('hashchange', onHashChange)})return {allDone,count,filteredTodos,remainingCount}}// 5. 存储待办事项const useStorage = () => {const KEY = 'TODOKEYS'const todos = ref(storage.getItem(KEY) || [])watchEffect(() => {storage.setItem(KEY, todos.value)})return todos}export default {name: 'App',setup () {const todos = useStorage()const { remove, removeCompleted } = useRemove(todos)return {todos,remove,removeCompleted,...useAdd(todos),...useEdit(remove),...useFilter(todos)}},directives: {editingFocus: (el, binding) => {binding.value && el.focus()}}}</script><style></style>
