Vue3 学习总结(复述)

vite原理

webpack

在使用vue2开发大项目时,每次启动需要耗时很久,这是因为Webpack需要预先将所有的模块文件进行编译打包。如果项目过大会导致时间变长,很影响到开发效率。
在这里插入图片描述

vite

vite基于esbuild开发的新一代前端打包工作,它拥有极快的打包速度,依赖于esm,也是作为了vue3或者其他框架的构建工具。
vite在启动时并不会把所有的依赖构建一遍,而是根据所访问的页面,动态编译。比如:我访问app.vue文件,那么它并不会把整个项目重新编译,而是只对app.vue这个文件依赖进行重新编译。如下图
在这里插入图片描述
而webpack则会全部进行打包成chunk
在这里插入图片描述

vue3 效率提升

编译提升

静态节点会被提升(没有动态绑定的内容)
在这里插入图片描述
在这里插入图片描述
属性也会被提升
在这里插入图片描述

预字符串化

当编译器遇见大量的静态节点,就不构建createvNode了(影响效率),它会将整体节点形成一个字符串。
在这里插入图片描述
当编译器遇到大量连续的静态内容,会直接将其编译为一个普通字符串节点

<div class=\"logo\"><h1>logo</h1></div><ul class=\"nav\"><li><a href=\"\">menu</a></li><li><a href=\"\">menu</a></li><li><a href=\"\">menu</a></li><li><a href=\"\">menu</a></li><li><a href=\"\">menu</a></li></ul><div class=\"user\"></div>
事件缓存
<button @click="count++">{{ count }}</button>
// vue2
render(ctx){
  return createVNode("button", {
    onClick: function($event){
      ctx.count++;
    }
  })
}

// vue3
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  return _openBlock(), _createElementBlock(
    "button",
    {
      onClick: _cache[0] || (_cache[0] = ($event) => $setup.count++)
    },
    _toDisplayString($setup.count),
    1
    /* TEXT */
  );
}
Block tree

vue2新旧DOM树对比时是逐层对比,这样会影响效率,而vue3是将把动态节点收集起来, 只对比动态的节点,静态的不进行对比。

<form>
  <div>
    <label>账号:</label>
    <input v-model="user.loginId" />
  </div>
  <div>
    <label>密码:</label>
    <input v-model="user.loginPwd" />
  </div>
</form>

在这里插入图片描述

Patch flag

patch flag是vue3确定哪些是动态的节点

 <div class="menu-bar-container">
  <div class="logo">
    <h1>logo</h1>
  </div>
  <ul class="nav">
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
  </ul>
  <div class="user">
    <span>{{ user.name }}</span>
  </div>
</div>
const _hoisted_2 = /* @__PURE__ */ _createStaticVNode('<div class="logo"><h1>logo</h1></div><ul class="nav"><li><a href="">menu</a></li><li><a href="">menu</a></li><li><a href="">menu</a></li><li><a href="">menu</a></li><li><a href="">menu</a></li></ul>', 2);
const _hoisted_4 = { class: "user" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  return _openBlock(), _createElementBlock("div", _hoisted_1, [
    _hoisted_2,
    _createElementVNode("div", _hoisted_4, [
      _createElementVNode(
        "span",
        null,
        _toDisplayString($setup.user.name),
        1
        /* TEXT */
      )
    ])
  ]);
}

标注着1为动态节点,这样只对比内容

为什么vue3去掉了Vue构造函数
  1. vue2在拥有多个vue实例时,所挂载的插入会在vue构造函数之上,并不是在实例之上,这样一来,在打包的时候体积会很大
  2. vue构造函数集成了太多功能,无法进行tree shaking,vue3则把这些功能分离出去。
  3. Vue构造函数既是一个应用又是一个组件,没有进行分开,所以vue3通过createApp创建应用,如果需要其他插入在后面use进行。
响应式变化
  1. vue3不再使用Object.defineProperty的方式定义完成数据响应式,而是使用Proxy。
  2. 除了Proxy本身效率比Object.defineProperty更高之外,由于不必递归遍历所有属性,而是直接得到一个Proxy。所以在vue3中,对数据的访问是动态的,当访问某个属性的时候,再动态的获取和设置,这就极大的提升了在组件初始阶段的效率。
  3. 同时,由于Proxy可以监控到成员的新增和删除,因此,在vue3中新增成员、删除成员、索引访问等均可以触发重新渲染,而这些在vue2中是难以做到的。

vue3 模板变化

写法一 通过旧方法实现组件双向绑定

父组件
如何后面不跟:默认为modelValue,可以往后追加修饰符,如:title.trim

<template>
  <!--<check-sel :modelValue="sel" @update:modelValue="sel = $event"></check-sel>-->
  <!--简写-->
  <check-sel v-model="sel" v-model:title.trim="title"></check-sel>
</template>

子组件

  1. 使用props接收父组件传递过来的参数。并绑定到子组件模板中
  2. 使用emit(“update:title”) 将值传递给父组件形成双向绑定
  3. 使用setup第二个参数 ctx.attrs 获取修饰符参数
<template>
  <div class="check-editor">
    <div class="check-editor-inner">
      <div class="checkbox" @click="handleChecked" :class="{ checked: modelValue }"></div>
      <input type="text" @input="handleTitle($event)" :value="title" class="editor" />
    </div>
  </div>
</template>
<script>
export default {
  props: {
    title: {
      type: String
    },
    modelValue: {
      type: Boolean
    }
  },
  setup(prop, ctx) {
    console.log('ctx:', ctx)
    console.log('prop:', prop)

    const { titleModifiers } = ctx.attrs //获取修饰符参数

    const handleTitle = (event) => {
      let value = event.target.value
      if (titleModifiers && titleModifiers.trim) {
        value = value.replace(/ /g, '')
      }
      ctx.emit('update:title', value)
    }

    const handleChecked = () => {
      ctx.emit('update:modelValue', !prop.modelValue)
    }

    return {
      handleTitle,
      handleChecked
    }
  }
}
</script>
写法二

父组件同上
子组件
使用defineModel方法实现双向绑定

<script setup>
const emit = defineEmits('update:modelValue')

const sel = defineModel()
const [title, titleModifiers] = defineModel('title', {
  set(value) {
    if (titleModifiers.trim) {
      return value.replace(/ /g, '')
    }
    return value
  }
})

const handleChecked = () => {
  emit('update:modelValue', !sel.value)
}
</script>
key

● 当使用进行v-for循环时,需要把key值放到中,而不是它的子元素中
● 当使用v-if v-else-if v-else分支的时候,不再需要指定key值,因为vue3会自动给予每个分支一个唯一的key
即便要手工给予key值,也必须给予每个分支唯一的key,不能因为要重用分支而给予相同的 key

Fragment

vue3现在允许组件出现多个根节点

vue3 组件变化

  1. defineAsyncComponent 异步组件
  2. Suspance
  3. teleport(将节点插入到顶层)

reativite api

入口

composition api

入口

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值