25 хитростей Vue, которые вам нужно знать

внешний интерфейс Vue.js
25 хитростей Vue, которые вам нужно знать

Автор: Майкл Тиссен Переводчик: Хай Йонг Источник: dev

🌊 Домашняя страница автора:Хай Йонг
🌊 Об авторе: 🥇Член основной команды HDZ, 🏆Высококачественные создатели в области полного стека, 🥈Входит в первую десятку еженедельного списка C station
🌊 Преимущества вентилятора:фанатская базаЧетыре книги в неделю и различные небольшие подарки каждый месяц (эмалевые кружки, декоративные подушки, коврики для мыши, кружки и т. д.)

Сегодня я предлагаю вам 25 приемов Vue, которые, я надеюсь, вам помогут.

1. Ограничить опоры в список типов

использовать в определениях реквизитаvalidatoroptions, вы можете ограничить свойство определенным набором значений:

export default {
  name: 'Image',
  props: {
    src: {
      type: String,
    },
    style: {
      type: String,
      validator: s => ['square', 'rounded'].includes(s)
    }
  }
};

Функция валидатора принимает реквизит и возвращает true или false. Его также можно использовать, когда вам нужно больше опций, чем позволяют логические значения. Тип кнопки или тип оповещения (Информация, Успех, Опасность, Предупреждение) являются одними из наиболее распространенных применений.

2. Контент по умолчанию и точки расширения

Слоты в Vue могут иметь содержимое по умолчанию, и вы можете создавать более простые в использовании компоненты:

<button class="button" @click="$emit('click')">
  <slot>
    <!-- 如果没有提供slot则使用 -->
    Click me
  </slot>
</button>

По сути, вы можете взять любую часть компонента, поместить ее в слот, а затем переопределить эту часть компонента чем угодно. По умолчанию он по-прежнему будет работать как обычно, но есть и другие варианты:

<template>
  <button class="button" @click="$emit('click')">
    <!-- 一开始在 slot 标签中添加什么都不做 -->
    <!-- 我们可以通过向 slot 提供内容来覆盖它 -->
    <slot>
      <div class="formatting">
        {{ text }}
      </div>
    </slot>
  </button>
</template>

Теперь вы можете использовать этот компонент по-разному. Простой способ по умолчанию или ваш собственный способ:

<!-- 使用组件的默认功能 -->
<ButtonWithExtensionPoint text="Formatted text" />

<!-- 使用扩展点创建自定义行为 -->
<ButtonWithExtensionPoint>
  <div class="different-formatting">
    在这里做一些不同的事情
  </div>
</ButtonWithExtensionPoint>

3. Используйте кавычки для наблюдения за вложенными значениями

Возможно, вы этого не знали: легко смотреть напрямую на вложенные значения, просто используя кавычки:

watch {
  '$route.query.id'() {
    // ...
  }
}

Это полезно для работы с глубоко вложенными объектами.

4. Знайте, когда использовать v-if (а когда его избегать)

иногда не используетсяv-if,использоватьv-showбыло бы эффективнее:

<ComplicatedChart v-show="chartEnabled" />

когдаv-ifОн полностью создает и уничтожает элементы при открытии и закрытии.v-showРазница в том, что элемент будет создан и оставлен там, установив его стиль наdisplay: noneчтобы скрыть это.

Это более эффективно, если вам нужно переключать компоненты, визуализация которых требует больших затрат. С другой стороны, если вам не нужно сразу использовать этот компонент, вы можете использоватьv-ifтак что он пропускает его рендеринг и загружает страницу быстрее.

5. Сокращение для слота с одним прицелом (тег шаблона не требуется!)

Слоты с прицелом более интересны, но для того, чтобы их использовать, вам также придется использовать многоtemplateЭтикетка.

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

Вместо того, чтобы писать это:

<DataTable>
  <template #header="tableAttributes">
    <TableHeader v-bind="tableAttributes" />
  </template>
</DataTable>

Мы можем написать это так:

<DataTable #header="tableAttributes">
  <TableHeader v-bind="tableAttributes" />
</DataTable>

Это проще и прямее.

6. Условно отображаемый слот

У каждого компонента Vue есть специальный объект $slots, содержащий все слоты. Слоты по умолчанию имеют ключи по умолчанию, и все именованные слоты используют свои имена в качестве ключей:

const $slots = {
  default: <default slot>,
  icon: <icon slot>,
  button: <button slot>,
};

но это$slotsобъект толькоприменительно кслот компонента, не каждыйОпределенныйслот.

В качестве примера возьмем этот компонент, определяющий несколько слотов, в том числе несколько именованных слотов:

<!-- Slots.vue -->
<template>
  <div>
    <h2>这里是一些slots</h2>
    <slot />
    <slot name="second" />
    <slot name="third" />
  </div>
</template>

Если мы применим к компоненту только один слот, только этот слот появится в нашем$slotsВ объекте:

<template>
  <Slots>
    <template #second>
      这将应用于第二个slot
    </template>
  </Slots>
</template>
$slots = { second: <vnode> }

Мы можем использовать его в наших сборках для обнаружения того, какой слот был применен к компоненту, например, скрывая элементы упаковки слотов:

<template>
  <div>
    <h2>一个包裹的slot</h2>
    <div v-if="$slots.default" class="styles">
      <slot />
    </div>
  </div>
</template>

Сейчасdiv, оболочка, которая применяет стили, будет отображаться только тогда, когда мы фактически заполним этот слот чем-то.

если мы не используемv-if,div如果我们没有slot,我们最终会得到一个空的和不必要的。 Согласно сdivиметь стили, которые могут испортить наш макет и заставить все выглядеть странно.

Почему мы хотим иметь возможность условно отображать слоты?

Есть три основные причины использования условных слотов:

  1. использовать оберткуdivдобавить стили по умолчанию
  2. слот пуст
  3. Когда мы комбинируем контент по умолчанию с вложенными слотами

Например, когда мы добавляем стили по умолчанию, мы добавляемdiv:

<template>
  <div>
    <h2>This is a pretty great component, amirite?</h2>
    <div class="default-styling">
      <slot >
    </div>
    <button @click="$emit('click')">Click me!</button>
  </div>
</template>

Однако, если родительский компонент не применяет содержимое к этому слоту, мы оказываемся на страницеdivделает пустым:

<div>
  <h2>这是一个非常棒的组件</h2>
  <div class="default-styling">
    <!-- slot中没有内容,但仍会呈现此 div-->
  </div>
  <button @click="$emit('click')">Click me!</button>
</div>

v-ifдобавьте его на упаковкуdiv可以解决问题。没有应用到slot的内容? так:

<div>
  <h2>这是一个非常棒的组件</h2>
  <button @click="$emit('click')">Click me!</button>
</div>

7. Как наблюдать за сменой слота

Иногда нам нужно знать, когда содержимое внутри слота изменилось:

<!-- 可惜这个活动不存在 -->
<slot @change="update" />

Жаль, что у Vue нет встроенного способа обнаружить это, очень удобный способ — использовать наблюдателей за мутациями:

export default {
  mounted() {
    // 当事情发生变化时调用`update`
    const observer = new MutationObserver(this.update);

    // 观察这个组件的变化
    observer.observe(this.$el, {
      childList: true,
      subtree: true
    });
  }
};

8. Смешивайте локальные и глобальные стили

Часто при использовании стилей мы хотим, чтобы они ограничивались одним компонентом:

<style scoped>
  .component {
    background: green;
  }
</style>

Вы также можете добавить блок стилей без области действия, чтобы добавить глобальные стили, если хотите:

<style>
  /*全局应用*/
  .component p {
    margin-bottom: 16px;
  }
</style>

