Home  >  Article  >  Web Front-end  >  Let’s talk about how Vue2 developers can quickly get started with Vue3

Let’s talk about how Vue2 developers can quickly get started with Vue3

青灯夜游
青灯夜游forward
2022-07-26 19:57:092725browse

How to get started with Vue3 quickly? The following article will compare Vue2 and Vue3, and introduce how Vue2 developers can quickly get started with Vue3. I hope it will be helpful to everyone!

Let’s talk about how Vue2 developers can quickly get started with Vue3

The author was a Vue2 React developer before. Since the project needs to be directly started with Vue3, I will learn it quickly and compare some differences related to React. Prerequisites for reading: Have already started the development of Vue2, the main issues discussed in this article:

  • The new features of Vue3

  • Some differences between Vue2 and Vue3

  • How Vue2 developers can quickly get started with Vue3

  • ##A simple comparison between Vue3 and React

  • Writing component library using Vue3

(Learning video sharing:

vue video tutorial)

Vue2 vs Vue3


1. To put it simply,


    Vue2 only supports
  • single node, and Vue3 template supports multiple nodes, similar to react fragments
  • Changes are basically in the script (Option api -> Composition api). You will no longer see this filling the screen! ! !
  • style supports
  • v-bind
  • Proxy instead of defineProperty
    • defineProperty cannot implement deep monitoring of array objects,
    • Proxy is The latest API of the browser is more powerful.
    • IE is no longer supported. If Vue2 wants to enjoy some of the updates brought by Vue3, you may consider upgrading to
    • Vue2.7 version
  • TypeScript support
    • Vue2 uses Facebook's
    • Flow and cannot perfectly support TypeScript (so the technology selection in the early stage of the project is very important)
    • Vue3 TypeScript
    • Completely rewritten, providing the same TS support as React
  • New ecology
    • Basically still the set of vue peripherals that accompany the Vue3 upgrade, but state management is recommended , changed from the original Vuex to
    • Pina
    • brand new
    • vite support, including vitest, etc., the official provides more peripheral tools
  • Other optimizations
    • Better performance, smaller sizeNeedless to say
    • Event listening cache , similar to the function bound by @click, no need to create multiple times, placed in the cacheHandler cache
    • SSR: Vue 3.0 will directly convert static tags into text. Compared with React, it will first JSX is converted into virtual DOM, and then the virtual DOM is converted into HTML. Vue3 is much faster.
    • Use Hooks Give up the past mixins and use Hooks to solve some shortcomings of past mixins

2. Source code

I don’t know much about it, I will add more later

Optimization of the diff algorithm

    is no longer the same as vue2, which completely compares two virtual DOM trees. Vue3 uses a
  • combination of dynamic and static methods to optimize diff performance
  • The static template is analyzed through the compilation stage, and the Block tree is compiled and generated. The update performance is related to
  • the overall size of the template =》and the amount of dynamic content, which is a very big performance breakthrough. Lifting the code outside of the render function avoids re-creating these objects on every render, greatly improving memory usage and reducing the frequency of garbage collection.

Source code management

    vue2
  • poly-repo
      The source code of vue2.x is hosted in src directory, and then split according to functions into compiler (code related to template compilation), core (general runtime code independent of the platform), platforms (platform-specific code), server (code related to server-side rendering), sfc (.vue single file parsing related code), shared (shared tool code) and other directories
  • vue3
  • mono-repo
      package can
    • Use independently of vue.js, so that if the user wants to use the reactive style of vue3.0, they can depend on reactive independently instead of relying on the entire vue.js, reducing the size of the reference package. But vue2.x cannot do this.
  • Source code structure comparison

Let’s talk about how Vue2 developers can quickly get started with Vue3

New API


What is a composite API? - Vue official

  • Solved the problem of difficulty in maintenance caused by optionsApi when components were too long in the past
  • The logic can be reused as a whole
  • All APIs are introduced by import, which is very important for Tree - Shaking is very friendly, the function is not used, it will be cleaned up when packaging, reducing the size of the package

