好事总会发生在下个转弯。希望你的愿望都能一一实现。
本文纯属个人理解,学习记录知识的笔记,如有错误请指出,我会及时改正谢谢!!
一、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和当前组件各种数据的四种策略
- 替换型策略:同名的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
}
}