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 {
    width200px;
    height200px;
    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] {
  width200px;
  height200px;
  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,
    compilerrequire("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"optionsundefined },
  { 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,
    filenamethis.resourcePath,
    id`data-v-${query.id}`,
    map: inMap,
    scoped: !!query.scoped,
    trimtrue,
  });

  if (errors.length) {
    this.callback(errors[0]);
  } else {
    this.callback(null, code, map);
  }
};

浠?stylePostLoader 鐨勫畾涔変腑锛屾垜浠煡閬撳畠鏄娇鐢ㄤ簡 @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>

涓嶇煡閬撳悓瀛︿滑鏄惁杩樿寰楀湪 2.2 鏋勯€犲苟瀵煎嚭缁勪欢瀹炰緥鐨勬椂鍊欙紝鎴戜滑璁蹭簡鍦ㄧ粍浠跺疄渚嬬殑 options 涓婄粦瀹?_scopeId 鏄疄鐜?template 鐨?Scope 鐨勫叧閿偣锛佷絾鏄紝褰撴椂鎴戜滑骞舵病鏈変粙缁嶈繖涓?_scopeId 鍒板簳鏄浣曞簲鐢ㄥ埌 template 涓婄殑鍏冪礌鐨?馃槻锛?/p>

濡傛灉锛屼綘鎯冲湪 vue-loader 鎴栬€?@vue/component-compiler-utils 鐨勪唬鐮佷腑鎵惧埌杩欎釜绛旀锛屾垜鍙互鍜屼綘璇?span>鎵句竴涓囧勾閮芥壘涓嶅埌锛?/strong> 鍥犱负锛岀湡姝e簲鐢?_scopeId 鐨勮繃绋嬫槸鍙戠敓鍦?Vue 杩愯鏃剁殑妗嗘灦浠g爜涓?/strong>锛堟病鎯冲埌鍚?馃樀锛夈€?/p>

浜嗚В杩?Vue 妯$増缂栬瘧杩囩▼鐨勫悓瀛︼紝鎴戞兂搴旇閮界煡閬?template 浼氳缂栬瘧鎴?render 鍑芥暟锛岀劧鍚庝細鏍规嵁 render 鍑芥暟鍒涘缓瀵瑰簲鐨?VNode锛屾渶鍚庡啀鏍规嵁 VNode 娓叉煋鎴愮湡瀹炵殑 DOM 鍦ㄩ〉闈笂锛?/p>

鑰?VNode 鍒扮湡瀹?DOM 杩欎釜杩囩▼鏄敱 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)
  } 
}

鍥犱负绗竴娆℃覆鏌?DOM锛屾墍浠ュ帇鏍逛笉瀛樺湪浠€涔?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-loader 鍜?Scope CSS 鐨勬枃绔犵殑鍚屽浼氬彂鐜帮紝寰堝鏂囩珷閮芥槸璇村湪 @vue/component-compiler-utils 鐨?compilerTemplate 鏂规硶涓簲鐢?scopeId 鐢熸垚浜?template 涓?HTML 鏍囩鐨勫睘鎬с€備絾鏄紝閫氳繃闃呰鏈枃锛屾垜浠細鍙戠幇杩欎袱鑰呭帇鏍?span>娌℃湁浠讳綍鍏崇郴锛圫SR 鐨勬儏鍐甸櫎澶栵級锛?/p>

骞朵笖锛屾垜鎯冲悓瀛︿滑涔熸敞鎰忓埌浜嗕竴鐐癸紝鏈枃涓彁鍙婄殑 Vue 杩愯鏃舵鏋剁殑浠g爜鏄?Vue 2.x 鐗堟湰鐨勶紙涓嶆槸 Vue3锛夈€傛墍浠ワ紝鏈夊叴瓒g殑鍚屽鍙互鍊熷姪鏈枃鎻愪緵鐨勮矾绾挎帹鏁蹭竴涓?Vue3 涓?Scope CSS 鐨勮繃绋嬶紝鐩镐俊浣犱細鏀惰幏婊℃弧 馃槑銆傛渶鍚庯紝濡傛灉鏈枃涓瓨鍦ㄨ〃杈句笉褰撴垨閿欒鐨勫湴鏂癸紝娆㈣繋鍚勪綅鍚屽鎻?Issue锝?/p>

鐐硅禐 馃憤銆佸湪鐪?馃憖

閫氳繃闃呰鏈瘒鏂囩珷锛屽鏋滄湁鏀惰幏鐨勮瘽锛屽彲浠?span>鐐逛釜璧?/strong>鍜?span>鍦ㄧ湅锛岃繖灏嗕細鎴愪负鎴戞寔缁垎浜殑鍔ㄥ姏锛屾劅璋綖

鍙傝€冭祫鏂?/span>

[1]

vue-loader: https://github.com/vuejs/vue-loader

[2]

@vue/component-compiler-utils: https://github.com/vuejs/component-compiler-utils

[3]

vue-template-compiler: https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#readme

[4]

銆恮ebpack杩涢樁銆戜綘鐪熺殑鎺屾彙浜唋oader涔堬紵- loader鍗侀棶: https://juejin.cn/post/6844903693070909447

[5]

postcss: https://postcss.org/api/


濡傛灉瑙夊緱涓嶉敊锛岀礌璐ㄤ笁杩炪€佹垨鑰呯偣涓€? 璧?/span>銆嶃€併€? 鍦ㄧ湅銆嶉兘鏄绗旇€呰帿澶х殑鏀寔锛岃阿璋㈠悇浣嶅ぇ浣暒~


鎴戠殑浠樿垂绀惧尯銆屽墠绔€庝箞鐜┿€?/span>

鍦ㄨ繖閲屼綘鑳借幏寰椾簺浠€涔堬紵

  • 鎴戝涔犵殑璺緞锛屽钩鏃剁湅鍒扮殑濂芥枃绔犮€佹兂娉曘€佽祫鏂欍€佹柊鎶€鏈兘浼氭暣鐞嗗ソ鍒嗕韩鍑烘潵锛屽府鍔╀綘鏇村揩鎴愰暱锛屽紑闃旂溂鐣岋紝鎷撳鎶€鏈爤銆?/p>

  • 浣犵殑鐤戦棶锛屽伐浣滀笂銆佹妧鏈€佽亴涓氱瓑绛夋棤闄愭鎻愰棶锛屼笉鏂逛究鏆撮湶闅愮杩樺彲浠ュ尶鍚嶆彁闂紝鎴戣兘鍥炵瓟鐨勮偗瀹氫細鑱婅亰鎴戠殑鎯虫硶銆?/p>

  • 涓嶅畾鏈熺殑绾夸笂瀛︿範娲诲姩缁勭粐锛屾墦鍗″垎浜€?/p>

  • 涓€鏈堜竴鏈熺殑楂樿川閲忓垎浜強绛旂枒锛屽寘鎷畝鍘嗕慨鏀广€佹ā鎷熼潰璇曠瓑銆?/p>

  • 涓€涓珮璐ㄩ噺鐨勫井淇$兢銆?/span>



以上是关于的主要内容,如果未能解决你的问题,请参考以下文章

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数

VSCode自定义代码片段8——声明函数