样式组件
在使用 Vue 组件时,webpack 编译器允许您使用几乎任何您喜欢的前端模板语言风格。例如,有几种方法可以直接或通过预处理来编译 CSS。在 Vue 模板中启用这些表达式语言的最简单方法,就是在使用 Vue CLI 提前设置项目时安装它们。
在 Vue 组件中使用样式(style)标签时,只要安装了相应的 webpack 加载器,就可以选择指定语言。在 Exercise 1.01 中,如果选择安装 SCSS 预处理器,就可以在样式标签中添加 lang="scss" 属性,开始使用 SCSS。
例如,如果您选择安装 Stylus 预处理器,则可以在样式标记中添加 lang="stylus" 属性,开始使用 Stylus:
<style lang="stylus">
ul
color: #2c3e50;
> h2
color: #22cc33;
</style>
Vue 范围(scoping)是一种方便的方法,可以阻止单个组件从虚拟 DOM 头继承样式。将 scoped 属性添加到样式(style)标签中,然后编写一些特定于组件的样式,这些样式将覆盖全局表中的任何其它 CSS 规则。一般规则是不对全局样式设范围。定义全局样式的常用方法是将这些样式分离到另一个样式表中,然后导入到您的 App.vue 中。
练习 1.03:将 SCSS 导入到作用域组件中
在本练习中,我们将利用样式(style)标签将 SCSS 预处理样式添加到组件并导入外部样式表。
要访问本练习的代码文件,请参阅 https://packt.live/3nBBZyl 。
-
打开命令行终端并导航到
Exercise1.03文件夹并按顺序运行以下命令:> cd Exercise1.03/ > code . > yarn > yarn serve -
在练习文件中,我们编写一些可以使用 SCSS 设置样式的 HTML。我们继续练习一下插值方法:
// src/components/Exercise1-03.vue <template> <div> <h1>{{ title }}</h1> <h2>{{ subtitle }}</h2> <ul> <li>{{ items[0] }}</li> <li>{{ items[1] }}</li> <li>{{ items[2] }}</li> </ul> </div> </template> <script> export default { data() { return { title: 'My list component!', subtitle: 'Vue JS basics', items: ['Item 1', 'Item 2', 'Item 3'] } }, } </script> -
将
lang属性添加到样式(style)标记并添加值scss以在样式块内启用 SCSS 语法:<style lang="scss"></style> -
在
src/目录中创建一个名为styles的文件夹。在这个新文件夹中创建一个名为typography.scss的文件:src/styles/typography.scss -
在 typography.scss 中,为您在组件中编写的模板添加一些样式:
/* typography.scss */ $color-green: #4fc08d; $color-grey: #2c3e50; $color-blue: #003366; h1 { margin-top: 60px; text-align: center; color: $color-grey; + h2 { text-align: center; color: $color-green; } } ul { display: block; margin: 0 auto; max-width: 400px; padding: 30px; border: 1px solid rgba(0,0,0,0.25); > li { color: $color-grey; margin-bottom: 4px; } }在 SCSS 中,您可以使用标准 CSS 选择器来选择组件中的元素。
ul > li将选择<ul>元素内的每个<li>元素进行样式设置。类似地,使用加法符号+意味着放置在第一个元素之后的元素如果符合条件则将被设置样式。例如,h1 + h2将指示H1之后的所有H2元素都将以某种方式设置样式,但H3不会。通过下面的例子你可以更好地理解这一点。在 CSS 中,您将按如下方式呈现此代码:
h1 + h2 { /* Add styling */ } ul > li { /* Add styling */ }在 SCSS 中,相同的代码可以表示如下:
h1 { + h2 { // Add styling } } ul { > li { // Add styling } } -
在您的组件中,使用 SCSS
@import方法导入这些样式:<style lang="scss"> @import '../styles/typography'; </style>这将生成如下输出:
Figure 1. Figure 1.10: When you save and reload, your project should have the style imported -
将
scoped属性添加到<style>标记中,以仅将这些样式应用于此组件实例。使用导入样式表$color-blue中的变量:<style lang="scss" scoped> @import '../styles/typography'; h1 { font-size: 50px; color: $color-blue; // Use variables from imported stylesheets } </style>上述代码的输出如下:
Figure 2. Figure 1.11: The outcome of scoping styles检查文档的 DOM,您会注意到在运行时,作用域已将
v-data-*属性应用于指定这些特定规则的 DOM 元素。我们的 typography.scss(我们将其范围限定为组件)引用了不在组件范围内的 HTML 标记。当 Vue 将数据属性添加到作用域组件时,如果组件中存在<body>标签,它会生成样式。在我们的例子中,事实并非如此。展开
<head>和<style>标签后,浏览器开发工具的Elements选项卡将显示以下内容:
Figure 3. Figure 1.12: Observe how the virtual DOM uses data attributes to assign scoped styles -
在
styles文件夹中创建一个名为global.scss的新样式表:/* /src/styles/global.scss */ body { font-family: 'Avenir', Helvetica, Arial, sans-serif; margin: 0; } -
将此样式表导入到您的
App.vue中:<style lang="scss"> @import './styles/global'; </style>我们的应用程序现在应该恢复正常,该组件混合了全局定义的样式和适当范围的样式,如下所示:
Figure 4. Figure 1.13: Properly scoped styles for Exercise 1.03在本练习中,我们插入了源自数组的数据,然后使用范围 SCSS 的形式设置组件的样式,这些形式既可以存在于
<style>标记内,也可以从项目中的另一个目录导入。