Vue2和Vue3的区别

官方文档

官方:Vue3迁移指南

非官方迁移指南:https://vue3.zcopy.site/guide/migration/introduction.html

总结

兼容性

Vue2 支持 IE11,Vue3不支持

更快

  • 基于Proxy 的响应式
  • 重写 Diff 算法
    • 静态标记,通过 静态树提升、静态属性 减少 patch 过程,提高性能
  • 优化 slots 的生成
  • v-if 优先级比 v-for 高

更小

通过Tree Shaking 摇树 优化核心库体积。

在保持代码运行结果不变的前提下,去除无用(dead code)的代码。

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

而Vue3源码引入tree shaking特性,将全局 API 进行分块。如果你不使用其某些功能,它们将不会包含在你的基础包中。就是比如你只使用 watch import {watch} from 'vue' 其他的 computed 没用到就不会打进包里,从而减少包体积

更友好

跨平台:编译器核心和运行时核心与平台无关,使得 Vue 更容易与任何平台(Web、
Android、iOS)一起使用

更易使用和维护性

  • Composition API(组合式 API ) 教程

  • 支持 TypeScript,编辑器能提供强有力的类型检查和错误及警告

  • 独立的响应化模块,许多包被解耦,更加模块化
    在这里插入图片描述

  • 更好的调试支持

  • 单文件组件组合式 API 语法糖 (<script setup>

  • Fragments 片段,支持多个根节点 v3 迁移指南

移除

非兼容性

  • Vue实例移除 propsData(propsData 选项) v3 迁移指南
  • 生命周期钩子 beforeDestroydestroyed 已经分别被重命名为 beforeUnmountunmounted
  • $listeners 事件侦听变成 $attrs 的一部分 v3 迁移指南
  • $attrs 包含 class & style v3 迁移指南
  • v-model 为Vue2 v-model.sync 的结合 v3 迁移指南
  • 在同一元素上使用的 v-ifv-for 优先级已更改 v3 迁移指南
  • v-bind 合并行为 (v-bind="object" 现在排序敏感) v3 迁移指南

扩展

基于 Proxy 的响应式系统

Vue 2 基于 Object.defineProperty() 的 getter 和 setter。Vue 3 使用 ES2015 Proxy 作为 其观察机制。

使用proxy带来如下变化:

  • 组件实例初始化的速度提高 100%
  • 使用 Proxy 节省以前一半的内存开销,加快速度,但是存在低浏览器版本的不兼容
  • 为了继续支持 IE11,Vue 3 将发布一个支持旧观察者机制和新 Proxy 版本的构建

在这里插入图片描述

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

  • proxy直接监听整个对象。对象响应式将无需遍历对象属性,并逐一进行监听。
  • 可以监听对象动态新增和删除。不再需要通过额外的API,Vue.set、Vue.observerable、Vue.delete 来实现响应式。
  • 可以监听数组变化
    • 不再像Vue2一样重写数组的7个修改方法 push、pop、shift、unshift、splice、sort、reverse。
    • 还可以监听数组的索引和 length 属性;
  • 代码更简化
// 丢掉麻烦的备份数据
let proxyObj = new Proxy(obj,{
  get : function (target,prop) {
    return prop in target ? target[prop] : 0
  },
  set : function (target,prop,value) {
    target[prop] = 888;
  }
})

虚拟 DOM 重写

期待更多的编译时提示来减少运行时开销,使用更有效的代码来创建虚拟节点。

组件快速路径+单个调用+子节点类型检测

  • 跳过不必要的条件分支

  • JS 引擎更容易优化

在这里插入图片描述

静态标记

静态标记减少新旧节点对比过程

静态树提升(Static Tree Hoisting)

使用静态树提升,这意味着 Vue 3 的编译器将能够检测到什么是静态的,然后将其提升,从而降低了渲 染成本。

  • 跳过修补整棵树,从而降低渲染成本

  • 即使多次出现也能正常工作

在这里插入图片描述

静态属性提升

使用静态属性提升,Vue 3 打补丁时将跳过这些属性不会改变的节点。
在这里插入图片描述

优化 slots 的生成

vue3 中可以单独重新渲染父级和子级

  • 确保实例正确的跟踪依赖关系

  • 避免不必要的父子组件重新渲染

在这里插入图片描述

使用

写法

Vue2
<script>
export default {
	inheritAttrs: false,
  
  props: {
    value: string
  },
  data() {
    return {}
  },
  computed: {},
  watch: {},
  
  // lifecycle
  beforeCreate() {},
  created() {},
  beforeMount() {},
  mounted() {},
  beforeUpdate() {},
  updated() {},
  beforeDestroy() {},
  destroy() {},
  activated() {},
  deactivated() {},
  
  // 方法
  methods: {}
}
</script>
Vue3 选项式
<script>
export default {
	inheritAttrs: false,
  
  props: {
    modelValue: string,
    modelModifiers: {
      default: () => ({})
    }
  },
  emits: [],
  data() {
    return {}
  },
  setup(props, ctx) {
    const {attrs, emit, slot} = ctx
  },
  
  computed: {},
  watch: {},
  
  // lifecycle
  beforeCreate() {},
  created() {},
  beforeMount() {},
  mounted() {},
  beforeUpdate() {},
  updated() {},
  beforeDestroy() {},
  destroy() {},
  activated() {},
  deactivated() {},
  
  // 方法
  methods: {}
}
</script>
Vue3 组合式
<script>
export default {
	inheritAttrs: false
}
</script>
<script setup>
import {ref, reactive, useAttrs, computed, watch, onMounted, }

const attrs = useAttrs()
onMounted(() => {
  console.log('attrs', attrs)
})

const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

const count = ref(0)
function add() {
  count.value++
}
const double = computed(() => {
  return count.value * 2
})


const obj = reactive({
  title: '',
  age: 18,
  info: {}
})

// 监听多个值
watch(
  [count, () => obj.title, () => obj.age],
  ([newCount, oldCount], [newTitle, oldTitle], [newAge, oldAge]) => {},
  {
    immediate: true,
    deep: true,
    flush: 'post'
  }
)
watch(
  obj, // 直接深层监听obj
  ([newObj, oldObj]) => {} // 注意 newObj 与 oldObj 一致
)
watch(
  () => obj.info, // 只有在 obj.info 被替换时解发,使用 deep: true 解决
  ([newInfo, oldInfo]) => {},
  { deep: true } // 直接深层侦听如0bj
)
  
watchEffect(() => {})
watchPostEffect(() => {})
  
  
// 模板引用
const inputRef = ref(null)
const inputsRef = ref([])

// 子组件使用 <script setup> ,父组件无法直接通过ref访问子组件的所有属性和方法,需要子组件通过  defineExpose 暴露属性和方法才可以访问到
definedExpose([count, add])
</script>

Composition API 解决什么问题

Vue2.0 中,随着功能的增加,组件变得越来越复杂,越来越难维护。且 Vue2.0 缺少一种较为简洁的低成本的机制来完成逻辑复用,虽然可以使用 minxis 完成逻辑复用,但是当 mixin 变多的时候,data、computed 或者 method 将难以对应来源于哪个 mixin,使得类型推断难以进行。另外,多个 mixin 的 property 存在变量命名冲突的风险。

所以 Composition API 的出现,主要是也是为了解决 Option API 带来的问题。

Option API 选项式 对比 Composition API 组合式

帮你在 Vueconf 上收获更大的一篇文章

杨村长 视频教程

Option API:

  • 代码碎片化,代码量大
  • 可复用性不高
  • 可读性差,可维护性差

Composition API :

  • 更好的代码组织
  • 更好的逻辑提取和复⽤性
  • 逻辑分明 可维护性 高
  • Hook:基于函数组合的 API,可以将一个功能的所有状态、方法、都封装到一个函数里面,方便统一管理

在这里插入图片描述

SFC 中组合式 API 语法糖 <script setup>

Composition API 的写法在该语法糖都支持,除了 name 和 inheritAttrs

注意项: inheritAttrs: false 需要在 export default 中写,无法写在语法糖中

优点:

  • 更灵活
  • 逻辑复用
  • 更好的类型推导
  • 更小的生产包体积

改变:

  • 没有 this
  • 没有响应式数据 data,改为响应式 API:ref、reactive、shallowRef、shallowReactive
  • 写法更改:
    • 组件通信:props、emits、attrs、依赖注入 Provide/inject
    • 响应式数据、computed、watch
    • 生命周期、method
    • nextTick 等

SFC 中的 <style scoped><style>

插槽内容(新增)

::v-slotted(.bar) {}:slotted(.bar) {}

注意:是在子组件中设置

编译结果: .bar[data-v-xxx-s] {}

后缀-s 表示只针对 slot 插槽内容

优先级:

  • .bar[data-v-xxx] {} 优先于 .bar[data-v-xxx-s] {}
  • 父组件设置插槽内容样式优先于子组件设置插槽内容样式
一次性全局规则(新增)

Vue3:
通过 ::v-global(.bar) {}:global(.bar) {} 设置全局样式。
编译结果:.bar {}
优先级:.bar {} 优先于 .bar[data-v-xxx] {}

Vue2 :
通过 <style></style> 来设置全局样式的。
缺点:这是永久修改,切换其他页面,样式为修改后的样式。

深度选择器(修改)

Vue3:
使用 ::v-deep(.bar) {}:deep(.bar) {} 深度修改样式

编译结果: [data-v-xxx] .bar {}

优先级:

  • [data-v-xxx] .bar {} 优先于 .bar[data-v-xxx] {}
  • deep 优先于 scoped

Vue2:
使用 ::v-deep .bar {}:deep .bar {} 深度修改样式
不推荐 /deep/ .bar {}>>> .bar {}

SFC 中状态驱动的 CSS 变量( style 中支持 v-bind

注意:

element-plus 的 Dialog 和 Drawer 中的样式不支持 v-bind

写法:

<script setup>
const theme = {
  color: red,
};
</script>

<style>
.bar {
  color: v-bind("theme.color");
}
</style>
  • 29
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值