vue的一些不常用的方法

294 阅读3分钟

好事总会发生在下个转弯。希望你的愿望都能一一实现。

本文纯属个人理解,学习记录知识的笔记,如有错误请指出,我会及时改正谢谢!!

一、slot插槽

定义:slot其实我理解的就是一个在组件中占位的作用,当使用slot标签时,会将标签中的内容替换slot标签中的内容,通过插槽可以增加组件的扩展性

slot的使用

1.默认使用

默认插槽: 子组件使用slot标签进行占位,父组件中引用对应的子组件时,如果没有往slot标签内传入内容则会展示slot中的默认内容,如果父组件有传入则会展示父组件传值的内容

具名插槽: 子组件在使用slot标签进行占位时,可以给其增加一个name属性

例如

<header>
  <slot name="header"></slot>
</header>

父组件在使用子组件时使用v-slot:“slot的name”中写入要传入的slot的值

<template v-slot:header>
  <h1>Here might be a page title</h1> 
</template>

slot的实现原理

slot其实返回的是VNode的函数(是Vue组件要渲染到页面上需要经过的一个过程)

补充: vue中组件要渲染到页面上需要经过templete -> render function -> VNode ->DOM的过程

下面手写一个slot的渲染函数:

function renderSlot(name, fallback, props, bindObject) {
    // 获取插槽内容函数
    var scopedSlotFn = this.$scopedSlots[name]
    var nodes
    // 如果存在插槽渲染函数,则执行函数返回node节点如果没有就使用默认值
    nodes = scopedSlotFn(props) || falllback;
    return nodes
}

scopedSlots这个方法是用来啊递归解析各个节点获取slot

function resolveSlots(children, context) {
    if (!children || !children.length) return {}
    var slots ={}
    for (var i = 0, l = children.length; i++) {
        var child = children[i]
        var data = child.data
        if (data && data.attrs && data.attrs.slots) {
            delete data.attrrs.slot;
        }
        if (data && data.attrs && data.attrs.slot) {
            delete data.attrs.slot
        }
        if ((child.context === context || child.fnContext === context) && data && data.slot !== null) {
            // slot为具名插槽则拿对应的名字作为key
            var name = data.slot
            var slot = (slots[name] || (slots[name] = []))
            if (child.tag === 'template') {
                slot.push.apply(slot, child.children || [])
            } else {
                slot.push(child)
            }
        } else {
            // 如果没有就默认是default
            (slots.default || (slot.default = [])).push(child)
        }
        for (var name$1 in slots) {
            if (slots[name$1].every(isWhitespace)) {
                delete slots[name$1]
            }
        }
        return slots
    }
}

二、Mixin

Mixins中存储一些公用的功能(可以是data,componeents,methds,created,computed等),当使用Mixin时将所有mixins对象混入到组件中,这样组件中就有了这些公用的的功能

注意事项:

1.当组件中存在与Minxin对象相同的数据是,组件中的数据会覆盖mixin中的数据 2.如果相同数据为生命周期钩子的时候,会合并成一个数组,会先执行mixin中的钩子再执行组件中的钩子函数

实现原理

1.优先递归处理mixins

2.先遍历合并parent中的key,调用mergeFileld方法进行合并,然后保存到options中

3.通过mergeFileld函数进行合并

合并mixin和当前组件各种数据的四种策略

  1. 替换型策略:同名的props、methdos、inject、computed会被后来者替换即组件的会替换掉mixin中的

2.合并型策略:data通过set方法进行合并和重新赋值

3.队列型策略: 生命周期函数和watch,原理是将函数存入一个数组,然后正序遍历依次执行,所以会先执行mixin中的生命周期再执行组件中的生命周期

4.叠加型策略: component、directives、filters通过原型链进行层层叠加

过滤器

过滤器其实是一个函数,它不改变原数据,只是将数据加工过滤后在进行调用处理,在vue3中已经被弃用了

注意事项:

1.局部过滤器优先于全局过滤器被调用

2.一个表达式可以使用多个过滤器,过滤器之间要用|隔开执行顺序是从左往右

Vue.use的过程

1.判断当前插件是否已经安装过,防止重复安装

2.处理参数,调用插件的install方法,第一个参数为Vue实例

import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
    Vue.use = function(plugin: Function | Object) {
        const inatlledPlugins = (this._installedPlugins || (this._installedPlugins = []))
        if (installedPlugins.indexOf(plugin) > -1) {
            return this
        }

        const args = toArray(arguments, 1)
        args.unshift(this)
        if (typeof plugin.install === 'function') {
            plugin.install.apply(plugin, args)
        } else if (typeof plugin === 'function') {
            plugin.apply(null, args)
        }
        installedPlugins.push(plugin)
        return this
    }
}