vue3 + настройка сахара + обмен опытом TS

внешний интерфейс Vue.js
vue3 + настройка сахара + обмен опытом TS

предисловие

В настоящее времяsetup sugarбыло завершено, иvue3 + setup sugar + TSСпособ написания выглядит очень ароматно, поэтому смело пробовал.За время нашёл небольшие проблемы и поделился своим опытом.Если будут какие-то проблемы прошу поправить меня.

Предварительная подготовка

  1. использоватьvue-cliСоздайте проект vue3 + TS

    Связано с пойтиcli.vuejs.org/zh/guide/Проверить

  2. vscodeинвалидVetur,скачатьVolar

    Соответствующие загрузки и инструкции можно найти наmarketplace.visual studio.com/items?item N…Проверить

Примечание. vue3 не поддерживает все системы IE (включая ie11), поскольку IE не поддерживает прокси-API. Если вы хотите использовать синтаксис, связанный с vue3, дождитесь выхода vue2.7. Ожидается, что vue2.7 будет выпущен в третьем или четвертом квартале 2021 г. Подробнее см.:GitHub.com/vUEJS/RFCs/…

что такое установочный сахар

Представляем новый компонент одного файла (SFC)<script>Тип Настройка. Он раскрывает все верхние привязки к шаблону.

Неиспользованныйsetup sugar

<template>
  <Foo :count="count" @click="inc" />
</template>
<script>
import Foo from './Foo.vue'
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(1)
    const inc = () => { count.value++ }

    return {
      Foo,
      count,
      inc
    }
  }
}
</script>

использовалsetup sugar

<template>
  <Foo :count="count" @click="inc" />
</template>
<script setup>
// 导入的组件也可直接可用于模板(指令同理,同样会被自动注册)
import Foo from './Foo.vue'
import { ref } from 'vue'

// 书写组合式 api 就像在正常的 setup 中一般,但是不需要进行手动地进行 return
const count = ref(0)
const inc = () => { count.value++ }
</script>

ты сможешьGitHub.com/vUEJS/RFCs/…так же какGitHub.com/vUEJS/RFCs/…посмотреть оsetup sugarа такжеref sugarДля дальнейшего обсуждения. лично не нравитсяref sugar,По моему мнению.valueПисьмо легче понять, в сочетании сVolarС помощью подсказок не возникает большой умственной нагрузки.

Вызовет ли комбинированный метод записи vue3 больше проблем?

В настоящее время многие люди в Интернете отвечают, что использование комбинированного API делает код более хаотичным. затем изvue2изoptions apiприбытьvue3изcomposition apiКаковы преимущества письма?

  1. Высшая логическая связь: вoptions apiКак функция, которую мы должны использоватьdata+method+watch...и еще apis, часть кода нельзя объединить вместе, нам нужно несколько раз перемещаться вверх и вниз, чтобы смотреть при чтении части логики. а такжеcomposition apiЭто решило проблему.
  2. Функциональное извлечение: благодаря функциональному программированию мы можем инкапсулировать функциональную логику в хук, мы можем напрямую импортировать хук и запустить метод.

Недостатки: отoptions apiпереключиться наcomposition apiСамая большая проблема такая же, как самая большая проблема в том, что нет обязательного разделения кода, Если человек, который его пишет, не имеет хороших навыков кодирования, то последующим людям будет очень неудобно. Пока я решил это так:

  • Самостоятельно закодируйте раздел и попробуйте разделить метод (написать комментарий), раздел выглядит следующим образом:
    1. родственное введение
    2. Реактивные данные, реквизиты, излучающие определения
    3. Жизненный цикл и запись часов
    4. определение метода
    5. Метод и свойства воздействия
  • Извлечение компонента: разделите страницу на две папки, одну дляviews, один дляcomponents. Папки представлений и компонентов имеют свои собственные файлы. Папка представлений — это запись страницы, которая отвечает за данные, а компоненты — это извлечение некоторых компонентов на странице. Если это общедоступный компонент, извлеките его в другое место в папке компонентов.
  • Извлечение хука: логика извлекается настолько, насколько это возможно, и повторно использовать ее не нужно.

Новый API, полученный из установочного сахара

определить макросы компилятора (макросы компилятора)

кdefineAPI в начале — это все макросы компилятора (макросы компилятора) api, которые можно использовать только в<script setup>используется в. Их не нужно импортировать, они обрабатываются в<script setup>компилируется.

Уведомление:defineAPI-интерфейс класса должен использоваться непосредственно в настройке, его нельзя поместить в метод.

Уведомление:defineХотя класс апи не нужно импортировать, но он не очень совместим с ТС, если не импортировать, то подскажетundefined, если импортируется, будетwarningнамекать.

Уведомление:defineХотя class api в настоящее время может использовать объявление типа TS, вы не можете импортировать интерфейс или тип для объявления типа (возможно объявление непосредственно в файле), потому что это сообщит об ошибке. Угадай, это иdefineСвязан с макросом компилятора, может быть исправлено позже.

  1. defineProps: Этот API легко понять, он предназначен для определения информации, связанной с реквизитом.

    Основное использование:

    defineProps({
     name: {
       type: String,
       required: false,
       default: 'Petter',
     },
     userInfo: Object,
     tags: Array,
    })
    

    Используйте объявления типа TS:

    const props = defineProps<{ 
        foo: string 
        bar?: number
    }>()
    

    Примечание: два варианта написания не могут использоваться вместе, т. е. одинdefinePropsВы не можете использовать как объявления типа TS, так и базовые использования.

  2. withDefaults: Этот метод не является частью макросов компилятора API, но это APIdefinePropsполученный. Значение по умолчанию не может быть установлено в объявлении типа TS.Этот API предназначен в основном для решения этого сценария.

    withDefaults(defineProps<{
      size?: number
      labels?: string[]
    }>(), {
      size: 3,
      labels: () => ['default label']
    })
    
  3. defineEmits: Этот API также хорошо понятен, который должен определять связанную информацию об излучении. Однако использование немного отличается от предыдущего.

    Основное использование:

    // 声明
    const emits = defineEmits(['change', 'delete'])
    // 使用
    emits('change')
    

    Тип декларации ТС:

    // 声明
    const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', value: string): void }>()
    // 使用
    emits('change',1)
    
  4. defineExpose: в традиционных компонентах Vue все, что отображается в шаблоне, неявно отображается в экземпляре компонента, то есть родительский компонент может получить все свойства и методы дочернего компонента через ref или дочернюю цепочку. В большинстве случаев эта полная экспозиция является чрезмерной, и экспозиция вручную должна выполняться в настройках vue3.

    const a = 1
    const b = ref(2)
    defineExpose({ a, b, })
    

    Примечание: в настоящее время найденоdefineExposeВыставленные свойства и методыunknownВведите, если есть способ исправить тип, добро пожаловать, чтобы добавить его в область комментариев.

hook api

Примечание. API useContext устарел в пользу более детализированного API.

  1. useAttrs: Зная название, это используется для получения данных attrs, но это отличается от vue2, который содержитclass,属性,方法.

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

    <component v-bind='$attrs',v-on='$listeners'></component>
    

    $listeners был удален в vue3, новый способ написания:

    <template>
      <component v-bind='attrs'></component>
    </template>
    <srcipt setup lang='ts'>
        const attrs = useAttrs();
    <script>
    
  2. useCSSModule: CSS Modules — это система модульности и композиции CSS. vue-loader интегрирует модули CSS, которые можно использовать для имитации CSS с ограниченной областью действия. Позволяет в одном файле компонентsetupДоступ к модулям CSS в формате . Я меньше использую этот API, но я буду вводить его больше.

  3. useSlots: Как следует из названия, получить данные слота.

  4. useCssVars: Этот API временно имеет меньше данных. представлятьv-bind in stylesупомянул.

    Подробнее см.:GitHub.com/vUEJS/RFCs/…

  5. useTransitionState: Этот API временно имеет меньше данных.

  6. useSSRContext: Этот API временно имеет меньше данных.

Текущие ограничения установочного сахара

Для изменения конфигурации опции требуется один скрипт

Отсутствие элементов конфигурации, иногда нам нужно изменить параметры компонента, вsetupВ настоящее время мы не можем этого сделать. мы должны上方представить еще одинscript, напишите соответствующийexportВот и все.

<script>
   export default {
       name: 'YourName',
       inheritAttrs: false,
       customOptions: {},
   } 
</script>
<script setup>
  // your code
</script>

Примечание. Vue 3 SFC обычно автоматически определяет имя компонента из имени файла компонента. В большинстве случаев явное объявление имени не требуется. Единственный случай, когда вам нужно<keep-alive>Это имя необходимо вам при включении, исключении или прямой проверке параметров компонентов.

Не идеальная интеграция с TS и ESLint

  1. а также@typescript-eslint/no-unused-varsПравила не совместимы, значение этого правила определено, а не используется. Это правило не имеет существенного влияния, и его можно закрыть.

    PS: создан с использованием последней версии vue-cli, проблема решена.

  2. Несовместимо с объявлениями импортированных типов, когда вы импортируете типы путем деструктурирования,setup sugarПроизойдет автоматический экспорт. В это время вы получите сообщение об ошибке от TS: Это тип, но он используется как значение. Обходной путь: введите экспорт, используяexport defaultИспользуется при экспорте или импортеimport * as xxимпортировать.

    Спасибо, что добавили в комментарии:import type { test } from "./test";Запись, как это, также может быть решена.

    На этом этапе вы можете подумать о написании скрипта выше, чтобы импортировать его, но это не сработает. Вещи, импортированные в скрипт выше, также будут автоматически экспортированы. Подробнее см.:GitHub.com/v UE JS/v UE-вы…

    PS: Проблема возникает из-за того, что используется препроцессор HTML.pug. Это поведение не произойдет, если препроцессор HTML не используется. Причина: Когда вы используете препроцессор HTML, SFC не будет знать, какие типы TS существуют.

