当前位置:网站首页>[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
role
Property tells the auxiliary device ( Such as screen reader ) The role of this element . In essence, it is to enhance semantics , When the existingHTML
When tags cannot fully express semantics , With the help ofrole
To illustrate .I don't quite understand why
title
anddescription
Attributes andslot
Judge , 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 nodetransition
perhapsanimationEnd
To 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
Transition
Nested inside the component isKeepAlive
Components , Then it will continue to look forKeepAlive
The first child element node of the nested component , As the element node of rendering . - If
Transition
No 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 )
Transition
Component allows us to pass inenterDuration
Thisprop
, It specifies the animation duration for entering the transition , Of course, if you don't specify ,Vue.js
The internal will monitor the animation end event , Then at the end of the animation , performfinishEnter
function
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 to calculate the bandwidth of video transmission? How much bandwidth is required to transmit 4K video?
- u盘安装kali并且持久化
- Programmer: after 5 years in a company with comfortable environment, do you want to continue to cook frogs in warm water or change jobs?
- [deep learning][pytorch][original]crnn trains loss on the higher version of pytorch as a solution for Nan
- Tencent cloud and the ICT Institute launched the preparation of the "cloud native open source white paper" to deeply interpret cloud native
- Deep learning ~11+ a new perspective on disease-related miRNA research
- 《opencv学习笔记》-- 离散傅里叶变换
- d的10个0符
- Jenkins remote publishing products
- Cloud native database: the outlet of the database, you can also take off
猜你喜欢
如何优雅的写 Controller 层代码?
Opencv learning notes - Discrete Fourier transform
【老卫搞机】090期:键盘?主机?全功能键盘主机!
"Meng Hua Lu" is about to have a grand finale. It's better to learn it first than to look ahead!
Basic path test of software test on the function of the previous day
GTest从入门到入门
QT -- the qtabwidget supports dragging tabbar items
How is the e-commerce red envelope realized? For interview (typical high concurrency)
保险APP适老化服务评测分析2022第06期
【直播回顾】战码先锋第七期:三方应用开发者如何为开源做贡献
随机推荐
打新债可以申请多少 开户是安全的吗
Opencv learning notes - loading and saving images
AXI低功耗接口
Difference between X12 830 and 862 messages
Install Kali on the U disk and persist it
10 zeros of D
《梦华录》要大结局了,看超前点映不如先来学学它!
[live review] battle code pioneer phase 7: how third-party application developers contribute to open source
美团基于 Flink 的实时数仓平台建设新进展
Fizz gateway secondary development integration tutorial
夜晚读书 -- 关于微服务和容器
Example of PHP observer mode [useful in the laravel framework]
Database migration tool flyway vs liquibase (II)
Basic path test of software test on the function of the previous day
[Architect (Part 41)] installation of server development and connection to redis database
【直播回顾】战码先锋第七期:三方应用开发者如何为开源做贡献
5分+的单基因泛癌纯生信思路!
How to develop mRNA vaccine? 27+ pancreatic cancer antigen and immune subtype analysis to tell you the answer!
JVM GC garbage collection detailed introduction quick check of learning notes
[206] use PHP language to generate the code of go language