Get started quickly with Vue3


Mainly to record what I learned from the video at station b, record notes, video address Shang Silicon Valley Vue2.0+Vue3.0 full set of tutorial丨vuejs from entry to master

Introduction

Vue.js released version 3.0 on September 18, 2020, codenamed: One Piece (One Piece), which
took more than 2 years, 2600+ submissions, 30+ RFCs, 60+ PRs, and 99 contributors

performance improvements

  • 41% reduction in bundle size
  • 55% faster initial render, 133% faster update render
  • 54% less memory

Source code upgrade

  • ProxyReactive using definePropertyinstead
  • Override virtual DOMimplementation and Tree-Shaking(import on demand)

Embrace TypeScript

  • Vue3 can better support TypeScript

new features

1. Composition API (combination API)

  • setupconfiguration
  • refandreactive
  • watchandwatchEffect
  • provideandinject

2. New built-in components

  • Fragment
  • Teleport
  • Suspense

3. Other changes

  • new lifecycle hook
  • The data option should always be declared as a function
  • Remove keyCode support as v-on modifier

Create a Vue3 project

1. Use vue-cli to create

Vue-cli official document

The version of vue-cli needs to be above 4.5.0 to install vue3 scaffolding. You can use vue --versionor vue --versionview the current version. If the version is lower than 4.5.0, use npm install -g @vue/clior yarn global add @vue/cliupgrade the version

## 查看@vue/cli版本
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建Vue项目,选择Vue3
vue create vue3_test
## 启动
cd vue3_test
npm run serve

When creating a project, it will prompt version 2.x and version 3.x, just choose Vue 3 here
insert image description here

2. What is Vite

Official document https://v3.cn.vuejs.org/guide/installation.html#vite
official website https://vitejs.cn/

  • It is a new generation of front-end construction tools created by the Vue team.
  • The advantages are as follows:
    • In the development environment, no packaging operation is required, and it can be cold started quickly.
    • Lightweight and fast Hot Reload (HMR).
    • True on-demand compilation, no longer waiting for the entire application to be compiled.
  • Comparison chart of traditional construction and viteconstruction There are construction tools such as , , and so on, which are still mainstream
    insert image description here
    insert image description here
    at present and relatively immature, but I believe it will become a trend in the future.vitegruntgulpwebpackwebpackvite
  • Create a project using vite
## 创建工程
npm init vite-app my_vite
## 进入工程目录
cd my_vite
## 安装依赖
npm install
## 运行
npm run dev

There is no node_modules dependency package for vitethe created project, so it needs to be installed manually

3. Analysis files

main.js

This is main.js in vue3, and then let's analyze this paragraph

