deep语法

在Statistics组件中复用Type组件
在一个组件中如果要修改子组件的css, 在scoped条件下, 是访问不到子组件的元素的, 需要使用deep语法

  1. <template>
  2. <Layout>
  3. <Types class-prefix="zzz" :value.sync="xxx"/>
  4. </Layout>
  5. </template>
  6. <script lang="ts">
  7. import Vue from 'vue'
  8. import {Component} from 'vue-property-decorator';
  9. import Types from '@/components/Money/Types.vue';
  10. @Component({
  11. components:{Types}
  12. })
  13. export default class Statistics extends Vue{
  14. xxx = '-'
  15. }
  16. </script>
  17. <style lang="scss" scoped>
  18. ::v-deep .zzz-item {
  19. background: #fff;
  20. &.selected{
  21. background: #C4C4C4;
  22. &::after{
  23. display: none;
  24. }
  25. }
  26. }
  27. </style>

class使用对象语法, 属性名中如果有变量, 使用[]

  1. <template>
  2. <div>
  3. <ul class="types">
  4. <li :class="{[classPrefix+'-item']: classPrefix, selected: value === '-'}"
  5. @click="selectType('-')">支出
  6. </li>
  7. <li :class="{[classPrefix+'-item']: classPrefix, selected: value === '+'}"
  8. @click="selectType('+')">收入
  9. </li>
  10. </ul>
  11. </div>
  12. </template>

将Types组件抽离成通用组件

Tabs组件

  1. <template>
  2. <ul class="tabs">
  3. <li v-for="item in dataSource" :key="item.value"
  4. :class="liClass(item)"
  5. @click="changeTab(item)"
  6. >{{item.text}}</li>
  7. </ul>
  8. </template>
  9. <script lang="ts">
  10. import Vue from 'vue';
  11. import {Component, Prop} from 'vue-property-decorator';
  12. type DateSourceItem = {text: string, value: string}
  13. @Component
  14. export default class Tabs extends Vue{
  15. @Prop({required:true, type: Array} ) dataSource!: DateSourceItem[]
  16. @Prop(String) classPrefix?: string
  17. @Prop(String) readonly value!:''
  18. liClass(item: DateSourceItem){
  19. return {
  20. [this.classPrefix+'-tabs-item']: this.classPrefix,
  21. selected: item.value === this.value
  22. }
  23. }
  24. changeTab(item: DateSourceItem){
  25. this.$emit('update:value', item.value)
  26. }
  27. }
  28. </script>
  29. <style lang="scss" scoped>
  30. .tabs {
  31. background: #C4C4C4;
  32. display: flex;
  33. font-size: 24px;
  34. color: #000;
  35. > li {
  36. width: 50%;
  37. height: 64px;
  38. display: flex;
  39. justify-content: center;
  40. align-items: center;
  41. position: relative;
  42. &.selected::after {
  43. content: '';
  44. position: absolute;
  45. width: 100%;
  46. height: 4px;
  47. background: #333333;
  48. left: 0;
  49. bottom: 0;
  50. }
  51. }
  52. }
  53. </style>

在Statistics组件中使用Tabs组件

  1. <template>
  2. <Layout>
  3. <Tabs class-prefix="type" :value.sync="type" :data-source="typeList"/>
  4. <Tabs class-prefix="interval" :value.sync="interval" :dataSource="tabList"/>
  5. </Layout>
  6. </template>
  7. <script lang="ts">
  8. import Vue from 'vue'
  9. import {Component} from 'vue-property-decorator';
  10. import Types from '@/components/Money/Types.vue';
  11. import Tabs from '@/components/Tabs.vue';
  12. @Component({
  13. components:{Types, Tabs}
  14. })
  15. export default class Statistics extends Vue{
  16. type = '-'
  17. interval = 'day'
  18. tabList = [
  19. {text: '按天', value: 'day'},
  20. {text: '按周', value: 'week'},
  21. {text: '按月', value: 'month'},
  22. ]
  23. typeList = [
  24. {text: '支出', 'value': '-'},
  25. {text: '收入', 'value': '+'},
  26. ]
  27. }
  28. </script>
  29. <style lang="scss" scoped>
  30. ::v-deep .type-tabs-item {
  31. background: #fff;
  32. &.selected{
  33. background: #C4C4C4;
  34. &::after{
  35. display: none;
  36. }
  37. }
  38. }
  39. </style>

Object.freeze()

将常量放到constants目录
使用Object.freeze声明不可变更的对象或数组

  1. export default Object.freeze([
  2. {text: '按天', value: 'day'},
  3. {text: '按周', value: 'week'},
  4. {text: '按月', value: 'month'},
  5. ])

修改Tabs组件高度

image.png
css选择器层级越多,优先级越高
image.png
或者把li的css变成一级
image.png
image.png
将2个v-deep合并

  1. <style lang="scss" scoped>
  2. ::v-deep .type-tabs-item {
  3. background: #fff;
  4. &.selected{
  5. background: #C4C4C4;
  6. &::after{
  7. display: none;
  8. }
  9. }
  10. }
  11. ::v-deep .interval-tabs-item {
  12. height: 48px;
  13. }
  14. </style>

合并后

  1. <style lang="scss" scoped>
  2. ::v-deep {
  3. .type-tabs-item {
  4. background: #fff;
  5. &.selected{
  6. background: #C4C4C4;
  7. &::after{
  8. display: none;
  9. }
  10. }
  11. }
  12. .interval-tabs-item {
  13. height: 48px;
  14. }
  15. }
  16. </style>