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
  1. It’s really easy to understand when you’re doing all sorts of things: data is data, method is operation
  • disadvantages
  1. 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
  1. ugly
  2. 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
  1. You can do Tree Shaking without using computed, but when code is built it removes computed code in VUe3
  2. 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