10 простых приемов, которые сделают ваш код vue.js более элегантным 🍊

Vue.js
10 простых приемов, которые сделают ваш код vue.js более элегантным 🍊

Предисловие 🍊

Что касается глубокой чистоты кода, мы все надеемся написать простой и эффективный код, сделать наш код более элегантным, давайте откажемся от сложного кода и вместе начнем простое путешествие~~

Новый синтаксис слотов соответствует версии 3.0.

Используйте новый синтаксис аббревиатуры именованного слота с «#», доступный в Vue 2.6.0+ 👍

Например:

При создании слота рекомендуется спланировать макет. Это макет моей статьи.Создание слота ничем не отличается от создания компонента. По сути, слоты — это сверхфункциональные компоненты. Давайте разберем схему выше. Компоненты выглядят так:

<!-- TidbitPage.vue -->
<template>
  <article-layout>

    <template #articleHeader>
      <h1>I am the header</h1>
    </template>

    <template #articleContent>
      <p>I am the content</p>
    </template>

    <template #articleFooter>
      <footer>I am the footer</footer>
    </template>

    <template #side>
      <aside>I am the side stuff</aside>
    </template>

    <template #banner>
      <div>I am the banner</div>
    </template>

  </article-layout>
<template>

Параметры динамической команды

Параметры директивы теперь могут принимать динамические выражения JavaScript. Значения динамических параметров должны быть строками, но разрешеныnullЭто было бы удобно в качестве специального значения, которое явно указывает, что привязку следует удалить. Любое другое нестроковое значение может привести к ошибке и вызвать предупреждение. (применимо только кv-bind和v-on)

<div v-bind:[attr]="attributeName"></div>
//简写
<div :[attr]="attributeName"></div>

здесьattributeNameБудет динамически оцениваться как выражение JavaScript, и полученное значение будет использоваться в качестве окончательного параметра. Например, если ваш экземпляр Vue имеет свойство данныхattributeName, значение которогоhref, то эта привязка будет эквивалентнаv-bind:href

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

<button v-on:[eventName]="handler"></button>
//简写
<button @[eventName]="handler"></button>

когдаeventNameценностьfocusчас,v-on:[eventName]будет эквивалентноv-on:focus.

То же самое можно применить к привязкам слотов:

<my-component>
<template v-slot:[slotName]>
Dynamic slot name
</template>
</my-component>
//简写
<foo>
<template #[name]>
Default slot
</template>
</foo>

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

<!-- 这会触发一个编译警告 且 无效 -->
<a v-bind:['foo' + bar]="value"> ... </a>

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

@зацепи эти штуки

Действия по обработке таймеров внутри компонентов. Обычно мы обычно делаем это:

<script>
  export default {
    mounted() {
      this.timer = setInterval(() => { ... }, 1000);
    },
    beforeDestroy() {
      clearInterval(this.timer);
    }
  };
</script>

Но на самом деле лучший способ:

<script>
  export default {
    mounted() {
      const timer = setInterval(() => { ... }, 1000);
      this.$once('hook:beforeDestroy', () => clearInterval(timer);)
    }
  };
</script>

представьте себе сценарий Если нам нужно сделать страницу до того, как данные будут отображены на страницеloading.mountedостановиться послеloading.beforeUpdataначать, когдаloading.updatadостановиться послеloading.

Самый простой способ — переписать функцию жизненного цикла компонента, чтобы сделать ее вmounted/beforeUpdata /updatadСообщите родительскому компоненту, чтобы показать или скрыть загрузку.

Это нехорошо, потому что это вторгается в логику самого компонента, а добавленная логика не связана с функцией самого компонента. Лучший способ - использоватьv-on="hook:xxx"Путь:

<v-chart
    @hook:mounted="loading = false"
    @hook:beforeUpdated="loading = true"
    @hook:updated="loading = false"
    :data="data"
/>

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

во вью$props,$attrsа также$listeners(Доступно для сборки вторичной упаковки)

$props: объект реквизита, полученный текущим компонентом. Экземпляр Vue проксирует доступ к своим свойствам объекта props.

Если есть поле ввода ввода. У нас есть много нативных свойств, таких как: имя, заполнитель, отключено и т. д. Было бы слишком громоздко, если бы мы все определяли отображение и прием в свойствах. Так появился официальный сайт:v-bind="$props"такая операция. Если родительский компонент передает много нативных свойств, то мы можем прямо в дочернем компоненте:

//good
<input v-bind="$props">
 
//bad
//而不是下面这样,如果很多的属性就特别繁琐
<input :name="name" :placeholder="placeholder" :disabled="disabled">

Мы можем использовать следующие способы$attrsПропустите нативные свойства непосредственно к дочерним компонентам, что является новым свойством Vue в 2.4.0, включая привязки свойств (кроме класса и стиля), которые не распознаются (и получены) как реквизиты в родительской области. Когда компонент не объявляет никаких реквизитов, все родительские привязки (кроме класса и стиль) включены здесь, и могут быть переданы внутреннему компонентам через V-Bind = «$ attrs» - при создании высокоуровневых компонентов очень полезно.

<input
   v-bind="$attrs"
   :value="value"
   @focus=$emit('focus', $event)"
   @input="$emit('input', $event.target.value)"