import {
    
     createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
// 引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数
import {
    
     createApp } from 'vue'
import App from './App.vue'

// 创建应用实例对象——app(类似于之前Vue2中的vm,但app比vm更“轻”)
// 这个轻指的是在app身上属性和方法相对于vm少了很多
const app = createApp(App)
// 来输出一下app为什么更轻
console.log(app)
// 挂载
app.mount('#app')

insert image description here

app.vue

<template>
	<img alt="Vue logo" src="./assets/logo.png">
	<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

In vue3, there is no need to add a div root element like vue2

Composition API

1. kicked offsetup

  • Understanding: A new configuration item in Vue3.0, the value is a function.
  • setup is the "stage of performance" of all Composition APIs (composition APIs).
  • The components used in the components: data, methods, etc., must be configured in the setup.
  • Two return values ​​of the setup function:
    1. If an object is returned, the properties and methods in the object can be used directly in the template. (Focus!)
    2. If it returns a rendering function: you can customize the rendering content. (just understand)
  • important point:
  1. Try not to mix with Vue2.x configuration

    • Properties and methods in setup can be accessed in Vue2.x configuration (data, methos, computed...).
    • But Vue2.x configuration (data, methos, computed...) cannot be accessed in setup.
    • If there are duplicate names, setup takes precedence.
  2. setup cannot be an async function, because the return value is no longer an object, but a promise, and the template cannot see the properties in the return object. (You can also return a Promise instance later, but it requires the cooperation of Suspense and asynchronous components)

<template>
  <h1>个人信息</h1>
  <h2>姓名:{
    
    {
    
    name}}</h2>
  <h2>性别:{
    
    {
    
    sex}}</h2>
  <h2>年龄:{
    
    {
    
    age}}</h2>
  <button @click="sayHello">输出</button>
</template>

<script>

export default {
    
    
  name: 'App',
  setup(){
    
    
    // 测试数据暂时不是响应式
    let name = "蜜枣"
    let age = 18
    let sex = "男"
    function sayHello() {
    
    
      alert(`我叫${
      
      name},今年${
      
      age}`)
    }
    return{
    
    
      name,
      age,
      sex,
      sayHello
    }
  }
}
</script>

Please add a picture description

2. refFunction

  • Role: Define a responsive data

  • grammar:const xxx = ref(initValue)

    • Create a reference object (reference object, ref object for short) that contains responsive data.
    • Data manipulation in JS:xxx.value
    • Read data in the template: No need .value, directly:<div>{ {xxx}}</div>
  • Remark:

    • The received data can be: basic type or object type.
    • Basic types of data: Responsiveness relies on class getterand settercompletion (we will see the source code later and you will know).
    • Object type data: internally "rescue" a new function in Vue3.0 - reactivefunction.
<template>
  <h1>个人信息</h1>
  <h2>姓名:{
    
    {
    
    name}}</h2>
  <h2>性别:{
    
    {
    
    sex}}</h2>
  <h2>年龄:{
    
    {
    
    age}}</h2>
  <button @click="sayHello">输出</button>
  <button @click="age++">一年后</button>
</template>

<script>
// 引入ref定义响应式的数据
import {
    
    ref} from "vue"
export default {
    
    
  name: 'App',
  setup(){
    
    
    let name = ref("蜜枣")
    let age = ref(18)
    let sex = ref("男")
    function sayHello() {
    
    
      alert(`我叫${
      
      name.value},今年${
      
      age.value}`)
    }
    return{
    
    
      name,
      age,
      sex,
      sayHello
    }
  }
}
</script>

Ref will return an instance object of RefImpl. Getter and setter are bound to the prototype object to detect data changes. Ref refers to reference, and Impl refers to implement, which is to refer to the implementation object

insert image description here
Please add a picture description

reactivefunction

  • Function: Define an object type of responsive data (do not use it for basic types, but use reffunctions)
  • Syntax: const 代理对象= reactive(源对象)Receive an object (or array) and return a proxy object ( Proxyan instance object, referred to as proxyan object)
  • reactiveReactive data is defined as "deep".
  • The internal Proxyimplementation , and the internal data of the source object is manipulated through the proxy object.
<template>
  <h1>个人信息</h1>
  <h2>姓名:{
    
    {
    
    userInfo.name}}</h2>
  <h2>性别:{
    
    {
    
    userInfo.sex}}</h2>
  <h2>年龄:{
    
    {
    
    userInfo.age}}</h2>
  <h2>职业:{
    
    {
    
    userInfo.type}}</h2>
  <h2>爱好:{
    
    {
    
    userInfo.hobby}}</h2>
  <h2 v-show="userInfo.data">新增data:{
    
    {
    
    userInfo.data}}</h2>
  <button @click="changeUserInfo">修改信息</button>
</template>

<script>
// 引入ref定义响应式的数据
import {
    
    reactive} from "vue"
export default {
    
    
  name: 'App',
  setup(){
    
    
    let userInfo = reactive({
    
    
      name:"蜜枣",
      age:18,
      sex:"男",
      type:"切图仔",
      hobby:["听歌","学习","玩游戏"]
    })
    function changeUserInfo() {
    
    
      userInfo.age = 22
      userInfo.type = "前端工程师"
      userInfo.hobby[0] = "唱歌"
    }
    return{
    
    
      userInfo,
      changeUserInfo
    }
  }
}
</script>

Responsive principle in Vue3.0

Responsiveness of Vue2.x

  • Realization principle
    • Object type: Object.defineProperty()Intercept (data hijacking) by reading and modifying properties.
    • Array type: interception is achieved by overriding a series of methods for updating the array. (The change method of the array is wrapped).
Object.defineProperty(data, 'count', {
    
    
	get () {
    
    }, 
	set () {
    
    }
}
  • There is a problem
    • Use Vue.set, Vue.deleteor vm.$set, vm.$deletethese APIs

Responsiveness of Vue3.0

<template>
  <h1>个人信息</h1>
  <h2>姓名:{
    
    {
    
    userInfo.name}}</h2>
  <h2>性别:{
    
    {
    
    userInfo.sex}}</h2>
  <h2>年龄:{
    
    {
    
    userInfo.age}}</h2>
  <h2>职业:{
    
    {
    
    userInfo.type}}</h2>
  <h2>爱好:{
    
    {
    
    userInfo.hobby}}</h2>
  <h2 v-show="userInfo.data">新增data:{
    
    {
    
    userInfo.data}}</h2>
  <button @click="changeUserInfo">修改信息</button>
  <button @click="addData">增加数据</button>
  <button @click="delHobby">删除数据</button>
</template>

<script>
// 引入ref定义响应式的数据
import {
    
    reactive} from "vue"
export default {
    
    
  name: 'App',
  setup(){
    
    
    let userInfo = reactive({
    
    
      name:"蜜枣",
      age:18,
      sex:"男",
      type:"切图仔",
      hobby:["听歌","学习","玩游戏"]
    })
    function changeUserInfo() {
    
    
      userInfo.age = 22
      userInfo.type = "前端工程师"
      userInfo.hobby[0] = "唱歌"
    }
    function addData(){
    
    
      userInfo.data = 666
    }
    function delHobby(){
    
    
      delete userInfo.data
    }
    return{
    
    
      userInfo,
      changeUserInfo,
      addData,
      delHobby
    }
  }
}
</script>

Please add a picture description

reactiveComparedref

  • Comparison from the perspective of definition data

    • refUsed to define: basic type data .
    • reactiveUsed to define: object (or array) type data .
    • Remarks: refIt can also be used to define object (or array) type data , which will be automatically converted to reactivea proxy object internally .
  • Comparison from a principle point of view

    • refResponsiveness (data hijacking) is achieved through getterAND in the class .setter
    • reactiveProxyResponsive (data hijacking) is achieved by using , and by Reflectmanipulating the data inside the source object.
  • From the point of view of use

    • refDefined data: required for .value operating data , but not required .value for direct reading in the template when reading data .
    • reactiveDefined data: operation data and read data: neither is required .value .

setuptwo points of attention

  • setupTiming of execution
    • beforeCreateDo it once before , thisyes undefined.
  • setupparameters
    • props: The value is an object, including: the properties passed from outside the component and received by the internal declaration of the component.

    • context: context object

      • attrs: The value is an object, including: attributes passed from outside the component but not propsdeclared in the configuration, equivalent to this.$attrs.
      • slots: Received slot content, equivalent to this.$slots.
      • emit: A function that dispatches a custom event, equivalent to this.$emit.
  1. Parent-child component passing value
    Parent component App.vue
<template>
  <Demo msg="Hello World"></Demo>
</template>

<script>
import Demo from './components/Demo.vue'
export default {
    
    
  components: {
    
     Demo },
  name: 'App'
}
</script>

Subgroup Demo.vue

<template>
    <h1>{
    
    {
    
    msg}}</h1>
</template>

<script>
export default {
    
    
    props:["msg"],
    setup(props,context){
    
    
        console.log('---props---',props);
        console.log('---context.attrs---', context.attrs)
    }    
}
</script>
  1. Custom event
    parent component App.vue
<template>
  <Demo @hello="sayHello" msg="hello world"></Demo>
</template>

<script>
import Demo from './components/Demo.vue'
export default {
    
    
  components: {
    
     Demo },
  name: 'App',
  
  setup(){
    
    
    function sayHello(value){
    
    
      alert(`你触发了hello事件,我收到的参数是:${
      
      value}`);
    }
    return{
    
    
      sayHello
    }
  }
}
</script>

Subgroup Demo.vue

<template>
    <div>{
    
    {
    
    msg}}</div>
    <button @click="test">点击触发一下Demo组件的Hello事件</button>
</template>

<script>
export default {
    
    
    props:["msg"],
    emits:["hello"], // 如果不写则控制台会出现警告,如下图
    setup(props,context){
    
    
        console.log('---props---',props);
        console.log('---context.attrs---', context.attrs)

        function test() {
    
    
            context.emit("hello", "Hello world");
        } 

        return{
    
    
            test
        }
    }
    
}
</script>![请添加图片描述](https://img-blog.csdnimg.cn/29d1ca70220b420c8c23e52ad51453e6.gif)

Please add a picture description

  1. slot
<!-- App.vue -->
<template>
  <Demo>
    <div>我是Demo组件的插槽</div>
  </Demo>
</template>

<script>
import Demo from './components/Demo.vue'
export default {
    
    
  components: {
    
     Demo },
  name: 'App'
}
</script>
<!-- Demo.vue -->
<template>
    <slot></slot>
</template>

insert image description here

Computed properties and monitoring

computedfunction

  • computedConsistent with the configuration function in Vue2.x
<template>
  姓:<input type="text" v-model="person.firstNmae">
  <br>
  名:<input type="text" v-model="person.lastName">
  <br>
  <span>全名:{
    
    {
    
    person.fullName}}</span>
  <br>
  <input type="text" v-model="person.fullName">
</template>

<script>
import {
    
     computed, reactive } from '@vue/reactivity';
export default {
    
    
  name: 'App',
  
  setup(){
    
    
    let person = reactive({
    
    
      firstNmae:"张",
      lastName:"三"
    })
    // 计算属性-简写(没有考虑计算属性被修改的情况)
    // 这种情况下去修改计算属性控制台会警告 computed value is readonly
    person.fullName = computed(()=>{
    
    
      return person.firstNmae + '-' + person.lastName
    })
    // 计算属性-完整(考虑读和写的情况)
    person.fullName = computed({
    
    
      get(){
    
    
        return person.firstNmae + '-' + person.lastName
      },
      set(value){
    
    
        const nameArr = value.split("-")
        person.firstName = nameArr[0]
        person.lastName = nameArr[1]
      }
    })
    return{
    
    
      person
    }
  }
}
</script>

watchfunction

  • watchConsistent with the configuration function in Vue2.x

  • Two small "pits":

    • When monitoring reactivethe defined responsive data: oldValueit cannot be obtained correctly, and the deep monitoring is forced to be turned on ( deepconfiguration invalidation).
    • When monitoring reactivea property in the defined reactive data: deepthe configuration is valid.
<template>
  <h2>sum:{
    
    {
    
    sum}}</h2>
  <button @click="sum++">点击+1</button>
  <h2>当前信息:{
    
    {
    
    msg}}</h2>
  <button @click="msg+='~'">修改信息</button>
  <h2>姓名:{
    
    {
    
    person.name}}</h2>
  <h2>年龄:{
    
    {
    
    person.age}}</h2>
  <button @click="person.name+='~'">修改姓名</button>
  <button @click="person.age++">修改年龄</button>
</template>
<script>
import {
    
    reactive,ref,watch} from "vue"
export default {
    
    
	name: 'Demo',
	setup(){
    
    
		let sum = ref(0)
		let msg = ref("你好啊")
		let person = reactive({
    
    
			name:"张三",
			age:20
		})
		//情况一:监视ref定义的响应式数据
		watch(sum,(newValue,oldValue)=>{
    
    
			console.log('sum变化了',newValue,oldValue)
		},{
    
    immediate:true})
		
		//情况二:监视多个ref定义的响应式数据
		watch([sum,msg],(newValue,oldValue)=>{
    
    
			console.log('sum或msg变化了',newValue,oldValue)
		}) 
		
		// 情况三:监视reactive定义的响应式数据的全部属性
		// 		1.注意:此处无法获取正确的oldValue
		// 		2.注意:强制开启深度监听(deep配置失效)
		watch(person,(newValue,oldValue)=>{
    
    
			console.log('person变化了',newValue,oldValue)
		},{
    
    immediate:true,deep:false}) //此处的deep配置无效
		
		// 情况四:监视reactive定义的响应式数据中的某个属性 
		watch(()=>person.name,(newValue,oldValue)=>{
    
    
			console.log('person的name变化了',newValue,oldValue)
		},{
    
    immediate:true,deep:true}) 
		
		//情况五:监视reactive定义的响应式数据中的某些属性
		watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
    
    
			console.log('person的job或者name变化了',newValue,oldValue)
		},{
    
    immediate:true,deep:true})
		
		//特殊情况
		watch(()=>person.job,(newValue,oldValue)=>{
    
    
		    console.log('person的job变化了',newValue,oldValue)
		},{
    
    deep:true}) //此处由于监视的是reactive所定义的对象中的某个属性,所以deep配置有效
		return{
    
    
			sum,
			msg,
			person
		}
	}
}
</script>

watchEffectfunction

  • watchThe routine is: specify not only the attribute of monitoring, but also the callback of monitoring.

  • watchEffectThe routine is: don't specify which attribute to monitor, which attribute is used in the monitoring callback, then monitor which attribute.

  • watchEffectSomething like computed:

    • But computedpay attention to the calculated value (the return value of the callback function), so the return value must be written.
    • And watchEffectmore attention is paid to the process (the function body of the callback function), so there is no need to write the return value.
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
    
    
    const x1 = sum.value
    const x2 = person.age
    console.log('watchEffect配置的回调执行了')
})