<style scoped>
  /*范围限定于此特定组件*/
  .component {
    background: green;
  }
</style>

9. Переопределение детских компонентов стилей - правильный путь

CSS с заданной областью действия легче содержать в чистоте, и стиль не будет случайно проникать в другие части приложения. Но иногда нужно охватить стиль подкомпонентов и пробить этот диапазон. У Vue естьdeepСелектор специально для этого:

<style scoped>
/* 覆盖子组件的 CSS,同时保持样式范围*/
.my-component >>> .child-component {
  font-size: 24px;
}
</style>

Примечание. Если вы используете препроцессор CSS, такой как SCSS, вам может понадобиться использовать/deep/.

10. Создавайте волшебство с помощью контекстно-зависимых компонентов

Контекстно-зависимые компоненты — это «волшебство» — они могут автоматически адаптироваться к тому, что происходит вокруг них, обрабатывать крайние случаи, обмениваться состоянием и т. д. Существует 3 основных типа контекстно-зависимых компонентов, но наиболее интересным из них я считаю настройку.

1. Обмен состояниями

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

можно поставитьDropdownКомпоненты разбиваются наSelectа такжеOptionкомпоненты для большей гибкости. Но для удобства использованияSelectа такжеOptionкомпоненты делят друг другаselectedусловие:

<!-- 为简单起见用作单个组件 -->
<Dropdown v-model="selected" :options="[]" />

<!-- 拆分以获得更大的灵活性 -->
<Select v-model="selected">
  <Option value="mustard">Mustard</Option>
  <Option value="ketchup">Ketchup</Option>
  <div class="relish-wrapper">
    <Option value="relish">Relish</Option>
  </div>
</Select>

2. Конфигурация

Иногда поведение компонента необходимо изменить в зависимости от остального приложения. Обычно это делается для автоматической обработки крайних случаев, которые в противном случае были бы громоздкими.PopupилиTooltipДолжен изменить свое положение, чтобы он не переполнял страницу. Однако, если компонент находится внутри модального окна, он должен изменить свое положение, чтобы он не переполнялся.modal. еслиTooltipЗная, когда он находится внутри модального окна, это можно сделать автоматически.

3. Стайлинг

При создании контекстно-зависимого CSS применяйте разные стили в зависимости от того, что происходит в родительских или родственных элементах.

.statistic {
  color: black;
  font-size: 24px;
  font-weight: bold;
}

/* 在彼此相邻的统计数据之间进行一些分离*/
.statistic + .statistic {
  margin-left: 10px;
}

Переменные в CSS делают нас на шаг впереди, позволяя устанавливать разные значения в разных частях страницы.

11. Как сделать переменные, созданные вне Vue, адаптивными?

Если вы получаете переменную извне Vue, приятно иметь возможность сделать ее отзывчивой. Таким образом, вы можете использовать его в вычисляемых свойствах, наблюдателях и везде, и оно работает так же, как и любое другое состояние в Vue.

Когда вы используете API опций, вы просто вставляете егоdataВ разделе компонентов:

const externalVariable = getValue();

export default {
  data() {
    return {
      reactiveVariable: externalVariable,
    };
  }
};

Вы можете использовать при использовании комбинированного API в Vue 3.refилиreactiveтак:

import { ref } from 'vue';

// 可以完全在 Vue 组件之外完成
const externalVariable = getValue();
const reactiveVariable = ref(externalVariable);

// 使用 .value 访问
console.log(reactiveVariable.value);

использоватьreactiveвместо:

import { reactive } from 'vue';

// 可以完全在 Vue 组件之外完成
const externalVariable = getValue();
// Reactive 仅适用于对象和数组
const anotherReactiveVariable = reactive(externalVariable);

// 直接访问
console.log(anotherReactiveVariable);

Если вы все еще используете Vue 2 (как и многие из нас), вы можете использоватьobservableвместоreactiveполучить точно такой же результат.

