在一个组件的<style>标签里,如果写了scoped ,表示只会影响当前组件的样式。以记账项目里的Money.vue和它的组件Layout.vue为例,
//Layout.vue
<template>
<div class="layout-wrapper">
<div class="content">
<slot></slot>
</div>
<Nav/>
</div>
</template>
这个组件的content类里有一个插槽,等待父组件将内容传进来。
在Money.vue里,通过:
<Layout>
<div></div>
<div></div>
</Layout>
把内容放到插槽的位置。
需求
现在我做好了Money.vue里的两个div,想给他们做整体上的布局,就需要获取这两个div的父元素的class,在Money.vue里写样式。也就是给Layout.vue里的content类加样式。
1. 直接在Layout组件上加
<Layout class="xxx">
<div></div>
<div></div>
</Layout>
如果直接在组件上加class,会发现这个class被加到了Layout组件上的class="layout-wrapper"这个元素上,而不是这两个div的父元素。这时Vue自动做的,就导致我们无法为想要的标签添加class。
2. class-prefix属性
//Layout.vue
<template>
<div class="layout-wrapper">
<div class="content" :class="classPrefix && `${classPrefix}-content` ">
<slot></slot>
</div>
<Nav/>
</div>
</template>
<script lang="ts">
export default {
name: 'Layout',
props:['classPrefix']
};
</script>
在组件这里添加一个props外部属性,作为前缀。给需要添加class的标签上,绑定一个class属性,值是以这个外部属性作为前缀,然后-content,-后边一般是现有class的名称。
然后在父组件里,传一个
<Layout class-prefix="layout">
....
</Layout>
那么组件里边的content就拥有了layout-content的class。
如果还有其他标签想这样做,也可以直接在自己身上绑定class,接收父组件传来的classPrefix
因为layout-content这个class不在Money.vue上,所以加了scoped的style标签影响不到。那就再写一个没有scoped的style标签:
<style lang="scss">
.layout-content{
border:1px solid red;
}
</style>
总结
我认为classPrefix的作用,就是我们一般写style标签时会加一个scoped,为了不影响其他组件的同名的选择器。但是如果父组件想获取子组件的class,加样式的时候,加了scoped就影响不到。
如果选择不加scoped,就可以影响到了。但是万一有其他的同名选择器,就会混乱。所以classPrefix这个前缀,就是为了给那个元素一个独特的,不会重复的class。使得我们可以放心的不加scoped。