>

$listeners: содержит родительскую область (исключая.nativeдекоратор) прослушиватель событий v-on. это может пройтиv-on="$listeners"Передача внутренних компонентов — полезно при создании компонентов более высокого уровня.

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

<template>
<div>
  ...
<childComponent v-on="$listeners" />...
</div>
</template>

Отзывчивые данные (новое в версии 2.6.0)

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

Vue.observable( object )Сделайте объект отзывчивым, который Vue будет использовать внутри для обработки объекта, возвращаемого функцией данных.

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

Официальный пример:

const state = Vue.observable({ count: 0 })

const Demo = {
  render(h) {
    return h('button', {
      on: { click: () => { state.count++ }}
    }, `count is: ${state.count}`)
  }
}

компонент шаблона jsx

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

<button v-if="status === 1" class="btn1" :class="status === 1" @click="">未开始</button>
<button v-if="status === 2" class="btn2" :class="status === 2" @click="">进行中</button>
<button v-if="status === 3" class="btn3" :class="status === 3" @click="">可领取</button>
<button v-if="status === 4" class="btn4" :class="status === 4" @click="">已领取</button>

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

<!DOCTYPE html>
<html lang="en">

<body>
    <div id="app">
        <child :status="status"></child>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('child', {
            props: {
                status: {
                    type: Number,
                    required: true
                }
            },
            render(createElement) {
                const innerHTML = ['未开始', '进行中', '可领取', '已领取'][this.status]
                return createElement('button', {
                    class: {
                        active: this.status
                    },
                    attrs: {
                        id: 'btn'
                    },
                    domProps: {
                        innerHTML
                    },
                    on: {
                        click: () => console.log(this.status)
                    }
                })
            }
        })
        var app = new Vue({
            el: '#app',
            data: {
                status: 0
            }
        })
    </script>
</body>

</html>

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

<child :status="status"></child>

динамические компоненты

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

Как показано на рисунке, это список v- для рендеринга (только этот раздел только начался, в данный момент есть только один), кружок - это компонент, то есть v- для динамических компонентов

фактическое использование

В начале были представлены основные компоненты

import ColorIn from '@/components/Magic/ColorIn.vue'
import LineIn from "@/components/Magic/LineIn.vue";
import Header from "@/components/Magic/Header.vue";
import Footer from "@/components/Magic/Footer.vue";

export default{
      components:{
        ColorIn,
        LineIn,
        Header,
        Footer
    }
}

Далее идет использование динамического v-для динамических компонентов,componentList:['ColorIn','LineIn','Header','Footer']Используйте следующий код, чтобы зациклить код последовательно

<component v-for="(item,index) in componentList" :key="index" :is="item"></component>

Эффект после компиляции

<ColorIn></ColorIn>
<LineIn></LineIn>
<Header></Header>
<Footer></Footer>

Vue.filter

Краткое введение в фильтр, как следует из названия, фильтрация — это данные, после этой фильтрации получается что-то еще, вы можете получить от нее то, что хотите, или добавить какое-то украшение к этим данным, тогда фильтр — это инструмент фильтрации. Например, из массива ['abc', 'abd', 'ade'] получить значение, содержащее 'ab', затем отфильтровать 'abc' и 'abd'; превратить "Hello" в "Hello World", затем вы можете использовать фильтры, чтобы добавить «Мир» после значения «Hello», или изменить узел времени на метку времени и т. д. Вы можете использовать фильтры.

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

// 使用
// 在双花括号中
{{ message | capitalize }}

// 在 `v-bind` 中
<div v-bind:id="rawId | formatId"></div>

// 全局注册
Vue.filter('stampToYYMMDD', (value) =>{
  // 处理逻辑
})

// 局部注册
filters: {
  stampToYYMMDD: (value)=> {
    // 处理逻辑
  }
}

// 多个过滤器全局注册
// /src/common/filters.js
let dateServer = value => value.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3') 
export { dateServer }
// /src/main.js
import * as custom from './common/filters/custom'
Object.keys(custom).forEach(key => Vue.filter(key, custom[key]))

.синхронный синтаксис

синхронизация заключается в достижении «двусторонней привязки» реквизита и все (родительский к дочернему, дочерний к родительскому, туда и обратно)

Этот метод полезен, когда вам нужно изменить значение родительского компонента в дочернем компоненте, и его механизм реализации такой же, как и v-model.

Улучшите производительность с помощью object.freeze

Object.freeze()способ заморозить объект. Замороженный объект больше не может быть изменен; когда объект заморожен, к объекту нельзя добавить новые свойства, существующие свойства нельзя удалить, а перечисляемость, конфигурируемость и возможность записи существующих свойств объекта нельзя изменить. и не может изменить значение существующего свойства. Кроме того, после замораживания объекта прототип объекта не может быть изменен.freeze()Возвращает тот же объект, что и переданный аргумент.

Допустим, нам нужно отобразить очень большой массив объектов, таких как список пользователей, список объектов, список статей и т. д.

export default {
  data: () => ({
    users: {}
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.users = users;
  }
};

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

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

export default {
  data: () => ({
    users: {}
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.users = Object.freeze(users);
  }
};