life cycle

Please add a picture description

  • The lifecycle hooks in Vue2.x can continue to be used in Vue3.0, but two of them have been renamed:
    • beforeDestroyrename tobeforeUnmount
    • destroyedrename tounmounted

Lifecycle hooks can be used directly in the form of configured items, or in the form of combined APIs, as uniform as possible. Generally speaking, the hooks in the combined API will be executed before the hooks of the configuration items. The name of the hook in the combined API Change

  • Vue3.0 also provides lifecycle hooks in the form of Composition API, and the corresponding relationship with the hooks in Vue2.x is as follows:
    insert image description here

custom hookfunction

  • what is hookit —— It is essentially a function that encapsulates the Composition API used in the setup function.

  • mixinSimilar to that in vue2.x.

  • Advantages of customization hook: Reuse code to make setupthe logic in it clearer and easier to understand.

Create a hooks folder in the src directory, and create a usePoint.js file in the folder to encapsulate the method of point management

import {
    
     reactive } from '@vue/reactivity';
import {
    
     onBeforeMount, onMounted } from '@vue/runtime-core';

export default function(){
    
    
    let point = reactive({
    
    
        x:0,
        y:0
    })
    //鼠标“打点”的方法
    function savePoint(event) {
    
    
        point.x = event.pageX;
        point.y = event.pageY;
        console.log(event.pageX, event.pageY);
    }
    onMounted(()=>{
    
    
        window.addEventListener("click",savePoint)
    })
    onBeforeMount(()=>{
    
    
        window.removeEventListener("click",savePoint)
    })
    
    return point
}

