Vue3学习笔记 - composition api

前言

在上篇笔记中 《vue3带来了什么?》中,聊到的其中一个改变是,vue3中带来一组全新的api,composition api,该 api 集中,可以更好的封装代码块逻辑,而不需要分散到每个option api 的钩子函数中。

function useMousePosition() {
  const position = Vue.reactive({
    x: 0,
    y: 0
  });

  const update = e => {
    position.x = e.pageX;
    position.y = e.pageY;
  };
  Vue.onMounted(() => {
    window.addEventListener("mousemove", update);
  });
  Vue.onUnmounted(() => {
    window.removeEventListener("mousemove");
  });

  return position;
}

const app = Vue.createApp({
  setup() {
    const position = useMousePosition();
    return {
      position
    };
  }
})

app.mount('#app')

就像例子中所示的,编写一个随着鼠标移动,将鼠标坐标显示在页面上

我们可以通过composition api 的方式,封装一个函数,后面我们只要对该事件处理函数进行维护和供其他函数所使用,这很大的提高了代码的可维护性。

而 vue2 中的option api将代码分割到各个钩子函数中,导致大型页面和组件后期代码臃肿,难于阅读的问题也得以解决。

今天,对 vue3 中的 composition api 学习过程中,做个简单 demo 记录。

生命周期钩子函数

composition api 中的生命周期,跟option api 中的生命周期函数类似,只是在命名中有所小改动,基本都在原有钩子命名中加了 on 为前缀

因为setup会在created后执行,所以composition里没有create相关的生命周期。

选项式 API Hook inside setup
beforeCreate Not needed*
created Not needed*
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered

reactive/toRefs/ref

reactive

接收一个对象作为参数,并将该参数转换成响应式对象(Proxy)返回。

function useMousePosition() {
  const position = Vue.reactive({
    x: 0,
    y: 0
  });

  const update = e => {
    position.x = e.pageX;
    position.y = e.pageY;
  };
  Vue.onMounted(() => {
    window.addEventListener("mousemove", update);
  });
  Vue.onUnmounted(() => {
    window.removeEventListener("mousemove");
  });

  return position;
}

const app = Vue.createApp({
  setup() {
    const position = useMousePosition()
    return {
      position
    };
  }
})

app.mount('#app')

toRefs

接收一个参数,将参数的所有属性转换成响应式数据。在 reactive 中,我们返回了positon 对象,当在setup 钩子中如果使用直接解构的方式,解构出来的是数据,不具备响应式。

Vue3学习笔记 - composition api_第1张图片

通过babel中 es6 转换成 es5 可以发现,解构是重新定义了两个变量,进行赋值。所以解构出来的数据,不是 Proxy 对象。

因此,vue3还提供了一个 toRefs 函数。

function useMousePosition() {
  const position = Vue.reactive({
    x: 0,
    y: 0
  });

  const update = e => {
    position.x = e.pageX;
    position.y = e.pageY;
  };
  Vue.onMounted(() => {
    window.addEventListener("mousemove", update);
  });
  Vue.onUnmounted(() => {
    window.removeEventListener("mousemove");
  });

  return Vue.toRefs(position);
}

const app = Vue.createApp({
  setup() {
    const {x, y} = useMousePosition();
    return {
      x,
      y
    };
  }
})

app.mount('#app')

将对象传入 toRefs 中,将会把对象中的所有属性都转换成 Proxy 对象,这样在解构后,让属性保持响应式作用。

ref

reactive 函数是将对象转换成 Proxy 对象,而 ref 是接收一个参数,将参数转换成 Proxy 对象,参数可为基础类型和引用类型,当参数为引用类型时, ref 内部还是会调用 reactive 函数,将其转为Proxy对象。

function useCount() {
  const count = Vue.ref(0)
  return {
    count,
    increase: () => {
      count.value++
    }
  }
}

const app = Vue.createApp({
  setup() {
    return {
      ...useCount()
    };
  }
})

app.mount('#app')

computed

计算属性,跟 option 中的使用方式类似, 接收一个函数,函数中返回计算后的结果。

function useCount() {
  const count = Vue.ref(0)
  return {
    count,
    increase: () => {
      count.value++
    }
  }
}

const app = Vue.createApp({
  setup() {
    const {count, increase} = useCount()
    
    const computedCount = Vue.computed(() => count.value + 2);
    
    return { count, increase, computedCount };
  }
})

app.mount('#app')

例子中,couputedCount 依赖于 count 的更新,所以当 count 更新时,couputedCount也会同样被更新。

watch

watch有三个参数

第一个参数:要监听的数据

第二个参数:监听到数据变化后执行的函数,这个函数有两个参数,分别为新值和旧值

第三个参数:选项对象,deep和immediate

watch的返回值

取消监听函数

使用方法跟 Option Api 中的Watch一致

WatchEffect

是watch函数的简化版本,也用来监视数据变化

接受一个函数作为参数,监听函数内响应式数据的变化

const app = Vue.createApp({
  setup() {
    const count = Vue.ref(0)
    const stop = Vue.watchEffect(() => {
      console.log(count.value);
    })
    return {
      count,
      stop,
      increase: () => {
        count.value++
      }
    };
  }
})

app.mount('#app')

你可能感兴趣的:(vue,typescript,vue.js,typescript,javascript)