VueJs: Как обновить ширину элемента на основе другого? - PullRequest
0 голосов
/ 08 марта 2020

Я создаю приложение Trivia, и у меня есть элемент <h1>, который меняется каждые 10 секунд. Я хочу сопоставить ширину компонента группы переключателей (b-form-group - это Bootstrap - Vue компонент ) с шириной элемента <h1>. Примерно так:

example image of the desired output Я пытался использовать watchers для обновления buttonWidth всякий раз, когда изменяется значение question. Но с этим кодом ширина группы кнопок, кажется, соответствует ширине предыдущего вопроса, а не текущего. Я также пробовал другие свойства, такие как updated, mounted, created. Я просто не могу заставить его работать правильно. Есть ли более простой способ сопоставить ширину двух элементов?

<template>
  <div>
    <div id="question">
       <h1 ref="quest">{{ question }}</h1>
    </div>

    <b-form-group>
      <b-form-radio-group :style=getWidth
        ref="opts"
        :options="options"
        buttons
        stacked
        button-variant="outline-primary"
        size="lg"
        name="radio-btn-stacked"
      ></b-form-radio-group>
    </b-form-group>
  </div>
</template>

Под моим сценарием у меня есть:

export default {
  props: ['question', 'options'],
  data() {
    return {
      buttonWidth: '0 px',
    };
  },
  methods: {
  },
  watch: {
    question() {
      // console.log('Updating button width to ', this.$refs.quest.clientWidth);
      this.buttonWidth = `width: ${this.$refs.quest.clientWidth}px;`;
    },
    // immediate: true,
  },
  computed: {
    getWidth() {
      return this.buttonWidth;
    },
  },
};

Ответы [ 2 ]

1 голос
/ 08 марта 2020

Чтобы заставить его работать с watch, вам понадобится $nextTick, иначе компонент еще не будет перерисован, и вы все равно будете измерять старую ширину:

watch: {
  question() {
    this.$nextTick(() => {
      this.buttonWidth = `width: ${this.$refs.quest.clientWidth}px;`;
    })
  }
}

Должно также быть возможно заставить это работать с крючками mounted и updated вместо watch. Вам не нужно $nextTick, если вы делаете это таким образом. Вы упомянули, что пытались это сделать в вопросе, но, не видя код, который вы пробовали, трудно понять, почему это не сработало для вас.

Кроме того, неясно, почему у вас есть вычисляемое свойство с именем getWidth. Почему бы просто не использовать buttonWidth напрямую?

0 голосов
/ 08 марта 2020

Моя ошибка заключалась в использовании clientWidth тега h1. Это не возвращало ширину текста в пикселях, а возвращало всю ширину div. Вот решение, которое сработало для меня:

<template>
  <div class="text-center center">
    <div id="question">
       <h1 ref="quest"><span ref="span">{{ question }}</span></h1>
    </div>

    <b-form-group>
      <b-form-radio-group :style=buttonWidth
        ref="opts"
        :options="options"
        buttons
        stacked
        button-variant="outline-primary"
        size="lg"
        name="radio-btn-stacked"
      ></b-form-radio-group>
    </b-form-group>
  </div>
</template>

<script>
export default {
  props: ['question', 'options'],
  data() {
    return {
      buttonWidth: 'width: 500px',
      value: 0,
    };
  },
  watch: {
    question() {
      console.log('Watcher is updating buttonWidth to ', this.$refs.quest.clientWidth);
      this.$nextTick(() => {
        console.log(this.$refs.span.offsetWidth);
        this.buttonWidth = `width: ${this.$refs.span.offsetWidth}px;`;
      });
    },
  },
};
</script>
...