Then introduce this method in the Demo component

<template>
  <h1>当前鼠标的坐标为:X:{
    
    {
    
    point.x}},Y:{
    
    {
    
    point.y}}</h1>
</template>

<script>
import usePoing from "../hooks/usePoint"
export default {
    
    
  name: "Demo",
  setup() {
    
    
    let point = usePoing()
    return {
    
    
        point
    };
  },
};
</script>

toRef

  • Function: Create an refobject whose valuevalue points to an attribute in another object.
  • grammar:const name = toRef(person,'name')
  • Application: When you want to provide a property in the responsive object for external use alone.
  • Extension: Same toRefsas toRefthe function, but multiple refobjects , syntax:toRefs(person)
<template>
  {
    
    {
    
    person}}
  <h1>姓名:{
    
    {
    
    name}}</h1>
  <h1>年龄:{
    
    {
    
    age}}</h1>
  <button @click="name+='!'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <demo></demo>
</template>

<script>
import {
    
     reactive, toRef, toRefs } from '@vue/reactivity';
import Demo from './components/Demo.vue';
export default {
    
    
  components: {
    
     Demo },
  name: 'App',
  setup(){
    
    
    let person = reactive({
    
    
      name:"蜜枣",
      age:18
    })
    return{
    
    
      person,
      // name:toRef(person,"name"),
      // age:toRef(person,"age"),
      ...toRefs(person)
    }
  }
}
</script>

