Vue2’s Options Api and Vue3’s Composition Api
A simple todo
-
Options Api
<template> <div> <input type="text" v-model="val" @keyup.enter="addTodo"> <u> <li v-for="todo in todos" :key="todo.id">{{todo.title}}</li> </u> </div> </template> <script> export default { data() { return { val: "", todos: [{id: 0, the title is: "to eat", done: false}, {id: 1, the title: "sleep", done: false},],}; }, methods: { addTodo() { this.todos.push({ id: this.todos.length, title: this.val, done: false, }); this.val = ""; ,}}}; </script>Copy the code
With the code above, we did a simple TOdo using the Options API
- advantages
- It’s really easy to understand when you’re doing all sorts of things: data is data, method is operation
- disadvantages
- Poor maintainability of data, methods, computed, watch, etc., may lead to repeated horizontal hopping up and down, so mixins can be used as a solution
<script> ... mixins: ['counter', 'mouse', ...] . </script>Copy the code
The biggest disadvantage of mixins is the naming conflict. Although it can solve the problem of repeatedly skipping, it is difficult to maintain in large projects. In addition, this is also a black box, so it is difficult to test and do type derivation, which is why VUe2 does not support TS well.
-
Compostion Api
<script> import { reactive, ref, toRefs } from "vue"; export default { setup() { let val = ref(""); Let todos = reactive ([{id: 0, the title is: "to eat", done: false}, {id: 1, the title: "sleep", done: false},]); function addTodo() { todos.push({ id: todos.length, title: val.value, done: false, }); val.value = ""; } return { val, todos, addTodo }; }};Copy the code
With the code above, we created a simple todo using the Composition API
- disadvantages
- ugly
- A return is a pain in the neck, and if the component is large, a return can also cause a hop up and down
Let’s simplify:
<script setup> import { reactive, ref, toRefs } from "vue"; let val = ref(""); Let todos = reactive ([{id: 0, the title is: "to eat", done: false}, {id: 1, the title: "sleep", done: false},]); function addTodo() { todos.push({ id: todos.length, title: val.value, done: false, }); val.value = ""; }Copy the code
Add setup to script tags to eliminate code redundancy and return hops to make code cleaner
- advantages
- You can do Tree Shaking without using computed, but when code is built it removes computed code in VUe3
- Easy composition, all logic is functions, composition is better than inheritance
Composition over Inheritance
- What is a combination?
To explain it in code, write an accumulator
Import {ref} from 'vue' export default function useCounter() {let counter = ref(1) function addCounter() { counter.value += 1 } return { counter, addCounter } }Copy the code
App.vue
<template>
<div>
<h1 @click="addCounter">{{counter}}</h1>
</div>
</template>
<script setup>
import useCounter from "./useCounter";
let { counter, addCounter } = useCounter();
</script>
Copy the code
Usecounter.js above is a combination, and todos above can be combined as well
// create a new usetodo.js file import {ref, reactive } from 'vue' export default function useTodo() { let val = ref('') let todos = reactive([ { id: 0, title: }) function addTodo() {todos.push({id: todos.length, title: 'todos.length ', title:' todos.length ', title: 'todos.length ', title:' todos.length ', title: 'todos.length ', title:' todos.length ', title: 'todos.length') val.value, done: false, }) val.value = '' } return { val, todos, addTodo } }Copy the code
App.vue
<template>
<div>
<h1 @click="addCounter">{{counter}}</h1>
<input type="text" v-model="val" @keyup.enter="addTodo">
<u>
<li v-for="todo in todos" :key="todo.id">{{todo.title}}</li>
</u>
</div>
</template>
<script setup>
import { reactive, ref, toRefs } from "vue";
import useCounter from "./useCounter";
import useTodo from "./useTodo";
let { counter, addCounter } = useCounter();
let { val, todos, addTodo } = useTodo();
</script>
Copy the code
The advantage of the composition approach is that components can be arbitrarily split and data flow is clear
React Hooks
Now we use React to write an accumulator
import React, { useState } from 'react'
function App() {
let [counter, setCounter] = useState(0)
return (
<div>
<h1 onClick={() => setCounter(counter + 1)}>{counter}</h1>
</div>
)
}
export default App
Copy the code
See if this sounds like the Composition API and React hooks
Vue3 changes are made by options -> Composition
React17 is fixed by class -> hooks
The criticism of Vue’s Composition is that it copies hooks, but their underlying implementations are vastly different
Hooks are in strict order
Composition follows by reactive
React is non-responsive, it’s just a VDOM, calculating diff
Vue is Reactive + VDOM
- Hooks
Import React, {useState} from 'React' function App() {// hooks have strict execution order. If (xx === 1) {let [counter, setCounter] = useState(0)} setCounter] = useState(0) return ( <div> <h1 onClick={() => setCounter(counter + 1)}>{counter}</h1> </div> ) } export default AppCopy the code