Best JavaScript code snippet using playwright-internal
jquery-3.6.0.min.js
Source:jquery-3.6.0.min.js
...1084 })1085 }1086 return e1087}1088function invokeDirectiveHook(e, t, n, r) {1089 const o = e.dirs, s = t && t.dirs;1090 for (let a = 0; a < o.length; a++) {1091 const i = o[a];1092 s && (i.oldValue = s[a].value);1093 let l = i.dir[r];1094 l && (pauseTracking(), callWithAsyncErrorHandling(l, n, 8, [e.el, i, e, t]), resetTracking())1095 }1096}1097function createAppContext() {1098 return {1099 app: null,1100 config: {1101 isNativeTag: NO,1102 performance: !1,1103 globalProperties: {},1104 optionMergeStrategies: {},1105 errorHandler: void 0,1106 warnHandler: void 0,1107 compilerOptions: {}1108 },1109 mixins: [],1110 components: {},1111 directives: {},1112 provides: Object.create(null),1113 optionsCache: new WeakMap,1114 propsCache: new WeakMap,1115 emitsCache: new WeakMap1116 }1117}1118let Ne = 0;1119function createAppAPI(e, t) {1120 return function createApp2(n, r = null) {1121 null == r || isObject(r) || (r = null);1122 const o = createAppContext(), s = new Set;1123 let a = !1;1124 const i = o.app = {1125 _uid: Ne++,1126 _component: n,1127 _props: r,1128 _container: null,1129 _context: o,1130 _instance: null,1131 version: Ze,1132 get config() {1133 return o.config1134 },1135 set config(e) {1136 },1137 use: (e, ...t) => (s.has(e) || (e && isFunction(e.install) ? (s.add(e), e.install(i, ...t)) : isFunction(e) && (s.add(e), e(i, ...t))), i),1138 mixin: e => (o.mixins.includes(e) || o.mixins.push(e), i),1139 component: (e, t) => t ? (o.components[e] = t, i) : o.components[e],1140 directive: (e, t) => t ? (o.directives[e] = t, i) : o.directives[e],1141 mount(s, l, c) {1142 if (!a) {1143 const u = De(n, r);1144 return u.appContext = o, l && t ? t(u, s) : e(u, s, c), a = !0, i._container = s, s.__vue_app__ = i, u.component.proxy1145 }1146 },1147 unmount() {1148 a && (e(null, i._container), delete i._container.__vue_app__)1149 },1150 provide: (e, t) => (o.provides[e] = t, i)1151 };1152 return i1153 }1154}1155const Ie = {scheduler: queueJob, allowRecurse: !0}, Me = function queueEffectWithSuspense(e, t) {1156 t && t.pendingBranch ? w(e) ? t.effects.push(...e) : t.effects.push(e) : function queuePostFlushCb(e) {1157 queueCb(e, he, de, me)1158 }(e)1159}, setRef = (e, t, n, r, o = !1) => {1160 if (w(e)) return void e.forEach(((e, s) => setRef(e, t && (w(t) ? t[s] : t), n, r, o)));1161 if (isAsyncWrapper(r) && !o) return;1162 const s = 4 & r.shapeFlag ? r.component.exposed || r.component.proxy : r.el, a = o ? null : s, {i, r: l} = e,1163 c = t && t.r, u = i.refs === g ? i.refs = {} : i.refs, f = i.setupState;1164 if (null != c && c !== l && (isString$1(c) ? (u[c] = null, hasOwn(f, c) && (f[c] = null)) : isRef(c) && (c.value = null)), isString$1(l)) {1165 const doSet = () => {1166 u[l] = a, hasOwn(f, l) && (f[l] = a)1167 };1168 a ? (doSet.id = -1, Me(doSet, n)) : doSet()1169 } else if (isRef(l)) {1170 const doSet = () => {1171 l.value = a1172 };1173 a ? (doSet.id = -1, Me(doSet, n)) : doSet()1174 } else isFunction(l) && callWithErrorHandling(l, i, 12, [a, u])1175};1176function createRenderer(e) {1177 return function baseCreateRenderer(e, t) {1178 const {1179 insert: n,1180 remove: r,1181 patchProp: o,1182 forcePatchProp: s,1183 createElement: a,1184 createText: i,1185 createComment: l,1186 setText: c,1187 setElementText: u,1188 parentNode: f,1189 nextSibling: p,1190 setScopeId: d = NOOP,1191 cloneNode: m,1192 insertStaticContent: y1193 } = e, patch = (e, t, n, r = null, o = null, s = null, a = !1, i = null, l = !1) => {1194 e && !isSameVNodeType(e, t) && (r = getNextHostNode(e), unmount(e, o, s, !0), e = null), -2 === t.patchFlag && (l = !1, t.dynamicChildren = null);1195 const {type: c, ref: u, shapeFlag: f} = t;1196 switch (c) {1197 case Ve:1198 processText(e, t, n, r);1199 break;1200 case He:1201 processCommentNode(e, t, n, r);1202 break;1203 case Be:1204 null == e && mountStaticNode(t, n, r, a);1205 break;1206 case Le:1207 processFragment(e, t, n, r, o, s, a, i, l);1208 break;1209 default:1210 1 & f ? processElement(e, t, n, r, o, s, a, i, l) : 6 & f ? processComponent(e, t, n, r, o, s, a, i, l) : (64 & f || 128 & f) && c.process(e, t, n, r, o, s, a, i, l, R)1211 }1212 null != u && o && setRef(u, e && e.ref, s, t || e, !t)1213 }, processText = (e, t, r, o) => {1214 if (null == e) n(t.el = i(t.children), r, o); else {1215 const n = t.el = e.el;1216 t.children !== e.children && c(n, t.children)1217 }1218 }, processCommentNode = (e, t, r, o) => {1219 null == e ? n(t.el = l(t.children || ""), r, o) : t.el = e.el1220 }, mountStaticNode = (e, t, n, r) => {1221 [e.el, e.anchor] = y(e.children, t, n, r, e.el && [e.el, e.anchor])1222 }, moveStaticNode = ({el: e, anchor: t}, r, o) => {1223 let s;1224 for (; e && e !== t;) s = p(e), n(e, r, o), e = s;1225 n(t, r, o)1226 }, removeStaticNode = ({el: e, anchor: t}) => {1227 let n;1228 for (; e && e !== t;) n = p(e), r(e), e = n;1229 r(t)1230 }, processElement = (e, t, n, r, o, s, a, i, l) => {1231 a = a || "svg" === t.type, null == e ? mountElement(t, n, r, o, s, a, i, l) : patchElement(e, t, o, s, a, i, l)1232 }, mountElement = (e, t, r, s, i, l, c, f) => {1233 let p, d;1234 const {type: g, props: v, shapeFlag: y, transition: b, patchFlag: R, dirs: w} = e;1235 if (e.el && void 0 !== m && -1 === R) p = e.el = m(e.el); else {1236 if (p = e.el = a(e.type, l, v && v.is, v), 8 & y ? u(p, e.children) : 16 & y && mountChildren(e.children, p, null, s, i, l && "foreignObject" !== g, c, f || !!e.dynamicChildren), w && invokeDirectiveHook(e, null, s, "created"), v) {1237 for (const t in v) k(t) || o(p, t, null, v[t], l, e.children, s, i, unmountChildren);1238 (d = v.onVnodeBeforeMount) && invokeVNodeHook(d, s, e)1239 }1240 setScopeId(p, e, e.scopeId, c, s)1241 }1242 w && invokeDirectiveHook(e, null, s, "beforeMount");1243 const _ = (!i || i && !i.pendingBranch) && b && !b.persisted;1244 _ && b.beforeEnter(p), n(p, t, r), ((d = v && v.onVnodeMounted) || _ || w) && Me((() => {1245 d && invokeVNodeHook(d, s, e), _ && b.enter(p), w && invokeDirectiveHook(e, null, s, "mounted")1246 }), i)1247 }, setScopeId = (e, t, n, r, o) => {1248 if (n && d(e, n), r) for (let s = 0; s < r.length; s++) d(e, r[s]);1249 if (o) {1250 if (t === o.subTree) {1251 const t = o.vnode;1252 setScopeId(e, t, t.scopeId, t.slotScopeIds, o.parent)1253 }1254 }1255 }, mountChildren = (e, t, n, r, o, s, a, i, l = 0) => {1256 for (let c = l; c < e.length; c++) {1257 const l = e[c] = i ? cloneIfMounted(e[c]) : normalizeVNode(e[c]);1258 patch(null, l, t, n, r, o, s, a, i)1259 }1260 }, patchElement = (e, t, n, r, a, i, l) => {1261 const c = t.el = e.el;1262 let {patchFlag: f, dynamicChildren: p, dirs: d} = t;1263 f |= 16 & e.patchFlag;1264 const m = e.props || g, v = t.props || g;1265 let y;1266 if ((y = v.onVnodeBeforeUpdate) && invokeVNodeHook(y, n, t, e), d && invokeDirectiveHook(t, e, n, "beforeUpdate"), f > 0) {1267 if (16 & f) patchProps(c, t, m, v, n, r, a); else if (2 & f && m.class !== v.class && o(c, "class", null, v.class, a), 4 & f && o(c, "style", m.style, v.style, a), 8 & f) {1268 const i = t.dynamicProps;1269 for (let t = 0; t < i.length; t++) {1270 const l = i[t], u = m[l], f = v[l];1271 (f !== u || s && s(c, l)) && o(c, l, u, f, a, e.children, n, r, unmountChildren)1272 }1273 }1274 1 & f && e.children !== t.children && u(c, t.children)1275 } else l || null != p || patchProps(c, t, m, v, n, r, a);1276 const b = a && "foreignObject" !== t.type;1277 p ? patchBlockChildren(e.dynamicChildren, p, c, n, r, b, i) : l || patchChildren(e, t, c, null, n, r, b, i, !1), ((y = v.onVnodeUpdated) || d) && Me((() => {1278 y && invokeVNodeHook(y, n, t, e), d && invokeDirectiveHook(t, e, n, "updated")1279 }), r)1280 }, patchBlockChildren = (e, t, n, r, o, s, a) => {1281 for (let i = 0; i < t.length; i++) {1282 const l = e[i], c = t[i],1283 u = l.el && (l.type === Le || !isSameVNodeType(l, c) || 6 & l.shapeFlag || 64 & l.shapeFlag) ? f(l.el) : n;1284 patch(l, c, u, null, r, o, s, a, !0)1285 }1286 }, patchProps = (e, t, n, r, a, i, l) => {1287 if (n !== r) {1288 for (const c in r) {1289 if (k(c)) continue;1290 const u = r[c], f = n[c];1291 (u !== f || s && s(e, c)) && o(e, c, f, u, l, t.children, a, i, unmountChildren)1292 }1293 if (n !== g) for (const s in n) k(s) || s in r || o(e, s, n[s], null, l, t.children, a, i, unmountChildren)1294 }1295 }, processFragment = (e, t, r, o, s, a, l, c, u) => {1296 const f = t.el = e ? e.el : i(""), p = t.anchor = e ? e.anchor : i("");1297 let {patchFlag: d, dynamicChildren: m, slotScopeIds: g} = t;1298 m && (u = !0), g && (c = c ? c.concat(g) : g), null == e ? (n(f, r, o), n(p, r, o), mountChildren(t.children, r, p, s, a, l, c, u)) : d > 0 && 64 & d && m && e.dynamicChildren ? (patchBlockChildren(e.dynamicChildren, m, r, s, a, l, c), (null != t.key || s && t === s.subTree) && traverseStaticChildren(e, t, !0)) : patchChildren(e, t, r, p, s, a, l, c, u)1299 }, processComponent = (e, t, n, r, o, s, a, i, l) => {1300 t.slotScopeIds = i, null == e ? 512 & t.shapeFlag ? o.ctx.activate(t, n, r, a, l) : mountComponent(t, n, r, o, s, a, l) : updateComponent(e, t, l)1301 }, mountComponent = (e, t, n, r, o, s, a) => {1302 const i = e.component = function createComponentInstance(e, t, n) {1303 const r = e.type, o = (t ? t.appContext : e.appContext) || Qe, s = {1304 uid: Je++,1305 vnode: e,1306 type: r,1307 parent: t,1308 appContext: o,1309 root: null,1310 next: null,1311 subTree: null,1312 update: null,1313 render: null,1314 proxy: null,1315 exposed: null,1316 withProxy: null,1317 effects: null,1318 provides: t ? t.provides : Object.create(o.provides),1319 accessCache: null,1320 renderCache: [],1321 components: null,1322 directives: null,1323 propsOptions: normalizePropsOptions(r, o),1324 emitsOptions: normalizeEmitsOptions(r, o),1325 emit: null,1326 emitted: null,1327 propsDefaults: g,1328 inheritAttrs: r.inheritAttrs,1329 ctx: g,1330 data: g,1331 props: g,1332 attrs: g,1333 slots: g,1334 refs: g,1335 setupState: g,1336 setupContext: null,1337 suspense: n,1338 suspenseId: n ? n.pendingId : 0,1339 asyncDep: null,1340 asyncResolved: !1,1341 isMounted: !1,1342 isUnmounted: !1,1343 isDeactivated: !1,1344 bc: null,1345 c: null,1346 bm: null,1347 m: null,1348 bu: null,1349 u: null,1350 um: null,1351 bum: null,1352 da: null,1353 a: null,1354 rtg: null,1355 rtc: null,1356 ec: null,1357 sp: null1358 };1359 return s.ctx = {_: s}, s.root = t ? t.root : s, s.emit = emit.bind(null, s), s1360 }(e, r, o);1361 if (isKeepAlive(e) && (i.ctx.renderer = R), function setupComponent(e, t = !1) {1362 Xe = t;1363 const {props: n, children: r} = e.vnode, o = isStatefulComponent(e);1364 initProps(e, n, o, t), ((e, t) => {1365 if (32 & e.vnode.shapeFlag) {1366 const n = t._;1367 n ? (e.slots = toRaw(t), def(t, "_", n)) : normalizeObjectSlots(t, e.slots = {})1368 } else e.slots = {}, t && normalizeVNodeSlots(e, t);1369 def(e.slots, Ue, 1)1370 })(e, r);1371 const s = o ? function setupStatefulComponent(e, t) {1372 const n = e.type;1373 e.accessCache = Object.create(null), e.proxy = function markRaw(e) {1374 return def(e, "__v_skip", !0), e1375 }(new Proxy(e.ctx, qe));1376 const {setup: r} = n;1377 if (r) {1378 const n = e.setupContext = r.length > 1 ? function createSetupContext(e) {1379 const expose = t => {1380 e.exposed = proxyRefs(t)1381 };1382 return {attrs: e.attrs, slots: e.slots, emit: e.emit, expose}1383 }(e) : null;1384 Ye = e, pauseTracking();1385 const o = callWithErrorHandling(r, e, 0, [e.props, n]);1386 if (resetTracking(), Ye = null, isPromise(o)) {1387 if (t) return o.then((t => {1388 handleSetupResult(e, t)1389 })).catch((t => {1390 handleError(t, e, 0)1391 }));1392 e.asyncDep = o1393 } else handleSetupResult(e, o)1394 } else finishComponentSetup(e)1395 }(e, t) : void 0;1396 return Xe = !1, s1397 }(i), i.asyncDep) {1398 if (o && o.registerDep(i, setupRenderEffect), !e.el) {1399 const e = i.subTree = De(He);1400 processCommentNode(null, e, t, n)1401 }1402 } else setupRenderEffect(i, e, t, n, o, s, a)1403 }, updateComponent = (e, t, n) => {1404 const r = t.component = e.component;1405 if (function shouldUpdateComponent(e, t, n) {1406 const {props: r, children: o, component: s} = e, {props: a, children: i, patchFlag: l} = t, c = s.emitsOptions;1407 if (t.dirs || t.transition) return !0;1408 if (!(n && l >= 0)) return !(!o && !i || i && i.$stable) || r !== a && (r ? !a || hasPropsChanged(r, a, c) : !!a);1409 if (1024 & l) return !0;1410 if (16 & l) return r ? hasPropsChanged(r, a, c) : !!a;1411 if (8 & l) {1412 const e = t.dynamicProps;1413 for (let t = 0; t < e.length; t++) {1414 const n = e[t];1415 if (a[n] !== r[n] && !isEmitListener(c, n)) return !01416 }1417 }1418 return !11419 }(e, t, n)) {1420 if (r.asyncDep && !r.asyncResolved) return void updateComponentPreRender(r, t, n);1421 r.next = t, function invalidateJob(e) {1422 const t = le.indexOf(e);1423 t > ce && le.splice(t, 1)1424 }(r.update), r.update()1425 } else t.component = e.component, t.el = e.el, r.vnode = t1426 }, setupRenderEffect = (e, t, n, r, o, s, a) => {1427 e.update = effect((function componentEffect() {1428 if (e.isMounted) {1429 let t, {next: n, bu: r, u: i, parent: l, vnode: c} = e, u = n;1430 n ? (n.el = c.el, updateComponentPreRender(e, n, a)) : n = c, r && invokeArrayFns(r), (t = n.props && n.props.onVnodeBeforeUpdate) && invokeVNodeHook(t, l, n, c);1431 const p = renderComponentRoot(e), d = e.subTree;1432 e.subTree = p, patch(d, p, f(d.el), getNextHostNode(d), e, o, s), n.el = p.el, null === u && function updateHOCHostEl({1433 vnode: e,1434 parent: t1435 }, n) {1436 for (; t && t.subTree === e;) (e = t.vnode).el = n, t = t.parent1437 }(e, p.el), i && Me(i, o), (t = n.props && n.props.onVnodeUpdated) && Me((() => invokeVNodeHook(t, l, n, c)), o)1438 } else {1439 let a;1440 const {el: i, props: l} = t, {bm: c, m: u, parent: f} = e;1441 if (c && invokeArrayFns(c), (a = l && l.onVnodeBeforeMount) && invokeVNodeHook(a, f, t), i && _) {1442 const hydrateSubTree = () => {1443 e.subTree = renderComponentRoot(e), _(i, e.subTree, e, o, null)1444 };1445 isAsyncWrapper(t) ? t.type.__asyncLoader().then((() => !e.isUnmounted && hydrateSubTree())) : hydrateSubTree()1446 } else {1447 const a = e.subTree = renderComponentRoot(e);1448 patch(null, a, n, r, e, o, s), t.el = a.el1449 }1450 if (u && Me(u, o), a = l && l.onVnodeMounted) {1451 const e = t;1452 Me((() => invokeVNodeHook(a, f, e)), o)1453 }1454 256 & t.shapeFlag && e.a && Me(e.a, o), e.isMounted = !0, t = n = r = null1455 }1456 }), Ie)1457 }, updateComponentPreRender = (e, t, n) => {1458 t.component = e;1459 const r = e.vnode.props;1460 e.vnode = t, e.next = null, function updateProps(e, t, n, r) {1461 const {props: o, attrs: s, vnode: {patchFlag: a}} = e, i = toRaw(o), [l] = e.propsOptions;1462 let c = !1;1463 if (!(r || a > 0) || 16 & a) {1464 let r;1465 setFullProps(e, t, o, s) && (c = !0);1466 for (const s in i) t && (hasOwn(t, s) || (r = C(s)) !== s && hasOwn(t, r)) || (l ? !n || void 0 === n[s] && void 0 === n[r] || (o[s] = resolvePropValue(l, i, s, void 0, e, !0)) : delete o[s]);1467 if (s !== i) for (const e in s) t && hasOwn(t, e) || (delete s[e], c = !0)1468 } else if (8 & a) {1469 const n = e.vnode.dynamicProps;1470 for (let r = 0; r < n.length; r++) {1471 let a = n[r];1472 const u = t[a];1473 if (l) if (hasOwn(s, a)) u !== s[a] && (s[a] = u, c = !0); else {1474 const t = S(a);1475 o[t] = resolvePropValue(l, i, t, u, e, !1)1476 } else u !== s[a] && (s[a] = u, c = !0)1477 }1478 }1479 c && trigger(e, "set", "$attrs")1480 }(e, t.props, r, n), ((e, t, n) => {1481 const {vnode: r, slots: o} = e;1482 let s = !0, a = g;1483 if (32 & r.shapeFlag) {1484 const e = t._;1485 e ? n && 1 === e ? s = !1 : (b(o, t), n || 1 !== e || delete o._) : (s = !t.$stable, normalizeObjectSlots(t, o)), a = t1486 } else t && (normalizeVNodeSlots(e, t), a = {default: 1});1487 if (s) for (const i in o) isInternalKey(i) || i in a || delete o[i]1488 })(e, t.children, n), pauseTracking(), flushPreFlushCbs(void 0, e.update), resetTracking()1489 }, patchChildren = (e, t, n, r, o, s, a, i, l = !1) => {1490 const c = e && e.children, f = e ? e.shapeFlag : 0, p = t.children, {patchFlag: d, shapeFlag: m} = t;1491 if (d > 0) {1492 if (128 & d) return void patchKeyedChildren(c, p, n, r, o, s, a, i, l);1493 if (256 & d) return void patchUnkeyedChildren(c, p, n, r, o, s, a, i, l)1494 }1495 8 & m ? (16 & f && unmountChildren(c, o, s), p !== c && u(n, p)) : 16 & f ? 16 & m ? patchKeyedChildren(c, p, n, r, o, s, a, i, l) : unmountChildren(c, o, s, !0) : (8 & f && u(n, ""), 16 & m && mountChildren(p, n, r, o, s, a, i, l))1496 }, patchUnkeyedChildren = (e, t, n, r, o, s, a, i, l) => {1497 t = t || v;1498 const c = (e = e || v).length, u = t.length, f = Math.min(c, u);1499 let p;1500 for (p = 0; p < f; p++) {1501 const r = t[p] = l ? cloneIfMounted(t[p]) : normalizeVNode(t[p]);1502 patch(e[p], r, n, null, o, s, a, i, l)1503 }1504 c > u ? unmountChildren(e, o, s, !0, !1, f) : mountChildren(t, n, r, o, s, a, i, l, f)1505 }, patchKeyedChildren = (e, t, n, r, o, s, a, i, l) => {1506 let c = 0;1507 const u = t.length;1508 let f = e.length - 1, p = u - 1;1509 for (; c <= f && c <= p;) {1510 const r = e[c], u = t[c] = l ? cloneIfMounted(t[c]) : normalizeVNode(t[c]);1511 if (!isSameVNodeType(r, u)) break;1512 patch(r, u, n, null, o, s, a, i, l), c++1513 }1514 for (; c <= f && c <= p;) {1515 const r = e[f], c = t[p] = l ? cloneIfMounted(t[p]) : normalizeVNode(t[p]);1516 if (!isSameVNodeType(r, c)) break;1517 patch(r, c, n, null, o, s, a, i, l), f--, p--1518 }1519 if (c > f) {1520 if (c <= p) {1521 const e = p + 1, f = e < u ? t[e].el : r;1522 for (; c <= p;) patch(null, t[c] = l ? cloneIfMounted(t[c]) : normalizeVNode(t[c]), n, f, o, s, a, i, l), c++1523 }1524 } else if (c > p) for (; c <= f;) unmount(e[c], o, s, !0), c++; else {1525 const d = c, m = c, g = new Map;1526 for (c = m; c <= p; c++) {1527 const e = t[c] = l ? cloneIfMounted(t[c]) : normalizeVNode(t[c]);1528 null != e.key && g.set(e.key, c)1529 }1530 let y, b = 0;1531 const R = p - m + 1;1532 let w = !1, _ = 0;1533 const k = new Array(R);1534 for (c = 0; c < R; c++) k[c] = 0;1535 for (c = d; c <= f; c++) {1536 const r = e[c];1537 if (b >= R) {1538 unmount(r, o, s, !0);1539 continue1540 }1541 let u;1542 if (null != r.key) u = g.get(r.key); else for (y = m; y <= p; y++) if (0 === k[y - m] && isSameVNodeType(r, t[y])) {1543 u = y;1544 break1545 }1546 void 0 === u ? unmount(r, o, s, !0) : (k[u - m] = c + 1, u >= _ ? _ = u : w = !0, patch(r, t[u], n, null, o, s, a, i, l), b++)1547 }1548 const x = w ? function getSequence(e) {1549 const t = e.slice(), n = [0];1550 let r, o, s, a, i;1551 const l = e.length;1552 for (r = 0; r < l; r++) {1553 const l = e[r];1554 if (0 !== l) {1555 if (o = n[n.length - 1], e[o] < l) {1556 t[r] = o, n.push(r);1557 continue1558 }1559 for (s = 0, a = n.length - 1; s < a;) i = (s + a) / 2 | 0, e[n[i]] < l ? s = i + 1 : a = i;1560 l < e[n[s]] && (s > 0 && (t[r] = n[s - 1]), n[s] = r)1561 }1562 }1563 s = n.length, a = n[s - 1];1564 for (; s-- > 0;) n[s] = a, a = t[a];1565 return n1566 }(k) : v;1567 for (y = x.length - 1, c = R - 1; c >= 0; c--) {1568 const e = m + c, f = t[e], p = e + 1 < u ? t[e + 1].el : r;1569 0 === k[c] ? patch(null, f, n, p, o, s, a, i, l) : w && (y < 0 || c !== x[y] ? move(f, n, p, 2) : y--)1570 }1571 }1572 }, move = (e, t, r, o, s = null) => {1573 const {el: a, type: i, transition: l, children: c, shapeFlag: u} = e;1574 if (6 & u) return void move(e.component.subTree, t, r, o);1575 if (128 & u) return void e.suspense.move(t, r, o);1576 if (64 & u) return void i.move(e, t, r, R);1577 if (i === Le) {1578 n(a, t, r);1579 for (let e = 0; e < c.length; e++) move(c[e], t, r, o);1580 return void n(e.anchor, t, r)1581 }1582 if (i === Be) return void moveStaticNode(e, t, r);1583 if (2 !== o && 1 & u && l) if (0 === o) l.beforeEnter(a), n(a, t, r), Me((() => l.enter(a)), s); else {1584 const {leave: e, delayLeave: o, afterLeave: s} = l, remove3 = () => n(a, t, r), performLeave = () => {1585 e(a, (() => {1586 remove3(), s && s()1587 }))1588 };1589 o ? o(a, remove3, performLeave) : performLeave()1590 } else n(a, t, r)1591 }, unmount = (e, t, n, r = !1, o = !1) => {1592 const {type: s, props: a, ref: i, children: l, dynamicChildren: c, shapeFlag: u, patchFlag: f, dirs: p} = e;1593 if (null != i && setRef(i, null, n, e, !0), 256 & u) return void t.ctx.deactivate(e);1594 const d = 1 & u && p;1595 let m;1596 if ((m = a && a.onVnodeBeforeUnmount) && invokeVNodeHook(m, t, e), 6 & u) unmountComponent(e.component, n, r); else {1597 if (128 & u) return void e.suspense.unmount(n, r);1598 d && invokeDirectiveHook(e, null, t, "beforeUnmount"), 64 & u ? e.type.remove(e, t, n, o, R, r) : c && (s !== Le || f > 0 && 64 & f) ? unmountChildren(c, t, n, !1, !0) : (s === Le && (128 & f || 256 & f) || !o && 16 & u) && unmountChildren(l, t, n), r && remove2(e)1599 }1600 ((m = a && a.onVnodeUnmounted) || d) && Me((() => {1601 m && invokeVNodeHook(m, t, e), d && invokeDirectiveHook(e, null, t, "unmounted")1602 }), n)1603 }, remove2 = e => {1604 const {type: t, el: n, anchor: o, transition: s} = e;1605 if (t === Le) return void removeFragment(n, o);1606 if (t === Be) return void removeStaticNode(e);1607 const performRemove = () => {1608 r(n), s && !s.persisted && s.afterLeave && s.afterLeave()1609 };1610 if (1 & e.shapeFlag && s && !s.persisted) {1611 const {leave: t, delayLeave: r} = s, performLeave = () => t(n, performRemove);1612 r ? r(e.el, performRemove, performLeave) : performLeave()1613 } else performRemove()1614 }, removeFragment = (e, t) => {1615 let n;...
note.js
Source:note.js
...465 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {466 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren);467 }468 if (dirs) {469 invokeDirectiveHook(vnode, null, parentComponent, 'created');470 }471 // props472 if (props) {473 for (const key in props) {474 if (!isReservedProp(key)) {475 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);476 }477 }478 if ((vnodeHook = props.onVnodeBeforeMount)) {479 invokeVNodeHook(vnodeHook, parentComponent, vnode);480 }481 }482 // scopeId483 setScopeId(el, scopeId, vnode, parentComponent);484 }485 {486 Object.defineProperty(el, '__vnode', {487 value: vnode,488 enumerable: false489 });490 Object.defineProperty(el, '__vueParentComponent', {491 value: parentComponent,492 enumerable: false493 });494 }495 if (dirs) {496 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');497 }498 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved499 // #1689 For inside suspense + suspense resolved case, just call it500 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&501 transition &&502 !transition.persisted;503 if (needCallTransitionHooks) {504 transition.beforeEnter(el);505 }506 hostInsert(el, container, anchor);507 if ((vnodeHook = props && props.onVnodeMounted) ||508 needCallTransitionHooks ||509 dirs) {510 queuePostRenderEffect(() => {511 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);512 needCallTransitionHooks && transition.enter(el);513 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');514 }, parentSuspense);515 }516 };517 const setScopeId = (el, scopeId, vnode, parentComponent) => {518 if (scopeId) {519 hostSetScopeId(el, scopeId);520 }521 if (parentComponent) {522 const treeOwnerId = parentComponent.type.__scopeId;523 // vnode's own scopeId and the current patched component's scopeId is524 // different - this is a slot content node.525 if (treeOwnerId && treeOwnerId !== scopeId) {526 hostSetScopeId(el, treeOwnerId + '-s');527 }528 let subTree = parentComponent.subTree;529 if ( subTree.type === Fragment) {530 subTree =531 filterSingleRoot(subTree.children) || subTree;532 }533 if (vnode === subTree) {534 setScopeId(el, parentComponent.vnode.scopeId, parentComponent.vnode, parentComponent.parent);535 }536 }537 };538 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) => {539 for (let i = start; i < children.length; i++) {540 const child = (children[i] = optimized541 ? cloneIfMounted(children[i])542 : normalizeVNode(children[i]));543 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);544 }545 };546 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, optimized) => {547 const el = (n2.el = n1.el);548 let { patchFlag, dynamicChildren, dirs } = n2;549 // #1426 take the old vnode's patch flag into account since user may clone a550 // compiler-generated vnode, which de-opts to FULL_PROPS551 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;552 const oldProps = n1.props || EMPTY_OBJ;553 const newProps = n2.props || EMPTY_OBJ;554 let vnodeHook;555 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {556 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);557 }558 if (dirs) {559 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');560 }561 if ( isHmrUpdating) {562 // HMR updated, force full diff563 patchFlag = 0;564 optimized = false;565 dynamicChildren = null;566 }567 if (patchFlag > 0) {568 // the presence of a patchFlag means this element's render code was569 // generated by the compiler and can take the fast path.570 // in this path old node and new node are guaranteed to have the same shape571 // (i.e. at the exact same position in the source template)572 if (patchFlag & 16 /* FULL_PROPS */) {573 // element props contain dynamic keys, full diff needed574 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);575 }576 else {577 // class578 // this flag is matched when the element has dynamic class bindings.579 if (patchFlag & 2 /* CLASS */) {580 if (oldProps.class !== newProps.class) {581 hostPatchProp(el, 'class', null, newProps.class, isSVG);582 }583 }584 // style585 // this flag is matched when the element has dynamic style bindings586 if (patchFlag & 4 /* STYLE */) {587 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);588 }589 // props590 // This flag is matched when the element has dynamic prop/attr bindings591 // other than class and style. The keys of dynamic prop/attrs are saved for592 // faster iteration.593 // Note dynamic keys like :[foo]="bar" will cause this optimization to594 // bail out and go through a full diff because we need to unset the old key595 if (patchFlag & 8 /* PROPS */) {596 // if the flag is present then dynamicProps must be non-null597 const propsToUpdate = n2.dynamicProps;598 for (let i = 0; i < propsToUpdate.length; i++) {599 const key = propsToUpdate[i];600 const prev = oldProps[key];601 const next = newProps[key];602 if (next !== prev ||603 (hostForcePatchProp && hostForcePatchProp(el, key))) {604 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);605 }606 }607 }608 }609 // text610 // This flag is matched when the element has only dynamic text children.611 if (patchFlag & 1 /* TEXT */) {612 if (n1.children !== n2.children) {613 hostSetElementText(el, n2.children);614 }615 }616 }617 else if (!optimized && dynamicChildren == null) {618 // unoptimized, full diff619 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);620 }621 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';622 if (dynamicChildren) {623 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);624 if ( parentComponent && parentComponent.type.__hmrId) {625 traverseStaticChildren(n1, n2);626 }627 }628 else if (!optimized) {629 // full diff630 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG);631 }632 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {633 queuePostRenderEffect(() => {634 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);635 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');636 }, parentSuspense);637 }638 };639 // The fast path for blocks.640 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG) => {641 for (let i = 0; i < newChildren.length; i++) {642 const oldVNode = oldChildren[i];643 const newVNode = newChildren[i];644 // Determine the container (parent element) for the patch.645 const container = 646 // - In the case of a Fragment, we need to provide the actual parent647 // of the Fragment itself so it can move its children.648 oldVNode.type === Fragment ||649 // - In the case of different nodes, there is going to be a replacement650 // which also requires the correct parent container651 !isSameVNodeType(oldVNode, newVNode) ||652 // - In the case of a component, it could contain anything.653 oldVNode.shapeFlag & 6 /* COMPONENT */ ||654 oldVNode.shapeFlag & 64 /* TELEPORT */655 ? hostParentNode(oldVNode.el)656 : // In other cases, the parent container is not actually used so we657 // just pass the block element here to avoid a DOM parentNode call.658 fallbackContainer;659 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, true);660 }661 };662 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {663 if (oldProps !== newProps) {664 for (const key in newProps) {665 if (isReservedProp(key))666 continue;667 const next = newProps[key];668 const prev = oldProps[key];669 if (next !== prev ||670 (hostForcePatchProp && hostForcePatchProp(el, key))) {671 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);672 }673 }674 if (oldProps !== EMPTY_OBJ) {675 for (const key in oldProps) {676 if (!isReservedProp(key) && !(key in newProps)) {677 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);678 }679 }680 }681 }682 };683 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {684 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));685 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));686 let { patchFlag, dynamicChildren } = n2;687 if (patchFlag > 0) {688 optimized = true;689 }690 if ( isHmrUpdating) {691 // HMR updated, force full diff692 patchFlag = 0;693 optimized = false;694 dynamicChildren = null;695 }696 if (n1 == null) {697 hostInsert(fragmentStartAnchor, container, anchor);698 hostInsert(fragmentEndAnchor, container, anchor);699 // a fragment can only have array children700 // since they are either generated by the compiler, or implicitly created701 // from arrays.702 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);703 }704 else {705 if (patchFlag > 0 &&706 patchFlag & 64 /* STABLE_FRAGMENT */ &&707 dynamicChildren) {708 // a stable fragment (template root or <template v-for>) doesn't need to709 // patch children order, but it may contain dynamicChildren.710 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG);711 if ( parentComponent && parentComponent.type.__hmrId) {712 traverseStaticChildren(n1, n2);713 }714 else if (715 // #2080 if the stable fragment has a key, it's a <template v-for> that may716 // get moved around. Make sure all root level vnodes inherit el.717 // #2134 or if it's a component root, it may also get moved around718 // as the component is being moved.719 n2.key != null ||720 (parentComponent && n2 === parentComponent.subTree)) {721 traverseStaticChildren(n1, n2, true /* shallow */);722 }723 }724 else {725 // keyed / unkeyed, or manual fragments.726 // for keyed & unkeyed, since they are compiler generated from v-for,727 // each child is guaranteed to be a block so the fragment will never728 // have dynamicChildren.729 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);730 }731 }732 };733 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {734 if (n1 == null) {735 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {736 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);737 }738 else {739 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);740 }741 }742 else {743 updateComponent(n1, n2, optimized);744 }745 };746 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {747 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));748 if ( instance.type.__hmrId) {749 registerHMR(instance);750 }751 {752 pushWarningContext(initialVNode);753 startMeasure(instance, `mount`);754 }755 // inject renderer internals for keepAlive756 if (isKeepAlive(initialVNode)) {757 instance.ctx.renderer = internals;758 }759 // resolve props and slots for setup context760 {761 startMeasure(instance, `init`);762 }763 setupComponent(instance);764 {765 endMeasure(instance, `init`);766 }767 // setup() is async. This component relies on async logic to be resolved768 // before proceeding769 if ( instance.asyncDep) {770 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);771 // Give it a placeholder if this is not hydration772 // TODO handle self-defined fallback773 if (!initialVNode.el) {774 const placeholder = (instance.subTree = createVNode(Comment));775 processCommentNode(null, placeholder, container, anchor);776 }777 return;778 }779 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);780 {781 popWarningContext();782 endMeasure(instance, `mount`);783 }784 };785 const updateComponent = (n1, n2, optimized) => {786 const instance = (n2.component = n1.component);787 if (shouldUpdateComponent(n1, n2, optimized)) {788 if (789 instance.asyncDep &&790 !instance.asyncResolved) {791 // async & still pending - just update props and slots792 // since the component's reactive effect for render isn't set-up yet793 {794 pushWarningContext(n2);795 }796 updateComponentPreRender(instance, n2, optimized);797 {798 popWarningContext();799 }800 return;801 }802 else {803 // normal update804 instance.next = n2;805 // in case the child component is also queued, remove it to avoid806 // double updating the same child component in the same flush.807 invalidateJob(instance.update);808 // instance.update is the reactive effect runner.809 instance.update();810 }811 }812 else {813 // no update needed. just copy over properties814 n2.component = n1.component;815 n2.el = n1.el;816 instance.vnode = n2;817 }818 };819 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {820 // create reactive effect for rendering821 instance.update = effect(function componentEffect() {822 if (!instance.isMounted) {823 let vnodeHook;824 const { el, props } = initialVNode;825 const { bm, m, parent } = instance;826 // beforeMount hook827 if (bm) {828 invokeArrayFns(bm);829 }830 // onVnodeBeforeMount831 if ((vnodeHook = props && props.onVnodeBeforeMount)) {832 invokeVNodeHook(vnodeHook, parent, initialVNode);833 }834 // render835 {836 startMeasure(instance, `render`);837 }838 const subTree = (instance.subTree = renderComponentRoot(instance));839 {840 endMeasure(instance, `render`);841 }842 if (el && hydrateNode) {843 {844 startMeasure(instance, `hydrate`);845 }846 // vnode has adopted host node - perform hydration instead of mount.847 hydrateNode(initialVNode.el, subTree, instance, parentSuspense);848 {849 endMeasure(instance, `hydrate`);850 }851 }852 else {853 {854 startMeasure(instance, `patch`);855 }856 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);857 {858 endMeasure(instance, `patch`);859 }860 initialVNode.el = subTree.el;861 }862 // mounted hook863 if (m) {864 queuePostRenderEffect(m, parentSuspense);865 }866 // onVnodeMounted867 if ((vnodeHook = props && props.onVnodeMounted)) {868 queuePostRenderEffect(() => {869 invokeVNodeHook(vnodeHook, parent, initialVNode);870 }, parentSuspense);871 }872 // activated hook for keep-alive roots.873 // #1742 activated hook must be accessed after first render874 // since the hook may be injected by a child keep-alive875 const { a } = instance;876 if (a &&877 initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {878 queuePostRenderEffect(a, parentSuspense);879 }880 instance.isMounted = true;881 }882 else {883 // updateComponent884 // This is triggered by mutation of component's own state (next: null)885 // OR parent calling processComponent (next: VNode)886 let { next, bu, u, parent, vnode } = instance;887 let originNext = next;888 let vnodeHook;889 {890 pushWarningContext(next || instance.vnode);891 }892 if (next) {893 updateComponentPreRender(instance, next, optimized);894 }895 else {896 next = vnode;897 }898 next.el = vnode.el;899 // beforeUpdate hook900 if (bu) {901 invokeArrayFns(bu);902 }903 // onVnodeBeforeUpdate904 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {905 invokeVNodeHook(vnodeHook, parent, next, vnode);906 }907 // render908 {909 startMeasure(instance, `render`);910 }911 const nextTree = renderComponentRoot(instance);912 {913 endMeasure(instance, `render`);914 }915 const prevTree = instance.subTree;916 instance.subTree = nextTree;917 // reset refs918 // only needed if previous patch had refs919 if (instance.refs !== EMPTY_OBJ) {920 instance.refs = {};921 }922 {923 startMeasure(instance, `patch`);924 }925 patch(prevTree, nextTree, 926 // parent may have changed if it's in a teleport927 hostParentNode(prevTree.el), 928 // anchor may have changed if it's in a fragment929 getNextHostNode(prevTree), instance, parentSuspense, isSVG);930 {931 endMeasure(instance, `patch`);932 }933 next.el = nextTree.el;934 if (originNext === null) {935 // self-triggered update. In case of HOC, update parent component936 // vnode el. HOC is indicated by parent instance's subTree pointing937 // to child component's vnode938 updateHOCHostEl(instance, nextTree.el);939 }940 // updated hook941 if (u) {942 queuePostRenderEffect(u, parentSuspense);943 }944 // onVnodeUpdated945 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {946 queuePostRenderEffect(() => {947 invokeVNodeHook(vnodeHook, parent, next, vnode);948 }, parentSuspense);949 }950 {951 devtoolsComponentUpdated(instance);952 }953 {954 popWarningContext();955 }956 }957 }, createDevEffectOptions(instance) );958 };959 const updateComponentPreRender = (instance, nextVNode, optimized) => {960 nextVNode.component = instance;961 const prevProps = instance.vnode.props;962 instance.vnode = nextVNode;963 instance.next = null;964 updateProps(instance, nextVNode.props, prevProps, optimized);965 updateSlots(instance, nextVNode.children);966 // props update may have triggered pre-flush watchers.967 // flush them before the render update.968 flushPreFlushCbs(undefined, instance.update);969 };970 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) => {971 const c1 = n1 && n1.children;972 const prevShapeFlag = n1 ? n1.shapeFlag : 0;973 const c2 = n2.children;974 const { patchFlag, shapeFlag } = n2;975 // fast path976 if (patchFlag > 0) {977 if (patchFlag & 128 /* KEYED_FRAGMENT */) {978 // this could be either fully-keyed or mixed (some keyed some not)979 // presence of patchFlag means children are guaranteed to be arrays980 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);981 return;982 }983 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {984 // unkeyed985 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);986 return;987 }988 }989 // children has 3 possibilities: text, array or no children.990 if (shapeFlag & 8 /* TEXT_CHILDREN */) {991 // text children fast path992 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {993 unmountChildren(c1, parentComponent, parentSuspense);994 }995 if (c2 !== c1) {996 hostSetElementText(container, c2);997 }998 }999 else {1000 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {1001 // prev children was array1002 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1003 // two arrays, cannot assume anything, do full diff1004 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1005 }1006 else {1007 // no new children, just unmount old1008 unmountChildren(c1, parentComponent, parentSuspense, true);1009 }1010 }1011 else {1012 // prev children was text OR null1013 // new children is array OR null1014 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {1015 hostSetElementText(container, '');1016 }1017 // mount new if array1018 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1019 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);1020 }1021 }1022 }1023 };1024 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {1025 c1 = c1 || EMPTY_ARR;1026 c2 = c2 || EMPTY_ARR;1027 const oldLength = c1.length;1028 const newLength = c2.length;1029 const commonLength = Math.min(oldLength, newLength);1030 let i;1031 for (i = 0; i < commonLength; i++) {1032 const nextChild = (c2[i] = optimized1033 ? cloneIfMounted(c2[i])1034 : normalizeVNode(c2[i]));1035 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, optimized);1036 }1037 if (oldLength > newLength) {1038 // remove old1039 unmountChildren(c1, parentComponent, parentSuspense, true, commonLength);1040 }1041 else {1042 // mount new1043 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, commonLength);1044 }1045 };1046 // can be all-keyed or mixed1047 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized) => {1048 let i = 0;1049 const l2 = c2.length;1050 let e1 = c1.length - 1; // prev ending index1051 let e2 = l2 - 1; // next ending index1052 // 1. sync from start1053 // (a b) c1054 // (a b) d e1055 while (i <= e1 && i <= e2) {1056 const n1 = c1[i];1057 const n2 = (c2[i] = optimized1058 ? cloneIfMounted(c2[i])1059 : normalizeVNode(c2[i]));1060 if (isSameVNodeType(n1, n2)) {1061 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);1062 }1063 else {1064 break;1065 }1066 i++;1067 }1068 // 2. sync from end1069 // a (b c)1070 // d e (b c)1071 while (i <= e1 && i <= e2) {1072 const n1 = c1[e1];1073 const n2 = (c2[e2] = optimized1074 ? cloneIfMounted(c2[e2])1075 : normalizeVNode(c2[e2]));1076 if (isSameVNodeType(n1, n2)) {1077 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);1078 }1079 else {1080 break;1081 }1082 e1--;1083 e2--;1084 }1085 // 3. common sequence + mount1086 // (a b)1087 // (a b) c1088 // i = 2, e1 = 1, e2 = 21089 // (a b)1090 // c (a b)1091 // i = 0, e1 = -1, e2 = 01092 if (i > e1) {1093 if (i <= e2) {1094 const nextPos = e2 + 1;1095 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;1096 while (i <= e2) {1097 patch(null, (c2[i] = optimized1098 ? cloneIfMounted(c2[i])1099 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG);1100 i++;1101 }1102 }1103 }1104 // 4. common sequence + unmount1105 // (a b) c1106 // (a b)1107 // i = 2, e1 = 2, e2 = 11108 // a (b c)1109 // (b c)1110 // i = 0, e1 = 0, e2 = -11111 else if (i > e2) {1112 while (i <= e1) {1113 unmount(c1[i], parentComponent, parentSuspense, true);1114 i++;1115 }1116 }1117 // 5. unknown sequence1118 // [i ... e1 + 1]: a b [c d e] f g1119 // [i ... e2 + 1]: a b [e d c h] f g1120 // i = 2, e1 = 4, e2 = 51121 else {1122 const s1 = i; // prev starting index1123 const s2 = i; // next starting index1124 // 5.1 build key:index map for newChildren1125 const keyToNewIndexMap = new Map();1126 for (i = s2; i <= e2; i++) {1127 const nextChild = (c2[i] = optimized1128 ? cloneIfMounted(c2[i])1129 : normalizeVNode(c2[i]));1130 if (nextChild.key != null) {1131 if ( keyToNewIndexMap.has(nextChild.key)) {1132 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);1133 }1134 keyToNewIndexMap.set(nextChild.key, i);1135 }1136 }1137 // 5.2 loop through old children left to be patched and try to patch1138 // matching nodes & remove nodes that are no longer present1139 let j;1140 let patched = 0;1141 const toBePatched = e2 - s2 + 1;1142 let moved = false;1143 // used to track whether any node has moved1144 let maxNewIndexSoFar = 0;1145 // works as Map<newIndex, oldIndex>1146 // Note that oldIndex is offset by +11147 // and oldIndex = 0 is a special value indicating the new node has1148 // no corresponding old node.1149 // used for determining longest stable subsequence1150 const newIndexToOldIndexMap = new Array(toBePatched);1151 for (i = 0; i < toBePatched; i++)1152 newIndexToOldIndexMap[i] = 0;1153 for (i = s1; i <= e1; i++) {1154 const prevChild = c1[i];1155 if (patched >= toBePatched) {1156 // all new children have been patched so this can only be a removal1157 unmount(prevChild, parentComponent, parentSuspense, true);1158 continue;1159 }1160 let newIndex;1161 if (prevChild.key != null) {1162 newIndex = keyToNewIndexMap.get(prevChild.key);1163 }1164 else {1165 // key-less node, try to locate a key-less node of the same type1166 for (j = s2; j <= e2; j++) {1167 if (newIndexToOldIndexMap[j - s2] === 0 &&1168 isSameVNodeType(prevChild, c2[j])) {1169 newIndex = j;1170 break;1171 }1172 }1173 }1174 if (newIndex === undefined) {1175 unmount(prevChild, parentComponent, parentSuspense, true);1176 }1177 else {1178 newIndexToOldIndexMap[newIndex - s2] = i + 1;1179 if (newIndex >= maxNewIndexSoFar) {1180 maxNewIndexSoFar = newIndex;1181 }1182 else {1183 moved = true;1184 }1185 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, optimized);1186 patched++;1187 }1188 }1189 // 5.3 move and mount1190 // generate longest stable subsequence only when nodes have moved1191 const increasingNewIndexSequence = moved1192 ? getSequence(newIndexToOldIndexMap)1193 : EMPTY_ARR;1194 j = increasingNewIndexSequence.length - 1;1195 // looping backwards so that we can use last patched node as anchor1196 for (i = toBePatched - 1; i >= 0; i--) {1197 const nextIndex = s2 + i;1198 const nextChild = c2[nextIndex];1199 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;1200 if (newIndexToOldIndexMap[i] === 0) {1201 // mount new1202 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG);1203 }1204 else if (moved) {1205 // move if:1206 // There is no stable subsequence (e.g. a reverse)1207 // OR current node is not among the stable sequence1208 if (j < 0 || i !== increasingNewIndexSequence[j]) {1209 move(nextChild, container, anchor, 2 /* REORDER */);1210 }1211 else {1212 j--;1213 }1214 }1215 }1216 }1217 };1218 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {1219 const { el, type, transition, children, shapeFlag } = vnode;1220 if (shapeFlag & 6 /* COMPONENT */) {1221 move(vnode.component.subTree, container, anchor, moveType);1222 return;1223 }1224 if ( shapeFlag & 128 /* SUSPENSE */) {1225 vnode.suspense.move(container, anchor, moveType);1226 return;1227 }1228 if (shapeFlag & 64 /* TELEPORT */) {1229 type.move(vnode, container, anchor, internals);1230 return;1231 }1232 if (type === Fragment) {1233 hostInsert(el, container, anchor);1234 for (let i = 0; i < children.length; i++) {1235 move(children[i], container, anchor, moveType);1236 }1237 hostInsert(vnode.anchor, container, anchor);1238 return;1239 }1240 // static node move can only happen when force updating HMR1241 if ( type === Static) {1242 moveStaticNode(vnode, container, anchor);1243 return;1244 }1245 // single nodes1246 const needTransition = moveType !== 2 /* REORDER */ &&1247 shapeFlag & 1 /* ELEMENT */ &&1248 transition;1249 if (needTransition) {1250 if (moveType === 0 /* ENTER */) {1251 transition.beforeEnter(el);1252 hostInsert(el, container, anchor);1253 queuePostRenderEffect(() => transition.enter(el), parentSuspense);1254 }1255 else {1256 const { leave, delayLeave, afterLeave } = transition;1257 const remove = () => hostInsert(el, container, anchor);1258 const performLeave = () => {1259 leave(el, () => {1260 remove();1261 afterLeave && afterLeave();1262 });1263 };1264 if (delayLeave) {1265 delayLeave(el, remove, performLeave);1266 }1267 else {1268 performLeave();1269 }1270 }1271 }1272 else {1273 hostInsert(el, container, anchor);1274 }1275 };1276 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false) => {1277 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;1278 // unset ref1279 if (ref != null && parentComponent) {1280 setRef(ref, null, parentComponent, parentSuspense, null);1281 }1282 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {1283 parentComponent.ctx.deactivate(vnode);1284 return;1285 }1286 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;1287 let vnodeHook;1288 if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {1289 invokeVNodeHook(vnodeHook, parentComponent, vnode);1290 }1291 if (shapeFlag & 6 /* COMPONENT */) {1292 unmountComponent(vnode.component, parentSuspense, doRemove);1293 }1294 else {1295 if ( shapeFlag & 128 /* SUSPENSE */) {1296 vnode.suspense.unmount(parentSuspense, doRemove);1297 return;1298 }1299 if (shouldInvokeDirs) {1300 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');1301 }1302 if (dynamicChildren &&1303 // #1153: fast path should not be taken for non-stable (v-for) fragments1304 (type !== Fragment ||1305 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {1306 // fast path for block nodes: only need to unmount dynamic children.1307 unmountChildren(dynamicChildren, parentComponent, parentSuspense);1308 }1309 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1310 unmountChildren(children, parentComponent, parentSuspense);1311 }1312 // an unmounted teleport should always remove its children1313 if (shapeFlag & 64 /* TELEPORT */) {1314 vnode.type.remove(vnode, internals);1315 }1316 if (doRemove) {1317 remove(vnode);1318 }1319 }1320 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {1321 queuePostRenderEffect(() => {1322 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);1323 shouldInvokeDirs &&1324 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');1325 }, parentSuspense);1326 }1327 };1328 const remove = vnode => {1329 const { type, el, anchor, transition } = vnode;1330 if (type === Fragment) {1331 removeFragment(el, anchor);1332 return;1333 }1334 if ( type === Static) {1335 removeStaticNode(vnode);1336 return;1337 }1338 const performRemove = () => {...
createApp.js
Source:createApp.js
...338 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {339 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren);340 }341 if (dirs) {342 invokeDirectiveHook(vnode, null, parentComponent, 'created');343 }344 // props345 if (props) {346 for (const key in props) {347 if (!isReservedProp(key)) {348 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);349 }350 }351 if ((vnodeHook = props.onVnodeBeforeMount)) {352 invokeVNodeHook(vnodeHook, parentComponent, vnode);353 }354 }355 // scopeId356 setScopeId(el, scopeId, vnode, parentComponent);357 }358 {359 Object.defineProperty(el, '__vnode', {360 value: vnode,361 enumerable: false362 });363 Object.defineProperty(el, '__vueParentComponent', {364 value: parentComponent,365 enumerable: false366 });367 }368 if (dirs) {369 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');370 }371 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved372 // #1689 For inside suspense + suspense resolved case, just call it373 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&374 transition &&375 !transition.persisted;376 if (needCallTransitionHooks) {377 transition.beforeEnter(el);378 }379 hostInsert(el, container, anchor);380 if ((vnodeHook = props && props.onVnodeMounted) ||381 needCallTransitionHooks ||382 dirs) {383 queuePostRenderEffect(() => {384 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);385 needCallTransitionHooks && transition.enter(el);386 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');387 }, parentSuspense);388 }389 };390 const setScopeId = (el, scopeId, vnode, parentComponent) => {391 if (scopeId) {392 hostSetScopeId(el, scopeId);393 }394 if (parentComponent) {395 const treeOwnerId = parentComponent.type.__scopeId;396 // vnode's own scopeId and the current patched component's scopeId is397 // different - this is a slot content node.398 if (treeOwnerId && treeOwnerId !== scopeId) {399 hostSetScopeId(el, treeOwnerId + '-s');400 }401 let subTree = parentComponent.subTree;402 if ( subTree.type === Fragment) {403 subTree =404 filterSingleRoot(subTree.children) || subTree;405 }406 if (vnode === subTree) {407 setScopeId(el, parentComponent.vnode.scopeId, parentComponent.vnode, parentComponent.parent);408 }409 }410 };411 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) => {412 for (let i = start; i < children.length; i++) {413 const child = (children[i] = optimized414 ? cloneIfMounted(children[i])415 : normalizeVNode(children[i]));416 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);417 }418 };419 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, optimized) => {420 const el = (n2.el = n1.el);421 let { patchFlag, dynamicChildren, dirs } = n2;422 // #1426 take the old vnode's patch flag into account since user may clone a423 // compiler-generated vnode, which de-opts to FULL_PROPS424 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;425 const oldProps = n1.props || EMPTY_OBJ;426 const newProps = n2.props || EMPTY_OBJ;427 let vnodeHook;428 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {429 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);430 }431 if (dirs) {432 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');433 }434 if ( isHmrUpdating) {435 // HMR updated, force full diff436 patchFlag = 0;437 optimized = false;438 dynamicChildren = null;439 }440 if (patchFlag > 0) {441 // the presence of a patchFlag means this element's render code was442 // generated by the compiler and can take the fast path.443 // in this path old node and new node are guaranteed to have the same shape444 // (i.e. at the exact same position in the source template)445 if (patchFlag & 16 /* FULL_PROPS */) {446 // element props contain dynamic keys, full diff needed447 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);448 }449 else {450 // class451 // this flag is matched when the element has dynamic class bindings.452 if (patchFlag & 2 /* CLASS */) {453 if (oldProps.class !== newProps.class) {454 hostPatchProp(el, 'class', null, newProps.class, isSVG);455 }456 }457 // style458 // this flag is matched when the element has dynamic style bindings459 if (patchFlag & 4 /* STYLE */) {460 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);461 }462 // props463 // This flag is matched when the element has dynamic prop/attr bindings464 // other than class and style. The keys of dynamic prop/attrs are saved for465 // faster iteration.466 // Note dynamic keys like :[foo]="bar" will cause this optimization to467 // bail out and go through a full diff because we need to unset the old key468 if (patchFlag & 8 /* PROPS */) {469 // if the flag is present then dynamicProps must be non-null470 const propsToUpdate = n2.dynamicProps;471 for (let i = 0; i < propsToUpdate.length; i++) {472 const key = propsToUpdate[i];473 const prev = oldProps[key];474 const next = newProps[key];475 if (next !== prev ||476 (hostForcePatchProp && hostForcePatchProp(el, key))) {477 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);478 }479 }480 }481 }482 // text483 // This flag is matched when the element has only dynamic text children.484 if (patchFlag & 1 /* TEXT */) {485 if (n1.children !== n2.children) {486 hostSetElementText(el, n2.children);487 }488 }489 }490 else if (!optimized && dynamicChildren == null) {491 // unoptimized, full diff492 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);493 }494 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';495 if (dynamicChildren) {496 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);497 if ( parentComponent && parentComponent.type.__hmrId) {498 traverseStaticChildren(n1, n2);499 }500 }501 else if (!optimized) {502 // full diff503 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG);504 }505 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {506 queuePostRenderEffect(() => {507 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);508 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');509 }, parentSuspense);510 }511 };512 // The fast path for blocks.513 const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG) => {514 for (let i = 0; i < newChildren.length; i++) {515 const oldVNode = oldChildren[i];516 const newVNode = newChildren[i];517 // Determine the container (parent element) for the patch.518 const container = 519 // - In the case of a Fragment, we need to provide the actual parent520 // of the Fragment itself so it can move its children.521 oldVNode.type === Fragment ||522 // - In the case of different nodes, there is going to be a replacement523 // which also requires the correct parent container524 !isSameVNodeType(oldVNode, newVNode) ||525 // - In the case of a component, it could contain anything.526 oldVNode.shapeFlag & 6 /* COMPONENT */ ||527 oldVNode.shapeFlag & 64 /* TELEPORT */528 ? hostParentNode(oldVNode.el)529 : // In other cases, the parent container is not actually used so we530 // just pass the block element here to avoid a DOM parentNode call.531 fallbackContainer;532 patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, true);533 }534 };535 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {536 if (oldProps !== newProps) {537 for (const key in newProps) {538 if (isReservedProp(key))539 continue;540 const next = newProps[key];541 const prev = oldProps[key];542 if (next !== prev ||543 (hostForcePatchProp && hostForcePatchProp(el, key))) {544 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);545 }546 }547 if (oldProps !== EMPTY_OBJ) {548 for (const key in oldProps) {549 if (!isReservedProp(key) && !(key in newProps)) {550 hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);551 }552 }553 }554 }555 };556 const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {557 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));558 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));559 let { patchFlag, dynamicChildren } = n2;560 if (patchFlag > 0) {561 optimized = true;562 }563 if ( isHmrUpdating) {564 // HMR updated, force full diff565 patchFlag = 0;566 optimized = false;567 dynamicChildren = null;568 }569 if (n1 == null) {570 hostInsert(fragmentStartAnchor, container, anchor);571 hostInsert(fragmentEndAnchor, container, anchor);572 // a fragment can only have array children573 // since they are either generated by the compiler, or implicitly created574 // from arrays.575 mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);576 }577 else {578 if (patchFlag > 0 &&579 patchFlag & 64 /* STABLE_FRAGMENT */ &&580 dynamicChildren) {581 // a stable fragment (template root or <template v-for>) doesn't need to582 // patch children order, but it may contain dynamicChildren.583 patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG);584 if ( parentComponent && parentComponent.type.__hmrId) {585 traverseStaticChildren(n1, n2);586 }587 else if (588 // #2080 if the stable fragment has a key, it's a <template v-for> that may589 // get moved around. Make sure all root level vnodes inherit el.590 // #2134 or if it's a component root, it may also get moved around591 // as the component is being moved.592 n2.key != null ||593 (parentComponent && n2 === parentComponent.subTree)) {594 traverseStaticChildren(n1, n2, true /* shallow */);595 }596 }597 else {598 // keyed / unkeyed, or manual fragments.599 // for keyed & unkeyed, since they are compiler generated from v-for,600 // each child is guaranteed to be a block so the fragment will never601 // have dynamicChildren.602 patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized);603 }604 }605 };606 const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {607 if (n1 == null) {608 if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {609 parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);610 }611 else {612 mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);613 }614 }615 else {616 updateComponent(n1, n2, optimized);617 }618 };619 const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {620 const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));621 if ( instance.type.__hmrId) {622 registerHMR(instance);623 }624 {625 pushWarningContext(initialVNode);626 startMeasure(instance, `mount`);627 }628 // inject renderer internals for keepAlive629 if (isKeepAlive(initialVNode)) {630 instance.ctx.renderer = internals;631 }632 // resolve props and slots for setup context633 {634 startMeasure(instance, `init`);635 }636 setupComponent(instance);637 {638 endMeasure(instance, `init`);639 }640 // setup() is async. This component relies on async logic to be resolved641 // before proceeding642 if ( instance.asyncDep) {643 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);644 // Give it a placeholder if this is not hydration645 // TODO handle self-defined fallback646 if (!initialVNode.el) {647 const placeholder = (instance.subTree = createVNode(Comment));648 processCommentNode(null, placeholder, container, anchor);649 }650 return;651 }652 setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);653 {654 popWarningContext();655 endMeasure(instance, `mount`);656 }657 };658 const updateComponent = (n1, n2, optimized) => {659 const instance = (n2.component = n1.component);660 if (shouldUpdateComponent(n1, n2, optimized)) {661 if (662 instance.asyncDep &&663 !instance.asyncResolved) {664 // async & still pending - just update props and slots665 // since the component's reactive effect for render isn't set-up yet666 {667 pushWarningContext(n2);668 }669 updateComponentPreRender(instance, n2, optimized);670 {671 popWarningContext();672 }673 return;674 }675 else {676 // normal update677 instance.next = n2;678 // in case the child component is also queued, remove it to avoid679 // double updating the same child component in the same flush.680 invalidateJob(instance.update);681 // instance.update is the reactive effect runner.682 instance.update();683 }684 }685 else {686 // no update needed. just copy over properties687 n2.component = n1.component;688 n2.el = n1.el;689 instance.vnode = n2;690 }691 };692 const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {693 // create reactive effect for rendering694 instance.update = effect(function componentEffect() {695 if (!instance.isMounted) {696 let vnodeHook;697 const { el, props } = initialVNode;698 const { bm, m, parent } = instance;699 // beforeMount hook700 if (bm) {701 invokeArrayFns(bm);702 }703 // onVnodeBeforeMount704 if ((vnodeHook = props && props.onVnodeBeforeMount)) {705 invokeVNodeHook(vnodeHook, parent, initialVNode);706 }707 // render708 {709 startMeasure(instance, `render`);710 }711 const subTree = (instance.subTree = renderComponentRoot(instance));712 {713 endMeasure(instance, `render`);714 }715 if (el && hydrateNode) {716 {717 startMeasure(instance, `hydrate`);718 }719 // vnode has adopted host node - perform hydration instead of mount.720 hydrateNode(initialVNode.el, subTree, instance, parentSuspense);721 {722 endMeasure(instance, `hydrate`);723 }724 }725 else {726 {727 startMeasure(instance, `patch`);728 }729 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);730 {731 endMeasure(instance, `patch`);732 }733 initialVNode.el = subTree.el;734 }735 // mounted hook736 if (m) {737 queuePostRenderEffect(m, parentSuspense);738 }739 // onVnodeMounted740 if ((vnodeHook = props && props.onVnodeMounted)) {741 queuePostRenderEffect(() => {742 invokeVNodeHook(vnodeHook, parent, initialVNode);743 }, parentSuspense);744 }745 // activated hook for keep-alive roots.746 // #1742 activated hook must be accessed after first render747 // since the hook may be injected by a child keep-alive748 const { a } = instance;749 if (a &&750 initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {751 queuePostRenderEffect(a, parentSuspense);752 }753 instance.isMounted = true;754 }755 else {756 // updateComponent757 // This is triggered by mutation of component's own state (next: null)758 // OR parent calling processComponent (next: VNode)759 let { next, bu, u, parent, vnode } = instance;760 let originNext = next;761 let vnodeHook;762 {763 pushWarningContext(next || instance.vnode);764 }765 if (next) {766 updateComponentPreRender(instance, next, optimized);767 }768 else {769 next = vnode;770 }771 next.el = vnode.el;772 // beforeUpdate hook773 if (bu) {774 invokeArrayFns(bu);775 }776 // onVnodeBeforeUpdate777 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {778 invokeVNodeHook(vnodeHook, parent, next, vnode);779 }780 // render781 {782 startMeasure(instance, `render`);783 }784 const nextTree = renderComponentRoot(instance);785 {786 endMeasure(instance, `render`);787 }788 const prevTree = instance.subTree;789 instance.subTree = nextTree;790 // reset refs791 // only needed if previous patch had refs792 if (instance.refs !== EMPTY_OBJ) {793 instance.refs = {};794 }795 {796 startMeasure(instance, `patch`);797 }798 patch(prevTree, nextTree, 799 // parent may have changed if it's in a teleport800 hostParentNode(prevTree.el), 801 // anchor may have changed if it's in a fragment802 getNextHostNode(prevTree), instance, parentSuspense, isSVG);803 {804 endMeasure(instance, `patch`);805 }806 next.el = nextTree.el;807 if (originNext === null) {808 // self-triggered update. In case of HOC, update parent component809 // vnode el. HOC is indicated by parent instance's subTree pointing810 // to child component's vnode811 updateHOCHostEl(instance, nextTree.el);812 }813 // updated hook814 if (u) {815 queuePostRenderEffect(u, parentSuspense);816 }817 // onVnodeUpdated818 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {819 queuePostRenderEffect(() => {820 invokeVNodeHook(vnodeHook, parent, next, vnode);821 }, parentSuspense);822 }823 {824 devtoolsComponentUpdated(instance);825 }826 {827 popWarningContext();828 }829 }830 }, createDevEffectOptions(instance) );831 };832 const updateComponentPreRender = (instance, nextVNode, optimized) => {833 nextVNode.component = instance;834 const prevProps = instance.vnode.props;835 instance.vnode = nextVNode;836 instance.next = null;837 updateProps(instance, nextVNode.props, prevProps, optimized);838 updateSlots(instance, nextVNode.children);839 // props update may have triggered pre-flush watchers.840 // flush them before the render update.841 flushPreFlushCbs(undefined, instance.update);842 };843 const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) => {844 const c1 = n1 && n1.children;845 const prevShapeFlag = n1 ? n1.shapeFlag : 0;846 const c2 = n2.children;847 const { patchFlag, shapeFlag } = n2;848 // fast path849 if (patchFlag > 0) {850 if (patchFlag & 128 /* KEYED_FRAGMENT */) {851 // this could be either fully-keyed or mixed (some keyed some not)852 // presence of patchFlag means children are guaranteed to be arrays853 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);854 return;855 }856 else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {857 // unkeyed858 patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);859 return;860 }861 }862 // children has 3 possibilities: text, array or no children.863 if (shapeFlag & 8 /* TEXT_CHILDREN */) {864 // text children fast path865 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {866 unmountChildren(c1, parentComponent, parentSuspense);867 }868 if (c2 !== c1) {869 hostSetElementText(container, c2);870 }871 }872 else {873 if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {874 // prev children was array875 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {876 // two arrays, cannot assume anything, do full diff877 patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);878 }879 else {880 // no new children, just unmount old881 unmountChildren(c1, parentComponent, parentSuspense, true);882 }883 }884 else {885 // prev children was text OR null886 // new children is array OR null887 if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {888 hostSetElementText(container, '');889 }890 // mount new if array891 if (shapeFlag & 16 /* ARRAY_CHILDREN */) {892 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);893 }894 }895 }896 };897 const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {898 c1 = c1 || EMPTY_ARR;899 c2 = c2 || EMPTY_ARR;900 const oldLength = c1.length;901 const newLength = c2.length;902 const commonLength = Math.min(oldLength, newLength);903 let i;904 for (i = 0; i < commonLength; i++) {905 const nextChild = (c2[i] = optimized906 ? cloneIfMounted(c2[i])907 : normalizeVNode(c2[i]));908 patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, optimized);909 }910 if (oldLength > newLength) {911 // remove old912 unmountChildren(c1, parentComponent, parentSuspense, true, commonLength);913 }914 else {915 // mount new916 mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, commonLength);917 }918 };919 // can be all-keyed or mixed920 const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized) => {921 let i = 0;922 const l2 = c2.length;923 let e1 = c1.length - 1; // prev ending index924 let e2 = l2 - 1; // next ending index925 // 1. sync from start926 // (a b) c927 // (a b) d e928 while (i <= e1 && i <= e2) {929 const n1 = c1[i];930 const n2 = (c2[i] = optimized931 ? cloneIfMounted(c2[i])932 : normalizeVNode(c2[i]));933 if (isSameVNodeType(n1, n2)) {934 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);935 }936 else {937 break;938 }939 i++;940 }941 // 2. sync from end942 // a (b c)943 // d e (b c)944 while (i <= e1 && i <= e2) {945 const n1 = c1[e1];946 const n2 = (c2[e2] = optimized947 ? cloneIfMounted(c2[e2])948 : normalizeVNode(c2[e2]));949 if (isSameVNodeType(n1, n2)) {950 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized);951 }952 else {953 break;954 }955 e1--;956 e2--;957 }958 // 3. common sequence + mount959 // (a b)960 // (a b) c961 // i = 2, e1 = 1, e2 = 2962 // (a b)963 // c (a b)964 // i = 0, e1 = -1, e2 = 0965 if (i > e1) {966 if (i <= e2) {967 const nextPos = e2 + 1;968 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;969 while (i <= e2) {970 patch(null, (c2[i] = optimized971 ? cloneIfMounted(c2[i])972 : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG);973 i++;974 }975 }976 }977 // 4. common sequence + unmount978 // (a b) c979 // (a b)980 // i = 2, e1 = 2, e2 = 1981 // a (b c)982 // (b c)983 // i = 0, e1 = 0, e2 = -1984 else if (i > e2) {985 while (i <= e1) {986 unmount(c1[i], parentComponent, parentSuspense, true);987 i++;988 }989 }990 // 5. unknown sequence991 // [i ... e1 + 1]: a b [c d e] f g992 // [i ... e2 + 1]: a b [e d c h] f g993 // i = 2, e1 = 4, e2 = 5994 else {995 const s1 = i; // prev starting index996 const s2 = i; // next starting index997 // 5.1 build key:index map for newChildren998 const keyToNewIndexMap = new Map();999 for (i = s2; i <= e2; i++) {1000 const nextChild = (c2[i] = optimized1001 ? cloneIfMounted(c2[i])1002 : normalizeVNode(c2[i]));1003 if (nextChild.key != null) {1004 if ( keyToNewIndexMap.has(nextChild.key)) {1005 warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);1006 }1007 keyToNewIndexMap.set(nextChild.key, i);1008 }1009 }1010 // 5.2 loop through old children left to be patched and try to patch1011 // matching nodes & remove nodes that are no longer present1012 let j;1013 let patched = 0;1014 const toBePatched = e2 - s2 + 1;1015 let moved = false;1016 // used to track whether any node has moved1017 let maxNewIndexSoFar = 0;1018 // works as Map<newIndex, oldIndex>1019 // Note that oldIndex is offset by +11020 // and oldIndex = 0 is a special value indicating the new node has1021 // no corresponding old node.1022 // used for determining longest stable subsequence1023 const newIndexToOldIndexMap = new Array(toBePatched);1024 for (i = 0; i < toBePatched; i++)1025 newIndexToOldIndexMap[i] = 0;1026 for (i = s1; i <= e1; i++) {1027 const prevChild = c1[i];1028 if (patched >= toBePatched) {1029 // all new children have been patched so this can only be a removal1030 unmount(prevChild, parentComponent, parentSuspense, true);1031 continue;1032 }1033 let newIndex;1034 if (prevChild.key != null) {1035 newIndex = keyToNewIndexMap.get(prevChild.key);1036 }1037 else {1038 // key-less node, try to locate a key-less node of the same type1039 for (j = s2; j <= e2; j++) {1040 if (newIndexToOldIndexMap[j - s2] === 0 &&1041 isSameVNodeType(prevChild, c2[j])) {1042 newIndex = j;1043 break;1044 }1045 }1046 }1047 if (newIndex === undefined) {1048 unmount(prevChild, parentComponent, parentSuspense, true);1049 }1050 else {1051 newIndexToOldIndexMap[newIndex - s2] = i + 1;1052 if (newIndex >= maxNewIndexSoFar) {1053 maxNewIndexSoFar = newIndex;1054 }1055 else {1056 moved = true;1057 }1058 patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, optimized);1059 patched++;1060 }1061 }1062 // 5.3 move and mount1063 // generate longest stable subsequence only when nodes have moved1064 const increasingNewIndexSequence = moved1065 ? getSequence(newIndexToOldIndexMap)1066 : EMPTY_ARR;1067 j = increasingNewIndexSequence.length - 1;1068 // looping backwards so that we can use last patched node as anchor1069 for (i = toBePatched - 1; i >= 0; i--) {1070 const nextIndex = s2 + i;1071 const nextChild = c2[nextIndex];1072 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;1073 if (newIndexToOldIndexMap[i] === 0) {1074 // mount new1075 patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG);1076 }1077 else if (moved) {1078 // move if:1079 // There is no stable subsequence (e.g. a reverse)1080 // OR current node is not among the stable sequence1081 if (j < 0 || i !== increasingNewIndexSequence[j]) {1082 move(nextChild, container, anchor, 2 /* REORDER */);1083 }1084 else {1085 j--;1086 }1087 }1088 }1089 }1090 };1091 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {1092 const { el, type, transition, children, shapeFlag } = vnode;1093 if (shapeFlag & 6 /* COMPONENT */) {1094 move(vnode.component.subTree, container, anchor, moveType);1095 return;1096 }1097 if ( shapeFlag & 128 /* SUSPENSE */) {1098 vnode.suspense.move(container, anchor, moveType);1099 return;1100 }1101 if (shapeFlag & 64 /* TELEPORT */) {1102 type.move(vnode, container, anchor, internals);1103 return;1104 }1105 if (type === Fragment) {1106 hostInsert(el, container, anchor);1107 for (let i = 0; i < children.length; i++) {1108 move(children[i], container, anchor, moveType);1109 }1110 hostInsert(vnode.anchor, container, anchor);1111 return;1112 }1113 // static node move can only happen when force updating HMR1114 if ( type === Static) {1115 moveStaticNode(vnode, container, anchor);1116 return;1117 }1118 // single nodes1119 const needTransition = moveType !== 2 /* REORDER */ &&1120 shapeFlag & 1 /* ELEMENT */ &&1121 transition;1122 if (needTransition) {1123 if (moveType === 0 /* ENTER */) {1124 transition.beforeEnter(el);1125 hostInsert(el, container, anchor);1126 queuePostRenderEffect(() => transition.enter(el), parentSuspense);1127 }1128 else {1129 const { leave, delayLeave, afterLeave } = transition;1130 const remove = () => hostInsert(el, container, anchor);1131 const performLeave = () => {1132 leave(el, () => {1133 remove();1134 afterLeave && afterLeave();1135 });1136 };1137 if (delayLeave) {1138 delayLeave(el, remove, performLeave);1139 }1140 else {1141 performLeave();1142 }1143 }1144 }1145 else {1146 hostInsert(el, container, anchor);1147 }1148 };1149 const unmount = (vnode, parentComponent, parentSuspense, doRemove = false) => {1150 const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;1151 // unset ref1152 if (ref != null && parentComponent) {1153 setRef(ref, null, parentComponent, parentSuspense, null);1154 }1155 if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {1156 parentComponent.ctx.deactivate(vnode);1157 return;1158 }1159 const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;1160 let vnodeHook;1161 if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {1162 invokeVNodeHook(vnodeHook, parentComponent, vnode);1163 }1164 if (shapeFlag & 6 /* COMPONENT */) {1165 unmountComponent(vnode.component, parentSuspense, doRemove);1166 }1167 else {1168 if ( shapeFlag & 128 /* SUSPENSE */) {1169 vnode.suspense.unmount(parentSuspense, doRemove);1170 return;1171 }1172 if (shouldInvokeDirs) {1173 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');1174 }1175 if (dynamicChildren &&1176 // #1153: fast path should not be taken for non-stable (v-for) fragments1177 (type !== Fragment ||1178 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {1179 // fast path for block nodes: only need to unmount dynamic children.1180 unmountChildren(dynamicChildren, parentComponent, parentSuspense);1181 }1182 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {1183 unmountChildren(children, parentComponent, parentSuspense);1184 }1185 // an unmounted teleport should always remove its children1186 if (shapeFlag & 64 /* TELEPORT */) {1187 vnode.type.remove(vnode, internals);1188 }1189 if (doRemove) {1190 remove(vnode);1191 }1192 }1193 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {1194 queuePostRenderEffect(() => {1195 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);1196 shouldInvokeDirs &&1197 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');1198 }, parentSuspense);1199 }1200 };1201 const remove = vnode => {1202 const { type, el, anchor, transition } = vnode;1203 if (type === Fragment) {1204 removeFragment(el, anchor);1205 return;1206 }1207 if ( type === Static) {1208 removeStaticNode(vnode);1209 return;1210 }1211 const performRemove = () => {...
patch.js
Source:patch.js
...415 vnode.suspense.unmount(parentSuspense, doRemove);416 return;417 }418 if (shouldInvokeDirs) {419 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');420 }421 if (dynamicChildren &&422 // #1153: fast path should not be taken for non-stable (v-for) fragments423 (type !== Fragment ||424 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {425 // fast path for block nodes: only need to unmount dynamic children.426 unmountChildren(dynamicChildren, parentComponent, parentSuspense);427 }428 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {429 unmountChildren(children, parentComponent, parentSuspense);430 }431 // an unmounted teleport should always remove its children432 if (shapeFlag & 64 /* TELEPORT */) {433 vnode.type.remove(vnode, internals);434 }435 if (doRemove) {436 remove(vnode);437 }438 }439 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {440 queuePostRenderEffect(() => {441 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);442 shouldInvokeDirs &&443 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');444 }, parentSuspense);445 }446};447const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) => {448 // patching & not same type, unmount old tree449 if (n1 && !isSameVNodeType(n1, n2)) {450 anchor = getNextHostNode(n1);451 unmount(n1, parentComponent, parentSuspense, true);452 n1 = null;453 }454 if (n2.patchFlag === -2 /* BAIL */) {455 optimized = false;456 n2.dynamicChildren = null;457 }458 const { type, ref, shapeFlag } = n2;459 switch (type) {460 case Text:461 processText(n1, n2, container, anchor);462 break;463 case Comment:464 processCommentNode(n1, n2, container, anchor);465 break;466 case Static:467 if (n1 == null) {468 mountStaticNode(n2, container, anchor, isSVG);469 }470 else {471 patchStaticNode(n1, n2, container, isSVG);472 }473 break;474 case Fragment:475 processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);476 break;477 default:478 if (shapeFlag & 1 /* ELEMENT */) {479 processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);480 }481 else if (shapeFlag & 6 /* COMPONENT */) {482 processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);483 }484 else if (shapeFlag & 64 /* TELEPORT */) {485 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);486 }487 else if ( shapeFlag & 128 /* SUSPENSE */) {488 type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals);489 }490 else {491 warn('Invalid VNode type:', type, `(${typeof type})`);492 }493 }494 // set ref495 if (ref != null && parentComponent) {496 setRef(ref, n1 && n1.ref, parentComponent, parentSuspense, n2);497 }498};499const processText = (n1, n2, container, anchor) => {500 if (n1 == null) {501 hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);502 }503 else {504 const el = (n2.el = n1.el);505 if (n2.children !== n1.children) {506 hostSetText(el, n2.children);507 }508 }509};510const processCommentNode = (n1, n2, container, anchor) => {511 if (n1 == null) {512 hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);513 }514 else {515 // there's no support for dynamic comments516 n2.el = n1.el;517 }518};519const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {520 isSVG = isSVG || n2.type === 'svg';521 if (n1 == null) {522 mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);523 }524 else {525 patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized);526 }527};528 const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {529 let el;530 let vnodeHook;531 const { type, props, shapeFlag, transition, scopeId, patchFlag, dirs } = vnode;532 {533 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is);534 // mount children first, since some props may rely on child content535 // being already rendered, e.g. `<select value>`536 if (shapeFlag & 8 /* TEXT_CHILDREN */) {537 hostSetElementText(el, vnode.children);538 }539 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {540 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren);541 }542 if (dirs) {543 invokeDirectiveHook(vnode, null, parentComponent, 'created');544 }545 // props546 if (props) {547 for (const key in props) {548 if (!isReservedProp(key)) {549 hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);550 }551 }552 if ((vnodeHook = props.onVnodeBeforeMount)) {553 invokeVNodeHook(vnodeHook, parentComponent, vnode);554 }555 }556 // scopeId557 setScopeId(el, scopeId, vnode, parentComponent);558 }559 {560 Object.defineProperty(el, '__vnode', {561 value: vnode,562 enumerable: false563 });564 Object.defineProperty(el, '__vueParentComponent', {565 value: parentComponent,566 enumerable: false567 });568 }569 if (dirs) {570 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');571 }572 // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved573 // #1689 For inside suspense + suspense resolved case, just call it574 const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&575 transition &&576 !transition.persisted;577 if (needCallTransitionHooks) {578 transition.beforeEnter(el);579 }580 hostInsert(el, container, anchor);581 if ((vnodeHook = props && props.onVnodeMounted) ||582 needCallTransitionHooks ||583 dirs) {584 queuePostRenderEffect(() => {585 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);586 needCallTransitionHooks && transition.enter(el);587 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');588 }, parentSuspense);589 }590 };591 function invokeDirectiveHook(vnode, prevVNode, instance, name) {592 const bindings = vnode.dirs;593 const oldBindings = prevVNode && prevVNode.dirs;594 for (let i = 0; i < bindings.length; i++) {595 const binding = bindings[i];596 if (oldBindings) {597 binding.oldValue = oldBindings[i].value;598 }599 const hook = binding.dir[name];600 if (hook) {601 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [602 vnode.el,603 binding,604 vnode,605 prevVNode606 ]);607 }608 }609 }610 function callWithAsyncErrorHandling(fn, instance, type, args) {611 if (isFunction(fn)) {612 const res = callWithErrorHandling(fn, instance, type, args);613 if (res && isPromise(res)) {614 res.catch(err => {615 handleError(err, instance, type);616 });617 }618 return res;619 }620 const values = [];621 for (let i = 0; i < fn.length; i++) {622 values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));623 }624 return values;625 }626 const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) => {627 for (let i = start; i < children.length; i++) {628 const child = (children[i] = optimized629 ? cloneIfMounted(children[i])630 : normalizeVNode(children[i]));631 patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized);632 }633 };634 const setScopeId = (el, scopeId, vnode, parentComponent) => {635 if (scopeId) {636 hostSetScopeId(el, scopeId);637 }638 if (parentComponent) {639 const treeOwnerId = parentComponent.type.__scopeId;640 // vnode's own scopeId and the current patched component's scopeId is641 // different - this is a slot content node.642 if (treeOwnerId && treeOwnerId !== scopeId) {643 hostSetScopeId(el, treeOwnerId + '-s');644 }645 let subTree = parentComponent.subTree;646 if ( subTree.type === Fragment) {647 subTree =648 filterSingleRoot(subTree.children) || subTree;649 }650 if (vnode === subTree) {651 setScopeId(el, parentComponent.vnode.scopeId, parentComponent.vnode, parentComponent.parent);652 }653 }654 };655 const queuePostRenderEffect = queueEffectWithSuspense656 function queueEffectWithSuspense(fn, suspense) {657 if (suspense && suspense.pendingBranch) {658 if (isArray(fn)) {659 suspense.effects.push(...fn);660 }661 else {662 suspense.effects.push(fn);663 }664 }665 else {666 queuePostFlushCb(fn);667 }668 }669 function queuePostFlushCb(cb) {670 queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);671 }672 function queueCb(cb, activeQueue, pendingQueue, index) {673 if (!isArray(cb)) {674 if (!activeQueue ||675 !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {676 pendingQueue.push(cb);677 }678 }679 else {680 // if cb is an array, it is a component lifecycle hook which can only be681 // triggered by a job, which is already deduped in the main queue, so682 // we can skip duplicate check here to improve perf683 pendingQueue.push(...cb);684 }685 queueFlush();686 }687 function queueJob(job) {688 // the dedupe search uses the startIndex argument of Array.includes()689 // by default the search index includes the current job that is being run690 // so it cannot recursively trigger itself again.691 // if the job is a watch() callback, the search will start with a +1 index to692 // allow it recursively trigger itself - it is the user's responsibility to693 // ensure it doesn't end up in an infinite loop.694 if ((!queue.length ||695 !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&696 job !== currentPreFlushParentJob) {697 queue.push(job);698 queueFlush();699 }700 }701 function queueFlush() {702 if (!isFlushing && !isFlushPending) {703 isFlushPending = true;704 currentFlushPromise = resolvedPromise.then(flushJobs);705 }706 }707 function flushJobs(seen) {708 isFlushPending = false;709 isFlushing = true;710 {711 seen = seen || new Map();712 }713 flushPreFlushCbs(seen);714 // Sort queue before flush.715 // This ensures that:716 // 1. Components are updated from parent to child. (because parent is always717 // created before the child so its render effect will have smaller718 // priority number)719 // 2. If a component is unmounted during a parent component's update,720 // its update can be skipped.721 // Jobs can never be null before flush starts, since they are only invalidated722 // during execution of another flushed job.723 queue.sort((a, b) => getId(a) - getId(b));724 try {725 for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {726 const job = queue[flushIndex];727 if (job) {728 if (true) {729 checkRecursiveUpdates(seen, job);730 }731 callWithErrorHandling(job, null, 14 /* SCHEDULER */);732 }733 }734 }735 finally {736 flushIndex = 0;737 queue.length = 0;738 flushPostFlushCbs(seen);739 isFlushing = false;740 currentFlushPromise = null;741 // some postFlushCb queued jobs!742 // keep flushing until it drains.743 if (queue.length || pendingPostFlushCbs.length) {744 flushJobs(seen);745 }746 }747 }748 function checkRecursiveUpdates(seen, fn) {749 if (!seen.has(fn)) {750 seen.set(fn, 1);751 }752 else {753 const count = seen.get(fn);754 if (count > RECURSION_LIMIT) {755 throw new Error(`Maximum recursive updates exceeded. ` +756 `This means you have a reactive effect that is mutating its own ` +757 `dependencies and thus recursively triggering itself. Possible sources ` +758 `include component template, render function, updated hook or ` +759 `watcher source function.`);760 }761 else {762 seen.set(fn, count + 1);763 }764 }765 }766 function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {767 callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [768 vnode,769 prevVNode770 ]);771 }772 function invokeDirectiveHook(vnode, prevVNode, instance, name) {773 const bindings = vnode.dirs;774 const oldBindings = prevVNode && prevVNode.dirs;775 for (let i = 0; i < bindings.length; i++) {776 const binding = bindings[i];777 if (oldBindings) {778 binding.oldValue = oldBindings[i].value;779 }780 const hook = binding.dir[name];781 if (hook) {782 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [783 vnode.el,784 binding,785 vnode,786 prevVNode787 ]);788 }789 }790 }791 const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {792 switch (key) {793 // special794 case 'class':795 patchClass(el, nextValue, isSVG);796 break;797 case 'style':798 patchStyle(el, prevValue, nextValue);799 break;800 default:801 if (isOn(key)) {802 // ignore v-model listeners803 if (!isModelListener(key)) {804 patchEvent(el, key, prevValue, nextValue, parentComponent);805 }806 }807 else if (shouldSetAsProp(el, key, nextValue, isSVG)) {808 patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);809 }810 else {811 // special case for <input v-model type="checkbox"> with812 // :true-value & :false-value813 // store value as dom properties since non-string values will be814 // stringified.815 if (key === 'true-value') {816 el._trueValue = nextValue;817 }818 else if (key === 'false-value') {819 el._falseValue = nextValue;820 }821 patchAttr(el, key, nextValue, isSVG);822 }823 break;824 }825 };826 // compiler should normalize class + :class bindings on the same element827 // into a single binding ['staticClass', dynamic]828 function patchClass(el, value, isSVG) {829 if (value == null) {830 value = '';831 }832 if (isSVG) {833 el.setAttribute('class', value);834 }835 else {836 // directly setting className should be faster than setAttribute in theory837 // if this is an element during a transition, take the temporary transition838 // classes into account.839 const transitionClasses = el._vtc;840 if (transitionClasses) {841 value = (value842 ? [value, ...transitionClasses]843 : [...transitionClasses]).join(' ');844 }845 el.className = value;846 }847 }848 function patchEvent(el, rawName, prevValue, nextValue, instance = null) {849 // vei = vue event invokers850 const invokers = el._vei || (el._vei = {});851 const existingInvoker = invokers[rawName];852 if (nextValue && existingInvoker) {853 // patch854 existingInvoker.value = nextValue;855 }856 else {857 const [name, options] = parseName(rawName);858 if (nextValue) {859 // add860 const invoker = (invokers[rawName] = createInvoker(nextValue, instance));861 addEventListener(el, name, invoker, options);862 }863 else if (existingInvoker) {864 // remove865 removeEventListener(el, name, existingInvoker, options);866 invokers[rawName] = undefined;867 }868 }869 }870 function createInvoker(initialValue, instance) {871 const invoker = (e) => {872 // async edge case #6566: inner click event triggers patch, event handler873 // attached to outer element during patch, and triggered again. This874 // happens because browsers fire microtask ticks between event propagation.875 // the solution is simple: we save the timestamp when a handler is attached,876 // and the handler would only fire if the event passed to it was fired877 // AFTER it was attached.878 const timeStamp = e.timeStamp || _getNow();879 if (timeStamp >= invoker.attached - 1) {880 callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);881 }882 };883 invoker.value = initialValue;884 invoker.attached = getNow();885 return invoker;886 }887 function patchStopImmediatePropagation(e, value) {888 if (isArray(value)) {889 const originalStop = e.stopImmediatePropagation;890 e.stopImmediatePropagation = () => {891 originalStop.call(e);892 e._stopped = true;893 };894 return value.map(fn => (e) => !e._stopped && fn(e));895 }896 else {897 return value;898 }899 }900 function shouldSetAsProp(el, key, value, isSVG) {901 if (isSVG) {902 // most keys must be set as attribute on svg elements to work903 // ...except innerHTML904 if (key === 'innerHTML') {905 return true;906 }907 // or native onclick with function values908 if (key in el && nativeOnRE.test(key) && isFunction(value)) {909 return true;910 }911 return false;912 }913 // spellcheck and draggable are numerated attrs, however their914 // corresponding DOM properties are actually booleans - this leads to915 // setting it with a string "false" value leading it to be coerced to916 // `true`, so we need to always treat them as attributes.917 // Note that `contentEditable` doesn't have this problem: its DOM918 // property is also enumerated string values.919 if (key === 'spellcheck' || key === 'draggable') {920 return false;921 }922 // #1787 form as an attribute must be a string, while it accepts an Element as923 // a prop924 if (key === 'form' && typeof value === 'string') {925 return false;926 }927 // #1526 <input list> must be set as attribute928 if (key === 'list' && el.tagName === 'INPUT') {929 return false;930 }931 // native onclick with string value, must be set as attribute932 if (nativeOnRE.test(key) && isString(value)) {933 return false;934 }935 return key in el;936 }937 function patchDOMProp(el, key, value, 938 // the following args are passed only due to potential innerHTML/textContent939 // overriding existing VNodes, in which case the old tree must be properly940 // unmounted.941 prevChildren, parentComponent, parentSuspense, unmountChildren) {942 if (key === 'innerHTML' || key === 'textContent') {943 if (prevChildren) {944 unmountChildren(prevChildren, parentComponent, parentSuspense);945 }946 el[key] = value == null ? '' : value;947 return;948 }949 if (key === 'value' && el.tagName !== 'PROGRESS') {950 // store value as _value as well since951 // non-string values will be stringified.952 el._value = value;953 const newValue = value == null ? '' : value;954 if (el.value !== newValue) {955 el.value = newValue;956 }957 return;958 }959 if (value === '' && typeof el[key] === 'boolean') {960 // e.g. <select multiple> compiles to { multiple: '' }961 el[key] = true;962 }963 else if (value == null && typeof el[key] === 'string') {964 // e.g. <div :id="null">965 el[key] = '';966 el.removeAttribute(key);967 }968 else {969 // some properties perform value validation and throw970 try {971 el[key] = value;972 }973 catch (e) {974 {975 warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +976 `value ${value} is invalid.`, e);977 }978 }979 }980 }981 function patchAttr(el, key, value, isSVG) {982 if (isSVG && key.startsWith('xlink:')) {983 if (value == null) {984 el.removeAttributeNS(xlinkNS, key.slice(6, key.length));985 }986 else {987 el.setAttributeNS(xlinkNS, key, value);988 }989 }990 else {991 // note we are only checking boolean attributes that don't have a992 // corresponding dom prop of the same name here.993 const isBoolean = isSpecialBooleanAttr(key);994 if (value == null || (isBoolean && value === false)) {995 el.removeAttribute(key);996 }997 else {998 el.setAttribute(key, isBoolean ? '' : value);999 }1000 }1001 }1002 const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;1003 const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);1004 /*1005 * å¯ä»¥æ ¹æ®shapeFlgæéæ©æ´æ°ï¼ç²åº¦æ´ç»1006 */1007 const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, optimized) => {1008 const el = (n2.el = n1.el);1009 let { patchFlag, dynamicChildren, dirs } = n2;1010 // #1426 take the old vnode's patch flag into account since user may clone a1011 // compiler-generated vnode, which de-opts to FULL_PROPS1012 patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;1013 const oldProps = n1.props || EMPTY_OBJ;1014 const newProps = n2.props || EMPTY_OBJ;1015 let vnodeHook;1016 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {1017 invokeVNodeHook(vnodeHook, parentComponent, n2, n1);1018 }1019 if (dirs) {1020 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');1021 }1022 if ( isHmrUpdating) {1023 // HMR updated, force full diff1024 patchFlag = 0;1025 optimized = false;1026 dynamicChildren = null;1027 }1028 if (patchFlag > 0) {1029 // the presence of a patchFlag means this element's render code was1030 // generated by the compiler and can take the fast path.1031 // in this path old node and new node are guaranteed to have the same shape1032 // (i.e. at the exact same position in the source template)1033 if (patchFlag & 16 /* FULL_PROPS */) {1034 // element props contain dynamic keys, full diff needed1035 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1036 }1037 else {1038 // class1039 // this flag is matched when the element has dynamic class bindings.1040 if (patchFlag & 2 /* CLASS */) {1041 if (oldProps.class !== newProps.class) {1042 hostPatchProp(el, 'class', null, newProps.class, isSVG);1043 }1044 }1045 // style1046 // this flag is matched when the element has dynamic style bindings1047 if (patchFlag & 4 /* STYLE */) {1048 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);1049 }1050 // props1051 // This flag is matched when the element has dynamic prop/attr bindings1052 // other than class and style. The keys of dynamic prop/attrs are saved for1053 // faster iteration.1054 // Note dynamic keys like :[foo]="bar" will cause this optimization to1055 // bail out and go through a full diff because we need to unset the old key1056 if (patchFlag & 8 /* PROPS */) {1057 // if the flag is present then dynamicProps must be non-null1058 const propsToUpdate = n2.dynamicProps;1059 for (let i = 0; i < propsToUpdate.length; i++) {1060 const key = propsToUpdate[i];1061 const prev = oldProps[key];1062 const next = newProps[key];1063 if (next !== prev ||1064 (hostForcePatchProp && hostForcePatchProp(el, key))) {1065 hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);1066 }1067 }1068 }1069 }1070 // text1071 // This flag is matched when the element has only dynamic text children.1072 if (patchFlag & 1 /* TEXT */) {1073 if (n1.children !== n2.children) {1074 hostSetElementText(el, n2.children);1075 }1076 }1077 }1078 else if (!optimized && dynamicChildren == null) {1079 // unoptimized, full diff1080 patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);1081 }1082 const areChildrenSVG = isSVG && n2.type !== 'foreignObject';1083 if (dynamicChildren) {1084 patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG);1085 if ( parentComponent && parentComponent.type.__hmrId) {1086 traverseStaticChildren(n1, n2);1087 }1088 }1089 else if (!optimized) {1090 // full diff1091 patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG);1092 }1093 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {1094 queuePostRenderEffect(() => {1095 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);1096 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');1097 }, parentSuspense);1098 }1099 };1100 const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {1101 if (oldProps !== newProps) {1102 for (const key in newProps) {1103 if (isReservedProp(key))1104 continue;1105 const next = newProps[key];1106 const prev = oldProps[key];1107 if (next !== prev ||1108 (hostForcePatchProp && hostForcePatchProp(el, key))) {1109 hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);1110 }...
renderer.js
Source:renderer.js
...266 }267 // æ令268 if (dirs) {269 // console.log('æ令ï¼created')270 invokeDirectiveHook(vnode, null, parentComponent, 'created')271 }272 if (props) {273 for (const key in props) {274 if (key !== 'value' && !isReservedProp(key)) {275 hostPatchProp(276 el,277 key,278 null,279 props[key],280 isSVG,281 vnode.children,282 parentComponent,283 parentSuspense,284 unmountChildren285 )286 }287 }288 if ('value' in props) {289 hostPatchProp(el, 'value', null, props.value)290 }291 if ((vnodeHook = props.onVnodeBeforeMount)) {292 invokeVNodeHook(vnodeHook, parentComponent, vnode)293 }294 }295 setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent)296 if (dirs) {297 // console.log('æ令ï¼beforeMount')298 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount')299 }300 const needCallTransitionHooks =301 (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&302 transition &&303 !transition.persisted304 if (needCallTransitionHooks) {305 transition.beforeEnter(el)306 }307 // æè½½å
ç´ 308 hostInsert(el, container, anchor)309 if (310 (vnodeHook = props && props.onVnodeMounted) ||311 needCallTransitionHooks ||312 dirs313 ) {314 queuePostRenderEffect(() => {315 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode)316 needCallTransitionHooks && transition.enter(el)317 dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted')318 }, parentSuspense)319 }320 }321 const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {322 if (scopeId) {323 hostSetScopeId(el, scopeId)324 }325 if (slotScopeIds) {326 for (let i = 0; i < slotScopeIds.length; i++) {327 hostSetScopeId(el, slotScopeIds[i])328 }329 }330 if (parentComponent) {331 let subTree = parentComponent.subTree332 if (vnode === subTree) {333 const parentVNode = parentComponent.vnode334 setScopeId(335 el,336 parentVNode,337 parentVNode.scopeId,338 parentVNode.slotScopeIds,339 parentComponent.parent340 )341 }342 }343 }344 const mountChildren = (345 children,346 container,347 anchor,348 parentComponent,349 parentSuspense,350 isSVG,351 slotScopeIds,352 start = 0353 ) => {354 for (let i = start; i < children.length; i++) {355 const child = (children[i] = normalizeVNode(children[i]))356 patch(357 null,358 child,359 container,360 anchor,361 parentComponent,362 parentSuspense,363 isSVG,364 slotScopeIds365 )366 }367 }368 const patchElement = (369 n1,370 n2,371 parentComponent,372 parentSuspense,373 isSVG,374 slotScopeIds375 ) => {376 const el = (n2.el = n1.el)377 let { patchFlag, dynamicChildren, dirs } = n2378 patchFlag |= n1.patchFlag & 16379 const oldProps = n1.props || EMPTY_OBJ380 const newProps = n2.props || EMPTY_OBJ381 let vnodeHook382 parentComponent && toggleRecurse(parentComponent, false)383 if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {384 invokeVNodeHook(vnodeHook, parentComponent, n2, n1)385 }386 if (dirs) {387 // console.log('æ令ï¼beforeUpdate')388 invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate')389 }390 parentComponent && toggleRecurse(parentComponent, true)391 const areChildrenSVG = isSVG && n2.type !== 'foreignObject'392 if (dynamicChildren) {393 patchBlockChildren(394 n1.dynamicChildren,395 dynamicChildren,396 el,397 parentComponent,398 parentSuspense,399 areChildrenSVG,400 slotScopeIds401 )402 } else {403 patchChildren(404 n1,405 n2,406 el,407 null,408 parentComponent,409 parentSuspense,410 areChildrenSVG,411 slotScopeIds,412 false413 )414 }415 if (patchFlag > 0) {416 if (patchFlag & 16) {417 patchProps(418 el,419 n2,420 oldProps,421 newProps,422 parentComponent,423 parentSuspense,424 isSVG425 )426 } else {427 if (patchFlag & 2) {428 if (oldProps.class !== newProps.class) {429 hostPatchProp(el, 'class', null, newProps.class, isSVG)430 }431 }432 if (patchFlag & 4) {433 hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG)434 }435 if (patchFlag & 8) {436 const propsToUpdate = n2.dynamicProps437 for (let i = 0; i < propsToUpdate.length; i++) {438 const key = propsToUpdate[i]439 const prev = oldProps[key]440 const next = newProps[key]441 if (next !== prev || key === 'value') {442 hostPatchProp(443 el,444 key,445 prev,446 next,447 isSVG,448 n1.children,449 parentComponent,450 parentSuspense,451 unmountChildren452 )453 }454 }455 }456 }457 if (patchFlag & 1) {458 if (n1.children !== n2.children) {459 hostSetElementText(el, n2.children)460 }461 }462 } else if (dynamicChildren == null) {463 patchProps(464 el,465 n2,466 oldProps,467 newProps,468 parentComponent,469 parentSuspense,470 isSVG471 )472 }473 if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {474 queuePostRenderEffect(() => {475 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1)476 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated')477 }, parentSuspense)478 }479 }480 const patchBlockChildren = (481 oldChildren,482 newChildren,483 fallbackContainer,484 parentComponent,485 parentSuspense,486 isSVG,487 slotScopeIds488 ) => {489 for (let i = 0; i < newChildren.length; i++) {490 const oldVNode = oldChildren[i]491 const newVNode = newChildren[i]492 const container =493 oldVNode.el &&494 (oldVNode.type === Fragment ||495 !isSameVNodeType(oldVNode, newVNode) ||496 oldVNode.shapeFlag & (6 | 64))497 ? hostParentNode(oldVNode.el)498 : fallbackContainer499 patch(500 oldVNode,501 newVNode,502 container,503 null,504 parentComponent,505 parentSuspense,506 isSVG,507 slotScopeIds,508 true509 )510 }511 }512 const patchProps = (513 el,514 vnode,515 oldProps,516 newProps,517 parentComponent,518 parentSuspense,519 isSVG520 ) => {521 if (oldProps !== newProps) {522 for (const key in newProps) {523 if (isReservedProp(key)) continue524 const next = newProps[key]525 const prev = oldProps[key]526 if (next !== prev && key !== 'value') {527 hostPatchProp(528 el,529 key,530 prev,531 next,532 isSVG,533 vnode.children,534 parentComponent,535 parentSuspense,536 unmountChildren537 )538 }539 }540 if (oldProps !== EMPTY_OBJ) {541 for (const key in oldProps) {542 if (!isReservedProp(key) && !(key in newProps)) {543 hostPatchProp(544 el,545 key,546 oldProps[key],547 null,548 isSVG,549 vnode.children,550 parentComponent,551 parentSuspense,552 unmountChildren553 )554 }555 }556 }557 if ('value' in newProps) {558 hostPatchProp(el, 'value', oldProps.value, newProps.value)559 }560 }561 }562 const processFragment = (563 n1,564 n2,565 container,566 anchor,567 parentComponent,568 parentSuspense,569 isSVG,570 slotScopeIds571 ) => {572 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''))573 const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''))574 let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2575 if (fragmentSlotScopeIds) {576 slotScopeIds = slotScopeIds577 ? slotScopeIds.concat(fragmentSlotScopeIds)578 : fragmentSlotScopeIds579 }580 if (n1 == null) {581 hostInsert(fragmentStartAnchor, container, anchor)582 hostInsert(fragmentEndAnchor, container, anchor)583 mountChildren(584 n2.children,585 container,586 fragmentEndAnchor,587 parentComponent,588 parentSuspense,589 isSVG,590 slotScopeIds591 )592 } else {593 if (594 patchFlag > 0 &&595 patchFlag & 64 &&596 dynamicChildren &&597 n1.dynamicChildren598 ) {599 patchBlockChildren(600 n1.dynamicChildren,601 dynamicChildren,602 container,603 parentComponent,604 parentSuspense,605 isSVG,606 slotScopeIds607 )608 if (609 n2.key != null ||610 (parentComponent && n2 === parentComponent.subTree)611 ) {612 traverseStaticChildren(n1, n2, true)613 }614 } else {615 patchChildren(616 n1,617 n2,618 container,619 fragmentEndAnchor,620 parentComponent,621 parentSuspense,622 isSVG,623 slotScopeIds624 )625 }626 }627 }628 const processComponent = (629 n1,630 n2,631 container,632 anchor,633 parentComponent,634 parentSuspense,635 isSVG,636 slotScopeIds637 ) => {638 n2.slotScopeIds = slotScopeIds639 if (n1 == null) {640 if (n2.shapeFlag & 512) {641 parentComponent.ctx.activate(n2, container, anchor, isSVG)642 } else {643 mountComponent(644 n2,645 container,646 anchor,647 parentComponent,648 parentSuspense,649 isSVG650 )651 }652 } else {653 updateComponent(n1, n2)654 }655 }656 const mountComponent = (657 initialVNode,658 container,659 anchor,660 parentComponent,661 parentSuspense,662 isSVG663 ) => {664 // å建ç»ä»¶å®ä¾665 const instance = (initialVNode.component = createComponentInstance(666 initialVNode,667 parentComponent,668 parentSuspense669 ))670 if (isKeepAlive(initialVNode)) {671 instance.ctx.renderer = internals672 }673 setupComponent(instance)674 if (instance.asyncDep) {675 parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect)676 if (!initialVNode.el) {677 const placeholder = (instance.subTree = createVNode(Comment))678 processCommentNode(null, placeholder, container, anchor)679 }680 return681 }682 setupRenderEffect(683 instance,684 initialVNode,685 container,686 anchor,687 parentSuspense,688 isSVG689 )690 }691 const updateComponent = (n1, n2) => {692 const instance = (n2.component = n1.component)693 if (shouldUpdateComponent(n1, n2)) {694 if (instance.asyncDep && !instance.asyncResolved) {695 updateComponentPreRender(instance, n2)696 return697 } else {698 instance.next = n2699 invalidateJob(instance.update)700 instance.update()701 }702 } else {703 n2.component = n1.component704 n2.el = n1.el705 instance.vnode = n2706 }707 }708 const setupRenderEffect = (709 instance,710 initialVNode,711 container,712 anchor,713 parentSuspense,714 isSVG715 ) => {716 // ç»ä»¶æ´æ°å½æ°717 const componentUpdateFn = () => {718 // ç»ä»¶æ¯å¦æè½½719 if (!instance.isMounted) {720 // å次æè½½721 let vnodeHook722 const { props } = initialVNode723 const { bm, m, parent } = instance724 const isAsyncWrapperVNode = isAsyncWrapper(initialVNode)725 toggleRecurse(instance, false)726 if (bm) {727 invokeArrayFns(bm)728 }729 if (730 !isAsyncWrapperVNode &&731 (vnodeHook = props && props.onVnodeBeforeMount)732 ) {733 invokeVNodeHook(vnodeHook, parent, initialVNode)734 }735 toggleRecurse(instance, true)736 const subTree = (instance.subTree = renderComponentRoot(instance))737 patch(null, subTree, container, anchor, instance, parentSuspense, isSVG)738 initialVNode.el = subTree.el739 if (m) {740 queuePostRenderEffect(m, parentSuspense)741 }742 if (743 !isAsyncWrapperVNode &&744 (vnodeHook = props && props.onVnodeMounted)745 ) {746 const scopedInitialVNode = initialVNode747 queuePostRenderEffect(748 () => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode),749 parentSuspense750 )751 }752 if (initialVNode.shapeFlag & 256) {753 instance.a && queuePostRenderEffect(instance.a, parentSuspense)754 }755 instance.isMounted = true756 initialVNode = container = anchor = null757 } else {758 // ç»ä»¶æ´æ°759 let { next, bu, u, parent, vnode } = instance760 let originNext = next761 let vnodeHook762 toggleRecurse(instance, false)763 if (next) {764 next.el = vnode.el765 updateComponentPreRender(instance, next)766 } else {767 next = vnode768 }769 if (bu) {770 invokeArrayFns(bu)771 }772 if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {773 invokeVNodeHook(vnodeHook, parent, next, vnode)774 }775 toggleRecurse(instance, true)776 const nextTree = renderComponentRoot(instance)777 const prevTree = instance.subTree778 instance.subTree = nextTree779 patch(780 prevTree,781 nextTree,782 hostParentNode(prevTree.el),783 getNextHostNode(prevTree),784 instance,785 parentSuspense,786 isSVG787 )788 next.el = nextTree.el789 if (originNext === null) {790 updateHOCHostEl(instance, nextTree.el)791 }792 if (u) {793 queuePostRenderEffect(u, parentSuspense)794 }795 if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {796 queuePostRenderEffect(797 () => invokeVNodeHook(vnodeHook, parent, next, vnode),798 parentSuspense799 )800 }801 }802 }803 const effect = (instance.effect = new ReactiveEffect(804 componentUpdateFn,805 () => queueJob(instance.update),806 instance.scope807 ))808 const update = (instance.update = effect.run.bind(effect))809 update.id = instance.uid810 toggleRecurse(instance, true)811 update()812 }813 const updateComponentPreRender = (instance, nextVNode) => {814 nextVNode.component = instance815 const prevProps = instance.vnode.props816 instance.vnode = nextVNode817 instance.next = null818 updateProps(instance, nextVNode.props, prevProps)819 updateSlots(instance, nextVNode.children)820 pauseTracking()821 flushPreFlushCbs(undefined, instance.update)822 resetTracking()823 }824 const patchChildren = (825 n1,826 n2,827 container,828 anchor,829 parentComponent,830 parentSuspense,831 isSVG,832 slotScopeIds833 ) => {834 const c1 = n1 && n1.children835 const prevShapeFlag = n1 ? n1.shapeFlag : 0836 const c2 = n2.children837 const { patchFlag, shapeFlag } = n2838 if (patchFlag > 0) {839 if (patchFlag & 128) {840 patchKeyedChildren(841 c1,842 c2,843 container,844 anchor,845 parentComponent,846 parentSuspense,847 isSVG,848 slotScopeIds849 )850 return851 } else if (patchFlag & 256) {852 patchUnkeyedChildren(853 c1,854 c2,855 container,856 anchor,857 parentComponent,858 parentSuspense,859 isSVG,860 slotScopeIds861 )862 return863 }864 }865 if (shapeFlag & 8) {866 if (prevShapeFlag & 16) {867 unmountChildren(c1, parentComponent, parentSuspense)868 }869 if (c2 !== c1) {870 hostSetElementText(container, c2)871 }872 } else {873 if (prevShapeFlag & 16) {874 if (shapeFlag & 16) {875 patchKeyedChildren(876 c1,877 c2,878 container,879 anchor,880 parentComponent,881 parentSuspense,882 isSVG,883 slotScopeIds884 )885 } else {886 unmountChildren(c1, parentComponent, parentSuspense, true)887 }888 } else {889 if (prevShapeFlag & 8) {890 hostSetElementText(container, '')891 }892 if (shapeFlag & 16) {893 mountChildren(894 c2,895 container,896 anchor,897 parentComponent,898 parentSuspense,899 isSVG,900 slotScopeIds901 )902 }903 }904 }905 }906 const patchUnkeyedChildren = (907 c1,908 c2,909 container,910 anchor,911 parentComponent,912 parentSuspense,913 isSVG,914 slotScopeIds915 ) => {916 c1 = c1 || EMPTY_ARR917 c2 = c2 || EMPTY_ARR918 const oldLength = c1.length919 const newLength = c2.length920 const commonLength = Math.min(oldLength, newLength)921 let i922 for (i = 0; i < commonLength; i++) {923 const nextChild = (c2[i] = normalizeVNode(c2[i]))924 patch(925 c1[i],926 nextChild,927 container,928 null,929 parentComponent,930 parentSuspense,931 isSVG,932 slotScopeIds933 )934 }935 if (oldLength > newLength) {936 unmountChildren(c1, parentComponent, parentSuspense, true, commonLength)937 } else {938 mountChildren(939 c2,940 container,941 anchor,942 parentComponent,943 parentSuspense,944 isSVG,945 slotScopeIds,946 commonLength947 )948 }949 }950 const patchKeyedChildren = (951 c1,952 c2,953 container,954 parentAnchor,955 parentComponent,956 parentSuspense,957 isSVG,958 slotScopeIds959 ) => {960 let i = 0961 const l2 = c2.length962 let e1 = c1.length - 1963 let e2 = l2 - 1964 while (i <= e1 && i <= e2) {965 const n1 = c1[i]966 const n2 = (c2[i] = normalizeVNode(c2[i]))967 if (isSameVNodeType(n1, n2)) {968 patch(969 n1,970 n2,971 container,972 null,973 parentComponent,974 parentSuspense,975 isSVG,976 slotScopeIds977 )978 } else {979 break980 }981 i++982 }983 while (i <= e1 && i <= e2) {984 const n1 = c1[e1]985 const n2 = (c2[e2] = normalizeVNode(c2[e2]))986 if (isSameVNodeType(n1, n2)) {987 patch(988 n1,989 n2,990 container,991 null,992 parentComponent,993 parentSuspense,994 isSVG,995 slotScopeIds996 )997 } else {998 break999 }1000 e1--1001 e2--1002 }1003 if (i > e1) {1004 if (i <= e2) {1005 const nextPos = e2 + 11006 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor1007 while (i <= e2) {1008 patch(1009 null,1010 (c2[i] = normalizeVNode(c2[i])),1011 container,1012 anchor,1013 parentComponent,1014 parentSuspense,1015 isSVG,1016 slotScopeIds1017 )1018 i++1019 }1020 }1021 } else if (i > e2) {1022 while (i <= e1) {1023 unmount(c1[i], parentComponent, parentSuspense, true)1024 i++1025 }1026 } else {1027 const s1 = i1028 const s2 = i1029 const keyToNewIndexMap = new Map()1030 for (i = s2; i <= e2; i++) {1031 const nextChild = (c2[i] = normalizeVNode(c2[i]))1032 if (nextChild.key != null) {1033 keyToNewIndexMap.set(nextChild.key, i)1034 }1035 }1036 let j1037 let patched = 01038 const toBePatched = e2 - s2 + 11039 let moved = false1040 let maxNewIndexSoFar = 01041 const newIndexToOldIndexMap = new Array(toBePatched)1042 for (i = 0; i < toBePatched; i++) newIndexToOldIndexMap[i] = 01043 for (i = s1; i <= e1; i++) {1044 const prevChild = c1[i]1045 if (patched >= toBePatched) {1046 unmount(prevChild, parentComponent, parentSuspense, true)1047 continue1048 }1049 let newIndex1050 if (prevChild.key != null) {1051 newIndex = keyToNewIndexMap.get(prevChild.key)1052 } else {1053 for (j = s2; j <= e2; j++) {1054 if (1055 newIndexToOldIndexMap[j - s2] === 0 &&1056 isSameVNodeType(prevChild, c2[j])1057 ) {1058 newIndex = j1059 break1060 }1061 }1062 }1063 if (newIndex === undefined) {1064 unmount(prevChild, parentComponent, parentSuspense, true)1065 } else {1066 newIndexToOldIndexMap[newIndex - s2] = i + 11067 if (newIndex >= maxNewIndexSoFar) {1068 maxNewIndexSoFar = newIndex1069 } else {1070 moved = true1071 }1072 patch(1073 prevChild,1074 c2[newIndex],1075 container,1076 null,1077 parentComponent,1078 parentSuspense,1079 isSVG,1080 slotScopeIds1081 )1082 patched++1083 }1084 }1085 const increasingNewIndexSequence = moved1086 ? getSequence(newIndexToOldIndexMap)1087 : EMPTY_ARR1088 j = increasingNewIndexSequence.length - 11089 for (i = toBePatched - 1; i >= 0; i--) {1090 const nextIndex = s2 + i1091 const nextChild = c2[nextIndex]1092 const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor1093 if (newIndexToOldIndexMap[i] === 0) {1094 patch(1095 null,1096 nextChild,1097 container,1098 anchor,1099 parentComponent,1100 parentSuspense,1101 isSVG,1102 slotScopeIds1103 )1104 } else if (moved) {1105 if (j < 0 || i !== increasingNewIndexSequence[j]) {1106 move(nextChild, container, anchor, 2)1107 } else {1108 j--1109 }1110 }1111 }1112 }1113 }1114 const move = (vnode, container, anchor, moveType, parentSuspense = null) => {1115 const { el, type, transition, children, shapeFlag } = vnode1116 if (shapeFlag & 6) {1117 move(vnode.component.subTree, container, anchor, moveType)1118 return1119 }1120 if (shapeFlag & 128) {1121 vnode.suspense.move(container, anchor, moveType)1122 return1123 }1124 if (shapeFlag & 64) {1125 type.move(vnode, container, anchor, internals)1126 return1127 }1128 if (type === Fragment) {1129 hostInsert(el, container, anchor)1130 for (let i = 0; i < children.length; i++) {1131 move(children[i], container, anchor, moveType)1132 }1133 hostInsert(vnode.anchor, container, anchor)1134 return1135 }1136 if (type === Static) {1137 moveStaticNode(vnode, container, anchor)1138 return1139 }1140 const needTransition = moveType !== 2 && shapeFlag & 1 && transition1141 if (needTransition) {1142 if (moveType === 0) {1143 transition.beforeEnter(el)1144 hostInsert(el, container, anchor)1145 queuePostRenderEffect(() => transition.enter(el), parentSuspense)1146 } else {1147 const { leave, delayLeave, afterLeave } = transition1148 const remove = () => hostInsert(el, container, anchor)1149 const performLeave = () => {1150 leave(el, () => {1151 remove()1152 afterLeave && afterLeave()1153 })1154 }1155 if (delayLeave) {1156 delayLeave(el, remove, performLeave)1157 } else {1158 performLeave()1159 }1160 }1161 } else {1162 hostInsert(el, container, anchor)1163 }1164 }1165 const unmount = (1166 vnode,1167 parentComponent,1168 parentSuspense,1169 doRemove = false1170 ) => {1171 const {1172 type,1173 props,1174 ref,1175 children,1176 dynamicChildren,1177 shapeFlag,1178 patchFlag,1179 dirs1180 } = vnode1181 if (ref != null) {1182 setRef(ref, null, parentSuspense, vnode, true)1183 }1184 if (shapeFlag & 256) {1185 parentComponent.ctx.deactivate(vnode)1186 return1187 }1188 const shouldInvokeDirs = shapeFlag & 1 && dirs1189 const shouldInvokeVnodeHook = !isAsyncWrapper(vnode)1190 let vnodeHook1191 if (1192 shouldInvokeVnodeHook &&1193 (vnodeHook = props && props.onVnodeBeforeUnmount)1194 ) {1195 invokeVNodeHook(vnodeHook, parentComponent, vnode)1196 }1197 if (shapeFlag & 6) {1198 unmountComponent(vnode.component, parentSuspense, doRemove)1199 } else {1200 if (shapeFlag & 128) {1201 vnode.suspense.unmount(parentSuspense, doRemove)1202 return1203 }1204 if (shouldInvokeDirs) {1205 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount')1206 }1207 if (shapeFlag & 64) {1208 vnode.type.remove(1209 vnode,1210 parentComponent,1211 parentSuspense,1212 internals,1213 doRemove1214 )1215 } else if (1216 dynamicChildren &&1217 (type !== Fragment || (patchFlag > 0 && patchFlag & 64))1218 ) {1219 unmountChildren(dynamicChildren, parentComponent, parentSuspense, false)1220 } else if (1221 (type === Fragment && patchFlag & (128 | 256)) ||1222 shapeFlag & 161223 ) {1224 unmountChildren(children, parentComponent, parentSuspense)1225 }1226 if (doRemove) {1227 remove(vnode)1228 }1229 }1230 if (1231 (shouldInvokeVnodeHook &&1232 (vnodeHook = props && props.onVnodeUnmounted)) ||1233 shouldInvokeDirs1234 ) {1235 queuePostRenderEffect(() => {1236 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode)1237 shouldInvokeDirs &&1238 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted')1239 }, parentSuspense)1240 }1241 }1242 const remove = vnode => {1243 const { type, el, anchor, transition } = vnode1244 if (type === Fragment) {1245 removeFragment(el, anchor)1246 return1247 }1248 if (type === Static) {1249 removeStaticNode(vnode)1250 return1251 }1252 const performRemove = () => {...
mini-vue.js
Source:mini-vue.js
...692 }693 }694 // æ令å¤ç695 if (dirs) {696 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount')697 }698 // æå
¥DOM699 HostElement.appendChild(container, el, anchor)700}701// æ´æ°ç»ä»¶Props702const patchProps = (el, vnode, oldProps, newProps, parentComponent) => {703 if (oldProps !== newProps) {704 for (const key in newProps) {705 const next = newProps[key]706 const prev = oldProps[key]707 if (next !== prev) {708 hostPatchProp(el, key, prev, next, parentComponent)709 }710 }711 if (oldProps !== EMPTY_OBJ) {712 for (const key in oldProps) {713 if (!(key in newProps)) {714 hostPatchProp(el, key, oldProps[key], null, parentComponent)715 }716 }717 }718 }719}720// ç»ä»¶å次æè½½æ¶åï¼propsåå§å721const initProps = (instance, rawProps) => {722 const props = {}723 const attrs = {}724 const { type } = instance725 const optionsProps = type.props726 if (rawProps) {727 for (const key in rawProps) {728 const value = rawProps[key]729 if (hasOwn(optionsProps, key)) {730 props[key] = value731 } else {732 attrs[key] = value733 }734 }735 }736 // æµ
ååº737 instance.props = shallowReactive(props)738 instance.attrs = attrs739}740// 移é¤Domå
ç´ 741const unmount = (vnode, parentComponent, doRemove = false) => {742 const { type, props, children } = vnode743 if (doRemove) {744 HostElement.remove(vnode)745 }746}747const unmountChildren = (children, parentComponent, doRemove = false, start = 0) => {748 for (let i = start; i < children.length; i++) {749 unmount(children[i], parentComponent, doRemove)750 }751}752const EMPTY_ARR = []753/**754 * VNode åèç¹æ¯å¯¹å½æ°ï¼è¿éç®åé个æ¯å¯¹ï¼Vue 3.0æºç ä¸å®é
éç¨æ´ä¼çç®æ³å¤æ度æ¯å¯¹755 * @param {*} n1 756 * @param {*} n2 757 * @param {*} container 758 * @param {*} anchor 759 * @param {*} parentComponent 760 */761const patchChildren = (n1, n2, container, anchor, parentComponent) => {762 let c1 = n1 && n1.children763 let c2 = n2.children764 c1 = c1 || EMPTY_ARR765 c2 = c2 || EMPTY_ARR766 const oldLength = c1.length767 const newLength = c2.length768 const commonLength = Math.min(oldLength, newLength)769 for (let i = 0; i < commonLength; i++) {770 patch(c1[i], c2[i], container, null, parentComponent)771 }772 if (oldLength > newLength) {773 // 移é¤èçèç¹774 unmountChildren(c1, parentComponent, true, commonLength)775 } else {776 // æè½½æ°çèç¹777 mountChildren(c2, container, anchor, parentComponent, commonLength)778 }779 return780}781// æ´æ°å
ç´ 782const patchElement = (n1, n2, parentComponent) => {783 const el = (n2.el = n1.el)784 const { dirs } = n2785 const oldProps = (n1 && n1.props) || EMPTY_OBJ786 const newProps = n2.props || EMPTY_OBJ787 patchProps(el, n2, oldProps, newProps, parentComponent)788 patchChildren(n1, n2, el, null, parentComponent)789 queuePostFlushCb(() => {790 dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated')791 })792}793const processElement = (n1, n2, container, anchor, parentComponent) => {794 // n1 为null表示为æè½½å
ç´ 795 if (n1 === null) {796 mountElement(n2, container, anchor, parentComponent)797 } else {798 patchElement(n1, n2, parentComponent)799 }800}801/**802 * å¨çæç»ä»¶å®ä¾ä¹åï¼renderå½æ°æ¸²æä¹åï¼ç»ä»¶å®ä¾è¿è¡åå§å设置803 * @param {*} instance 804 */...
stable_fragment.js
Source:stable_fragment.js
...94 vnode.suspense.unmount(parentSuspense, doRemove);95 return;96 }97 if (shouldInvokeDirs) {98 invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');99 }100 if (dynamicChildren &&101 // #1153: fast path should not be taken for non-stable (v-for) fragments102 (type !== Fragment ||103 (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {104 // fast path for block nodes: only need to unmount dynamic children.105 unmountChildren(dynamicChildren, parentComponent, parentSuspense);106 }107 else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {108 unmountChildren(children, parentComponent, parentSuspense);109 }110 // an unmounted teleport should always remove its children111 if (shapeFlag & 64 /* TELEPORT */) {112 vnode.type.remove(vnode, internals);113 }114 if (doRemove) {115 remove(vnode);116 }117 }118 if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {119 queuePostRenderEffect(() => {120 vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);121 shouldInvokeDirs &&122 invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');123 }, parentSuspense);124 }125};126function createRootCodegen(root, context) {127 const { helper } = context;128 const { children } = root;129 if (children.length === 1) {130 const child = children[0];131 // if the single child is an element, turn it into a block.132 if (isSingleElementRoot(root, child) && child.codegenNode) {133 // single element root is never hoisted so codegenNode will never be134 // SimpleExpressionNode135 const codegenNode = child.codegenNode;136 if (codegenNode.type === 13 /* VNODE_CALL */) {...
directives.js
Source:directives.js
...93 // å¤çåèç¹æ¯æ°ç»çæ
åµï¼æè½½åèç¹94 mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren)95 }96 if (dirs) {97 invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount')98 }99 // æå建ç DOM å
ç´ èç¹æè½½å° container ä¸100 hostInsert(el, container, anchor)101 if (dirs) {102 queuePostRenderEffect(()=>{ 103 invokeDirectiveHook(vnode, null, parentComponent, 'mounted')104 })105 }106}107function invokeDirectiveHook(vnode, prevVNode, instance, name) {108 const bindings = vnode.dirs109 const oldBindings = prevVNode && prevVNode.dirs110 for (let i = 0; i < bindings.length; i++) {111 const binding = bindings[i]112 if (oldBindings) {113 binding.oldValue = oldBindings[i].value114 }115 const hook = binding.dir[name]116 if (hook) {117 callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [118 vnode.el,119 binding,120 vnode,121 prevVNode...
Using AI Code Generation
1const { invokeDirectiveHook } = require('@playwright/test/lib/test');2invokeDirectiveHook('beforeEach', async ({ testInfo }) => {3 testInfo.attachments.push({4 });5});6const { invokeDirectiveHook } = require('@playwright/test/lib/test');7invokeDirectiveHook('afterEach', async ({ testInfo }) => {8 testInfo.attachments.push({9 });10});11module.exports = {12 use: {13 reportAttachment: async ({ name, path, contentType }) => {14 console.log('Attachment name: ' + name);15 console.log('Attachment path: ' + path);16 console.log('Attachment content type: ' + contentType);17 },18 },19};20### `test.skip([reason,] fn)`21const { test } = require('@playwright/test');22test('skipped test', test.skip(), async ({}) => {23});24### `test.fixme([reason,] fn)`25const { test } = require('@playwright/test');26test('skipped test', test.fixme(), async ({}) => {27});28### `test.beforeAll(fn)`29const { test } = require('@playwright/test');30test.beforeAll(async ({}) => {31});32test('test 1', async ({}) => {33});34test('test 2', async ({}) => {35});
Using AI Code Generation
1const { invokeDirectiveHook } = require('playwright-core/lib/server/injected/injectedScript');2invokeDirectiveHook('testDirective', 'testData');3const { registerDirective } = require('playwright-core/lib/server/injected/injectedScript');4registerDirective('testDirective', (data) => {5 console.log(data);6});7const { registerDirective } = require('playwright-core/lib/server/injected/injectedScript');8registerDirective('testDirective', (data) => {9 expect(data).toBe('testData');10});11const unregister = registerDirective('testDirective', (data) => {12 console.log(data);13});14unregister();15const { registerDirective } = require('playwright-core/lib/server/injected/injectedScript');16registerDirective('testDirective', (data) => {17 expect(data).toBe('testData');18});19const { registerDirective } = require('playwright-core/lib/server/injected/injectedScript');20registerDirective('testDirective', (data) => {21 expect(data).toBe('testData');22});
Using AI Code Generation
1const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');2const directive = { name: 'testDirective', params: {} };3invokeDirectiveHook(directive);4return directive;5const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');6const directive = { name: 'testDirective', params: {} };7invokeDirectiveHook(directive);8return directive;9const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');10const directive = { name: 'testDirective', params: {} };11invokeDirectiveHook(directive);12return directive;13const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');14const directive = { name: 'testDirective', params: {} };15invokeDirectiveHook(directive);16return directive;17const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');18const directive = { name: 'testDirective', params: {} };19invokeDirectiveHook(directive);20return directive;21const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');22const directive = { name: 'testDirective', params: {} };23invokeDirectiveHook(directive);24return directive;25const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');26const directive = { name: 'testDirective', params: {} };27invokeDirectiveHook(directive);28return directive;29const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');30const directive = { name: 'testDirective', params: {} };31invokeDirectiveHook(directive);32return directive;33const { invokeDirectiveHook } = require('playwright/lib/server/injected/injectedScript');34const directive = { name: 'testDirective', params: {} };35invokeDirectiveHook(directive);
Using AI Code Generation
1const { invokeDirectiveHook } = require('playwright/lib/server/chromium/crPage');2invokeDirectiveHook('intercept', (interceptedRequest) => {3});4const { invokeMethod } = require('playwright/lib/server/chromium/crPage');5invokeMethod('intercept', (interceptedRequest) => {6});7const { invokeMethodAsync } = require('playwright/lib/server/chromium/crPage');8invokeMethodAsync('intercept', (interceptedRequest) => {9});10const { invokeEvent } = require('playwright/lib/server/chromium/crPage');11invokeEvent('intercept', (interceptedRequest) => {12});13const { invokeEventAsync } = require('playwright/lib/server/chromium/crPage');14invokeEventAsync('intercept', (interceptedRequest) => {15});16const { invokeEventAsync } = require('playwright/lib/server/chromium/crPage');17invokeEventAsync('intercept', (interceptedRequest) => {18});19const { invokeEventAsync } = require('playwright/lib/server/chromium/crPage');20invokeEventAsync('intercept', (interceptedRequest) => {21});22const { invokeEventAsync } = require('playwright/lib/server/chromium/crPage');23invokeEventAsync('intercept', (interceptedRequest) => {24});25const { invokeEventAsync } = require('playwright/lib/server/chromium/crPage');26invokeEventAsync('intercept', (interceptedRequest) => {27});
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!