vue3 学习笔记

174 阅读3分钟

vue3比vue2🈶什么优势

  1. 性能更好
  2. 体积更小
  3. 更好的TS支持
  4. 更好的代码组织 composition api带来的好处
  5. 更好的逻辑抽离 -> hooks
  6. 更多新功能

描述vue3生命周期

在vue3中既支持vue2的生命周期又支持vue3的生命周期,不同的地方是将vue2中的beforeDestroy和destroyed换成了beforeUnMount和unmounted。在compsition api中setup将相当于beforeCreate和created,所有钩子函数都写在setup里面,需要从vue中导出。

如何看待composition api和options api

composition api优势: 1) 更好的代码组织 2) 更好的逻辑复用 3) 更好的类型推导 composition api是为了解决复杂业务逻辑而设计的 compsosition api就像Hooks在react中的地位

如何理解ref、toRef 和 toRefs

ref: 生成值类型的响应式数据; 可用于模板和reactive; 用 .value修改值; reactive: 生成对象类型的响应式数据 使用: 1) 用reactive做对象的响应式,用ref做值类型的响应式; 2) setup中返回toRefs(state),或者toRef(state, 'xxx'); 3) ref的变量命名都用xxxRef; 4) 合成函数返回响应式对象时,使用toRefs 深入: 为何需要Ref?为何需要.value? 1、返回值类型的数据 会丢失响应式, -> vue3中响应式是基于proxy实现的,而值类型的数据无法实现代理 2、在setup、computed、合成函数中 都有可能返回值类型 ref是一个对象(不丢失响应式),value存储值;通过.value属性的get和set实现响应式

为何需要toRef、toRefs?
  在不丢失响应式的情况下,把对象数据 ```分解/扩散```
  针对的是响应式数据而非普通对象
  notify:不创造响应式、而是延续响应式

模拟computed实现
  function computed(fn) {
    let value = 0;

    setTimeout(() => {
      value = fn()
    }, 1500)

    return value
  }

  <!-- ref是一个对象的优势 -->
  function computed(fn) {
    let ref = {
      value: null
    };

    setTimeout(() => {
      ref.value = fn()
    }, 1500)

    return ref
  }

vue3升级了哪些重要的功能

createApp、emits属性、生命周期、多事件、fragment、移除.sync、异步组件的写法、移除filter、teleport、suspense、composition api

composition api如何实现代码逻辑复用

  import { ref, onMounted, onUnmounted } from 'vue'


  function useMousePosition() {
    let x = ref(0)
    let y = ref(0)

    const update = (e) => {
      x.value = e.pageX
      y.value = e.pageY
    }

    onMounted(() => {
      window.addEventListener("mousemove", update)
    })

    onUnmounted(() => {
      window.removeEventListener('mousemove', update)
    })

    return {
      x,
      y
    }
  }

  export default useMousePosition

vue3 如何实现响应式

vue2使用Object.defineProperty实现响应式 一次性深度监听,无法监听数组和新增、删除属性,所以重写了数组原型上的方法,有Vue.set和Vue.delete

vue3使用Proxy实现响应式,解决了上述问题,但是低版本浏览器无法兼容proxy,还是会自动降级到vue2的处理方法,且proxy无法被polyfill

// const data = {
//   name: 'phil',
//   age: '25'
// }

const data = ['a', 'b', 'c']

const proxyData = new Proxy(data, {
  get(target, key, receiver) {
    const ownKeys = Reflect.ownKeys(target)

    if(target.includes(key)) {
      console.log('target get', key);
    }

    const result = Reflect.get(target, key, receiver)
    return result
  },

  set(target, key, value, receiver) {
    
    if( value === target[key] ) {
        return true
    }
    const result = Reflect.set( target, key, value, receiver )
    console.log('target set', key, value);
    return result
  },

  deleteProperty(target, key, receiver) {
    const result = result.deleteProperty(target, key, receiver)

    console.log('result', result);
    return result
  }
})

watch和watchEffect的区别是什么?

1)两者都可监听data属性变化 2)watch需要明确监听哪个属性 3)watchEffect会根据其中的属性,自动监听其变化

setup如何获取组件实例

在composition api中是没有this的,可以通过getCurrentInstance获取当前组件实例 const instance = getCurrentInstance() onMounted(() => { console.log('this', instance.data.name); })

vue3为何比vue2快?

patchflag

编译模板的时候,给动态节点做标记
标记分为不同的类型:TEXT/PROPS/CLASS
diff算法时,可以区分静态节点、以及不同类型的动态节点。

hoistStatic

将静态节点的定义提升到副作用域、缓存起来
多个相邻的静态节点 会被合并起来 -> 用空间换取时间

cacheHandler: 缓存事件

SSR优化:静态节点不经过vdom,直接渲染

tree-shaking:用到什么才导入相应的api,没用到的不导入。

Vite是什么?

为什么快?开发环境使用ES6module,无需打包----非常快;生产环境使用rollup,并不会快很多