Quickly learn the difference between Vue2 and Vue3

Posted by s1akr on Wed, 05 Jan 2022 19:13:12 +0100

Create data

Here is the biggest difference between Vue2 and Vue3 - Vue2 uses option type API compared with Vue3 synthetic API

The old optional API divides different attributes in the code, such as data, computed, methods, etc; The new composite API allows us to use methods to split, and use attributes to share compared with the old API, so that the code will be simpler and cleaner.

Vue2 -- put two data in the data attribute here

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  }
}

Vue3 -- we need to use a new setup() method, which is triggered when the component initializes the construction

In order to let developers have more control over reactive data, we can directly use Vue3's reactive API

Use the following three steps to establish reactive data;

1. Introduce reactive from Vue

2. Use the reactive() method to declare our data as reactive data

3. Use the setup() method to return our reactive data, so that our template can obtain these reactive data

Look at the code, it's easier to understand

import { reactive } from 'vue'

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: ''
    })

    return { state }
  }
}

Vue is written in comparison with Vue3's metheds

Vue2's optional API divides methods into independent attribute areas. We can directly add methods to this attribute to handle various front-end logic

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login () {
      // Login method
    }
  }
}

The setup() method in Vue3's synthetic API can also be used to manipulate methods. Creating a declared method is actually the same as declaring the data state. We need to declare a method first and then return it in the setup() method, so that this method can be called in our component

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: ''
    })

    const login = () => {
      // Login method
    }
    return { 
      login,
      state
    }
  }
}

Declaration cycle hook

In Vue2, we can directly invoke the life cycle hook of Vue in component properties. The following is the use of a component that has been mounted (mounted) lifecycle trigger hook.

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  },
  mounted () {
    console.log('Component mounted')
  },
  methods: {
    login () {
      // login method
    }
  }
}

Now the setup() method in Vue3's synthetic API can contain everything. Life cycle hook is one of them!

However, in the Vue3 lifecycle, hooks are not globally callable and need to be introduced from Vue. Like the reactive just introduced, the life cycle mount hook is called onMounted.

After the introduction, we can use the onMounted hook in the setup() method.

import { reactive, onMounted } from 'vue'

export default {
  props: {
    title: String
  },
  setup () {
    // ..

    onMounted(() => {
      console.log('Component mounted')
    })

    // ...
  }
}

Calculated properties - calculated properties

Let's try adding a calculated attribute to convert username to lowercase.

To implement in Vue2, we only need to add it in the option attribute in the component

export default {
  // .. 
  computed: {
    lowerCaseUsername () {
      return this.username.toLowerCase()
    }
  }
}

Vue3's design pattern allows developers to introduce dependent packages as needed. In this way, there is no need for redundant references, resulting in performance problems or too big problems after packaging. Vue2 has this persistent problem.

Therefore, to use calculated properties in Vue3, we first need to introduce calculated in the component.

It is used in the same way as reactive data. Add a calculation attribute to state:

import { reactive, onMounted, computed } from 'vue'

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: '',
      lowerCaseUsername: computed(() => state.username.toLowerCase())
    })

    // ...
  }

Receive} Props

The transfer of props parameters of the receiving component brings us the biggest difference between vue2 and vue3. this represents something completely different from vue2 in vue3.

In Vue2, this represents the current component, not a specific attribute. Therefore, we can directly use this to access the prop attribute value. For example, the following example prints the parameter title of the currently passed in component after mounting.

mounted () {
    console.log('title: ' + this.title)
}

However, in Vue3 , this cannot directly get props attribute, emit events and other attributes in the component. However, the new setup() method can accept two parameters:

  1. props - immutable component parameters
  2. context - Vue3 exposed attributes (emit, slots, attrs)

Therefore, receiving and using props in Vue3 will become like this

setup (props) {
    // ...

    onMounted(() => {
      console.log('title: ' + props.title)
    })

    // ...
}

Events - Emitting Events

Customizing events in Vue2 is very direct, but in Vue3, we will have more freedom of control.

For example, now we want to trigger a login event when we click the submit button.

In Vue2, we will call this$ Emit then passes in the event name and parameter object.

login () {
      this.$emit('login', {
        username: this.username,
        password: this.password
      })
 }

However, in Vue3, we just said that this does not represent this component with vue2, so we need different ways to customize events.

So what?! Benefit (benefit)

Don't panic. There is emit in the content object of the second parameter in setup(), which is the same as this$ Emit is the same. Then, as long as we use the decomposition object method to extract emit in the second parameter received by setup(), we can use it freely in the setup method.

Then we write the login event in the login method:

setup (props, { emit }) {
    // ...

    const login = () => {
      emit('login', {
        username: state.username,
        password: state.password
      })
    }

    // ...
}

It's really great. You can see the children's shoes here. Now you basically see that vue2 and vue3 have the same concept and concept. Only some attribute acquisition methods, reputation and definition methods have changed slightly. People who have been crying and howling, you can breathe a sigh of relief.

To sum up, I think Vue3 has brought a new development experience to our front-end developers, better use flexibility and greatly improved controllability. If you are a person who has learned or contacted "React" and now wants to use Vue, you should be particularly excited, because many ways of using Vue are very similar to React!

The new Composition API can improve the decoupling degree of code - especially for large front-end applications. In addition, the on-demand reference has more subtle controllability, so that the performance and packaging size of the project can be better controlled.

Finally, I will send the completed component codes of Vue2 and Vue3 to you:

Vue2

<template>
  <div class='form-element'>
    <h2> {{ title }} </h2>
    <input type='text' v-model='username' placeholder='Username' />
    
    <input type='password' v-model='password' placeholder='Password' />

    <button @click='login'>
      Submit
    </button>
    <p> 
      Values: {{ username + ' ' + password }}
    </p>
  </div>
</template>
<script>
export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  },
  mounted () {
    console.log('title: ' + this.title)
  },
  computed: {
    lowerCaseUsername () {
      return this.username.toLowerCase()
    }
  },
  methods: {
    login () {
      this.$emit('login', {
        username: this.username,
        password: this.password
      })
    }
  }
}
</script>

Vue3

<template>
  <div class='form-element'>
    <h2> {{ state.title }} </h2>
    <input type='text' v-model='state.username' placeholder='Username' />
    
    <input type='password' v-model='state.password' placeholder='Password' />

    <button @click='login'>
      Submit
    </button>
    <p> 
      Values: {{ state.username + ' ' + state.password }}
    </p>
  </div>
</template>
<script>
import { reactive, onMounted, computed } from 'vue'

export default {
  props: {
    title: String
  },
  setup (props, { emit }) {
    const state = reactive({
      username: '',
      password: '',
      lowerCaseUsername: computed(() => state.username.toLowerCase())
    })

    onMounted(() => {
      console.log('title: ' + props.title)
    })

    const login = () => {
      emit('login', {
        username: state.username,
        password: state.password
      })
    }

    return { 
      login,
      state
    }
  }
}
</script>

Topics: Javascript Vue.js html