当前位置:网站首页>[day ui] alert component learning
[day ui] alert component learning
2022-06-24 12:21:00 【Uncertainty】
From the perspective of style function , The whole is not very complicated ,alert The components mainly include theme colors ,title, close button , Closing event , In the middle , Bold, etc
Source code
- template<template> <!-- Show and hide have animation effect --> <!-- Not used in development , I don't quite understand why I use v-show Judgment display --> <transition name="d-alert-fade"> <div class="d-alert" :class="[typeClass, center ? 'is-center' : '', 'is-' + effect]" v-show="visible" role="alert" > <!-- Left Icon --> <i class="d-alert__icon" :class="[iconClass, isBigIcon]" v-if="showIcon" ></i> <!-- title and describe --> <div class="d-alert__content"> <span class="d-alert__title" :class="[isBoldTitle]" v-if="title || $slots.title" > <slot name="title">{{ title }}</slot> </span> <p v-if="$slots.default && !description" class="d-alert__description"> <slot></slot> </p> <p v-if="description && !$slots.default" class="d-alert__description"> {{ description }} </p> <i class="d-alert__closebtn" :class="{ 'is-customed': closeText !== '', 'd-icon-close': closeText === '' }" v-show="closable" @click="close" >{{ closeText }}</i > </div> </div> </transition> </template>
Use
roleProperty tells the auxiliary device ( Such as screen reader ) The role of this element . In essence, it is to enhance semantics , When the existingHTMLWhen tags cannot fully express semantics , With the help ofroleTo illustrate .I don't quite understand why
titleanddescriptionAttributes andslotJudge , There are clear friends who can help answer
- props Properties are more general , I won't introduce it here setup(props, { emit, slots }) { // The accepted attribute is converted to a response const { description, type } = toRefs(props) // Use v-show Show hidden const visible = ref(true) // Closing event const close = () => { visible.value = false emit('close') } const typeClass = computed(() => { return `d-alert--${type.value}` }) const iconClass = computed(() => { return TYPE_CLASSES_MAP[type.value] || 'd-icon-info' }) const isBigIcon = computed(() => { return description.value || slots.default ? 'is-big' : '' }) const isBoldTitle = computed(() => { return description.value || slots.default ? 'is-bold' : '' }) return { close, visible, typeClass, iconClass, isBigIcon, isBoldTitle } }
This concludes the introduction to components , Relatively simple . To make up the words , Here is the introduction transition Components
transition
Most friends know that this is a built-in animation component for component animation . There are usually three ways to use :
- CSS transition
- CSS Animation
- Javascript hook
CSS transition
The method we usually use ,css To configure enter and leave
<template>
<div class="app">
<button @click="show = !show">
Toggle render
</button>
<transition name="fade">
<p v-if="show"> I'm testing </p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
}
}
</script>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>CSS Animation
<template>
<div class="app">
<button @click="show = !show">Toggle show</button>
<transition name="bounce">
<p v-if="show"> I'm testing </p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
}
}
</script>
<style>
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
// reverse Is the key
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
</style>js hook
monitor transition Component's built-in methods ,js Control the animation
<template>
<div class="app">
<button @click="show = !show">
Toggle render
</button>
<transition
@before-enter="beforeEnter"
@enter="enter"
@before-leave="beforeLeave"
@leave="leave"
css="false"
>
<p v-if="show">hello</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
},
methods: {
beforeEnter(el) {
el.style.opacity = 0
el.style.transition = 'opacity 0.5s ease'
},
enter(el) {
this.$el.offsetHeight
el.style.opacity = 1
},
beforeLeave(el) {
el.style.opacity = 1
},
leave(el) {
el.style.transition = 'opacity 0.5s ease'
el.style.opacity = 0
}
}
}
</script>If the formal parameter does not specify
done, It indicates that the user does not manually control the end of the animation , And then the nodetransitionperhapsanimationEndTo mark the end of the animation , Start callbackafterEnter.
The number of formal parameters of hook function is greater than 1, Indicates that the formal parameter contains done, That is, the user must manually control when the animation ends . So once you configure done Shape parameter , Then you tell the frame , When does the animation end . Need to call... At the right time done, otherwise afterEnter The interface cannot be called .
Animation triggers
- Conditions apply colours to a drawing (v-if)
- Condition display (v-show)
- Dynamic components
- Component root
Execution principle
example
<template>
<div class="app">
<button @click="show = !show">
Toggle render
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
</template> Compile generated render function ( Not a template component used )
import {
createVNode as _createVNode,
openBlock as _openBlock,
createBlock as _createBlock,
createCommentVNode as _createCommentVNode,
Transition as _Transition,
withCtx as _withCtx,
} from "vue";
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (
// Collect dynamic nodes Such as v-if v-for
_openBlock(),
_createBlock("template", null, [
_createVNode("div", { class: "app" }, [
_createVNode(
"button",
{
onClick: ($event) => (_ctx.show = !_ctx.show),
},
" Toggle render ",
8 /* PROPS */,
["onClick"]
),
_createVNode(
_Transition,
{ name: "fade" },
{
// transition There is only one child node , Default slot . Errors reported by multiple child nodes
default: _withCtx(() => [
_ctx.show
? (_openBlock(), _createBlock("p", { key: 0 }, "hello"))
: _createCommentVNode("v-if", true),
]),
_: 1,
}
),
]),
])
);
}So how to execute events when a build is created and destroyed ?———— Create hook function
transition The component returns the first child node processed
- If
TransitionNested inside the component isKeepAliveComponents , Then it will continue to look forKeepAliveThe first child element node of the nested component , As the element node of rendering . - If
TransitionNo child nodes are nested inside the component , Then it renders an empty annotation node .
trantion Component definition
const Transition = (props, { slots }) =>
//esolveTransitionProps The main function is , Before we give Transition Delivered Props Make a layer of packaging on the basis of , And then back to a new Props object , Because it contains all Props Handle
h(BaseTransition, resolveTransitionProps(props), slots);
const BaseTransition = {
name: `BaseTransition`,
props: {
mode: String,
appear: Boolean,
persisted: Boolean,
// enter
onBeforeEnter: TransitionHookValidator,
onEnter: TransitionHookValidator,
onAfterEnter: TransitionHookValidator,
onEnterCancelled: TransitionHookValidator,
// leave
onBeforeLeave: TransitionHookValidator,
onLeave: TransitionHookValidator,
onAfterLeave: TransitionHookValidator,
onLeaveCancelled: TransitionHookValidator,
// appear
onBeforeAppear: TransitionHookValidator,
onAppear: TransitionHookValidator,
onAfterAppear: TransitionHookValidator,
onAppearCancelled: TransitionHookValidator,
},
setup(props, { slots }) {
const instance = getCurrentInstance();
const state = useTransitionState();
let prevTransitionKey;
return () => {
const children =
slots.default && getTransitionRawChildren(slots.default(), true);
if (!children || !children.length) {
return;
}
// Transition Components only allow one child element node , Multiple warnings , Prompt use TransitionGroup Components
if (process.env.NODE_ENV !== "production" && children.length > 1) {
warn(
"<transition> can only be used on a single element or component. Use " +
"<transition-group> for lists."
);
}
// There is no need to track the response , So change to the original value , Lifting performance
const rawProps = toRaw(props);
const { mode } = rawProps;
// Check mode Is it legal
if (
process.env.NODE_ENV !== "production" &&
mode &&
!["in-out", "out-in", "default"].includes(mode)
) {
warn(`invalid <transition> mode: ${mode}`);
}
// Get the first child element node
const child = children[0];
if (state.isLeaving) {
return emptyPlaceholder(child);
}
// Handle <transition><keep-alive/></transition> The situation of
const innerChild = getKeepAliveChild(child);
if (!innerChild) {
return emptyPlaceholder(child);
}
const enterHooks = resolveTransitionHooks(
innerChild,
rawProps,
state,
instance
);
setTransitionHooks(innerChild, enterHooks);
const oldChild = instance.subTree;
const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
let transitionKeyChanged = false;
const { getTransitionKey } = innerChild.type;
if (getTransitionKey) {
const key = getTransitionKey();
if (prevTransitionKey === undefined) {
prevTransitionKey = key;
} else if (key !== prevTransitionKey) {
prevTransitionKey = key;
transitionKeyChanged = true;
}
}
if (
oldInnerChild &&
oldInnerChild.type !== Comment &&
(!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)
) {
const leavingHooks = resolveTransitionHooks(
oldInnerChild,
rawProps,
state,
instance
);
// Update the hook function of the old tree
setTransitionHooks(oldInnerChild, leavingHooks);
// Switch between two views
if (mode === "out-in") {
state.isLeaving = true;
// Returns an empty placeholder node , When the transition is over , Rerender component
leavingHooks.afterLeave = () => {
state.isLeaving = false;
instance.update();
};
return emptyPlaceholder(child);
} else if (mode === "in-out") {
leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
const leavingVNodesCache = getLeavingNodesForType(
state,
oldInnerChild
);
leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
// early removal callback
el._leaveCb = () => {
earlyRemove();
el._leaveCb = undefined;
delete enterHooks.delayedLeave;
};
enterHooks.delayedLeave = delayedLeave;
};
}
}
return child;
};
},
}; In the process of rendering ,Transition Components will also pass through resolveTransitionHooks To define the hook function object in the component creation and deletion stage , And then through setTransitionHooks Function to set the hook function object to vnode.transition On .
hooks Definition
const hooks = {
mode,
persisted,
beforeEnter(el) {
let hook = onBeforeEnter;
if (!state.isMounted) {
if (appear) {
hook = onBeforeAppear || onBeforeEnter;
} else {
return;
}
}
if (el._leaveCb) {
el._leaveCb(true /* cancelled */);
}
const leavingVNode = leavingVNodesCache[key];
if (
leavingVNode &&
isSameVNodeType(vnode, leavingVNode) &&
leavingVNode.el._leaveCb
) {
leavingVNode.el._leaveCb();
}
callHook(hook, [el]);
},
enter(el) {
let hook = onEnter;
let afterHook = onAfterEnter;
let cancelHook = onEnterCancelled;
if (!state.isMounted) {
if (appear) {
hook = onAppear || onEnter;
afterHook = onAfterAppear || onAfterEnter;
cancelHook = onAppearCancelled || onEnterCancelled;
} else {
return;
}
}
let called = false;
const done = (el._enterCb = (cancelled) => {
if (called) return;
called = true;
if (cancelled) {
callHook(cancelHook, [el]);
} else {
callHook(afterHook, [el]);
}
if (hooks.delayedLeave) {
hooks.delayedLeave();
}
el._enterCb = undefined;
});
if (hook) {
hook(el, done);
if (hook.length <= 1) {
done();
}
} else {
done();
}
},
leave(el, remove) {
const key = String(vnode.key);
if (el._enterCb) {
el._enterCb(true /* cancelled */);
}
if (state.isUnmounting) {
return remove();
}
callHook(onBeforeLeave, [el]);
let called = false;
const done = (el._leaveCb = (cancelled) => {
if (called) return;
called = true;
remove();
if (cancelled) {
callHook(onLeaveCancelled, [el]);
} else {
callHook(onAfterLeave, [el]);
}
el._leaveCb = undefined;
if (leavingVNodesCache[key] === vnode) {
delete leavingVNodesCache[key];
}
});
leavingVNodesCache[key] = vnode;
if (onLeave) {
onLeave(el, done);
if (onLeave.length <= 1) {
done();
}
} else {
done();
}
},
clone(vnode) {
return resolveTransitionHooks(vnode, props, state, instance);
},
}; The hook function object defines 4 A hook function , Namely beforeEnter,enter,leave and clone. At the node patch Stage mountElement Function , Before the node is inserted and there is an excess, it will execute vnode.transition Medium beforeEnter function
//beforeEnter The main thing hook functions do is based on appear The value of and DOM Whether to mount , To execute onBeforeEnter Function or onBeforeAppear function .appear Whether to execute animation when the node is realistic
beforeEnter(el) {
let hook = onBeforeEnter
if (!state.isMounted) {
if (appear) {
hook = onBeforeAppear || onBeforeEnter
}
else {
return
}
}
if (el._leaveCb) {
el._leaveCb(true /* cancelled */)
}
const leavingVNode = leavingVNodesCache[key]
if (leavingVNode &&
isSameVNodeType(vnode, leavingVNode) &&
leavingVNode.el._leaveCb) {
leavingVNode.el._leaveCb()
}
callHook(hook, [el])
}resolveTransitionProps function
function resolveTransitionProps(rawProps) {
let {
name = "v",
type,
css = true,
duration,
enterFromClass = `${name}-enter-from`,
enterActiveClass = `${name}-enter-active`,
enterToClass = `${name}-enter-to`,
appearFromClass = enterFromClass,
appearActiveClass = enterActiveClass,
appearToClass = enterToClass,
leaveFromClass = `${name}-leave-from`,
leaveActiveClass = `${name}-leave-active`,
leaveToClass = `${name}-leave-to`,
} = rawProps;
const baseProps = {};
for (const key in rawProps) {
if (!(key in DOMTransitionPropsValidators)) {
baseProps[key] = rawProps[key];
}
}
if (!css) {
return baseProps;
}
const durations = normalizeDuration(duration);
const enterDuration = durations && durations[0];
const leaveDuration = durations && durations[1];
const {
onBeforeEnter,
onEnter,
onEnterCancelled,
onLeave,
onLeaveCancelled,
onBeforeAppear = onBeforeEnter,
onAppear = onEnter,
onAppearCancelled = onEnterCancelled,
} = baseProps;
const finishEnter = (el, isAppear, done) => {
removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
done && done();
};
const finishLeave = (el, done) => {
removeTransitionClass(el, leaveToClass);
removeTransitionClass(el, leaveActiveClass);
done && done();
};
const makeEnterHook = (isAppear) => {
return (el, done) => {
const hook = isAppear ? onAppear : onEnter;
const resolve = () => finishEnter(el, isAppear, done);
hook && hook(el, resolve);
nextFrame(() => {
removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
addTransitionClass(el, isAppear ? appearToClass : enterToClass);
if (!(hook && hook.length > 1)) {
if (enterDuration) {
setTimeout(resolve, enterDuration);
} else {
whenTransitionEnds(el, type, resolve);
}
}
});
};
};
return extend(baseProps, {
onBeforeEnter(el) {
onBeforeEnter && onBeforeEnter(el);
addTransitionClass(el, enterActiveClass);
addTransitionClass(el, enterFromClass);
},
onBeforeAppear(el) {
onBeforeAppear && onBeforeAppear(el);
addTransitionClass(el, appearActiveClass);
addTransitionClass(el, appearFromClass);
},
onEnter: makeEnterHook(false),
onAppear: makeEnterHook(true),
onLeave(el, done) {
const resolve = () => finishLeave(el, done);
addTransitionClass(el, leaveActiveClass);
addTransitionClass(el, leaveFromClass);
nextFrame(() => {
removeTransitionClass(el, leaveFromClass);
addTransitionClass(el, leaveToClass);
if (!(onLeave && onLeave.length > 1)) {
if (leaveDuration) {
setTimeout(resolve, leaveDuration);
} else {
whenTransitionEnds(el, type, resolve);
}
}
});
onLeave && onLeave(el, resolve);
},
onEnterCancelled(el) {
finishEnter(el, false);
onEnterCancelled && onEnterCancelled(el);
},
onAppearCancelled(el) {
finishEnter(el, true);
onAppearCancelled && onAppearCancelled(el);
},
onLeaveCancelled(el) {
finishLeave(el);
onLeaveCancelled && onLeaveCancelled(el);
},
});
} Let's see onBeforeEnter function , Its internal implementation of the foundation props Incoming onBeforeEnter Hook function , And give DOM Elements el Added enterActiveClass and enterFromClass style .
among ,props Incoming onBeforeEnter The function is that we write Transition Component is added beforeEnter Hook function .enterActiveClass The default value is v-enter-active,enterFromClass The default value is v-enter-from, If Transition Component passed in name Of prop, such as fade, that enterActiveClass The value is fade-enter-active,enterFromClass The value is fade-enter-from.(onBeforeAppear and onBeforeEnter The logic of is similar to , I won't go into that , It is before we give Transition Component in appear Of Prop, And is executed during the first mount . After execution beforeEnter Hook function , Then insert the element into the page , And then it will execute vnode.transition Medium enter Hook function , above hooks in )
stay enter Internal function , First, execute the basic props Incoming onEnter Hook function , Then give... At the next frame DOM Elements el Removed enterFromClass, At the same time, added enterToClass style ( Animation is the so-called alternation of styles )
TransitionComponent allows us to pass inenterDurationThisprop, It specifies the animation duration for entering the transition , Of course, if you don't specify ,Vue.jsThe internal will monitor the animation end event , Then at the end of the animation , performfinishEnterfunction
Look at its implementation
const finishEnter = (el, isAppear, done) => {
removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
done && done();
};In fact, it's for DOM Element removal enterToClass as well as enterActiveClass, At the same time done function , And then perform onAfterEnter Hook function
leave The main functions of the hook are enter contrary . You can check it by yourself .
That's right alert Component learning , If there is any mistake, please correct it .
边栏推荐
- How does wechat and QQ chat work? So simple!!!
- 如何优雅的写 Controller 层代码?
- Is it safe to apply for new bonds to open an account
- PHP SMS notification + voice broadcast automatic double call
- Difference between X12 830 and 862 messages
- ArrayList#subList这四个坑,一不小心就中招
- Is it safe to open an account under the conditions of new bonds
- 深圳市人民医院程立新课题组提出多组学数据在肝细胞癌的诊断与预后分析的新方法meGPS
- 2021-06-03: Boolean operation. Given a Boolean expression and an expected cloth
- 【数字IC/FPGA】Booth乘法器
猜你喜欢

Insurance app aging service evaluation analysis 2022 issue 06

Basic path test of software test on the function of the previous day

保险APP适老化服务评测分析2022第06期

电商红包雨是如何实现的?拿去面试用(典型高并发)

GTEST from getting started to getting started

New progress in the construction of meituan's Flink based real-time data warehouse platform

TP-LINK 1208 router tutorial (2)
[mysql_16] variables, process control and cursors

Tools and methods - use code formatting tools in source insight

Installation and operation of libuv
随机推荐
打新债的条件 开户是安全的吗
11+的基于甲基化组和转录组综合分析识别葡萄膜黑色素瘤中新的预后 DNA 甲基化特征~
Coinbase将推出首个针对零售交易员的加密衍生产品
Speculation London gold short-term stable money making skills? Where is it safe to fry London gold?
How to develop mRNA vaccine? 27+ pancreatic cancer antigen and immune subtype analysis to tell you the answer!
Installation and operation of libuv
基于AM335X开发板 ARM Cortex-A8——Acontis EtherCAT主站开发案例
单基因泛癌+简单实验就能发表7分+
FreeRTOS overview and experience
Example of SMS interface verification code function implemented by ThinkPHP framework
How to calculate the bandwidth of video transmission? How much bandwidth is required to transmit 4K video?
夜晚读书 -- 关于微服务和容器
【老卫搞机】090期:键盘?主机?全功能键盘主机!
万名校园开发者花式玩AI,亮点看这张图就够啦!
11+! Methylation modification patterns based on m6A regulatory factors in colon cancer are characterized by different tumor microenvironment immune spectra
怎么申请打新债 开户是安全的吗
Can Tencent's tendis take the place of redis?
5分+的单基因泛癌纯生信思路!
Linker --- linker
The opportunity to teach cloud development a lesson has finally come!