Vue3 Oncreated

Posted on  by admin

Vue3 新特性

在 vue3 的 script 中不再使用 data 和 methods ,而是使用 setup() 方法. ref, computed 等都是属于 composition API. reactive 可以将需要导出的数据都包裹在一个对象中,而不是单独存在. 同时, vue3 还支持直接新增 data 中的数据以及修改 data 中数组和对象的每一项,这样的修改也是响应式的。.

在旧的 beforeCreate 钩子函数之后和 created 的钩子函数之前立即调用 setup 方法。因此,我们不再需要这两个钩子,我们可以简单地将本应有的代码放在 setup() 方法中。.

5、 Watch 侦听变化

此外,还有 9 个旧的生命周期函数可以在 setup() 中使用,使用前必须先导入. 由于将代码都写入 setup() 会使代码过于冗余和复杂,故对多次需要使用的代码实现模块化.

src / hooks / useMousePosition.ts. 使用 defineComponent 能够让传入的对象获得类型以及能够获得自动提示.

4、生命周期钩子

有时在组件中需要用到弹窗时,将弹窗的代码全部写到层层嵌套的组件中,不太符合逻辑也不太方便查看。使用Teleport 能将组件的内容挂在到其他组件上.

可以使用 onErrorCaptured() 生命周期函数监听网络请求的错误.

在讲解数据请求前,我看先看看 setup() 方法,组合 API 需要通过 setup() 方法来启动,setup() 返回的数据可以在模板内使用,可以简单理解为 Vue 2 里面 data() 方法返回的数据,不同的是,返回的数据需要先经过 reactive() 方法进行包裹,将数据变成响应式。

9、 emits向父组件触发事件

在 Vue 2 中,我们请求数据时,通常需要将发起请求的代码放到某个生命周期中(createdmounted)。在 setup() 方法内,我们可以使用 Vue 3 提供的生命周期钩子将请求放到特定生命周期内,关于生命周期钩子方法与之前生命周期的对比如下:

可以看到,基本上就是在之前的方法名前加上了一个 on,且并没有提供 onCreated 的钩子,因为在 setup() 内执行就相当于在 created 阶段执行。下面我们在 mounted 阶段来请求数据:

最后效果如下:

鼠标追踪器

Hacker News 的查询接口有一个 query 参数,前面的案例中,我们将这个参数固定了,现在我们通过响应式的数据来定义这个变量。

现在我们在输入框修改,就能触发 state.query 同步更新,但是并不会触发 fetch 重新调用,所以我们需要通过 watchEffect() 来监听响应数据的变化。

由于 watchEffect() 首次调用的时候,其回调就会执行一次,造成初始化时会请求两次接口,所以我们需要把 onMounted 中的 fetchData 删掉。

watchEffect() 会监听传入函数内所有的响应式数据,一旦其中的某个数据发生变化,函数就会重新执行。如果要取消监听,可以调用 watchEffect() 的返回值,它的返回值为一个函数。下面举个例子:

当我们在输入框输入 "vue3" 后,就不会再发起请求了。

3、reactive 的使用

现在有个问题就是 input 内的值每次修改都会触发一次请求,我们可以增加一个按钮,点击按钮后再触发 state.query 的更新。

可以注意到 button 绑定的 click 事件的方法,也是通过 setup() 方法返回的,我们可以将 setup() 方法返回值理解为 Vue2 中 data() 方法和 methods 对象的合并。

原先的返回值 state 变成了现在返回值的一个属性,所以我们在模板层取数据的时候,需要进行一些修改,在前面加上 state.

7、defineComponent 的使用

作为强迫症患者,在模板层通过 state.xxx 的方式获取数据实在是难受,那我们是不是可以通过对象解构的方式将 state 的数据返回呢?

答案是『不可以』。修改代码后,可以看到页面虽然发起了请求,但是页面并没有展示数据。

state 在解构后,数据就变成了静态数据,不能再被跟踪,返回值类似于:

为了跟踪基础类型的数据(即非对象数据),Vue3 也提出了解决方案:ref()

上面为 Vue 3 的官方案例,ref() 方法返回的是一个对象,无论是修改还是获取,都需要取返回对象的 value 属性。

我们将 state 从响应对象改为一个普通对象,然后所有属性都使用 ref 包裹,这样修改后,后续的解构才做才能生效。这样的弊端就是,state 的每个属性在修改时,都必须取其 value 属性。但是在模板中不需要追加 .value,Vue 3 内部有对其进行处理。

有没有办法保持 state 为响应对象,同时又支持其对象解构的呢?当然是有的,Vue 3 也提供了解决方案:toRefs()toRefs() 方法可以将一个响应对象变为普通对象,并且给每个属性加上 ref()

6、模块化

通常,我们发起请求的时候,需要为请求添加 Loading 和 Error 状态,我们只需要在 state 中添加两个变量来控制这两种状态即可。

同时在模板使用这两个变量:

展示 Loading、Error 状态:

useURLLoader

用过 umi 的同学肯定知道 umi 提供了一个叫做 useRequest 的 Hooks,用于请求数据非常的方便,那么我们通过 Vue 的组合 API 也可以抽象出一个类似于 useRequest 的公共方法。

接下来我们新建一个文件 useRequest.js

然后在 App.vue 中引入:

当前的 useRequest 还有两个缺陷:

  1. 传入的 url 是固定的,query 修改后,不能及时的反应到 url 上;
  2. 不能自动请求,需要手动调用一下 run 方法;

经过修改后,我们的逻辑就变得异常简单了。

当然,这个 useRequest 还有很多可以完善的地方,例如:不支持 http 方法修改、不支持节流防抖、不支持超时时间等等。最后,希望大家看完文章后能有所收获。