Vue组件封装和使用

185 阅读3分钟

封装Vue组件的原则及技巧

根据组件单向数据流和和事件通信机制,需要由子组件通过事件通知父组件,并在父组件中修改原始的prop数据,完成状态的更新,(如购物车的商品数量counter组件)。在子组件中修改父组件的数据的场景在业务中也是比较常见的,那么有什么办法可以“绕开”单向数据流的限制呢? v-model 解决 可以拆解为 props: value 和 events: input

像v-model的这种,用提供了手动挂载的方法$mount

本文整理了几种实现Vue组件的技巧

  • 以counter计数器组件为例,展示了通过v-model语法糖同步父子组件的方式
  • 以表单验证组件为例,展示了通过获取子组件的实例来封装组件的方法
  • 以全局弹窗组件为例,展示了手动mount挂载组件封装API组件的方式
  • 以throttle节流组件为例,展示了在vue中一种实现高阶组件的方式

Vue父子组件生命周期执行顺序是什么?

programs.wiki/wiki/vue-pa…

流程问题

Figure 27. Previewing the timing breakdown of a request

#Timing breakdown phases explained

Here's more information about each of the phases you may see in the Timing tab:

  • Queueing. The browser queues requests when:

    • There are higher priority requests.
    • There are already six TCP connections open for this origin, which is the limit. Applies to HTTP/1.0 and HTTP/1.1 only.
    • The browser is briefly allocating space in the disk cache
  • Stalled. The request could be stalled for any of the reasons described in Queueing.

  • DNS Lookup. The browser is resolving the request's IP address.

  • Initial connection. The browser is establishing a connection, including TCP handshakes/retries and negotiating an SSL.

  • Proxy negotiation. The browser is negotiating the request with a proxy server.

  • Request sent. The request is being sent.

  • ServiceWorker Preparation. The browser is starting up the service worker.

  • Request to ServiceWorker. The request is being sent to the service worker.

  • Waiting (TTFB) . The browser is waiting for the first byte of a response. TTFB stands for Time To First Byte. This timing includes 1 round trip of latency and the time the server took to prepare the response.

  • Content Download. The browser is receiving the response, either directly from the network or from a service worker. This value is the total amount of time spent reading the response body. Larger than expected values could indicate a slow network, or that the browser is busy performing other work which delays the response from being read.

  • Receiving Push. The browser is receiving data for this response via HTTP/2 Server Push.

  • Reading Push. The browser is reading the local data previously received.

通信问题

vue中组件之间的通信方式?

父子组件

  • 父子props去传
  • 子父通过$emit派发自定义事件
  • 在子代通过$parent去访问老爹
  • 老爹中通过ref去访问孩子(存在暴露子组件问题,要注意用的场景)
  • 爷孙透传$attrs

兄弟组件

  • 采用桥接模式:parent.parent.root,手写eventbus
  • vuex

跨层级的关系

  • eventbus
  • vuex
  • provide+inject

vue被废除的组件

  • 在 3.x 中,childrenproperty已被移除,且不再支持。如果你需要访问子组件实例,建议使用children property 已被移除,且不再支持。如果你需要访问子组件实例,建议使用 refs
  • onon,off 和 $once 实例方法已被移除,组件实例不再实现事件触发接口,如eventbus。我们可以替换成外部使用,例如 mitt 或 tiny-emitter

在绝大多数情况下,不鼓励使用全局的事件总线在组件之间进行通信。虽然在短期内往往是最简单的解决方案,但从长期来看,它维护起来总是令人头疼。根据具体情况来看,有多种事件总线的替代方案:

  • Prop 和事件应该是父子组件之间沟通的首选。兄弟节点可以通过它们的父节点通信。
  • Provide 和 inject 允许一个组件与它的插槽内容进行通信。这对于总是一起使用的紧密耦合的组件非常有用。
  • provide/inject 也能够用于组件之间的远距离通信。它可以帮助避免“prop 逐级透传”,即 prop 需要通过许多层级的组件传递下去,但这些组件本身可能并不需要那些 prop。
  • Prop 逐级透传也可以通过重构以使用插槽来避免。如果一个中间组件不需要某些 prop,那么表明它可能存在关注点分离的问题。在该类组件中使用 slot 可以允许父节点直接为它创建内容,因此 prop 可以被直接传递而不需要中间组件的参与。
  • 全局状态管理,比如 Vuex

Provide / Inject

为了增加 provide 值和 inject 值之间的响应性,我们可以在 provide 值时使用 ref 或 reactive。

provide/inject实现原理总结

通过上面的分析,可以得知provide/inject实现原理还是比较简单的,就是巧妙地利用了原型和原型链进行数据的继承和获取。provide API调用设置的时候,设置父级的provides为当前provides对象原型对象上的属性,在inject获取provides对象中的属性值时,优先获取provides对象自身的属性,如果自身查找不到,则沿着原型链向上一个对象中去查找。

拓展:Object.create原理

Object.myCreate = function (proto, propertyObject = undefined) {
    if (propertyObject === null) {
        // 这里没有判断propertyObject是否是原始包装对象
        throw 'TypeError'
    } else {
        function Fn () {}
        // 设置原型对象属性
        Fn.prototype = proto
        const obj = new Fn()
        if (propertyObject !== undefined) {
            Object.defineProperties(obj, propertyObject)
        }
        if (proto === null) {
            // 创建一个没有原型对象的对象,Object.create(null)
            obj.__proto__ = null
        }
        return obj
    }
}