Ссылки Vue 3 ведут себя по-разному, если они являются свойством объекта

#vue.js #vuejs3 #vue-composition-api

#vue.js #vuejs3 #vue-composition-api

Вопрос:

При использовании Composition API Vue 3 я заметил, что внутри templte ссылки ведут себя по-разному, когда к ним обращаются как к свойству объекта. Я думаю, что это лучше всего изложить в этом примере на игровой площадке SFC, но вот ключевой код (из одного файлового компонента)::

     <script>
    import { ref } from 'vue';
    export default {
      setup() {
        const wut = ref(false);
        const obj = { wut };
        return {
          wut,
          obj,
        };
      },
    };
    </script>
    
    <template>
      <!-- obj.wut - false -->
      <h3>obj.wut - {{ obj.wut }}</h3>
      <!-- !!obj.wut - true -->
      <h3>!!obj.wut - {{ !!obj.wut }}</h3>
      <!-- obj.wut.value - false -->
      <h3>obj.wut.value - {{ obj.wut.value }}</h3>
      <!-- !!obj.wut.value - false -->
      <h3>!!obj.wut.value - {{ !!obj.wut.value }}</h3>
      <!-- does display -->
      <h3 v-if="obj.wut">display logic for this: v-if="obj.wut"</h3>
      <!-- does not display -->
      <h3 v-if="!obj.wut">display logic for this: v-if="!obj.wut"</h3>
      <!-- typeof obj.wut - object -->
      <h3>typeof obj.wut - {{ typeof obj.wut }}</h3>
    </template>
 

Кто-нибудь может объяснить, почему в некоторых случаях он рассматривает ссылку как объект и интерпретирует ее значение в других случаях? Это ошибка или так задумано?

Ответ №1:

Короткий ответ: это сделано специально.

Длинный ответ:

Пожалуйста, ознакомьтесь с Руководством Vue3 -> Дополнительные руководства -> Реактивность -> Основы реактивности -> Разворачивание ссылки

Повторное разворачивание

Когда ссылка возвращается как свойство в контексте рендеринга (объект, возвращаемый из setup()), и к нему обращаются в шаблоне, он автоматически неглубоко разворачивает внутреннее значение. В шаблоне потребуется только вложенная ссылка .value :

В вашем примере шаблона obj.wut это объект ref, wut это развернутое примитивное значение (логическое значение)

Дополнительные услуги:

  1. В вашем примере obj.wut отображается как false на странице, кажется, что он работает без .value . Это происходит из-за toDisplayString функции в vue, она принимает объект ref ( obj.wut ), он выполняет JSON.stringify внутреннее значение объекта ref. Если значение wut равно a string ( const wut = ref('a string'); ) , вы увидите дополнительные двойные кавычки вокруг него на отображаемой странице, например "a string"
  2. В документе есть еще один совет: вы можете обернуть объект в reactive ( const obj = reactive({ wut }) ), чтобы получить доступ к развернутому значению в шаблоне.