1, setup

  • new setup Options are executed before the component is created. Once props is parsed, it will be used as the entry point to the composite API.
  • Can be used as the beforeCreate and create life cycle of Vue2
  • Can be written directlyawait syntax
  • Used directly in SFC single file component&lt ;script lang="ts" setup> is enough, or you can use
    <script>
    const result = await Http.get(&#39;/getUserInfo&#39;)
    </script>
    // or 
    export default {
      setup(props, context) {
        // Attribute (非响应式对象,等同于 $attrs)
        console.log(context.attrs)
        // 插槽 (非响应式对象,等同于 $slots)
        console.log(context.slots)
        // 触发事件 (方法,等同于 $emit)
        console.log(context.emit)
        // 暴露公共 property (函数)
        console.log(context.expose)
      }
    }
2, ref

in combination with export default

  • ref is used to create responsive data of basic type
  • The value is called by default in template to display data, and .value needs to be used in script to call
  • It’s similar to react ref, react uses .current to get the value, and vue3 uses .value.
  • The essence of Ref is created through Reactive. Ref(10)=>Reactive({value:10})

has a certain mental burden, especially It is also clearly stated that direct access in script will not be supported. The reason is that the basic type cannot intercept its changes. Of course, some people have proposed using syntax similar to new String('foo') to wrap the basic type. Personally, I feel that it would be good to directly use the supported reactive

Related api

  • Ref ts definition import { type Ref } from 'vue';
  • isRef Determine whether it is a ref object. Generally, variables created by ref, toRef, toRefs
  • toRefs Deconstruct the reactive object into a single responsive object
  • shallowRef Create a ref that tracks changes in its own .value, but does not make its value responsive. It is simply understood as creating a non-responsive variable with the same structure as ref
  • triggerRef Force update page DOM. Even if the created ref has not changed, if you want to update the dom, you can use
  • customRef to provide get and set similar to computed, and you can customize the ref behavior

3. reactive

  • reactive is used to create responsive data of reference type
  • The essence of reactive is to parse the data at each layer The responsiveness of the proxy object
  • reactive is recursive by default. If the value of a certain layer is changed, it will be called recursively to re-render the dom.
  • Deconstruct directly, the responsiveness will be lost, and it needs to be wrapped with toRefs. Directly changing the reference address of the reference type will also result in loss of responsiveness

Related api

  • readonly Change the value of reactive It is read-only
  • shallowReactive It can only respond to shallow data. If it is deep data, it will only change the value but not the view
import { reactive, toRefs } from 'vue'

const book = reactive({
  author: 'Vue Team',
  year: '2020',
  title: 'Vue 3 Guide',
  description: 'You are reading this book right now ;)',
  price: 'free'
})

let { author, title } = toRefs(book)

title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref
console.log(book.title) // 'Vue 3 Detailed Guide'

4. Life cycle

There is not much difference. Use setup as created, and treat the rest as renamed

<script>
import { onMounted } from &#39;vue&#39;;

const getUserInfo = () => {
  console.log(&#39;获取用户信息&#39;);
};
onMounted(getUserInfo);
</script>

Let’s talk about how Vue2 developers can quickly get started with Vue3

5、watch & watchEffect

watch

  • 功能和vue2一致
  • watch(监听参数,变化回调,配置参数)
  • 注意监听对象的单个属性:watch(() => articleInfo.author, (newVal) => {}),第一个参数为箭头函数返回要监听的目标属性
import { ref, reactive, watch } from 'vue'

const counter1 = ref(0)
const counter2 = ref(0)
// 监听多个
watch([counter1, counter2], (newValue, oldValue) => {
  console.log('The new counter1 value is: ' + counter1.value)
  console.log('The new counter2 value is: ' + counter2.value)
})

const obj = reactive({
  name: 'JJ',
  age: 18
})
// 深度监听对象
watch(obj, (newValue, oldValue) => {
  console.log('The new obj value is: ' + obj.value)
}, {
   deep: true,
   immediate: true
})
// watch监听单个属性
watch(() => obj.name, (newValue, oldValue) => {
  console.log('The new obj value is: ' + obj.value)
}, {
   deep: true,
   immediate: true
})

watchEffect

  • 类似React useEffect,但是不需要写依赖项,只要我们回调中引用了 响应式的属性
  • 和watch的区别:
    • 同一个功能的两种不同形态,底层的实现是一样的
    • watch 可以获取到新值与旧值(更新前的值),而 watchEffect 是拿不到的。
    • watch - 显式指定依赖源,watchEffect - 自动收集依赖源
    • watchEffect 在组件初始化的时候就会执行一次用以收集依赖,watch指定了依赖,所以不需要。
    • 可以理解为watchEffect 就是配置了{ immediate: true } 的watch
  • 使用场景:antfu小哥:推荐在大部分时候用 watch 显式的指定依赖以避免不必要的重复触发,也避免在后续代码修改或重构时不小心引入新的依赖。watchEffect 适用于一些逻辑相对简单,依赖源和逻辑强相关的场景(或者懒惰的场景 )。
const stopWatch = watchEffect(
  (oninvalidate): void => {
    oninvalidate(() => {
      console.log("前置校验函数");
    });
    // 引用了响应式的属性 count
    console.log("watchEffect count变化", count.value);
  },
  {
    // 副作用刷新时机 flush 一般使用post
    // 可选:pre(组件更新前执行)/sync(强制效果始终同步触发)/post(组件更新后执行)
    flush: "post",
    // 开发调试
    onTrigger() {
      console.log("开发调试");
    },
  }
);

6、computed

  • 更加灵活,可以在定义响应式变量时声明
  • 作用和vue2无差异
import { ref, computed } from 'vue'

const counter = ref(0)
const twiceTheCounter = computed(() => counter.value * 2)
// get set写法
const plusOne = computed({
  get: () => counter.value + 1,
  set: (val) => {
    counter.value = val - 1
  },
})

plusOne.value = 1
console.log(counter.value) // 0

counter.value++
console.log(counter.value) // 1
console.log(twiceTheCounter.value) // 2

组件


1、异步组件

  • 通过进行引入defineAsyncComponent
  • 可配合Suspense 进行更多操作,可用于loading和骨架屏相关,和react Suspense基本一致。不过react Suspense基本一致这个属性都不太好用,vue的不清楚实际场景咋样
// template
<suspense>
  <template>
    <asynccomponent></asynccomponent>
  </template>

  <template>
    <div>loading...</div>
  </template>
</suspense>

// script
const AsyncComponent = defineAsyncComponent(() => import('./asyncComponent.vue'))

2、Teleport传送组件

Teleport 是一种能够将我们的模板渲染至指定DOM节点,不受父级style、v-show等属性影响,但data、prop数据依旧能够共用的技术;类似于 React 的 Portal。之前写react是不怎么用这个属性,vue3这个估计也没多大用。

主要解决的问题 因为Teleport节点挂载在其他指定的DOM节点下,完全不受父级style样式影响

to 属性 插入指定元素位置,body,html,自定义className等等

<teleport>
    <loading></loading>
</teleport>

3、keep-alive缓存组件

  • 作用和vue2还是一样的,生命周期名称变了
  • 初次进入时:onMounted> onActivated
  • 退出后触发 deactivated
  • 再次进入:只会触发 onActivated

4、组件通信

defineXxxx

defineXxxx 无需import即可直接使用

  • defineProps 代替过去的props
  • defineEmits 代替过去的$emit
  • defineOptions 自定义一些组件属性,比如组件名称(需要插件支持)
  • defineComponent 用于render函数、TSX、IDE提醒等
  • defineExpose 子组件声明的数据,暴露给父组件直接用

provide/inject

和vue2一致

vuex & pina

两者用法,除了pina没有Mutations,差别不大。但是官方推荐的东西,自然有它的各种优点

  • Vuex: State、Gettes、Mutations(同步)、Actions(异步)
  • Pinia: State、Gettes、Actions(同步异步都支持)
  • Vuex4 用于 Vue3 ,Vuex3 用于 Vue2
  • Pinia2.x 即支持 Vue2 也支持 Vue3

TS支持


  • 可以让写react的兄弟,快速上手写vue3
  • react中 {{}} => {}

  • 兼容的指令:v-model,v-if,v-show
import { ref } from 'vue'
let v = ref<string>('')
const renderDom = () => {
    return (
        
           <input>
           <div>
               {v.value}
           </div>
        >
    )
}
export default renderDom</string>

插件


1、开源插件

unplugin-auto-import/vite

无需导入xxx,import { reactive,ref } from "vue";,只需要用即可

unplugin-vue-define-options

自定义组件名称,需要引入插件unplugin-vue-define-options,并在vite中配置

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import DefineOptions from 'unplugin-vue-define-options/vite';

export default defineConfig({
  plugins: [vue(), DefineOptions()],
});

不使用插件,也可以通过多写一个script标签来单独写options

<script>
    export default {
        name: "TButton",
    };
</script>
<script>
  defineOptions({
    name: &#39;TButton&#39;,
  });
</script>

2、vscode插件

volar vscode

  • vetur只支持vue2,volar只支持vue3,两者冲突。
  • 建议禁用vetur,格式化代码使用prettier,本地使用volar做代码高亮。
  • 或者通过项目配置,指定相关插件配置

Let’s talk about how Vue2 developers can quickly get started with Vue3

指令


1、v-model

  • 底层语法糖时间改变,之前vue2是update:input,vue3 是update:modelValue
  • 支持多个v-model
  • 支持自定义修饰符
  • 弃用.sync等

2、自定义指令

生命周期(和vue3一致)

  • created 元素初始化的时候
  • beforeMount 指令绑定到元素后调用 只调用一次
  • mounted 元素插入父级dom调用
  • beforeUpdate 元素被更新之前调用
  • update 这个周期方法被移除 改用updated
  • beforeUnmount 在元素被移除前调用
  • unmounted 指令被移除后调用 只调用一次

自定义拖拽指令v-move

  • 比如这个v-move 封装自定义拖拽指令
import { Directive } from "vue";
const vMove: Directive = {
  mounted(el: HTMLElement) {
    let moveEl = el.firstElementChild as HTMLElement;
    const mouseDown = (e: MouseEvent) => {
      //鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离
      console.log(e.clientX, e.clientY, "-----起始", el.offsetLeft);
      let X = e.clientX - el.offsetLeft;
      let Y = e.clientY - el.offsetTop;
      const move = (e: MouseEvent) => {
        el.style.left = e.clientX - X + "px";
        el.style.top = e.clientY - Y + "px";
        console.log(e.clientX, e.clientY, "---改变");
      };
      document.addEventListener("mousemove", move);
      document.addEventListener("mouseup", () => {
        document.removeEventListener("mousemove", move);
      });
    };
    moveEl.addEventListener("mousedown", mouseDown);
  },
};

Hook


用了react hook的人都知道很香,vue3支持这个相当不错,能解决很多业务场景的封装

1、自定义Hook

可以当做mixins写

// useWindowResize
import { onMounted, onUnmounted, ref } from "vue";

function useWindowResize() {
  const width = ref(0);
  const height = ref(0);
  function onResize() {
    width.value = window.innerWidth;
    height.value = window.innerHeight;
  }
  onMounted(() => {
    window.addEventListener("resize", onResize);
    onResize();
  });
  onUnmounted(() => {
    window.removeEventListener("resize", onResize);
  });
  
  return {
    width,
    height
  };
}

export default useWindowResize;

2、hook库

3、react vs vue3

Let’s talk about how Vue2 developers can quickly get started with Vue3

结语


  • Vue3 的依赖追踪是全自动的,不需要担心传了错误的依赖数组给 useEffect/useMemo/useCallback 从而导致回调中- 使用了过期的值

  • Vue3 Hook也没React Hook那么多限制,后续用用看怎么样

  • 个人比较喜欢SFC语法,html、js、css分离开

笔者vue3也刚用不久,如有错误,还请兄弟们指出

本文所有demo都在该仓库中JJ-UI 一款Vue3组件库,参考大佬文章刚刚搭建好,后续会基于这个架子开发自己的vue3组件库

Let’s talk about how Vue2 developers can quickly get started with Vue3

【相关视频教程推荐:vuejs入门教程web前端入门

The above is the detailed content of Let’s talk about how Vue2 developers can quickly get started with Vue3. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete