vue scoped 原理

103 阅读1分钟

当我们在 vue文件中的style部分添加了scoped属性之后

<template>
<div class="container">
   <div class="row-info">测试数据</div>
</div>
</template>
<style scoped>
.container{
 color:red
 }
 .row-info{
 color:blue
 }
</style>

编译完到渲染dom时

<html>
  <div class="container" data-v-065d6bd4>
     <div class="row-info" data-v-065d6bd4>
       测试数据
     </div>
  </div>
</html>

<style>
.container[data-v-065d6bd4]{
  color:red
}
.row-info[data-v-065d6bd4]{
  color:red
}

</style>

一、单个vue文件,使用同一个id如 data-v-065d6bd4

二、vue文件通过vue-loader加载,vue-loader中就是通过resourceQuery并拼接不同的query参数,将各个标签分配给对应的loader进行处理。

模板部分template,由template-loader处理添加hash id.

一个组件的render方法返回的VNode,描述了组件对应的HTML标签和结构,HTML标签对应的DOM节点是从虚拟DOM节点构建的,一个Vnode包含了渲染DOM节点需要的基本属性

`

// templateLoader.js
const { compileTemplate } = require('@vue/component-compiler-utils')

module.exports = function (source) {
 const { id } = query
 const options = loaderUtils.getOptions(loaderContext) || {}
 const compiler = options.compiler || require('vue-template-compiler')
 // 可以看见,scopre=true的template的文件会生成一个scopeId
 const compilerOptions = Object.assign({
  outputSourceRangetrue
 }, options.compilerOptions, {
  scopeId: query.scoped ? `data-v-${id}` : null,
  comments: query.comments
 })
 // 合并compileTemplate最终参数,传入compilerOptions和compiler
 const finalOptions = {source, filenamethis.resourcePath, compiler,compilerOptions}
 const compiled = compileTemplate(finalOptions)
 
 const { code } = compiled

 // finish with ESM exports
 return code + `\nexport { render, staticRenderFns }`
}

`

参考原文地址 www.codebaoku.com/it-web/it-w…