Vue3 型特性介绍

简介: patch flag 的强大之处在于,当你的 diff 算法走到 _createBlock 函数的时候,会忽略所有的静态节点,只对有标记的动态节点进行对比,而且在多层的嵌套下依然有效。

19d62a8aaf18406c89941dbe720364b4.png

vue2


基于Object.defineProperty()实现


vue3 基于Proxy


proxy与Object.defineProperty(obj, prop, desc)方式相比有以下优势:


  1. 丢掉麻烦的备份数据
  2. 省去for in 循环
  3. 可以监听数组变化
  4. 代码更简化


Vue2  这个对数组并不友好所以vue2 没有绑定数组


let data={name: ' peak ' ,age: 10}
参数一:劫持的对象
//参数二:劫持的属性
I
//参数三:给属性添加的set, get方法
Object.defineProperty(data,'name ' ,{
get: ()=>{console.log('访问了name属性');,
set: (newvalue)=>{data[name]=newvalue;console.log('设置了name属性')}
})
console.log(100)
data.name=20


看一段类似于vue2的源码


       class Observer {
            constructor(data) {
                this._data = data
                this.walk(this._data)
            }
            walk(data) {
                Object.keys(data).forEach(key => {
                    this.defineReactive(data, key, data[key])
                })
            }
            defineReactive(data, key, value) {
                if (value.constructor.name === "Object") {
                    this.walk(value)
                }
                console.log(value)
                Object.defineProperty(data, key, {
                    get() {
                        return value
                    },
                    set(newVal) {
                        value = newVal
                    }
                })
            }
        }


Vue3 proxy省去了for in 并且支持绑定数组


   var obj = {};
     var obj1 = new Proxy(obj, {
         // target就是第一个参数obj, receive就是返回的obj(返回的proxy对象)
         get: function (target, key, receive) {
             // 返回该属性值
             return target[key];
         },
         set: function (target, key, newVal, receive) {
             // 执行赋值操作
             target[key] = newVal;
             document.getElementById('text').innerHTML = target[key];
         }
     })


Vue3 优化Vdom


patch flag 优化静态树


当我们创建了一个动态的 dom 元素:


<span>Hello world!</span>
<span>Hello world!</span>
<span>Hello world!</span>
<span>Hello world!</span>
<span>{{msg}}/span>
<span>Hello world!</span>
<span>Hello world! </span>


Vue3 编译后的 Vdom 是这个样子的:


export function render(_ctx,_cache,$props,$setup,$data,$options){return (_openBlock(),_createBlock(_Fragment,null,[
_createvNode( "span", null,"Hello world ! "),
_createvNode( "span",null,"Hello world! "),
_createvNode( "span",null,"Hello world! "),
_createvNode( "span", null,"Hello world! "),
_createVNode("span", null,_toDisplaystring(_ctx.msg),1/* TEXT */),
_createvNode( "span", null,"Hello world! "),
_createvNode( "span", null,"Hello world! ")],64/*STABLE_FRAGMENT */))


新增了 patch flag 标记


TEXT = 1 // 动态文本节点
CLASS=1<<1,1 // 2//动态class
STYLE=1<<2,// 4 //动态style
PROPS=1<<3,// 8 //动态属性,但不包含类名和样式
FULLPR0PS=1<<4,// 16 //具有动态key属性,当key改变时,需要进行完整的diff比较。
HYDRATE_ EVENTS = 1 << 5,// 32 //带有监听事件的节点
STABLE FRAGMENT = 1 << 6, // 64 //一个不会改变子节点顺序的fragment
KEYED_ FRAGMENT = 1 << 7, // 128 //带有key属性的fragment 或部分子字节有key
UNKEYED FRAGMENT = 1<< 8, // 256 //子节点没有key 的fragment
NEED PATCH = 1 << 9, // 512 //一个节点只会进行非props比较
DYNAMIC_SLOTS = 1 << 10 // 1024 // 动态slot
HOISTED = -1 // 静态节点
BALL = -2


我们发现创建动态 dom 元素的时候,Vdom 除了模拟出来了它的基本信息之外,还给它加了一个标记: 1 /* TEXT */


这个标记就叫做 patch flag(补丁标记)


patch flag 的强大之处在于,当你的 diff 算法走到 _createBlock 函数的时候,会忽略所有的静态节点,只对有标记的动态节点进行对比,而且在多层的嵌套下依然有效。


尽管 JavaScript 做 Vdom 的对比已经非常的快,但是 patch flag 的出现还是让 Vue3 的 Vdom 的性能得到了很大的提升,尤其是在针对大组件的时候。


Vue3 Fragment


上一篇文章讲过了可以同时支持多个根节点


<template>
  <div>12</div>
  <div>23</div>
</template>


还有一个就是支持jsx


render


    render() {
        return (
            <>
                {this.visable ? (
                    <div>{this.obj.name}</div>
                ) : (
                    <div>{this.obj.price}</div>
                )}
                <input v-model={this.val}></input>
                {[1, 2, 3].map((v) => {
                   return <div>{v}-----</div>;
                })}
            </>
        );
    },


Vue3 Tree shaking


简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码


在Vue2中,无论我们使用什么功能,它们最终都会出现在生产代码中。主要原因是Vue实例在项目中是单例的,捆绑程序无法检测到该对象的哪些属性在代码中被使用到


而Vue3源码引入tree shaking特性,将全局 API 进行分块。如果你不使用其某些功能,它们将不会包含在你的基础包中


就是比如你要用watch 就是import {watch} from 'vue' 其他的computed 没用到就不会给你打包减少体积


Vue 3 Composition Api


也就是 Setup 上一篇文章已经讲完了


Vue3 食用方法_qq1195566313的博客-CSDN博客

目录
相关文章
|
3天前
|
缓存 JavaScript 前端开发
Vue 3的响应式系统
【5月更文挑战第31天】Vue 3的响应式系统
8 1
|
3天前
|
JavaScript 前端开发 API
vue2 /vue3【nextTick】的使用方法及实现原理,一文全搞懂!
vue2 /vue3【nextTick】的使用方法及实现原理,一文全搞懂!
|
3天前
|
JavaScript 开发者
[vue2/vue3] -- 深入剖析v-model的原理、父子组件双向绑定的多种写法
[vue2/vue3] -- 深入剖析v-model的原理、父子组件双向绑定的多种写法
[vue2/vue3] -- 深入剖析v-model的原理、父子组件双向绑定的多种写法
|
3天前
|
JavaScript API
vue3父子组件相互调用方法详解
vue3父子组件相互调用方法详解
|
10天前
|
JavaScript API
Vue3 基础语法
该内容介绍了Vue项目的创建和Vue3的语法、响应式API、生命周期、组件通信及跨组件通信方法。包括使用`npm init vue@latest`创建项目,`npm install`初始化,Vue3的`setup`语法,`reactive`、`ref`、`computed`和`watch`的用法,生命周期图解,以及父子组件间的数据传递。此外,还提到了Vue3中使用`provide`和`inject`进行跨层数据传递,以及通过Pinia库进行状态管理。
36 0
Vue3 基础语法
|
14天前
|
JavaScript 定位技术 API
在 vue3 中使用高德地图
在 vue3 中使用高德地图
23 0
|
14天前
vue3 键盘事件 回车发送消息,ctrl+回车 内容换行
const textarea = textInput.value.textarea; //获取输入框元素
29 3
|
16天前
|
JavaScript 前端开发 CDN
vue3速览
vue3速览
29 0
|
17天前
|
设计模式 JavaScript 前端开发
Vue3报错Property “xxx“ was accessed during render but is not defined on instance
Vue3报错Property “xxx“ was accessed during render but is not defined on instance
|
17天前
|
JavaScript 前端开发 安全
Vue3官方文档速通(下)
Vue3官方文档速通(下)
28 0