12. Разрушивание в V-для

ты знаешь, что можешьv-forДеконструкция?

<li
  v-for="{ name, id } in users"
  :key="id"
>
  {{ name }}
</li>

Как мы все знаем, вы можете получить индекс из v-for, используя такой кортеж:

<li v-for="(value, key) in [
  'Hai Yong',
  'Frozen',
  'Web Beginner'
]">
  {{ index + 1 }} - {{ value }}
</li>

При работе с объектами также можно захватить клавишу:

<li v-for="(value, key) in {
  name: 'Hai Yong',
  released: 2021,
  director: 'A blogger',
}">
  {{ key }}: {{ value }}
</li>

Вы также можете комбинировать эти два метода, чтобы получить ключ и индекс свойства:

<li v-for="(value, key, index) in {
  name: 'Hai Yong',
  released: 2021,
  director: 'A blogger',
}">
  #{{ index + 1 }}. {{ key }}: {{ value }}
</li>

13. Зациклить диапазон в Vue

v-forКоманда позволяет нам перемещаться по массиву, но также позволяет нам перемещаться по диапазону:

<template>
  <ul>
    <li v-for="n in 5">项目#{{ n }}</li>
  </ul>
</template>

эффект отображения:

  • Пункт №1
  • Пункт № 2
  • Пункт №3
  • Пункт №4
  • Пункт № 5

когда мы используемv-forдиапазон, он будет начинаться с 1 и заканчиваться номером, который мы укажем.

14. Наблюдайте что-нибудь в компоненте

Любой ответ в вашем компоненте можно наблюдать:

export default {
  computed: {
    someComputedProperty() {
      // 更新计算道具
    },
  },
  watch: {
    someComputedProperty() {
      // 当计算的 prop 更新时做一些事情
    }
  }
};

Вы можете смотреть:

  • вычислительный реквизит
  • реквизит
  • вложенные значения

Если вы используете составной API, пока этоrefилиreactiveЗатем объект может отслеживать любое значение.

15. Типы предметов для кражи

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

Например, мыIconВ этом компоненте используется компонент:

<template>
  <div>
    <h2>{{ heading }}</h2>
    <Icon
      :type="iconType"
      :size="iconSize"
      :colour="iconColour"
    />
  </div>
</template>

Чтобы это заработало, нам нужно добавить правильный тип реквизита, начиная сIconСкопируйте в компонент:\

import Icon from './Icon';
export default {
  components: { Icon },
  props: {
    iconType: {
      type: String,
      required: true,
    },
    iconSize: {
      type: String,
      default: 'medium',
      validator: size => [
        'small',
        'medium',
        'large',
        'x-large'
      ].includes(size),
    },
    iconColour: {
      type: String,
      default: 'black',
    },
    heading: {
      type: String,
      required: true,
    },
  },
};

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

Итак, вот почему мы их воруем:

import Icon from './Icon';
export default {
  components: { Icon },
  props: {
    ...Icon.props,
    heading: {
      type: String,
      required: true,
    },
  },
};

За исключением нашего примера, мы добавили «иконка» в начало имени каждого реквизита. Поэтому нам нужно проделать дополнительную работу, чтобы это произошло:

import Icon from './Icon';

const iconProps = {};

// Do some processing beforehand
Object.entries(Icon.props).forEach((key, val) => {
  iconProps[`icon${key[0].toUpperCase()}${key.substring(1)}`] = val;
});

export default {
  components: { Icon },
  props: {
    ...iconProps,
    heading: {
      type: String,
      required: true,
    },
  },
};

Сейчас еслиIconТипы свойств в компоненте изменены, и наш компонент будет оставаться в актуальном состоянии.

Но если вIconКак насчет добавления или удаления типа пропса из компонента? Чтобы покрыть эти случаи, мы можем использоватьv-bindРассчитайте реквизиты, чтобы сохранить динамику.

16. Обнаружение кликов снаружи (или внутри) элемента

Иногда нам нужно обнаружить, что клик произошел на определенном элементеelизвнутреннийещевнешний. Это метод, который мы обычно используем:

window.addEventListener('mousedown', e => {
  // 获取被点击的元素
  const clickedEl = e.target;

  // `el` 是你正在检测外部点击的元素
  if (el.contains(clickedEl)) {
    // 单击“el”内部
  } else {
    // 在`el`之外点击
  }
});

17. Слот рекурсии

мы можемv-forИспользовать только шаблоны для создания компонента? Попутно я обнаружил, как рекурсивно использовать слоты.

Вот так выглядит компонент:

<!-- VFor.vue -->
<template>
    <div>
        <!-- 渲染第一项 -->
    {{ list[0] }}
        <!-- 如果我们有更多的项目可以继续,但需要离开我们刚刚渲染的项目 -->
    <v-for
      v-if="list.length > 1"
            :list="list.slice(1)"
        />
    </div>
</template>

Если вы хотите сделать это со слотами с ограниченной областью действия — почему бы и нет? ! — просто нужно внести некоторые коррективы:

<template>
  <div>
    <!-- 将项目传递到要渲染的slot中 -->
    <slot v-bind:item="list[0]">
      <!-- Default -->
      {{ list[0] }}
    </slot>

    <v-for
      v-if="list.length > 1"
      :list="list.slice(1)"
    >
      <!-- 递归向下传递作用域slot -->
      <template v-slot="{ item }">
        <slot v-bind:item="item" />
      </template>
    </v-for>
  </div>
</template>

Вот как использовать этот компонент:

<template>
  <div>
    <!-- 常规列表 -->
    <v-for :list="list" />

    <!-- 带有粗体项目的列表 -->
    <v-for :list="list">
      <template v-slot="{ item }">
        <strong>{{ item }}</strong>
      </template>
    </v-for>
  </div>
</template>

18. Метаданные компонента

Не каждый бит информации, которую вы добавляете к компоненту, является состоянием. Иногда вам нужно добавить некоторые метаданные вразноеКомпоненты предоставляют больше информации.

Например, если вы создаете кучу разных виджетов для аналитических панелей, таких как Google Analytics:

image.png

Если вы хотите, чтобы макет знал, сколько столбцов должен занимать каждый виджет, вы можете добавить это непосредственно в компонент в виде метаданных:

export default {
  name: 'LiveUsersWidget',
  // 👇 只需将其添加为额外属性
  columns: 3,
  props: {
    // ...
  },
  data() {
    return {
      //...
    };
  },
};

Вы найдете эти метаданные как свойство компонента:

import LiveUsersWidget from './LiveUsersWidget.vue';
const { columns } = LiveUsersWidget;

Вы также можете использовать спец.$optionsСвойства получают доступ к метаданным изнутри компонента:

export default {
  name: 'LiveUsersWidget',
  columns: 3,
  created() {
    // 👇 `$options` 包含组件的所有元数据
    console.log(`Using ${this.$options.metadata} columns`);
  },
};

Помните, что эти метаданные одинаковы для каждого экземпляра компонента, инетОтзывчивый.

Другие виды использования включают (но не ограничиваются):

  • Сохраняйте номер версии каждого компонента
  • Пользовательские флаги для инструментов сборки, позволяющие по-разному обрабатывать компоненты
  • Добавьте пользовательскую функцию к компоненту, помимо вычислительных реквизитов, данных, наблюдателя и т. д.

19. Многофайловый компонент с одним файлом

Это малоизвестная особенность SFC. Вы можете импортировать файл как обычный файл HTML:

<!-- "single" 文件组件 -->
<template src="./template.html"></template>
<script src="./script.js"></script>
<style scoped src="./styles.css"></style>

Это удобно, если вам нужно поделиться стилями, документацией или чем-то еще. Также отлично подходит для тех очень длинных файлов компонентов, которые изнашивают ваши пальцы от вращения.

