Статьи

5 самых востребованных функций для Vue.js в 2018 году

Vue славится простотой использования и простотой. Отчасти это достигается благодаря наличию сфокусированного и небольшого API без слишком большого количества посторонних функций.

Тем не менее, пользователи и сопровождающие всегда думают о потенциально полезных новых функциях. В этой статье рассматриваются пять наиболее востребованных функций доски объявлений Vue GitHub .

  1. Поддержка итерируемого протокола с v-for
  2. Многокорневые шаблоны (фрагменты)
  3. Реактивные ссылки
  4. Пользовательские v-modelмодификаторы
  5. Пакет для пользовательских рендеров

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

1. Поддержка итерируемого протокола с v-for

Что это?

Когда вы думаете об итерации, вы, скорее всего, думаете о массивах. ES2015 представил итеративный протокол, который, когда он реализован, позволяет итерировать любой тип объекта с использованием for...of. ES2015 также представил новые итерируемые типы данных, такие как Mapи Set.

В настоящее время v-forдиректива Vue может перебирать массивы и простые объекты, но не другие итерируемые объекты или типы данных. Если вы используете Map, например, и хотите повторить его v-for, сначала вам нужно преобразовать его в массив или простой объект.

Примечание. Карты, наборы и другие новые итерируемые типы данных также не являются реактивными.

Почему пользователи хотят это?

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

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

Будет ли это добавлено?

Может быть. Проблема была закрыта на GitHub, так как сопровождающие не были уверены, что итерируемые объекты и типы данных обычно используются для состояния пользовательского интерфейса. Кроме того, создание итеративных объектов и типов данных реагирующих потребовало бы значительной работы.

Однако система наблюдения Vue должна быть реорганизована в версии 2.x-next, что было бы идеальным временем для реализации этой функции.

Узнайте больше на GitHub .

2. Многокорневые шаблоны (фрагменты)

Что это?

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

<template>
  <div/>
</template>

Но это не так

<template>
  <div/>
  <div/>
</template>

Некоторые пользователи Vue запрашивают многокорневые шаблоны, особенно теперь, когда эта функция была добавлена ​​в React.

Почему пользователи хотят это?

If you want your component to render child nodes for some parent element, you’ll need to add a wrapper to comply with the single-root restriction:

<template>
  <div><!--Need to add this wrapper-->
    <child1/>
    <child2/>
    ...
  </div>
</template>

Having a wrapper in the structure will interfere with the requirements of certain HTML or CSS features. For example, if you have a parent element with display: flex, having a wrapper between the parent and children won’t work.

<template>
  <div style="display:flex">
    <!--This pattern won't work because of the wrapper:/-->
    <FlexChildren/>
  </div>
</template>

Will it Be Added?

According to the maintainers, the way the virtual DOM diffing algorithm works makes this feature difficult to implement and would require a major rewrite. As such, this feature is not on the roadmap for development.

Read more on GitHub.

3. Reactive refs

What Is It?

An essential design aspect of Vue components is that they must be isolated and communicate by props and events. However, sometimes you need one component to be able to mutate the state of another. For example, you may want a form component to switch on the focus of a child input component.

The solution is to use refs, which give a component an escape hatch into another component’s data model. However, when accessed via refs, the component’s data model is not reactive so it can’t be watched or included in a computed property. Reactive refs would allow it to be.

Why Do Users Want It?

Components normally communicate through props and events, and only in a parent/child relationship. For a parent component to track a child component’s data, the child must emit its state changes via events. This requires the parent to have a listener, a handler, and local data properties for storing the tracked state.

For an example of this, imagine a parent form component tracking the state of a child input’s «valid» state:

<template>
  <form-input @valid="updateValidEmail">
    </template>
<script>
export default {
  data() => ({
    emailValid: false  
  }),
  methods: {
    updateValidEmail(value) {
      this.emailValid = value;
    }
  }
}
</script>

This code works fine. The only problem is that every single child input in the form needs similar, unique code. If the form has 10s or 100s of inputs, the form component will become massive.

Using reactive refs, the parent would not need to track the child and could simply watch its state with a computed property, reducing excessive code.

<template>
  <form-input ref="email">
    </template>
<script>
export default {
  computed: {
    emailValid() {
      // Currently this won't work as $refs is not reactive
      this.$refs.email.isValid;
    }
  }
}
</script>

Will It Be Added?

While it is a highly requested feature, there are no plans to add it. One concern is that the feature violates good component design. Refs are meant to only be a last resort when the props/events interface can’t be used. Making refs reactive would allow for anti-patterns where refs were used instead of events.

Read more on GitHub.

Custom v-model Modifiers

What Is It?

You can use the v-model directive to create two-way data bindings on form inputs:

<input v-model="message"/>
<!--Message automatically updates as the input is used-->
<p>Message is: {{ message }}</p>
<script>
new Vue({
  data: {
    message: null
  }  
});
</script>

v-model is syntactic sugar over a prop and event listener.

Several modifiers are available to transform the event. For example, the .number modifier, used like v-model.number="num", will automatically typecast the input as a number. This is useful because even with type="number" on the input, the value returned from HTML input elements is always a string.

This feature request is to allow custom v-model modifiers defined by users.

Why Do Users Want It?

Let’s say you wanted to automatically format a Thai phone number as a user typed it into an input, for example, typing «0623457654» would be transformed to «+66 6 2345 7654». You could write a custom modifier, say, .thaiphone, and use it on your input. Easy.

Without this feature, either a computed property needs to be created for each input to perform the transform, or a custom input component needs to be created where the transform logic occurs before the event is emitted. Both of these options work but require additional code that seems easy to avoid.

Will It Be Added?

Unlikely. This and related issues have been closed by the maintainers who recommend the workarounds just mentioned.

Read more on GitHub.

Package for Custom Renderers

What Is It?

Currently, Vue’s renderer is hard-coded for HTML elements, as Vue was initially intended only for use on the web. The idea of this feature is to isolate the HTML renderer from the main Vue package.

Why Do Users Want It?

Vue is now being used in non-web environments, e.g. on mobile via projects like NativeScript. Isolating the renderer would make it easy for a library author to replace the HTML renderer with a renderer suitable for their chosen environment.

Vue.use(NonWebRenderer);

new Vue({
  render(h) => h('non-web-element', { text: 'Hello World' });
});

Will It Be Added?

Yes! This will be part of a larger change where many Vue internals will be split into separate packages with their own APIs, allowing this and other kinds of Vue custom builds. This change has been added to the Vue.js Roadmap and is slated for version 3.x.