样式组件
在使用 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>
标记内,也可以从项目中的另一个目录导入。