蛋糕店网站建设,徐州seo外包公司,wordpress gallery插件,如何搭建电影网站Vue 中存在 scoped 属性#xff0c;HTML5中也存在一个 scoped 属性#xff0c;而且#xff0c;这两者都是针对 css 样式处理的属性#xff0c;所以很多文章在 解释 Vue scoped 的时候#xff0c;都会把两者混为一谈#xff0c;直接进把 HTML5 scoped 的定义搬到 Vue scop… Vue 中存在 scoped 属性HTML5中也存在一个 scoped 属性而且这两者都是针对 css 样式处理的属性所以很多文章在 解释 Vue scoped 的时候都会把两者混为一谈直接进把 HTML5 scoped 的定义搬到 Vue scoped 上其实这是不对的这两个不是一个东西。 HTML5 scoped 在 W3C 和 MDN 文档上是这么说的
该属性已被移除不建议使用。
该属性是一个布尔属性。如果使用该属性则样式仅仅应用到 style 元素的父元素及其子元素。
第一句话就是不建议使用这玩意。Vue 这么大受众的框架肯定不会不考虑到这一点。 再就是这玩意只有火狐支持更不符合项目初衷。
使用方法 和 Vue scoped 一致直接写在 style 标签内部
divstyle typetext/css scopedh1 {color: red;}p {color: blue;}/styleh1这个标题是红色的/h1p这个段落是蓝色的。/p/div
展示效果 控制台DMO结构 可以看到在 DMO 结构中 只是把我编写的代码原封不动的渲染了并没有做任何处理这就是和 Vue scoped 的最大区别
后面再讲到 Vue scoped 原理的时候会做个对比更容易看出区别在哪。 Vue 组件的样式覆盖 Vue 项目中每个组件内都会存在一个 style/style 用来编写组件样式如果组件过多那么在开发过程中难免会出现类名相同的情况。一旦类名相同那么在编译的时候就可能出现问题。
例如 组件 Student 存在一个 demo 的class组件 School 也同时存在 demo 的class 虽然说这两个 class 代表的样式在各自组件中是不一样的但是展示的效果却不是我们想要的。
// Student 组件
templatedivp classdemoStudent组件/p/div
/templatestyle.demo {background:orange}
/style// School 组件
templatedivp classdemoSchool组件/p/div
/templatestyle.demo {background:red}
/style// App 组件使用
templatediv idappSchool /Student //div
/template
如果按照我们设想的School 组件展示 红色 Student 组件展示橙色但是实际效果是 两个组件都展示的 橙色Student 组件的样式覆盖了School 组件的样式。这是因为我们在引入组件的时候Student 组件是后引入的。如果我们先引入 Student 组件那展示效果又不一样了。 这是因为在webpack 编译的时候所有组件内的 style 都会合并相同类名的样式自然就会放到一起根据css规则后面的样式自然会覆盖前面的样式。
我把这个空项目打包一下看看这两个组件的style合并之后长啥样。 可以看到当前只存在一个 .demo 的类名但是这个类名中存在两个 background 属性按照顺序也就是 Student 组件的样式 和 School 组件的样式。
为了避免这个问题 Vue 使用了 scoped 属性来作为样式隔离。 Vue scoped 样式隔离 先说使用方法只需要在组件中的 style/style 标签中加入 scoped 属性即可Vue 会自动处理样式就像下面这样。
style scoped.demo {background:red}
/style 我在 School 组件 和 Student 组件 中都加上这个属性然后再来看看页面展示效果 打包看下编译后的 css 文件长啥样。
.demo[data-v-2578f57b]{background:orange}
.demo[data-v-5c5da36a]{background:red}
存在两个 demo 类名但是两个 demo 类名上都新增了一个 [data-v-xxxx] 的属性这个就是Vue 底层根据我们的 scopde 属性针对这些样式做了处理导致在编译的时候这些样式不被认为是同名样式所以不会导致样式覆盖。
再来看看控制台上的 DOM节点和样式 可以看到控制台上的样式和 打包之后的样式是一致的但是在 DOM 节点上我们可以发现两个组件的根元素和子元素上都添加了一个 data-v-xxxx 属性而且还是相同的。
这是因为 Vue有一个 自带的插件 Vue-loader通过这个插件就可以实现这些转化而且不用引入别的第三方包。( Vue-loader 使用的是 Post-CSS 来实现这些转换在深入的源码研究就暂时不说了我也还没看到那里去。。。 ) Scoped CSS 和 CSS Modules 一个是在编译之后给类名上加上属性选择器的同时还需要给 DOM 节点增加自定义属性用来隔离样式 -- Scoped CSS 一个是在编译之后直接在 DOM 节点上给类名增加一个hash后缀不会在节点上增加自定义属性用来隔离样式且DOM节点与样式文件展示类名一致 -- CSS Modules。 这样一对比发现 CSS Modules 是更好用一点哈。所以在 Vue Loader v15 及以上版本 增加了 CSS Modules 功能但是需要手动开启该功能
CSS Modules 必须通过向 css-loader 传入 modules: true 来开启
// webpack.config.js
{module: {rules: [// ... 其它规则省略{test: /\.css$/,use: [vue-style-loader,{loader: css-loader,options: {// 开启 CSS Modulesmodules: true,// 自定义生成的类名localIdentName: [local]_[hash:base64:8]}}]}]}
} 然后在你的 style 上添加 module 特性就和添加 scoped 属性一样
style module
.red {color: red;
}
.bold {font-weight: bold;
}
/style 总结 Vue scoped 作用 给当前组件的所有标签添加一个不重复的data属性形如data-v-40b76154来表示唯一性 为了避免影响全局样式给每句CSS选择器末尾编译后生成的CSS语句加一个当前组件的data-v-hash属性选择器来私有化样式 为了避免影响子组件的样式只会给子组件的最外层标签上添加当前组件的data-v-hash属性 CSS Modules 模块化应用越来越好也越来越广泛我觉得还是 CSS Modules 比较好至少看起来比较清爽一点不会在节点上增加很多自定义属性