Доступ к данным компонента Vue с помощью $ref.

В этой статье предполагается, что у вас есть базовые знания о реактивной системе Vue и Vue.

Чрезвычайные ситуации — это данность, и иногда мы получаем одну из них при создании интерфейсных приложений, к счастью, большинство этих интерфейсных фреймворков предоставляют нам несколько способов справиться с чрезвычайными ситуациями. В Vue одним из многих аварийных люков является $ref атрибут.

Как правило, атрибут ref обычно используется для чистых HTML-элементов (например, <input /> element) в Vue точно так же вы можете иметь ссылку на пользовательский компонент (<my-custom-componet />) и иметь доступ к его вычисляемым значениям, методам, свойствам данных и т. д. Это, однако, следует использовать только в экстренных ситуациях или в крайнем случае.

Доступ к данным — общий подход

Скажем, у нас есть два дочерних компонента (компонент A и компонент B) внутри родительского компонента, и нам по какой-то причине нужно отобразить некоторые данные из компонента A в B и наоборот. видеть грубый набросок ниже:

совместное использование данных компонентов

Общим и рекомендуемым подходом будет отправка данных из A, добавление прослушивателя/обработчика в родительский компонент, а затем передача значения в компонент B через реквизиты. Это будет выглядеть примерно так:

вью реактивная система

В некоторых случаях нам может понадобиться взломать наш путь и исключить некоторые шаги из этого потока, чтобы немного сократить путь передачи данных. Сказать ComponentA не нужно будет передавать значение данных родительскому компоненту, тогда мы можем удалить шаги отправки и прослушивания и получить прямой доступ к значениям в ComponentA из родительского компонента.

Использование $ref

Скажем, у нас есть два одинаковых компонента — Компонент А и Компонент Б.

Компонент А имеет два метода; setThought который устанавливает значение a thought data на любое значение, переданное из редактируемого div, и другой метод — readMind это пока ничего не дает.

<template>
  <div>
    <div contenteditable @input="setThought($event.target.innerText)">
      {{ thought }}
    </div>
    <div>
      <button @click="readMind">What is B thinking?</button> {{ otherThought }}
    </div>
  </div>
</template>

<script>
export default {
  name: "ComponentA",
  data() {
    return {
      thought: 'I should steal a cookie',
      otherThought: '',
    };
  },
  methods: {
    setThought(value) {
      this.thought = value;
    },
    readMind() { }
  },
};
</script>

Компонент Б похожа, только с небольшой разницей в содержании:

<template>
  <div>
    <div contenteditable @input="setThought($event.target.innerText)">
      {{ thought }}
    </div>
    <div class="">
      <button @click="readMind">What is A thinking?</button> {{ otherThought }}
    </div>
  </div>
</template>

<script>
export default {
  name: "ComponentB",
  data() {
    return {
      thought: 'I like school a tiny bit',
      otherThought: '',
    };
  },
  methods: {
    setThought(value) {
      this.thought = value
    },
    readMind() { }
  },
};
</script>

Возможно, вы уже поняли, что мы хотим здесь сделать, а может и нет. Нам нужно, чтобы Компонент А мог читать мысли Компонента Б, без того, чтобы Компонент Б излучал свои мысли.

Для этого у обоих компонентов должно быть что-то общее — их родитель. Чтобы разделить datjsa между двумя компонентами, используя $ref , они должны быть дочерними элементами одного и того же родительского компонента. Таким образом, в родительском компоненте мы импортируем компоненты A и B в родительский компонент и назначаем атрибуты ref им обоим.

<template>
  <div id="app">
    <ComponentA ref="componentA" />
    <ComponentB ref="componentB" />
  </div>
</template>

<script>
import ComponentA from './components/ComponentA.vue'
import ComponentB from './components/ComponentB.vue'
export default {
  name: 'App',
  components: {
    ComponentA,
    ComponentB
  },
}
</script>

С помощью этой структуры мы можем легко получить доступ к каждому компоненту по ссылке из его родителя следующим образом:

this.$parent.$refs.componentA
OR
this.$parent.$refs.componentB

Теперь мы можем обновить readMind метод для Component A чтобы при нажатии кнопки Component A точно знал бы, что Component B думает:

<script>
  export default {
    name: "ComponentA",
    methods: {
      ...
      readMind() {
        this.otherThought = this.$parent.$refs.componentB.thought
      }
      ...
    }
  }
</script>

Обратите внимание, что мы можем получить доступ к thought data в ComponentB, установив для него атрибут ref и обратившись к нему из его родителя.

Мы можем сделать аналогичное обновление для readMind метод в Компонент Б сделать то же самое — выяснить, что Компонент А думает.

<script>
  export default {
    name: "ComponentB",
    methods: {
      ...
      readMind() {
        this.otherThought = this.$parent.$refs.componentA.thought
      }
      ...
    }
  }
</script>

Как это выглядит?

Можем ли мы также установить значения компонентов?

Конечно, как и 2010 фильм — Начало, давайте заставим мысли Компонента B быть именно теми, о которых думает Компонент A. Мы можем установить значение свойств данных таким же образом:

<script>
  export default {
    name: "ComponentA",
    methods: {
      ...
      setThought(value) {
        this.thought = value;
        this.$parent.$refs.componentB.thought = value;
      },
      ...
    }
  }
</script>

В качестве альтернативы вы можете позвонить в setThought метод КомпонентB из сложный:

<script>
  export default {
    name: "ComponentA",
    methods: {
      ...
      setThought(value) {
        this.thought = value;
        this.$parent.$refs.componentB.setThought(value);
      },
      ...
    }
  }
</script>

Как это будет выглядеть?

О, рефери реактивные?

Нет, они не. То, что вы видите, является только результатом вызова setThought метод каждый раз, когда есть ввод в компоненте А, и, в свою очередь, установка значения this.$parent.$refs.componentB.thought к тому же значению, что и thought свойство данных в ComponentA.

Ссылки — одна из необычных частей Vue, и они могут вызвать проблемы, если вы не понимаете их правильное использование. Самый безопасный способ их использования — вне хуков вашего жизненного цикла и только внутри методов. Кроме того, избегайте прямого использования в шаблонах компонентов или вычисляемых свойствах.

Если вы хотите повозиться с исходным кодом, вы найдете его здесь:

Также, Вот подробное руководство о том, как и где безопасно получить доступ к ссылкам, и, конечно же, официальная документация.

Привет ☕️

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *