Как Vue3 Composition API заменяет Vue Mixins

Vue.js
Как Vue3 Composition API заменяет Vue Mixins

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

Самая умная часть Composition API заключается в том, что он позволяет Vue совместно использовать код, опираясь на меры безопасности, встроенные в собственный JavaScript, такие как передача переменных функциям и системе модулей.

Хотите поделиться кодом между вашими компонентами Vue? если вы знакомы сVue 2вы, возможно, знаете, как использовать примеси, но новыйComposition APIобеспечивает лучшее решение.

В этой статье мы рассмотрим недостатки примесей и посмотрим, как Composition API преодолевает их и делает приложения Vue более масштабируемыми.

Обзор возможностей миксинов

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

Как правило, компонент Vue определяется объектом JavaScript, который имеет различные свойства, представляющие нужные нам функции, такие какdata,methods,computedЖдать.

// MyComponent.js
export default {
  data: () => ({
    myDataProperty: null
  }),
  methods: {
    myMethod () { ... }
  }
  // ...
}

Когда мы хотим использовать одни и те же свойства между компонентами, мы можем выделить общие свойства в отдельный модуль:

// MyMixin.js
export default {
  data: () => ({
    mySharedDataProperty: null
  }),
  methods: {
    mySharedMethod () { ... }
  }
}

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

// ConsumingComponent.js
import MyMixin from "./MyMixin.js";

export default {
  mixins: [MyMixin],
  data: () => ({
    myLocalDataProperty: null
  }),
  methods: {
    myLocalMethod () { ... }
  }
}

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

export default {
  data: () => ({
    mySharedDataProperty: null
    myLocalDataProperty: null
  }),
  methods: {
    mySharedMethod () { ... },
    myLocalMethod () { ... }
  }
}

Миксины считаются «вредными»

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

К сожалению, те же недостатки, которые он упомянул о миксинах React, применимы и к Vue. Прежде чем увидеть, как Composition API преодолевает эти недостатки, давайте ознакомимся с ними.

конфликт имен

Мы видели, как шаблон миксина объединяет два объекта во время выполнения. Что произойдет, если они оба используют собственность с одним и тем же именем?

const mixin = {
  data: () => ({
    myProp: null
  })
}

export default {
  mixins: [mixin],
  data: () => ({
    // 同名!
    myProp: null
  })
}

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

Стратегия слияния по умолчанию (но настраиваемая) для компонентов Vue указывает, что локальные параметры переопределяют параметры миксина. Стратегия слияния по умолчанию (дополнительно настраиваемая) для компонентов Vue указывает, что локальные параметры переопределяют параметры миксина. Однако есть исключения, например, если у нас есть несколько хуков жизненного цикла одного типа, эти хуки будут добавлены в массив хуков, и все они будут вызываться последовательно.

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

неявная зависимость

Между миксином и компонентами, которые его используют, нет иерархической связи. Это означает, что компонент может использовать свойства данных, определенные в миксине (например, mySharedDataProperty), но миксин также может использовать свойства данных, которые, как предполагается, определены в компоненте (например, myLocalDataProperty). Такая ситуация обычно возникает, когда примеси используются для проверки общих входных данных. Примеси могут ожидать, что компонент будет иметь входное значение, которое он будет использовать в своем собственном методе проверки.

Однако это может вызвать некоторые проблемы. Что произойдет, если позже мы захотим провести рефакторинг компонента и изменить имя переменной, которая нужна примеси? Когда мы смотрим на этот компонент, нет никаких проблем. Линтер тоже не найдет, мы просто увидим ошибку во время выполнения.

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

Миграция с миксинов

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

Недостатком примесей является один из основных драйверов Composition API, давайте кратко рассмотрим, как он работает, а затем посмотрим, как он решает проблему примесей.

API для быстрого старта композиции

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

Возьмите этот классический компонент Vue 2, который определяет функцию «счетчик»:

//Counter.vue
export default {
  data: () => ({
    count: 0
  }),
  methods: {
    increment() {
      this.count++;
    }
  },
  computed: {
    double () {
      return this.count * 2;
    }
  }
}

Ниже приведен точно такой же компонент, определенный с помощью Composition API.

// Counter.vue
import { ref, computed } from "vue";

export default {
  setup() {
    const count = ref(0);
    const double = computed(() => count * 2)
    function increment() {
      count.value++;
    }
    return {
      count,
      double,
      increment
    }
  }
}

Первое, на что следует обратить внимание, это то, что мы импортировалиrefфункция, которая позволяет нам определить реактивную переменную, которая действует какdataПеременные почти одинаковые. То же самое относится и к вычисляемым свойствам.

incrementМетод не является пассивным, поэтому его можно объявить как обычную функцию JavaScript. Обратите внимание, что нам нужно изменить подсвойствоcountизvalueизменить реактивную переменную. Это потому, что использованиеrefСозданные реактивные переменные должны быть объектами, чтобы оставаться реактивными при передаче.

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

извлечение кода

Первым очевидным преимуществом Composition API является простота извлечения логики.

Давайте реорганизуем компоненты, определенные выше, с помощью Composition API, чтобы определенная нами функциональность находилась в модуле JavaScript.useCounter(Добавление «использовать» к описанию функции является соглашением об именах Composition API.).

//useCounter.js
import { ref, computed } from "vue";

export default function () {
  const count = ref(0);
  const double = computed(() => count * 2)
  function increment() {
    count.value++;
  }
  return {
    count,
    double,
    increment
  }
}

повторное использование кода

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

// MyComponent.js
import useCounter from "./useCounter.js";

export default {
  setup() {
    const { count, double, increment } = useCounter();
    return {
      count,
      double,
      increment
    }
  }
}

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

Конфликт имен разрешен

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

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

export default {
  setup () {
    const { someVar1, someMethod1 } = useCompFunction1();
    const { someVar2, someMethod2 } = useCompFunction2();
    return {
      someVar1,
      someMethod1,
      someVar2,
      someMethod2
    }
  }
}

Конфликты имен разрешаются так же, как и любые другие переменные JavaScript.

Неявная зависимость... решена!

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

Функция композиции также может вызывать локальные переменные, определенные в потребляющем компоненте. Разница, однако, в том, что теперь эта переменная должна быть явно передана в функцию композиции.

import useCompFunction from "./useCompFunction";

export default {
  setup () {
    // 某个局部值的合成函数需要用到
    const myLocalVal = ref(0);

    // 它必须作为参数显式地传递
    const { ... } = useCompFunction(myLocalVal);
  }
}

Суммировать

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

Самая умная часть Composition API заключается в том, что он позволяет Vue совместно использовать код, опираясь на меры безопасности, встроенные в собственный JavaScript, такие как передача переменных функциям и системе модулей.

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


источник:css-tricks.com
автор:Anthony Gore


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