繁体   English   中英

如何在Vue中设置父组件的样式

[英]How to style parent component in Vue

我目前正在使用Vue 2.x构建自定义叠加层组件。 组件有一个支柱,可以使它处于绝对位置或固定位置。

问题是,当我打开绝对位置时,我想添加position: relative对于父组件。 我希望这是一个可重用的组件,所以我希望能够在不了解任何有关父项(id,class等)的情况下执行此操作。 在此处向自定义组件的父项添加样式属性的最佳方法是什么?

这是我的自定义组件当前的外观:

<template>
  <component
    class="custom-overlay"
    :style="overlayStyle"
    :is="type"
    v-if="value">
    <slot :style="overlayContentStyle">
    </slot>
  </component>
</template>

<script>
import { colorShiftHelpers } from '../../mixins/helpers'

export default {
  props: {
    value: {
      default: true,
      type: Boolean
    },
    dark: {
      default: false,
      type: Boolean
    },
    absolute: {
      default: false,
      type: Boolean
    },
    color: {
      default: 'rgb(23, 30, 38)',
      type: String
    },
    opacity: {
      default: 0.46,
      type: Number | String
    },
    type: {
      default: 'div',
      type: String
    },
    zIndex: {
      default: 5,
      type: Number | String
    }
  },
  mixins: [colorShiftHelpers],
  computed: {
    overlayStyle({ absolute, color, opacity, zIndex }) {
      return {
        position: absolute ? 'absolute' : 'fixed',
        background: this.addAlpha(color, opacity),
        'z-index': zIndex
      }
    }
  }
}
</script>

<style scoped>
.custom-overlay {
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
}
</style>

有两种可能的方法可以实现:

惠特·维克斯

从一个状态变量控制所有样式。

商店

state: {
  absolute: false;
}
mutations: {
  setAbsolute(state, value) {
    state.absolute = value  // Here value should be true or false
  }
}

父级

<template>
  <div :class="{relative: absolute}">
    <child-component
      :is-absolute="absolute"
    />
  </div>
</template>

<script>
  export default {
    computed: {
      absolute() {
        return this$store.state.absolute
      }
    }
  }
</script>

在前面的示例中,我在商店上有一个名为absolute的变量,并且有一个变量来为该属性设置一个值,在这种情况下,您始终要传递一个布尔值,还可以像这样进行切换器突变:

mutations: {
    switchAbsolute(state) {
      state.absolute = !state.absolute
    }
  }

每当你想改变那只是打电话

  $store.commit('switchAbsolute')

或以下,如果您想使用第一种方法手动设置值

  $store.commit('setAbsolute', [the value you want absolute to be])

绝对值在您的父级上作为计算属性接收,从那里您可以控制父级的样式,并将与prop相同的值传递给子级。 注意条件类绑定,.relative类应将位置设置为相对。

与观察者和事件

接下来是逻辑:在子组件上,只要prop发生更改,就发出一个事件,并在父组件上处理该事件以更改其样式:

儿童

props: {
  absolute: {
    type: Boolean,
    default: false
  }
},
watch: {
  absolute: function(newVal, oldVal) {
    if (newVal === true) {
      this.$emit('childIsAbsolute')
    }
  }
}

在父母身上*

<template>
  <div :styles="relativePosition">
    <child-component @childIsAbsolute="handleChange($event)" 
     :absolute="absolute"
    />
  </div>
</template>
<scrip>
  export default {
    data() {
      relative: false;
      absolute: false
    },
    methods: {
      handleChange(event) {
        this.relative = event //here event is true or false, depending  
        on the value of the child's prop, emited from the watcher
      }
    },
    computed: {
      relativePosition() {
        return `position: ${this.relative ? 'relative' : 'static'}`
      }
    }
  }
</script>

我们在这里所做的是:

为孩子设置一个prop绝对值,我们观察它在更改时发出一个事件,该事件将prop的新值发送给父对象,然后我们对该事件做出反应并根据该新值更改样式(如果child是绝对的,如果不是,则为false)。 我真的不知道你在哪里处理那个道具的价值,在这个例子中我说没有必要用事件来处理它,因为我们实际上拥有我们想要在父母中做出反应的价值,但是我不是真的知道你是从哪里寄来的。

正如David Weldon在我的问题评论中所说的那样,在干净的编码实践中实际上不建议我要实现的目标(当孩子的道具为x时,使孩子组件操纵父母的风格)。 他说的更好,所以我在这里粘贴他的评论:

通常,如果代码库的子单元(在本例中为组件)具有显式关系,则代码库更易于维护。 您需要的解决方案是一个隐式关系-将组件C添加到组件P的操作将改变P。想象一下,一年后,您将P转换为模态,并且由于C的行为而突然中断。 一个明确的解决方案是添加位置:相对于P(带有注释),或向P添加类似o-container的类,其中o-container是可重用的CSS对象类,在您的应用中具有明确的用途。

我最终要做的只是创建一个可重用的CSS类,并将其添加到父类中,而不是让子组件操纵父组件的样式。

.relative {
    position: relative;
}

我不建议为此使用vuex状态-正如MattAft在评论中也指出的那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM