我们知道,在Vue组件的style标签里,加上scoped属性,会使写的样式只影响当前的组件,不会影响到子组件。
去掉scoped就可以了,但是去掉scoped同时也会导致其他问题,可能会影响到别的。
有什么方法能在父组件的css里影响子组件的样式,同时保留scoped呢?

deep有两种写法,::v-deep兼容性最强, 优先使用这个。
使用方法:在想要影响子组件的那个元素的选择器的前边加上::v-deep

  1. //Statistics.vue父组件
  2. <template>
  3. <Layout>
  4. <Type/>
  5. </Layout>
  6. </template>
  7. <style lang="scss" scoped>
  8. ::v-deep li{
  9. border:1px solid black;
  10. }
  11. ::v-deep ul{
  12. border:1px solid red;
  13. }
  14. </style>

Type子组件里有ul和li元素,想要在父组件里改变它的样式,就在选择器前加::v-deep,表示深入到子组件里边找这个选择器。可以发现成功影响了自组件的样式。

例如

1. 修改支出收入

image.png

问题1 :如何通过 CSS 选择器 选择到里面的 ‘支出’,‘收入’

方案一: .x li{ }
image.png
失败 :不行,因为我们使用了 scoped ,只影响当前所在的组件里的东西,不能影响其他组件里面的东西
li 是 tags 里面的东西,我们是影响不到的
方案二: 去掉 scoped
失败:CSS 成功,但是影响了里面的组件
image.png

方案三:deep 语法 既需要 scoped 也需要 不影响里面的组件
/deep/ 或 ::v-deep 意思是 .x 深入到里面的组件,不看外面组件
image.png
image.png

可是如果子组件里有很多个li,或者li嵌套li,那只在外边说深入里边的li不准确。怎么精确的定位到子组件里的某个元素呢?

classPrefix 前缀

可以给子组件传一个prop,是classPrefix。在子组件里判断,如果外边给传了这个classPrefix,那某个元素就拥有了一个class,叫做"xxx-item",xxx是classPrefix变量的值。
然后在父组件的css里,就可以deep 这个加了前缀的选择器,就可以精准找到这个元素了。

例如

使用 前缀 classPrefix

image.png
xxx 由外部控制的,如果其他文件有这个 xxx 那么,那么就不会混淆了

image.png

给元素绑定class

给一个元素添加class可以使用&&,也可以使用对象形式。

  1. <li :class="type==='-' && 'selected'"
  2. @click="selectType('-')">支出
  3. </li>
  4. 复制代码

如果前边的表达式为True,这个元素就拥有了后边的class。如果我这时再给它添加一个class绑定,会出错,不能同时有两个:class,所以升级使用对象

  1. <li :class="{selected:type==='-',
  2. [classPrefix+'-item']:classPrefix}"
  3. @click="selectType('-')">支出
  4. </li>
  5. 复制代码

绑定的class是一个对象,里边是key-value。表示如果value表达式为真,我就拥有了key这个class。因为对象可以有很多个键值对,所以使用对象可以同时动态绑定多个class。
我要绑定的第二个class,是xxx-item,xxx是父组件要给我传的一个prop。如果给传了,即如果classPrefix这个外部属性给传了,我就拥有了以它为前缀的一个class。可是这个classPrefix是一个变量,在这里使用${}插值不合法。有ES6的新语法:如果一个key里边有变量,就用[]把这个key包起来,里边用字符串相加的方式表达。

例如

可以使用 :class , 但是这里的 : 已经被占用了,如何操作呢
image.png
改成对象的形式 : 表驱动法
image.png
第二个 class 表示 :可能会有 一个叫 selected 的类,在 value === ‘-’ 为 true 的时候 给 li 加上。就是后面如果是真 ,就要这个class,为假,就不需要
image.png
怎么将 classPrefix 放到 xxx 位置呢
ES6 新语法 :如果 key 里面有变量,用中括号包起来

image.png

image.png