Должен быть установлен новый плагин

Для этого нового требуется интегрированная среда разработки.<script setup>Модели обеспечивают специализированную обработку, чтобы обеспечить проверку типа выражения шаблона / проверку реквизитов и т. д. УстановитьVolarТакже для этой цели.

Как реализовать интернационализацию в vue3

  1. скачать последнююvue-i18n,текущая версия"vue-i18n": "^9.1.7".
  2. Создайте папку в srclocalesи создайте соответствующую языковую копию (здесь лучше всего использовать json).
    import en from "./en.json";
    import zhHans from "./zh-cn.json";
    import zhHant from "./zh-hk.json";
    import { createI18n } from "vue-i18n";
    import { judgeLang } from "@/utils/url";
    
    const messages = {
        en: en,
        "zh-hans": zhHans,
        "zh-hant": zhHant,
    };
    
    const i18n = createI18n({
        locale: judgeLang(),
        messages,
    });
    
    export default i18n;
    
  3. main.tsi18n был представлен в
    import { createApp } from "vue";
    import App from "./App.vue";
    import router from "./router";
    import store from "./store";
    import i18n from "@/locales/index";
    
    createApp(App).use(store).use(router).use(i18n).mount("#app");
    
  4. Создаватьi18n hook
    import { provide, inject } from "vue";
    import { useI18n } from "vue-i18n";
    
    export function useProvideI18n(): void {
        const { t } = useI18n();
        // 注入翻译函数
        provide("t", t);
    }
    
    export function useInjectI18n(): (text: string) => string {
       const t = inject("t") as (text: string) => string;
       return t;
    }
    
  5. существуетapp.vue, вводить. Тогда его можно будет получить и использовать везде.
  6. скачатьi18n Allyдля просмотра переводов в реальном времени (настоятельно рекомендуется).

Vue-i18n, см.:Карточка группы теща.GitHub.IO/v UE-i18you/this…Подробнее о плагине i18n Ally см.:GitHub.com/lokaricolor/i1…

Добавлено интересное в новой версии vue

v-memo (новое в Vue3.2)

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

<div v-memo="[valueA, valueB]">
  ...
</div>

При повторном рендеринге компонента, еслиvalueAа такжеvalueBпостоянный,<div>Все обновления для этого компонента и его подкомпонентов будут пропущены. На самом деле, даже создание Virtual DOM VNode будет пропущено, потому что копия поддерева в памяти может быть повторно использована.

На официальном сайте упоминаетсяv-memoИспользуется только для микрооптимизации в сценариях, критичных к производительности, обычно там, где его следует использовать для рендеринга большихv-forсписок (из нихlength > 1000).

<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
  <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
  <p>...more child nodes</p>
</div>

v-bindin<style>(экспериментальный синтаксис)

PS: В настоящее время не рекомендуется! Подробнее см.:GitHub.com/v UE JS/v UE-вы…, в рабочей среде из-за многопоточного загрузчика webpack произойдет сбой, ожидая устранения проблемы.

Поддержка переменных CSS, управляемых состоянием компонента, в стилях компонентов с одним файлом. На самом деле, это предложение существует уже давно (просто изменили способ написания), и оно по сути используетCSS var() 函数.

<template>
  <div class="text">hello</div>
</template>

<script>
  export default {
    data() {
      return {
        color: 'red',
        font: {
          size: '2em',
        },
      }
    },
  }
</script>

<style>
  .text {
    color: v-bind(color);

    /* 表达式需用引号括起来 */
    font-size: v-bind('font.size');
  }
</style>

Вы можете увидеть больше об этом здесьGitHub.com/vUEJS/RFCs/…

проблемы, с которыми вы можете столкнуться

Мобильный инструмент отладкиvConsoleпроизошло переполнение стека

Общая мобильная отладка заключается в использованииvConsoleОн легкий и простой в использовании, но в настоящее время он не совместим с Vue 3. После определенного периода использования произойдет переполнение стека. Вот еще один инструмент отладки, рекомендуемыйeruda,erudaВ настоящее время особых проблем с его использованием нет, но этот плагин очень большой, более 500 кб для мобильных терминалов невыносимо, даже после сжатия остается больше 100 кб. Здесь нам просто нужно судить в соответствии с окружением и использовать скрипт для его динамической вставки.

export default function debugInit(): void {
  const script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "//cdn.bootcdn.net/ajax/libs/eruda/2.3.3/eruda.js";
  document.getElementsByTagName("head")[0].appendChild(script);
  script.onload = function () {
    window.eruda.init();
  };
}

image.png

Используйте нерутированные компоненты с осторожностью

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

Например:transitionКомпоненты в настоящее время имеют случайные проблемы с этим способом записи.