Other Composition APIs

shallowReactiveandshallowRef

  • shallowReactive: Responsive (shallow responsive) that only deals with the outermost properties of the object.

  • shallowRef: Only handle the responsiveness of basic data types, not the responsiveness of objects.

  • When to use it?

    • If there is an object data, the structure is relatively deep, but only the outer attribute changes ===> when changing shallowReactive.
    • If there is an object data, subsequent functions will not modify the properties in the object, but generate new objects to replace ===> shallowRef.

readonlyandshallowReadonly

  • readonly: Make a reactive data read-only (deep read-only).
  • shallowReadonly: Make a reactive data read-only (shallow read-only).
  • Application scenario: When the data is not expected to be modified.

toRawandmarkRaw

<template>
  <input type="text" v-model="keyWord" />
  <h3>{
    
    {
    
     keyWord }}</h3>
</template>

<script>
import {
    
     customRef } from "vue";
export default {
    
    
  name: "App",
  setup() {
    
    
    //自定义一个ref——名为:myRef
    function myRef(value, delay) {
    
    
      let timer;
      // 通过curstomRef去实现自定义
      return customRef((track, trigger) => {
    
    
        return {
    
    
          get() {
    
    
            console.log(`有人从myRef这个容器中读取数据了,我把${
      
      value}给他了`);
            track(); // 通知Vue追踪value的变化(提前和get商量一下,让他认为这个value是有用的)
            return value;
          },
          set(newValue) {
    
    
            console.log(`有人把myRef这个容器中数据改为了:${
      
      newValue}`);
            clearTimeout(timer);
            timer = setTimeout(() => {
    
    
              value = newValue;
              trigger(); // 告诉vue去更新页面
            }, delay);
          },
        };
      });
    }

    // let keyWord = ref('hello') //使用Vue提供的ref
    let keyWord = myRef("hello", 500); //使用自定义的ref

    return {
    
     keyWord };
  },
};
</script>