20. Многоразовые компоненты — это не то, что вы думаете

Повторно используемые компоненты не обязательно должны быть большими или сложными, я часто делаю маленькие и короткие компоненты повторно используемыми. Поскольку я не собираюсь переписывать этот код повсюду, его гораздо проще обновлять, и я могу убедиться, что каждыйOverflowMenuВыглядит и работает точно так же - потому что они одинаковы!

<!-- OverflowMenu.vue -->
<template>
  <Menu>
    <!-- 添加自定义按钮来触发我们的菜单 -->
    <template #button v-slot="bind">
      <!-- 使用 bind 传递点击处理程序、a11y 属性等。 -->
      <Button v-bind="bind">
        <!-- 使用我们自己的“...”图标,此按钮没有文字 -->
        <template #icon>
          <svg src="./ellipsis.svg" />
        </template>
      </Button>
    </template>
  </Menu>
</template>

Здесь мы используемMenuкомпонента, но добавляет значок "..." (многоточие) к кнопке, которая вызывает его открытие. Вероятно, не стоит создавать повторно используемые компоненты, так как это всего несколько строк. каждый раз, когда мы хотим использоватьMenuВ такие моменты мы не можем просто добавить значки? но этоOverflowMenuБудет использоваться десятки раз, теперь, если мы хотим обновить иконку или ее поведение, мы можем легко это сделать. И это намного проще в использовании!

<template>
  <OverflowMenu
    :menu-items="items"
    @click="handleMenuClick"
  />
</template>

21. Вызов метода извне компонента

Вы можете вызвать метод извне компонента, задав емуref:

<!-- Parent.vue -->
<template>
  <ChildComponent ref="child" />
</template>
// Parent.vue 中的某个地方
this.$refs.child.method();

Обычно мы используем свойства и события для связи между компонентами. Реквизиты отправляются дочерним компонентам, а события отправляются обратно родительским компонентам.

<template>
  <ChildComponent
    :tell-me-what-to-do="someInstructions"
    @something-happened="hereIWillHelpYouWithThat"
  />
</template>

Но иногда вы можете столкнуться с ситуациями, когда вам нужно, чтобы родительский компонент запускал метод в дочернем компоненте. Здесь только передача реквизита не работает. Можно передать логическое значение и заставить дочерний компонент наблюдать за ним:

<!-- Parent.vue -->
<template>
  <ChildComponent :trigger="shouldCallMethod" />
</template>
// Child.vue
export default {
  props: ['trigger'],
  watch: {
    shouldCallMethod(newVal) {
      if (newVal) {
        // 当触发器设置为 `true` 时调用该方法
        this.method();
      }
    }
  }
}

Это работает нормально, но только при первом вызове. Если вам нужно запустить это действие несколько раз, вы должны очистить и сбросить состояние. Тогда логика выглядит так:

  1. Доставка родительского компонентаtrueДатьtriggerprop
  2. Watch запускается, и дочерний компонент вызывает метод
  3. Дочерний компонент генерирует событие, чтобы сообщить родительскому компоненту об успешном запуске метода.
  4. Сброс родительского компонентаtriggerназадfalse, так что мы можем сделать это снова

какие.

Вместо этого, если мы установим дочерний компонентref, мы можем вызвать этот метод напрямую:

<!-- Parent.vue -->
<template>
  <ChildComponent ref="child" />
</template>
// Parent.vue 中的某个地方
this.$refs.child.method();

Мы нарушили правило «реквизит вниз, события вверх» и нарушили инкапсуляцию, но это стало понятнее и проще для понимания, и оно того стоит!

Иногда «Лучшее» решение в конечном итоге становитсяхудшийрешение.

22. Наблюдение за массивами и объектами

