Posted 鍓嶇鐪熷ソ鐜?/a> 鍒ㄦ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了相关的知识,希望对你有一定的参考价值。
鍓嶈█
鎴戞兂澶у搴旇閮藉 Vue 鐨?Scope CSS 鑰崇啛鑳借浜嗭紝浣嗘槸璇磋捣 Vue 鐨?Scope CSS 瀹炵幇鐨勫師鐞嗭紝寰堝浜哄簲璇ヤ細璇翠笉灏辨槸缁?html銆丆SS 娣诲姞灞炴€у悧 馃檭锔忥紵
纭疄鏄繖鏍风殑锛屼笉杩囪繖鍙槸鏈€缁?Scope CSS 鍛堢幇鐨勭粨鏋溿€傝€岃繖涓繃绋嬪張鏄浣曞疄鐜扮殑锛熸垜鎯宠兘鍥炵瓟涓婁竴浜岀殑鍚屽搴旇涓嶅銆?/p>
閭d箞锛屽洖鍒颁粖澶╂湰鏂囷紝鎴戝皢浼氬洿缁曚互涓?3 鐐癸紝鍜屽ぇ瀹朵竴璧蜂粠 Vue 鐨?Scope CSS 鐨勬渶缁堝憟鐜扮粨鏋滃嚭鍙戯紝娣卞叆娴呭嚭涓€鐣叾瀹炵幇鐨勫簳灞傚師鐞嗭細
-
浠€涔堟槸 Scope CSS -
vue-loader 澶勭悊缁勪欢锛?vue 鏂囦欢锛? -
Patch 闃舵搴旂敤 ScopeId 鐢熸垚 HTML 鐨勫睘鎬?
1 浠€涔堟槸 Scope CSS
Scope CSS 鍗充綔鐢ㄥ煙 CSS锛?span>缁勪欢鍖?/strong>鎵€瀵嗕笉鍙垎鐨勪竴閮ㄥ垎銆係cope CSS 浣垮緱鎴戜滑鍙互鍦ㄥ悇缁勪欢涓畾涔夌殑 CSS 涓嶄骇鐢熸薄鏌撱€備緥濡傦紝鎴戜滑鍦?Vue 涓畾涔変竴涓粍浠讹細
<!-- App.vue -->
<template>
<div class="box">scoped css</div>
</template>
<script>
export default {};
</script>
<style scoped>
.box {
width: 200px;
height: 200px;
background: #aff;
}
</style>
閫氬父鎯呭喌涓嬶紝鍦ㄥ紑鍙戠幆澧冩垜浠殑缁勪欢浼氬厛缁忚繃 vue-loader[1] 鐨勫鐞嗭紝鐒跺悗缁撳悎杩愯鏃剁殑妗嗘灦浠g爜娓叉煋鍒伴〉闈笂銆傜浉搴斿湴锛屽畠浠搴旂殑 HTML 鍜?CSS 鍒嗗埆浼氭槸杩欐牱锛?/p>
HTML 閮ㄥ垎锛?/p>
<div data-v-992092a6>scoped css</div>
CSS 閮ㄥ垎锛?/p>
.box[data-v-992092a6] {
width: 200px;
height: 200px;
background: #aff;
}
鍙互鐪嬪埌 Scope CSS 鐨勬湰璐ㄦ槸鍩轰簬 HTML 鍜?CSS 閫夋嫨鍣ㄧ殑灞炴€э紝閫氳繃鍒嗗埆缁?HTML 鏍囩鍜?CSS 閫夋嫨鍣ㄦ坊鍔?data-v-xxxx
灞炴€х殑鏂瑰紡瀹炵幇銆?/p>
2 vue-loader 澶勭悊缁勪欢锛?vue 鏂囦欢锛?/h2>
鍓嶉潰锛屾垜浠篃鎻愬強浜嗗湪寮€鍙戠幆澧冧笅涓€涓粍浠讹紙.vue 鏂囦欢锛変細鍏堢敱 vue-loader 鏉ュ鐞嗐€傞偅涔堬紝閽堝 Scope CSS 鑰岃█锛寁ue-loader 浼氬仛杩?3 浠朵簨锛?/p>
-
瑙f瀽缁勪欢锛屾彁鍙栧嚭 template
銆?script
銆?style
瀵瑰簲鐨勪唬鐮佸潡 -
鏋勯€犲苟瀵煎嚭 export
缁勪欢瀹炰緥锛屽湪缁勪欢瀹炰緥鐨勯€夐」涓婄粦瀹?ScopId -
瀵? style
鐨?CSS 浠g爜杩涜缂栬瘧杞寲锛屽簲鐢?ScopId 鐢熸垚閫夋嫨鍣ㄧ殑灞炴€?
娉ㄦ剰锛岃繖閲岃鐨勫彧鏄?vue-loader 瀵?.vue 鏂囦欢鐨勫鐞嗛儴鍒嗭紝涓嶆秹鍙?HMR銆侀厤鍚?Devtool 鐨勯€昏緫锛屾湁鍏磋叮鐨勫悓瀛﹀彲浠ヨ嚜琛屼簡瑙o綖
鐒惰€岋紝涔嬫墍浠?vue-loader 鏈夎繖涔堝鐨勮兘鍔涳紝涓昏鏄洜涓?vue-loader 鐨勫簳灞備娇鐢ㄤ簡 Vue 瀹樻柟鎻愪緵鐨勫寘锛坧ackage锛?@vue/component-compiler-utils[2]锛屽叾鎻愪緵浜嗚В鏋愮粍浠讹紙.vue 鏂囦欢锛夈€佺紪璇戞ā鐗?template
銆佺紪璇?style
绛?3 绉嶈兘鍔涖€?/p>
閭d箞锛屼笅闈㈡垜浠氨鍏堟潵鐪嬩竴涓?vue-loader 鏄浣曚娇鐢?@vue/component-compiler-utils
鏉ヨВ鏋愮粍浠舵彁鍙?template
銆?code class="mq-99">script銆?code class="mq-100">style 鐨勩€?/p>
2.1 鎻愬彇 template銆乻cript銆乻tyle
vue-loader 鎻愬彇 template銆乻cript銆乻tyle 鐨勮繃绋嬩富瑕佹槸浣跨敤浜?@vue/component-compiler-utils
鐨?parse
鏂规硶锛岃繖涓繃绋嬪搴旂殑浠g爜锛堜吉浠g爜锛変細鏄繖鏍凤細
// vue-loader/lib/index.js
const { parse } = require("@vue/component-compiler-utils");
module.exports = function (source) {
const loaderContext = this;
const { sourceMap, rootContext, resourcePath } = loaderContext;
const sourceRoot = path.dirname(path.relative(context, resourcePath));
const descriptor = parse({
source,
compiler: require("vue-template-compiler"),
filename,
sourceRoot,
needMap: sourceMap,
});
};
鎴戜滑鏉ラ€愮偣鍒嗘瀽涓€涓嬭繖娈典唬鐮侊紝棣栧厛锛屼細鑾峰彇褰撳墠涓婁笅鏂?loaderContext
锛屽畠浼氬寘鍚?webpack 鎵撳寘杩囩▼鏍稿績瀵硅薄 compiler
銆?code class="mq-130">compilation 绛夈€?/p>
鍏舵锛屽啀鏋勫缓鏂囦欢璧勬簮鍏ュ彛 sourceRoot
锛屼竴鑸儏鍐典笅瀹冩寚鐨勬槸 src 鏂囦欢鐩綍锛屽畠涓昏鐢ㄤ簬鏋勫缓 source-map
浣跨敤銆?/p>
鏈€鍚庯紝鍒欎細浣跨敤 @vue/component-compiler-utils
鎻愪緵鐨?parse
鏂规硶鏉ヨВ鏋?source
锛堢粍浠朵唬鐮侊級銆傝繖閲岋紝鎴戜滑鏉ョ湅涓€涓?parse
鏂规硶鐨勫嚑涓弬鏁帮細
-
soruce
婧愪唬鐮佸潡锛岃繖閲屾槸缁勪欢瀵瑰簲鐨勪唬鐮侊紝鍗冲寘鍚簡template
銆?style
銆?script
-
compiler
缂栬瘧鏍稿績瀵硅薄锛屽畠鏄竴涓?CommonJS 妯″潡锛? vue-template-compiler [3]锛夛紝parse
鏂规硶鍐呴儴浼氫娇鐢ㄥ畠鎻愪緵鐨?parseComponent
鏂规硶鏉ヨВ鏋愮粍浠? -
filename
褰撳墠缁勪欢鐨勬枃浠跺悕锛屼緥濡?App.vue
-
sourceRoot
鏂囦欢璧勬簮鍏ュ彛锛岀敤浜庢瀯寤?source-map
浣跨敤 -
needMap
鏄惁闇€瑕?source-map
锛?parse
鏂规硶鍐呴儴浼氭牴鎹?needMap
鐨勫€硷紙true
鎴?false
锛岄粯璁や负true
锛夋潵鍒ゆ柇鏄惁鐢熸垚script
銆?style
瀵瑰簲鐨?source-map
鑰?parse
鏂规硶鐨勬墽琛屽垯浼氳繑鍥炰竴涓璞$粰 desciptor
锛屽畠浼氬寘鍚?template
銆?code class="mq-172">style銆?code class="mq-173">script 鍒嗗埆瀵瑰簲鐨勪唬鐮佸潡銆?/p>
閭d箞锛屽彲浠ョ湅鍒扮殑鏄?vue-loader 瑙f瀽缁勪欢鐨勮繃绋嬶紝鍑犱箮澶栧寘缁欎簡 Vue 鎻愪緵鐨勫伐鍏峰寘锛坧ackage锛夈€傚苟涓旓紝鎴戞兂杩欎釜鏃跺€欒偗瀹氫細鏈夊悓瀛﹂棶锛氳繖浜涘拰 Vue 鐨?Scope CSS 鏈夊嚑姣涢挶鍏崇郴 馃檭锔忥紵
鏈夊緢澶х殑鍏崇郴锛佸洜涓?Vue 鐨?Scope CSS 鍙笉鏄?span>鏃犵背涔嬬倞锛屽畠瀹炵幇鐨勫墠鎻愭槸缁勪欢琚В鏋愪簡锛岀劧鍚庡啀鍒嗗埆澶勭悊 template
鍜?style
閮ㄥ垎鐨勪唬鐮侊紒
閭d箞锛屾樉鐒跺埌杩欓噷鎴戜滑宸茬粡瀹屾垚浜嗗缁勪欢鐨勮В鏋愩€傛帴鐫€锛屽垯闇€瑕佹瀯閫犲拰瀵煎嚭缁勪欢瀹炰緥锝?/p>
2.2 鏋勯€犲拰瀵煎嚭缁勪欢瀹炰緥
vue-loader 鍦ㄨВ鏋愬畬缁勪欢鍚庯紝浼氬垎鍒鐞嗗苟鐢熸垚 template
銆?code class="mq-184">script銆?code class="mq-185">style 鐨勫鍏?import
璇彞锛屽啀璋冪敤 normalizer
鏂规硶姝e父鍖栵紙normalizer锛夌粍浠讹紝鏈€鍚庡皢瀹冧滑鎷兼帴鎴愪唬鐮佸瓧绗︿覆锛?/p>
let templateImport = `var render, staticRenderFns`;
if (descriptor.template) {
// 鏋勯€?nbsp;template 鐨?nbsp;import 璇彞
}
let scriptImport = `var script = {}`;
if (descriptor.script) {
// 鏋勯€?nbsp;script 鐨?nbsp;import 璇彞
}
let stylesCode = ``;
if (descriptor.styles.length) {
// 鏋勯€?nbsp;style 鐨?nbsp;import 璇彞
}
let code =
`
${templateImport}
${scriptImport}
${stylesCode}
import normalizer from ${stringifyRequest(`!${componentNormalizerPath}`)}
var component = normalizer(
script,
render,
staticRenderFns,
${hasFunctional ? `true` : `false`},
${/injectStyles/.test(stylesCode) ? `injectStyles` : `null`},
${hasScoped ? JSON.stringify(id) : `null`},
${isServer ? JSON.stringify(hash(request)) : `null`}
${isShadow ? `,true` : ``}
)
`.trim() + `\n`;
鍏朵腑锛?code class="mq-229">templateImport銆?code class="mq-230">scriptImport銆?code class="mq-231">stylesCode 绛夋瀯閫犲ソ鐨?template
銆?code class="mq-233">script銆?code class="mq-234">style 閮ㄥ垎鐨勫鍏?import
璇彞鐪嬭捣鏉ヤ細鏄繖鏍凤細
import {
render,
staticRenderFns,
} from "./App.vue?vue&type=template&id=7ba5bd90&scoped=true&";
import script from "./App.vue?vue&type=script&lang=js&";
// 鍏煎鍛藉悕鏂瑰紡鐨勫鍑?/span>
export * from "./App.vue?vue&type=script&lang=js&";
import style0 from "./App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css&";
涓嶇煡閬撳悓瀛︿滑娉ㄦ剰 鈿狅笍 鍒版病锛?code class="mq-253">template 鍜?style
鐨勫鍏?import
璇彞閮芥湁杩欎箞涓€涓?span>鍏卞悓鐨勯儴鍒?/strong> id=7ba5bd90&scoped=true
锛岃繖琛ㄧず姝ゆ椂缁勪欢鐨?template
鍜?style
鏄渶瑕?Scope CSS 鐨勶紝骞朵笖 scopeId
涓?7ba5bd90
銆?/p>
褰撶劧锛岃繖浠呬粎鏄憡鐭ュ悗缁殑 template
鍜?style
缂栬瘧鏃堕渶瑕佹敞鎰忕敓鎴?Scope CSS锛屼篃鏄疄鐜?Scope CSS 鐨勭涓€姝ワ紒閭d箞锛屾帴鐫€鍒欎細璋冪敤 normalizer
鏂规硶鏉ュ璇ョ粍浠惰繘琛屾甯稿寲锛圢ormalizer锛夊鐞嗭細
import normalizer from "!../node_modules/vue-loader/lib/runtime/componentNormalizer.js";
var component = normalizer(
script,
render,
staticRenderFns,
false,
null,
"7ba5bd90",
null
);
export default component.exports;
娉ㄦ剰锛?code class="mq-280">normalizer 鏄噸鍛藉悕浜嗗師鏂规硶
normalizeComponent
锛屼互涓嬬粺绉?normalizeComponent
~
鎴戞兂鍚屽浠簲璇ラ兘娉ㄦ剰鍒颁簡锛屾鏃?scopeId
浼氫綔涓哄弬鏁颁紶缁?normalizeComponent
鏂规硶锛岃€屼紶缁?normalizeComponent
鐨勭洰鐨勫垯鏄负浜嗗湪缁勪欢瀹炰緥鐨?options
涓?/strong>缁戝畾 scopeId
銆傞偅涔堬紝鎴戜滑鏉ョ湅涓€涓?normalizeComponent
鏂规硶锛堜吉浠g爜锛夛細
function normalizeComponent (
scriptExports,
render,
staticRenderFns,
functionalTemplate,
injectStyles,
scopeId,
moduleIdentifier, /* server only */
shadowMode /* vue-cli only */
) {
...
var options = typeof scriptExports === 'function'
? scriptExports.options
: scriptExports
// scopedId
if (scopeId) {
options._scopeId = 'data-v-' + scopeId
}
...
}
鍙互鐪嬪埌锛岃繖閲岀殑 options._scopeId
浼氱瓑浜?data-v-7ba5bd90
锛岃€屽畠鐨勪綔鐢ㄤ富瑕佹槸鐢ㄤ簬鍦?patch
鐨勬椂鍊欙紝涓哄綋鍓嶇粍浠剁殑 HTML 鏍囩娣诲姞鍚嶄负 data-v-7ba5bd90
鐨勫睘鎬с€傚洜姝わ紝杩欎篃鏄?template 涓轰粈涔堜細褰㈡垚甯︽湁 scopeId
鐨勭湡姝f墍鍦?/strong>锛?/p>
2.3 缂栬瘧鏍峰紡 Style锛屽簲鐢?ScopId 鐢熸垚閫夋嫨鍣ㄧ殑灞炴€?span class="mq-312">
鍦ㄦ瀯閫犲畬 Style 瀵瑰簲鐨勫鍏ヨ鍙ュ悗锛岀敱浜庢鏃?import
璇彞涓殑 query
鍖呭惈 vue
锛屽垯浼氳 vue-loader 鍐呴儴鐨?Pitching Loader 澶勭悊銆傝€?Pitching Loader 鍒欎細閲嶅啓 import
璇彞锛屾嫾鎺ヤ笂鍐呰仈锛坕nline锛夌殑 Loader锛岃繖鐪嬭捣鏉ヤ細鏄繖鏍凤細
export * from '
"-!../node_modules/vue-style-loader/index.js??ref--6-oneOf-1-0
!../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1
!../node_modules/vue-loader/lib/loaders/stylePostLoader.js
!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2
!../node_modules/cache-loader/dist/cjs.js??ref--0-0
!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css&"
'
鐒跺悗锛寃ebpack 浼氳В鏋愬嚭妯″潡鎵€闇€瑕佺殑 Loader锛屾樉鐒惰繖閲屼細瑙f瀽鍑?6 涓?Loader锛?/p>
[
{ loader: "vue-style-loader", options: "?ref--6-oneOf-1-0" },
{ loader: "css-loader", options: "?ref--6-oneOf-1-1" },
{ loader: "stylePostLoader", options: undefined },
{ loader: "postcss-loader", options: "?ref--6-oneOf-1-2" },
{ loader: "cache-loader", options: "?ref--0-0" },
{ loader: "vue-loader", options: "?vue-loader-options" }
]
閭d箞锛屾鏃?webpack 鍒欎細鎵ц杩?6 涓?Loader锛堝綋鐒惰繕鏈夎В鏋愭ā鍧楁湰韬級銆傚苟涓旓紝杩欓噷浼氬拷鐣?webpack.config.js 涓鍚堣鍒欑殑 Normal Loader锛坴ue-style-loader 杩樹細蹇界暐鍓嶇疆 Loader锛夈€?/p>
涓嶄簡瑙e唴鑱?Loader 鐨勫悓瀛︼紝鍙互鐪嬩竴涓嬭繖绡囨枃绔?span class="mq-355">銆恮ebpack杩涢樁銆戜綘鐪熺殑鎺屾彙浜唋oader涔堬紵- loader鍗侀棶[4]
鑰屽浜?Scope CSS 鑰岃█锛屽瘑鍒囩浉鍏崇殑灏辨槸 stylePostLoader銆備笅闈紝鎴戜滑鏉ョ湅涓€涓?stylePostLoader 鐨勫畾涔夛細
const { compileStyle } = require("@vue/component-compiler-utils");
module.exports = function (source, inMap) {
const query = qs.parse(this.resourceQuery.slice(1));
const { code, map, errors } = compileStyle({
source,
filename: this.resourcePath,
id: `data-v-${query.id}`,
map: inMap,
scoped: !!query.scoped,
trim: true,
});
if (errors.length) {
this.callback(errors[0]);
} else {
this.callback(null, code, map);
}
};
浠?stylePostLoader 鐨勫畾涔変腑锛屾垜浠煡閬撳畠鏄娇鐢ㄤ簡 鑰屽湪 涓嶇煡閬撳悓瀛︿滑鏄惁杩樿寰楀湪 2.2 鏋勯€犲苟瀵煎嚭缁勪欢瀹炰緥鐨勬椂鍊欙紝鎴戜滑璁蹭簡鍦ㄧ粍浠跺疄渚嬬殑 濡傛灉锛屼綘鎯冲湪 vue-loader 鎴栬€? 浜嗚В杩?Vue 妯$増缂栬瘧杩囩▼鐨勫悓瀛︼紝鎴戞兂搴旇閮界煡閬? 鑰?VNode 鍒扮湡瀹?DOM 杩欎釜杩囩▼鏄敱 鍥犱负绗竴娆℃覆鏌?DOM锛屾墍浠ュ帇鏍逛笉瀛樺湪浠€涔? 鍙互鐪嬪埌锛屾鏃朵細鎵ц 鍦? 濡傛灉锛屾湁鍦ㄧ綉涓婃煡鎵捐繃鍏充簬 vue-loader 鍜?Scope CSS 鐨勬枃绔犵殑鍚屽浼氬彂鐜帮紝寰堝鏂囩珷閮芥槸璇村湪 骞朵笖锛屾垜鎯冲悓瀛︿滑涔熸敞鎰忓埌浜嗕竴鐐癸紝鏈枃涓彁鍙婄殑 Vue 杩愯鏃舵鏋剁殑浠g爜鏄?Vue 2.x 鐗堟湰鐨勶紙涓嶆槸 Vue3锛夈€傛墍浠ワ紝鏈夊叴瓒g殑鍚屽鍙互鍊熷姪鏈枃鎻愪緵鐨勮矾绾挎帹鏁蹭竴涓?Vue3 涓?Scope CSS 鐨勮繃绋嬶紝鐩镐俊浣犱細鏀惰幏婊℃弧 馃槑銆傛渶鍚庯紝濡傛灉鏈枃涓瓨鍦ㄨ〃杈句笉褰撴垨閿欒鐨勫湴鏂癸紝娆㈣繋鍚勪綅鍚屽鎻?Issue锝?/p>
閫氳繃闃呰鏈瘒鏂囩珷锛屽鏋滄湁鏀惰幏鐨勮瘽锛屽彲浠?span>鐐逛釜璧?/strong>鍜?span>鍦ㄧ湅锛岃繖灏嗕細鎴愪负鎴戞寔缁垎浜殑鍔ㄥ姏锛屾劅璋綖 vue-loader: https://github.com/vuejs/vue-loader @vue/component-compiler-utils: https://github.com/vuejs/component-compiler-utils vue-template-compiler: https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#readme 銆恮ebpack杩涢樁銆戜綘鐪熺殑鎺屾彙浜唋oader涔堬紵- loader鍗侀棶: https://juejin.cn/post/6844903693070909447 postcss: https://postcss.org/api/@vue/component-compiler-utils
鎻愪緵鐨?compileStyle
鏂规硶鏉ュ畬鎴愬缁勪欢 style
鐨勭紪璇戙€傚苟涓旓紝姝ゆ椂浼氫紶鍏ュ弬鏁?id
涓?data-v-${query.id}
锛屽嵆 data-v-7ba5bd90
锛岃€岃繖涔熸槸 style
涓0鏄庣殑閫夋嫨鍣ㄧ殑灞炴€т负 scopeId
鐨勫叧閿偣锛?/p>
compileStyle
鍑芥暟鍐呴儴锛屽垯鏄娇鐢ㄧ殑鎴戜滑鎵€鐔熺煡 postcss[5] 鏉ュ畬鎴愬 style
浠g爜鐨勭紪璇戝拰鏋勯€犻€夋嫨鍣ㄧ殑 scopeId
灞炴€с€傝嚦浜庡浣曚娇鐢?postcss
瀹屾垚杩欎釜杩囩▼锛岃繖閲屽氨涓嶅仛杩囧浠嬬粛锛屾湁鍏磋叮鐨勫悓瀛﹁嚜琛屼簡瑙e搱锝?/p>
3 Patch 闃舵搴旂敤 ScopeId 鐢熸垚 HTML 鐨勫睘鎬?/h2>
options
涓婄粦瀹?_scopeId
鏄疄鐜?template
鐨?Scope 鐨勫叧閿偣锛佷絾鏄紝褰撴椂鎴戜滑骞舵病鏈変粙缁嶈繖涓?_scopeId
鍒板簳鏄浣曞簲鐢ㄥ埌 template
涓婄殑鍏冪礌鐨?馃槻锛?/p>
@vue/component-compiler-utils
鐨勪唬鐮佷腑鎵惧埌杩欎釜绛旀锛屾垜鍙互鍜屼綘璇?span>鎵句竴涓囧勾閮芥壘涓嶅埌锛?/strong> 鍥犱负锛岀湡姝e簲鐢?_scopeId
鐨勮繃绋嬫槸鍙戠敓鍦?Vue 杩愯鏃剁殑妗嗘灦浠g爜涓?/strong>锛堟病鎯冲埌鍚?馃樀锛夈€?/p>
template
浼氳缂栬瘧鎴?render
鍑芥暟锛岀劧鍚庝細鏍规嵁 render
鍑芥暟鍒涘缓瀵瑰簲鐨?VNode锛屾渶鍚庡啀鏍规嵁 VNode 娓叉煋鎴愮湡瀹炵殑 DOM 鍦ㄩ〉闈笂锛?/p>
patch
鏂规硶瀹屾垚鐨勩€傚亣璁撅紝姝ゆ椂鎴戜滑鏄涓€娆℃覆鏌?DOM锛岃繖鍦?patch
鏂规硶涓細鍛戒腑 isUndef(oldVnode)
涓?true
鐨勯€昏緫锛?/p>
function patch (oldVnode, vnode, hydrating, removeOnly) {
if (isUndef(oldVnode)) {
// empty mount (likely as component), create new root element
isInitialPatch = true
createElm(vnode, insertedVnodeQueue)
}
}
oldVnode
馃樁createElm
鏂规硶銆傝€屽湪 createElm
鏂规硶涓垯浼氬垱寤?VNode 瀵瑰簲鐨勭湡瀹?DOM锛屽苟涓斿畠杩樺仛浜?span>涓€浠跺緢閲嶈鐨勪簨锛岃皟鐢?setScope
鏂规硶搴旂敤 _scopeId
鍦?DOM 涓婄敓鎴?data-v-xxx
鐨勫睘鎬э紒瀵瑰簲鐨勪唬鐮侊紙浼唬鐮侊級锛?/p>
// packages/src/core/vdom/patch.js
function createElm(
vnode,
insertedVnodeQueue,
parentElm,
refElm,
nested,
ownerArray,
index
) {
...
setScope(vnode);
...
}setScope
鏂规硶涓垯浼氫娇鐢ㄧ粍浠跺疄渚嬬殑 options._scopeId
浣滀负灞炴€ф潵娣诲姞鍒?DOM 涓婏紝浠庤€岀敓鎴愪簡 template
涓殑 HTML 鏍囩涓婂悕涓?data-v-xxx
鐨勫睘鎬с€傚苟涓旓紝杩欎釜杩囩▼浼氱敱 Vue 灏佽濂界殑宸ュ叿鍑芥暟 nodeOps.setStyleScope
瀹屾垚锛屽畠鐨勬湰璐ㄦ槸璋冪敤 DOM 瀵硅薄鐨?setAttribute
鏂规硶锛?/p>
// src/platforms/web/runtime/node-ops.js
export function setStyleScope (node: Element, scopeId: string) {
node.setAttribute(scopeId, '')
}缁撹
@vue/component-compiler-utils
鐨?compilerTemplate
鏂规硶涓簲鐢?scopeId
鐢熸垚浜?template
涓?HTML 鏍囩鐨勫睘鎬с€備絾鏄紝閫氳繃闃呰鏈枃锛屾垜浠細鍙戠幇杩欎袱鑰呭帇鏍?span>娌℃湁浠讳綍鍏崇郴锛圫SR 鐨勬儏鍐甸櫎澶栵級锛?/p>
鐐硅禐 馃憤銆佸湪鐪?馃憖
鍙傝€冭祫鏂?/span>
鎴戠殑浠樿垂绀惧尯銆屽墠绔€庝箞鐜┿€?/span>
鍦ㄨ繖閲屼綘鑳借幏寰椾簺浠€涔堬紵
鎴戝涔犵殑璺緞锛屽钩鏃剁湅鍒扮殑濂芥枃绔犮€佹兂娉曘€佽祫鏂欍€佹柊鎶€鏈兘浼氭暣鐞嗗ソ鍒嗕韩鍑烘潵锛屽府鍔╀綘鏇村揩鎴愰暱锛屽紑闃旂溂鐣岋紝鎷撳鎶€鏈爤銆?/p>
浣犵殑鐤戦棶锛屽伐浣滀笂銆佹妧鏈€佽亴涓氱瓑绛夋棤闄愭鎻愰棶锛屼笉鏂逛究鏆撮湶闅愮杩樺彲浠ュ尶鍚嶆彁闂紝鎴戣兘鍥炵瓟鐨勮偗瀹氫細鑱婅亰鎴戠殑鎯虫硶銆?/p>
涓嶅畾鏈熺殑绾夸笂瀛︿範娲诲姩缁勭粐锛屾墦鍗″垎浜€?/p>
涓€鏈堜竴鏈熺殑楂樿川閲忓垎浜強绛旂枒锛屽寘鎷畝鍘嗕慨鏀广€佹ā鎷熼潰璇曠瓑銆?/p>
涓€涓珮璐ㄩ噺鐨勫井淇$兢銆?/span>
以上是关于的主要内容,如果未能解决你的问题,请参考以下文章