Vue3学习笔记

11 篇文章 0 订阅
本文分析了Vue3中Proxy与definedProperty的差异,讨论了Vue3的setup方法、响应式数据创建、生命周期更新、父子组件通信方式的变化,以及diff算法和插槽、样式穿透和vue-router的升级。
摘要由CSDN通过智能技术生成
  • Proxy和definedProperty对比
  1. Proxy 作为新标准将受到浏览器厂商重点持续的性能优化。
  2. Proxy 不兼容IE,也没有 polyfill, defineProperty 能支持到IE9。
  3. Proxy 能观察的类型比 defineProperty 更丰富。
  4. Object.definedProperty 是劫持对象的属性,新增元素需要再次 definedProperty。而 Proxy 劫持的是整个对象,不需要做特殊处理。
  5. 使用 defineProperty 时,我们修改原来的 obj 对象就可以触发拦截,而使用 proxy,就必须修改代理对象,即 Proxy 的实例才可以触发拦截。
  6. defineProperty只能监听某个属性,不能对全对象监听,可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)。
  7. proxy 可以监听数组,不⽤再去单独的对数组做特异性操作,通过Proxy可以直接拦截所有对象类型数据的操作,完美⽀持对数组的监听。
  • vue2是把数据放入data中;
  • vue3就需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。
  • vue3 ref 跟 reactive 都是响应系统的核心方法,作为整个系统的入口。

vue3使用以下三个步骤来建立响应数据:

  1. 从vue引入reactive;( import {ref , reactive} from ‘vue’ //按需引入)
  2. 使用reactive() 方法来声明数据为响应性数据;(const _name= reactive({a:1,b:2}))
  3. 使用setup()方法来返回我们的响应性数据,从而template可以获取这些响应性数据。
  • 生命周期对比
vue2                                         vue3
beforeCreate                            ->   setup()
Created                                 ->   setup()
beforeMount                             ->   onBeforeMount
mounted                                 ->   onMounted
beforeUpdate                            ->   onBeforeUpdate
updated                                 ->   onUpdated
beforeDestroyed                         ->   onBeforeUnmount
destroyed                               ->   onUnmounted
activated                               ->   onActivated
deactivated                             ->   onDeactivated

vue2是选项式API: data,computed,methods等;

data() { return {}; }, methods:{ }

vue3是组合式API:数据和⽅法都定义在setup中,并统⼀进⾏return{}

vue3:setup(props,context){ console.log(‘props’,props)return{} }
  • 父子传参对比
  1. vue3:setup()函数接收两个参数:props、context(包含attrs、slots、emit);
  2. vue3:因为setup函数中,props是响应式得,当传入新的prop时,它将会被更新,所以不能使用es6解构,因为它会消除prop得响应性。在组合式API中,如果想在子组件中用其它变量接收props的值时需要使用toRef将props中的属性转为响应式。
  • 给父组件传值emit对比
vue2:this.$emit()
vue3:setup(props,context){context.emit()}
  • 组件通信对比

在这里插入图片描述

  • attrs和listeners对比
  1. vue2:子组件使用$attrs可以获得父组件除了props传递的属性。
  2. vue2:子组件使用$listeners可以获得父组件(不含.native修饰器的)所有v-on事件监听器。
  3. vue3:attrs不仅可以获得父组件传来的属性也可以获得父组件v-on事件监听器。
  • v-for和v-if的优先级对比
  1. vue2:v-for的优先级高于v-if,可以放在一起使用,但增加性能开销。
  2. vue3:v-if的优先级高于v-for,一起使用会报错;通过在外部添加一个标签,将v-for放在外层。
  • diff算法对比

vue2:diff算法遍历每一个虚拟节点,进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方。用patch记录的消息去更新dom。缺点:比较每一个节点,而对于一些不参与更新的元素,进行比较是有点消耗性能的。
vue3:在初始化的时候会给每一个虚拟节点添加一个patchFlags,是一种优化的标识,只会比较patchFlags发生变化的节点,进行视图更新,而对于patchFlags没有变化的元素作静态标记,在渲染的时候直接使用。

  • 插槽方式对比
    vue2:匿名插槽
//子组件:
<div>
	<slot></slot>
</div>
//父组件:
<child>
  <span>我是插槽插入的内容</span>
</child>

vue2:具名插槽

//子组件:
<div>
  <slot name="person"></slot>
</div>
//父组件:
<child>
  <span slot="person">插槽插入的内容</span>
</child>

vue2:作用域插槽:父组件模板的所有代码都在父级作用域内编译;子组件模板的所有代码都在子级作用域内编译。可以在父组件中使用slot-scope 特性从子组件获取数据。

<div>
  <slot :data="data"></slot>
</div>
//父组件:
<child>
  <span slot-scope="data">插槽插入的内容</span>
</child>

vue3:匿名插槽和vue2一样。
具名插槽:使用v-slot:

//子组件:
<div>
  <slot name="person"></slot>
</div>
//父组件:
<child>
  <template v-slot:person>
    <span>插槽插入的内容</span>
  </template>
</child>

vue3作用域插槽:

//子组件:
<div>
  <slot :data="data"></slot>
</div>
//父组件:
<child>
  <span #data>插槽插入的内容</span> 或者 <span #default="{data}">插槽插入的内容</span>
</child>

总结:
具名插槽使用方式不同:vue2使用slot=‘’,vue3使用v-slot:‘’
作用域插槽使用方式不同:vue2中在父组件中使用slot-scope=“data"从子组件获取数据,vue3中在父组件中使用 #data 或者 #default=”{data}"获取。

  • 样式穿透对比

vue2

/deep/ 样式名{}
::v-deep 样式名{}

vue3

:deep (样式名{})
::v-deep(样式名{})
  • vue-router对比

Vue3的路由管理器在处理动态路由、嵌套路由和异步组件等方面提供了更多的便利。

// vue2写法
import Vue from 'vue';
import Router from 'vue-router';
import routes from '/xx/xx';
Vue.use(Router)
const router = new Router({
	mode: 'history',
	routes
})
export default router;

//vue3写法
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    // path: '*',  // vue2  使用*,vue3 使用报错
    // path: '/:pathMatch(.*)',  // vue3 使用带有自定义regexp的参数定义
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]
const router = createRouter({
  history: createWebHashHistory(),
  routes   // 注释掉routes之后 编译会报错
})
export default router;
import router from '@/router'
...
  mounted() {
  // vue3特性 -> 不匹配的命名路由 既不会推送到not-found -> 也不会推送到 / 
    router.push({name: 'errorName'})
  }
获取路由参数(通过query/params方式传递的)
//vue2
const id = this.$route.query.id
//const id = this.$route.params.id

//vue3需要先引入useRoute,执行useRoute()
import { useRoute } from 'vue-router';
const route = useRoute();
const id = route.query.id
//const id = route.params.id
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**之火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值