15 minutes to get started vue3 0 (summary)

Posted by Tjk on Sun, 20 Feb 2022 01:28:41 +0100

This article mainly introduces the 15 minute start vue3 0. The example code introduced in this paper is very detailed, which has a certain reference value for everyone's study or work

Vue 3 has not been officially released, but the Alpha version has been released.
***

Shouting that I can't learn anymore, I honestly opened the Vue 3 document with both hands

Create project

Vue officials have kindly provided a github warehouse so that we can quickly experience the new features of Vue 3:
git clone https://github.com/vuejs/vue-next-webpack-preview.git vue3-start cd vue3-start

npm install or yarn intall
When the development environment is ready, start the command:
npm run dev
Open in browser http://127.0.0.1:8080 , you can see a simple counter page:

Open package JSON, the vue version currently used is: 3.0.0-beta two

What's new in Vue 3

Vue 3 is designed to be faster, smaller, and better support TypeScript.
Some new features include:

  1. Composition API
  2. Multiple root elements
  3. Suspense
  4. Multiple V-models
  5. Reactivity
  6. Teleport
  7. Transition
  8. Remove Filter
  9. App configuration

1,Composition API

Vue officially released the official plug-in of Composition API, which enables users to Enjoy the new experience brought by Function Base in X.
In vue 3, there is no need to install plug-ins separately, which can be used out of the box.
Open app Vue, you will see the setup() method:

<template>
 <img src="./logo.png">
 <h1>Hello Vue 3!</h1>
 <button @click="inc">Clicked {{ count }} times.</button>
</template>
 
<script>
import { ref } from 'vue'
 
export default {
 setup() {
 const count = ref(0)
 const inc = () => {
  count.value++
 }
 
 return {
  count,
  inc
 }
 }
}
</script>
 
<style scoped>
img {
 width: 200px;
}
h1 {
 font-family: Arial, Helvetica, sans-serif;
}
</style>

Composition API provides two main benefits:
1. Clear code structure
2. De duplication logic

<template>
 <div class="counter">
 <p>count: {{ count }}</p>
 <p>NewVal (count + 2): {{ countDouble }}</p>
 <button @click="inc">Increment</button>
 <button @click="dec">Decrement</button>
 <p> Message: {{ msg }} </p>
 <button @click="changeMessage()">Change Message</button>
 </div>
</template>
<script>
import { ref, computed, watch } from 'vue'
export default {
 setup() {
 /* ---------------------------------------------------- */
 let count = ref(0)
 const countDouble = computed(() => count.value * 2)
 watch(count, newVal => {
  console.log('count changed', newVal)
 })
 const inc = () => {
  count.value += 1
 }
 const dec = () => {
  if (count.value !== 0) {
  count.value -= 1
  }
 }
 /* ---------------------------------------------------- */
 let msg= ref('some text')
 watch(msg, newVal => {
  console.log('msg changed', newVal)
 })
 const changeMessage = () => {
  msg.value = "new Message"
 }
 /* ---------------------------------------------------- */
 return {
  count,
  inc,
  dec,
  countDouble,
  msg,
  changeMessage
 }
 }
}
</script>

If you don't like using the Composition API, you can also continue to use 2 Traditional approach to X:

<template>
 <div class="counter">
 <p>count: {{ count }}</p>
 <p>NewVal (count + 2): {{ countDouble }}</p>
 <button @click="inc">Increment</button>
 <button @click="dec">Decrement</button>
 <p> Message: {{ msg }} </p>
 <button @click="changeMessage()">Change Message</button>
 </div>
</template>
<script>
export default {
 data() {
 return {
  count: 0,
  msg: 'some message'
 }
 },
 computed: {
 countDouble() {
  return this.count*2
 }
 },
 watch: {
 count(newVal) {
  console.log('count changed', newVal)
 },
 msg(newVal) {
  console.log('msg changed', newVal)
 }
 },
 methods: {
  inc() {
  this.count += 1
 },
 dec() {
  if (this.count !== 0) {
  this.count -= 1
  }
 },
 changeMessage() {
  msg = "new Message"
 }
 }
 
}
</script>

The above two codes are completely equivalent in effect

The advantage of using Composition API: it allows us to better organize the code (state, methods, calculated properties, watcher, etc.).

With the growth of component scale, how to organize our business code has gradually become an important issue to ensure that new developers can easily understand the code without taking too much time.

We used to use mixin to reuse code. However, the biggest pain point of mixin is that we need to track the States and methods in different components, which often brings a certain mental burden to the development. Accidentally, mixin may cover the existing states or methods in components.

Using the Composition API makes code reuse easier.
We can also extract the code of repeated functions:

// message.js
import { ref, watch } from "vue";
export function message() {
 let msg = ref(123);
 watch(msg, (newVal) => {
 console.log("msg changed", newVal);
 });
 const changeMessage = () => {
 msg.value = "new Message";
 };
 return { msg, changeMessage };
}

Use the above components in other components:

<template>
 <div class="counter">
 <p>count: {{ count }}</p>
 <p>NewVal (count + 2): {{ countDouble }}</p>
 <button @click="inc">Increment</button>
 <button @click="dec">Decrement</button>
 <p>Message: {{ msg }}</p>
 <button @click="changeMessage()">change message</button>
 </div>
</template>
<script>
import { ref, computed, watch } from 'vue'
import { message } from './common/message'
export default {
 setup() {
 let count = ref(0)
 const countDouble = computed(() => count.value * 2)
 watch(count, newVal => {
  console.log('count changed', newVal)
 })
 const inc = () => {
  count.value += 1
 }
 const dec = () => {
  if (count.value !== 0) {
  count.value -= 1
  }
 }
 let { msg, changeMessage } = message()
 return {
  count,
  msg,
  changeMessage,
  inc,
  dec,
  countDouble
 }
 }
}
</script>

2,Multiple root elements

In Vue 2, tempalt can only take one root element. Even if we have only two < p > tags, we must include them in one < div > tag:

<template>
 <div class="counter">
 <p> Count: {{ count }} </p>
 <button @click="increment"> Increment </button>
 <button @click="decrement"> Decrement</button>
 </div>
</template>

In order to compile, we usually add a root node.

This design is really bad. I make complaints about it many times. Because it will lead to unnecessary code nesting and indentation.

Fortunately, this restriction was removed in Vue 3:
You can use any number of labels directly in:

<template>
 <p> Count: {{ count }} </p>
 <button @click="increment"> Increment </button>
 <button @click="decrement"> Decrement </button>
</template>

When you open the template with VScode, you see some lint errors. This is because the official plug-in eslint plugin Vue does not support the new template syntax.

3,Suspense

Suspend is a Vue 3 new feature.
Usually, the front-end and back-end interaction is an asynchronous process: by default, we provide an animation in loading, and use v-if to control the data display when the data is returned.
The emergence of suspend greatly simplifies the process: it provides two states: default and fallback:

<template>
 <Suspense>
 <template #default>
  <div v-for="item in articleList" :key="item.id">
  <article>
   <h2>{{ item.title }}</h2>
   <p>{{ item.body }}</p>
  </article>
  </div>
 </template>
 <template #fallback>
  Articles loading...
 </template>
 </Suspense>
</template>
<script>
import axios from 'axios'
export default {
 async setup() {
 let articleList = await axios
  .get('https://jsonplaceholder.typicode.com/posts')
  .then(response => {
  console.log(response)
  return response.data
  })
 return {
  articleList
 }
 }
}
</script>

4,Multiple v-models

We all know that v-models are used for two-way data binding. Generally used with form elements. Sometimes we use it in custom components.
Vue 2 allows only one v-models to be used on one component. In Vue 3, we can bind any number of v-models to our custom components:

<template>
 <survey-form v-model:name="name" v-model:age="age">
 {" "}
 </survey-form>
</template>
SurveyForm.vue:
<template>
 <div>
  <label>Name: </label>
  <input :value="name" @input="updateName($event.target.value)" />
  <label>Age: </label>
  <input :value="age" @input="updateAge($event.target.value)" />
 </div>
</template>
<script>
 export default {
  props: {
  name: String,
  age: Number
  },
  setup(props, { emit }) {
  const updateName = value => {
   emit('update:name', value)
  }
  const updateAge = value => {
   emit('update:age', +value)
  }
  return { updateName, updateAge }
  }
 }
</script>

5,Reactivity

Vue 2's response is already excellent, but there are some problems in a few cases:

<template>
 <div class="hello" @click="test">test {{list }} {{ myObj }}</div>
</template>
<script>
export default {
 name: "HelloWorld",
 data() {
 return {
  list: [1, 2],
  myObj: { name: "Preetish" }
 };
 },
 watch: {
 list: {
  handler: () => {
  console.log("watcher triggered");
  },
  deep: true
 }
 },
 methods: {
 test() {
  this.list[2] = 4;
  this.myObj.last = "HS";
  delete this.myObj.name;
 }
 }
};
</script>

We found that through this List subscript to modify the element does not trigger the watcher listener function. In order to achieve this goal, we have to use Vue Set() or Vue Delete() these methods.
In vue 3, we don't need other API s:

export default {
 setup() {
 let list = ref([1, 2]);
 let myObj = ref({ name: "Preetish" });
 function myFun() {
  list.value[3] = 3;
  myObj.value.last = "HS";
  delete myObj.value.name;
 }
 return { myFun, list, myObj };
 },
};

6,Portals

Portals provides the ability to render components into any DOM node of the page. In Vue 2, a third-party plug-in of portal Vue is used to do this.
Direct use in vue 3:

<Teleport to="#modal-layer">
 <div class="modal">hello</div>
</Teleport>

< report > is a specific tag provided in vue3 to create a portal.
The contents appearing in the middle of < report > < / report > will appear in the node specified by to:
<div id="modal-target"></div>
So far, < report > cannot be used in Alpha version

7,Transition

I was confused when I used v-enter-active, v-enter and v-enter-to.
Now Vue 3 is named more intuitively: v-enter becomes v-enter-from, and v-leave becomes v-leave-from.
8,Remove Filter
Vue 3 abandons the use of Filter and recommends using calculation attributes or methods:

<!-- vue 2.x -->
{{ date | format }}
 
<!-- vue 3.0 -->
{{ format(date) }}

9,App configration

In Vue 2, if you want to use use use(), mixin(), directive() and other methods, you need to cooperate with the global Vue object:

import Vue from "vue";
import App from "./App";
 
Vue.use(/* ... */);
Vue.mixin(/* ... */);
Vue.component(/* ... */);
Vue.directive(/* ... */);
 
new Vue({
 el: "#app",
 template: "<App/>",
 components: {
  App,
 },
});

In Vue 3, the Vue instance returned by createApp is changed:

import { createApp } from "vue";
import App from "./App.vue";
 
const app = createApp(App);
 
app.use(/* ... */);
app.mixin(/* ... */);
app.component(/* ... */);
app.directive(/* ... */);
 
app.mount("#app");

Concluding remarks

In short, Vue 3 provides a simple way to organize and share code, and provides strong TypeScript support. The new code organization will have a significant impact on future application development.

At the same time, some other features, such as suspend and multiple v-models, will also bring great convenience to the development.
At the same time, the performance is faster and the volume is smaller. Please refer to another article I wrote: Vue JS Author: About vue3 The story behind 0

Topics: Javascript TypeScript Vue Vue.js