Самая сложная часть использования наблюдателя заключается в том, что иногда кажется, что он не срабатывает должным образом. Обычно потому, что вы пытаетесь просмотреть массив или объект, но не устанавливаетеdeepдляtrue:

export default {
  name: 'ColourChange',
  props: {
    colours: {
      type: Array,
      required: true,
    },
  },
  watch: {
    // 使用对象语法而不仅仅是方法
    colours: {
      // 这将让 Vue 知道查看数组内部
      deep: true,

      // 我们必须将我们的方法移动到处理程序字段
      handler()
        console.log('颜色列表已更改!');
      }
    }
  }
}

Реактивное API с Vue 3 выглядит так:

watch(
  colours,
  () => {
    console.log('颜色列表已更改!');
  },
  {
    deep: true,
  }
);

Если вы хотите узнать больше информации, вы можете обратиться кVue 3а такжеVue 2документация.

23. Глубокая связь с Vue Router

Вы можете сохранить (некоторое) состояние в URL-адресе, что позволит вам перейти непосредственно к определенному состоянию на странице.

Например, вы можете загрузить страницу с выбранным фильтром диапазона дат:

someurl.com/edit?date-range=last-week

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

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

использоватьvue-routerПолучите такой запрос (это также работает с большинством фреймворков Vue, таких как Nuxt и Vuepress):

const dateRange = this.$route.query.dateRange;

Чтобы изменить его, мы используемRouterLinkкомпоненты и обновлениеquery:

<RouterLink :to="{
  query: {
    dateRange: newDateRange
  }
}">

24. Еще одно применение тегов шаблонов

ДолженtemplateТеги можно использовать в любом месте шаблона для лучшей организации кода.

Мне нравится использовать его для упрощенияv-ifлогика, иногдаv-forСлишком.

В этом примере у нас есть несколько элементов, использующих один и тот жеv-ifусловие:\

<template>
  <div class="card">
    <img src="imgPath" />
    <h3>
      {{ title }}
    </h3>
    <h4 v-if="expanded">
      {{ subheading }}
    </h4>
    <div v-if="expanded" class="card-content">
      <slot/>
    </div>
    <SocialShare v-if="expanded" />
  </div>
</template>

Это немного неуклюже и поначалу не очевидно, куча этих элементов отображается и скрывается вместе. На более крупных и сложных компонентах ситуация может быть еще хуже!

Но мы можем это исправить.

мы можем использоватьtemplateтеги группируют эти элементы и повышают ихv-ifприбытьtemplateСам ярлык: \

<template>
  <div class="card">
    <img src="imgPath" />
    <h3>
      {{ title }}
    </h3>
    <template v-if="expanded">
      <h4>
        {{ subheading }}
      </h4>
      <div class="card-content">
        <slot/>
      </div>
      <SocialShare/>
    </template>
  </div>
</template>

25. Лучший способ обработки ошибок (и предупреждений)

Вы можете предоставить собственные обработчики ошибок и предупреждений в Vue:

// Vue 3
const app = createApp(App);
app.config.errorHandler = (err) => {
  alert(err);
};

// Vue 2
Vue.config.errorHandler = (err) => {
  alert(err);
};

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

Например, если ошибка не обрабатывается, приложение не только аварийно завершает работу, но и может отображать полностраничный экран с ошибкой и просить пользователя обновить или попробовать что-то еще.

В Vue 3 обработчики ошибок были доступны только для ошибок шаблона и наблюдателя, но обработчики ошибок Vue 2 ловят почти все. Обработчики предупреждений в обеих версиях предназначены только для разработки.

написано в конце

Я уже довольно давно занимаюсь техническим блоггером, и в основном с помощью самородков, вот мои 25 советов по Vue. Я люблю делиться технологиями и радостью через статьи. Вы можете посетить мой блог:Талант /user/204034…Чтобы получить больше информации. Надеюсь, вам это понравится! 😊

💌 Все желающие могут оставлять комментарии и предложения в комментариях! 💌