Please add a picture description

provideandinject

  • Role: Realize communication between ancestor and descendant components

  • Routine: The parent component has a provide option to provide data, and the descendant components have an inject option to start using the data
    insert image description here

In the parent component:

setup(){
    
    
	......
    let car = reactive({
    
    name:'奔驰',price:'40万'})
    provide('car',car) // 给自己的后代组件传递数据
    ......
}

In descendant components:

setup(props,context){
    
    
	......
    const car = inject('car') // 拿到祖先的数据
    return {
    
    car}
	......
}

Responsive Data Judgment

  • isRef: checks if a value is an refobject
  • isReactive: Checks if an object was reactivecreated a reactive proxy
  • isReadonly: Checks if an object is a read-only proxy created by readonly`
  • isProxy: checks if an object reactiveis readonlya proxy created by the or method

V3 new components

Fragment

  • In Vue2: Components must have a root tag
  • In Vue3: Components can have no root tags, and multiple tags will be included in a Fragment virtual element internally
  • Benefits: Reduce label levels, reduce memory usage

Teleport

  • what is Teleportit Teleportis a technique that can move our component htmlstructure to a specified location.

Here is an example to assign a dialog popup window to the body

app.vue

<template>
  <div class="app">
    <h3>我是App组件</h3>
    <Child />
  </div>
</template>

<script>
import Child from "./components/Child";
export default {
    
    
  name: "App",
  components: {
    
     Child },
};
</script>

<style>
.app {
    
    
  background-color: gray;
  padding: 10px;
}
</style>

Child.vue

<template>
  <div class="child">
    <h3>我是Child组件</h3>
    <Son />
  </div>
</template>

<script>
import Son from "./Son";
export default {
    
    
  name: "Child",
  components: {
    
     Son },
};
</script>

<style>
.child {
    
    
  background-color: skyblue;
  padding: 10px;
}
</style>

Sound.view

<template>
  <div class="son">
    <h3>我是Son组件</h3>
    <Dialog />
  </div>
</template>

<script>
import Dialog from "./Dialog.vue";
export default {
    
    
  name: "Son",
  components: {
    
     Dialog },
};
</script>

<style>
.son {
    
    
  position: relative;
  background-color: orange;
  padding: 10px;
}
</style>

Dialog.view

<template>
  <div>
    <button @click="isShow = true">点我弹个窗</button>
     <!-- <teleport to='body'> -->
      <div v-if="isShow" class="mask">
        <div class="dialog">
          <h3>我是一个弹窗</h3>
          <h4>一些内容</h4>
          <h4>一些内容</h4>
          <h4>一些内容</h4>
          <button @click="isShow = false">关闭弹窗</button>
        </div>
      </div>
    <!-- </teleport> -->
  </div>
</template>

<script>
import {
    
     ref } from "vue";
export default {
    
    
  name: "Dialog",
  emits:["isShow"],
  setup(props,context) {
    
    
    console.log(props,context)
    let isShow = ref(false);
    context.emit("isShow",isShow)
    return {
    
     isShow };
  },
};
</script>

<style>
.mask {
    
    
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.5);
}
.dialog {
    
    
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: 300px;
  height: 300px;
  background-color: #eee;
}
</style>

Here you can see that the mask mask layer will be on the descendant components, so you need to use teleportthe label
insert image description here
and then untie the comment of the label in the code teleportto see that the mask mask layer points to the body
insert image description here

Suspense

  • Render some extra content while waiting for asynchronous components, so that the application has a better user experience

  • Steps for usage:

    • Import components asynchronously
import {
    
    defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))

Use Suspensethe wrapper component, and configure it defaultwithfallback

<template>
	<div class="app">
		<h3>我是App组件</h3>
		<Suspense>
			<template v-slot:default>
				<Child/>
			</template>
			<template v-slot:fallback>
				<h3>加载中.....</h3>
			</template>
		</Suspense>
	</div>
</template>

other

Global API transfer

  • Vue 2.x has many global APIs and configurations.
    • For example: registering global components, registering global directives, etc.
//注册全局组件
Vue.component('MyButton', {
    
    
  data: () => ({
    
    
    count: 0
  }),
  template: '<button @click="count++">Clicked {
    
    { count }} times.</button>'
})

//注册全局指令
Vue.directive('focus', {
    
    
  inserted: el => el.focus()
}

These APIs have been adjusted in Vue3.0:

  • Adjust the global API, namely: Vue.xxx to the application instance (app)
2.x Global API (Vue) 3.x instance API (app)
Vue.config.xxxx app.config.xxxx
Vue.config.productionTip remove
Vue.component app.component
Directive.view app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties

other changes

  • dataOptions should always be declared as a function
  • Transitional class name changes
  • Vue2.x writing method:
.v-enter,
.v-leave-to {
    
    
  opacity: 0;
}
.v-leave,
.v-enter-to {
    
    
  opacity: 1;
}
  • Vue3.x writing method:
.v-enter-from,
.v-leave-to {
    
    
  opacity: 0;
}

.v-leave-from,
.v-enter-to {
    
    
  opacity: 1;
}
  • Removed askeyCode a modifier for and also no longer supportsv-onconfig.keyCodes
  • remove v-on.nativemodifier
    • Bind event in parent component
<my-component
  v-on:close="handleComponentEvent"
  v-on:click="handleNativeClickEvent"
/>
  • Declare custom events in subcomponents
<script>
  export default {
    
    
    emits: ['close']
  }
</script>
  • Remove Filters filter
    While this seems convenient, it requires a custom syntax that breaks the assumption that expressions inside curly braces are "just JavaScript", which has not only a learning cost, but an implementation cost as well! It is recommended to replace filters with method calls or computed properties.

Guess you like

Origin blog.csdn.net/m0_48995032/article/details/120862982