vue2中有没有仅在父组件写好代码,不需要修改子组件代码就能让子组件自动触发的方式?

假设有

父组件A > 子组件B > 子组件C

现在有一个值height仅在父组件A中使用,但是子组件B、C的加载或更新都可能导致这个值height发生变化
有没有一种方法可以把代码集中写到父组件A中,不管父组件A有多少个子组件或子子组件,当这些子组件发生更新时,自动触发height的更新

注意所有的代码都在父组件A中,其子组件不添加代码(不能使用state或inject)

阅读 1.6k
3 个回答

父组件使用MutationObserver(不考虑兼容问题可以用)监听到dom结构变化,此时去更新父组件的height。如果再简单粗暴一点,定时器

vue2 是这个
.修饰符.sync

由于保持数据的单向性,从父组件传到子组件的数据,子组件如果修改了项目还可以运行浏览器上会报错,加上.sync后子组件内部改变props属性值并更新到父组件中

<child :name.sync="name"></child> // 父组件

// 子组件事件
changePropsInChild(){
      this.$emit('update:name', 'I am from child');
}

:name.sync就是:name="name" @update:name="name = $event"的缩写

我写了一个mixin,有需要的可以自取

/**
 * 监听 sticky-top 元素及其子元素的变化,动态计算 top 值,
 * 以实现 sticky-top 元素高度较小时,顶部粘住;高度较大时,底部粘住的效果(类似知乎首页侧边栏)
 *
 * class="StickyTopBox",需要 sticky-top 的元素
 * class="StickyTopOffset",会影响 top 值的元素,如页头,二级页头,其它 sticky-top 的顶部导航栏等
 *
 * 使用:
 * mixins 方式注入需要 sticky-top 的元素所在组件(元素获取方式为 this.$el.querySelector)
 *
 * 注意:
 * 确保页面中没有无效 StickyTopOffset 影响计算
 * 多个 StickyTopBox 请自行探索
 */
const stickyTopBox = {
  data() {
    return {
      stickyTopBoxObserver: null,
    };
  },
  computed: {
    stickyTopBox() {
      return this.$el.querySelector(".StickyTopBox");
    },
  },
  created() {
    this.stickyTopBoxObserver = new MutationObserver(this.updateStickyTop);
  },
  mounted() {
    this.stickyTopBox.style.zIndex -= 1; // 在 StickyTopOffset 默认值之下
    this.updateStickyTop();
    window.addEventListener("resize", this.updateStickyTop);
    this.stickyTopBoxObserver.observe(this.stickyTopBox, {
      attributes: true,
      characterData: true,
      childList: true,
      subtree: true,
    });
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.updateStickyTop);
    this.stickyTopBoxObserver.disconnect();
  },
  methods: {
    updateStickyTop() {
      const windowHeight = window.innerHeight;
      const sideHeight = this.stickyTopBox.clientHeight;
      let stickyTop = [...document.querySelectorAll(".StickyTopOffset")].reduce(
        (a, b) => a.clientHeight + b.clientHeight
      );
      this.stickyTopBox.style.top =
        windowHeight - stickyTop > sideHeight
          ? `${stickyTop}px`
          : `${windowHeight - sideHeight}px`;
    },
  },
};

export default stickyTopBox;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