[Внешний движок] Полная версия метода связи между компонентами Vue.

внешний интерфейс Vue.js
[Внешний движок] Полная версия метода связи между компонентами Vue.

предисловие

Само собой разумеется, насколько широко сегодня используется Vue.js, и главной особенностью Vue является компонентизация. В этом выпуске я хочу рассказать о методах связи между компонентами Vue, что является почти обязательным вопросом в интервью Vue в последние годы. Примечание. Все примеры в этой статье основаны на скаффолдинге Vue, и некоторые из них будут использоватьсяElement UIПример.

[Дорога к развитию клиентской части] будет издан в виде новой серии, и в будущем будет больше высококачественного пользовательского контента. Заинтересованные студенты могут захотеть обратить внимание. Статья заканчивается нагруппа обменаа такжеНет публики, вы можете учиться и общаться вместе, спасибо 🍻.

  • Следующее уведомление: Углубленный принцип отзывчивости Vue, напишите mvvm

компоненты

Компоненты — это многократно используемые экземпляры Vue. —Официальная документация Vue;

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

  • Местные компоненты (местная регистрация)
  • Глобальные компоненты (глобальная регистрация)

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

// 全局注册
// install.js
import Icon from './Icon.vue';
const install = {
    install:function(Vue){
        Vue.component('VIcon', Icon);
    }
};
export default install;
// main.js
import install from './install.js'; // 引入全局插件
Vue.use(install); // 注册

// 局部注册
import VIcon from './Icon.vue';
export default{
    components: {
        VIcon
    }
}

// 使用
<v-icon> </v-icon>

По различным сценариям применения его можно разделить на:

  • Компоненты страницы: когда мы используем Vue, страницу, представленную каждым маршрутом, можно назвать компонентом.
  • Базовый компонент: Как и компонент Icon в каштане выше, это типичный базовый компонент. В принципе бизнес-логика не смешана, ее можно много использовать в проекте, и ее легко трансплантировать. Подобными базовыми компонентами являются Button, Input и т. д., которые распространены в различных библиотеках компонентов пользовательского интерфейса.
  • Бизнес-компоненты. Между бизнес-компонентами и конкретной бизнес-логикой проекта существует множество взаимосвязей, которые обычно отделены от текущего проекта.

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

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

Связь между компонентами

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

Props

В Vue самым основным методом связи является Props, который представляет собой способ передачи значений от родительских компонентов к дочерним компонентам при обмене данными между родительскими и дочерними компонентами. Разрешено получать в виде массива, но рекомендуется включить проверку типов. Для более подробной проверки типов перейдите кvue-документация.

// communication.vue
<communication-sub v-bind="dataProps"></communication-sub>
// v-bind="dataProps" 等同于 :title="title",适用于多个参数一起传递
···
data() {
    return {
        dataProps: {
            title: '我是父组件的值',
        }
    }
}
// communication-sub.vue
<div class="communication-sub">
    {{title}}
</div>
···
props: ['title']
// 更推荐开启类型检查
props: {
    title: {
        type: String,
        required: true,
        default: '' // 允许指定默认值,引用类型需要函数返回
    }
}
···

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

props: ['title'],
data: function () {
  return {
    text: this.title
  };
}

Почему это не ссылочный тип, ведь в JavaScript присвоение ссылочного типа — это фактически передача адреса памяти. Таким образом, простое присваивание в приведенном выше каштане, очевидно, будет указывать на один и тот же адрес памяти, поэтому, если это массив или объект, вам может понадобиться глубокая копия.

let obj = JSON.parse(JSON.stringify(obj));

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

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

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

<communication-sub v-bind="dataProps" class="one" type="div"></communication-sub>

Результат выглядит следующим образом:

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

...
inheritAttrs: false,
props: ['title']

Используя inheritAttrs, мы также можем легко перенести другие возможности привязки компонентов к указанным нами элементам. Вот о чем мы поговорим дальше$attrs.

атрибуты, слушатели

Когда мы используем библиотеку компонентов, мы часто пишем это:

<el-input v-model="input" placeholder="请输入内容"></el-input>

После фактического рендеринга:

Вы можете видеть, что указанный нами заполнитель отображается на входе, но вход не является корневым элементом. Все ли они объявлены с помощью реквизитов, а затем назначены для ввода? В этом случае можно использовать$attrsТеперь давайте трансформируем каштан, который у нас был раньше.

// communication.vue
<template>
    <div class="communication">
        <communication-sub v-bind="dataProps" class="input" type="text" placeholder="请输入内容">
        </communication-sub>
    </div>
</template>
<script>
import communicationSub from './communication-sub.vue';
export default{
    name: 'communication',
    data() {
        return {
            dataProps: {
                title: '我是 communication 的值',
            }
        }
    },
    components: {
        communicationSub
    }
}
</script>

// communication-sub.vue
···
<div class="communication-sub">
    <input v-bind="$attrs" v-model="title"></input>
</div>
···
 export default {
    inheritAttrs: false
}

Как видите, тип был передан в тег ввода дочернего элемента, а класс — нет. Это потому чтоinheritAttrs: falseПараметры не влияют на привязку стилей и классов.Как можно заметить$attrsЭто объект, который собирает передаваемые по значению (также называемые свойствами, не относящимися к реквизитам), которые не объявлены реквизитами внутри компонента., а затем привязать его к указанному элементу через v-bind. Это также стратегия, принятая библиотеками компонентов, такими как Element.

Здесь следует отметить, что атрибуты, присвоенные элементу через $attrs, не будут объединены или заменены исходными атрибутами элемента, но исходные атрибуты будут иметь преимущественную силу.. Например, предположим, что я установил тип ввода выше на пароль по умолчанию.

<input v-bind="$attrs" v-model="title" type="password"></input>

Тип: 'текст' в $attrs использоваться не будет, а пароль будет иметь преимущественную силу, поэтому, если вам нужны атрибуты со значениями по умолчанию, рекомендуется не использовать этот метод.

$listenersтакой же$attrsаналогичный,Его можно рассматривать как объект, который содержит все прослушиватели событий в компоненте (включая пользовательские события, за исключением оформленных событий .native).. Он также поддерживает вышеупомянутый метод записи, который подходит для размещения событий на указанных элементах в компонентах.

// communication.vue
<communication-sub v-bind="dataProps"
class="input"
type="text"
placeholder="请输入内容"
@focus="onFocus" >
</communication-sub>
···
methods: {
    onFocus() {
        console.log('onFocus');
    }
}
// communication-sub.vue
<input v-bind="$attrs" v-model="title" v-on="$listeners"></input>

Привязать событие фокуса к предыдущему каштану, передать его в дочерний компонент$listenersПривязка к входу срабатывает, когда вход сфокусирован.

Итак, какие другие сценарии можно использовать в дополнение к такой ситуации, когда вы указываете свойства и события привязки элементов в компонентах? Официальное примечание: полезно при создании компонентов более высокого уровня. Например, передача данных во внучатом компоненте после запуска события во внучатом компоненте должна соответствующим образом обновляться в прародителях. Мы продолжаем предыдущий каштан: запускаем событие click в компоненте grandchild, а затем изменяем соответствующие данные в прародителе.

// communication.vue
<communication-sub v-bind="dataProps"
                @click="onCommunicationClick">
</communication-sub>
···
methods: {
    onCommunicationClick() {
        this.dataProps.title = '我是点击之后的值';
    }
};

// communication-sub.vue
<communication-min-sub v-on="$listeners"></communication-min-sub> // 子组件中将事件透传到孙辈

// communication-min-sub.vue
<template>
    <div class="communication-min-sub">
        <p>我是 communication-min-sub</p>
        <button v-on="$listeners">click</button>
    </div>
</template>
<script>
export default{
    name: 'communication-min-sub',
    inheritAttrs: false
}
</script>

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

Внедрение зависимостей

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

<el-select v-model="value" placeholder="请选择">
    <el-option
      v-for="item in options"
      :key="item.value"
      :label="item.label"
      :value="item.value">
    </el-option>
</el-select>

Я считаю, что все использовали Shangli или базовые компоненты, похожие на Shangli, они используют vueслотвыполнить. Итак, в настоящее время обмен данными между el-select и el-option, наш предыдущий$attrs,$listenersЭто бесполезно. Некоторые студенты могут не понять, почему приведенный выше код должен взаимодействовать.Позвольте мне кратко представить метод обработки Element:

Можем просто подумать (исходники Element немного сложнее этого, для облегчения понимания упростите его, при необходимости можно сразу перейти к исходникам читать), есть элемент input в el-select , и отображается строка в el-option.li. Согласно требованиям, когда мы выбираем li, нам нужно уведомить ввод для отображения соответствующих данных. И когда мы на самом деле используем его, он обычно сопровождается такими компонентами, как el-form и el-form-item, поэтому существует острая необходимость в способе:

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

Некоторые студенты могут подумать, что такого рода многоуровневость может использовать Vuex, EventBus и другие методы, конечно. Просто наша текущая предпосылка — это базовый компонент, как правило, сторонняя библиотека компонентов не добавит каких-то дополнительных зависимостей. На самом деле, сам Vue не рекомендует напрямую использовать в бизнесе provider и inject, как правило, он больше используется в компонентах и ​​библиотеках плагинов.

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

// communication.vue
<communication-sub v-bind="dataProps" >
</communication-sub>
// @click="onCommunicationClick" 移除之前绑定的时间
···
// 在 provide 添加子代需要接收的方法 onCommunicationClick,
// 也可以直接指定为 this,子代便能访问父代所有的数据和方法。
provide: function () {
    return {
        onCommunicationClick: this.onCommunicationClick
    }
},
methods: {
    onCommunicationClick() {
        this.dataProps.title = '我是点击之后的值';
    }
};

// communication-sub.vue
<communication-min-sub></communication-min-sub>
// 移除之前的 v-on="$listeners",因为在这个组件中不需要用到父组件的方法,所以不用做其它处理

// communication-min-sub.vue
<template>
    <div class="communication-min-sub">
        ···
        <button @click="onCommunicationClick">click</button>
        // 移除 v-on="$listeners",然后绑定 inject 接收到的方法
    </div>
</template>
<script>
export default{
    name: 'communication-min-sub',
    inject: ['onCommunicationClick'] // inject 接收父组件的方法
}
</script>

Этот способ написания имеет тот же эффект, что и предыдущие $listeners, поэтому он больше не отображается. Вы можете попробовать сами или перейти к исходному кодуwebrtc-stream.

думать: Некоторые студенты могут подумать, что если я нахожусь в корневом экземпляре, это устанавливается в app.vue:

<script>
  export default {
    provide () {
      return {
        app: this // 设置app为this
      }
    },
    data () {
      return {
        userInfo: null,
        otherState: null
      }
    }
  }
</script>

Затем поместите все управление состоянием в app.data, можно ли разделить его между всеми детьми? Разве не нужен Vuex? Фактически, сам Vue предоставляет метод доступа к корневому экземпляру.$root, так что это можно сделать даже без предоставления . Так почему бы не использовать его таким образом? По указанным выше причинам он не способствует отслеживанию и сопровождению, а также теряет смысл так называемого управления состоянием. Однако, если ваш проект достаточно мал, вы все равно можете использовать его таким образом.

ссылка, родитель, дети

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

  • ref

Проще говоря, это получение объекта Dom и экземпляра дочернего компонента элемента. При использовании в обычном элементе DOM ссылка указывает на элемент DOM; при использовании в дочернем компоненте ссылка указывает на экземпляр компонента. Получение элементов Dom — это выполнение некоторых операций с Dom.Для использования после загрузки Дом, иначе он может быть недоступен. Например, я хочу изменить цвет шрифта предыдущего ввода на красный:

<input type="text" v-model="dataProps.title" ref="input">
...
mounted() {
    this.$nextTick(_ => { // 确保 Dom 更新完成
        this.$refs['input'].style.color = 'red';
    });
}
// 这里只是举一个栗子,实际项目中的需求,最好通过 class 的方式,尽量减少 Dom 操作。

Итак, когда вам нужно получить экземпляр компонента? Например, изменение состояния родительского элемента требует, чтобы дочерний компонент сделал HTTP-запрос для обновления данных. Обычно мы выбираем передачу состояния подкомпоненту через Props, а затем подкомпонент следит за часами, и если есть изменение, выполняется соответствующая операция. На этом этапе мы можем использовать ref.

<child ref="child"></child>
···
<script>
  export default {
    methods () {
      onStateChange() { // 变更状态后直接调用子组件方法进行更新
          this.$refs['child'].updateData();
      }
    }
  }
</script>
  • $children,$parent

По совпадению,$childrenТа же задача, что и выше, может быть выполнена.$childrenа также$parent, как следует из названия, можно найти дочерний компонент текущего компонента и найти родительский компонент текущего компонента. Если есть несколько подкомпонентов, вам нужно полагаться на свойство имени экземпляра компонента. Перепишите приведенный выше метод:

<script>
  export default {
    methods () {
      onStateChange() { // 子组件返回的是一个数组,多个子组件用 $options.name 区分。
          this.$children[0].updateData();
      }
    }
  }
</script>

$parentа также$childrenТо же использование, но$parentВозвращенный экземпляр родительского компонента не является массивом, поскольку должен быть только один родительский компонент. Один из недостатков ref, parent и children заключается в том, что они не могут обрабатывать компоненты на разных уровнях и компоненты-братья.Позже мы представим методы диспетчеризации и широковещания для обеспечения межуровневого взаимодействия.

излучать, включать, выключать

$emit, я думаю, что все хорошо знакомы с ним.Мы обычно используем его для связи между родительским и дочерним компонентами, и мы также называем его пользовательскими событиями.$emitа также$onявляются методами самого компонента,$onможет контролировать$emitотправленные события,$offИспользуется для отмены мониторинга событий. Это также принцип, на который опирается EventBus, метод связи, о котором мы поговорим далее.

// 父组件
<template>
    <button-component @clickButton="clickButton"></button-component>
    // 在父组件利用 v-on 监听
</template>
<script>
export default {
    methods: {
      clickButton () { ··· }
    }
}
</script>

// 子组件
<template>
    <button @click="handleClick"></button>
</template>
<script>
export default {
    methods: {
      handleClick () { // 触发 $emit
        this.$emit('clickButton');
      }
    },
    mounted() {
        this.$on('clickButton', (...arr) => { // 也可以自己监听 $emit,虽然没什么用···
            console.log(...arr);
        })
    }
}
</script>

EventBus

$emitПроблема по-прежнему в том, что он не поддерживает межуровневые и одноуровневые компоненты.Vue официально рекомендует использовать новый экземпляр Vue для глобальной связи событий (или центральной шины событий...), которая представляет собой EventBus, который мы собираемся использовать. говорить о. Студенты, знакомые с ним, знают, что обычная шина, мы обычно монтируем ее на прототипе Vue, что удобно для глобальных вызовов.

// main.js
Vue.prototype.$bus = new Vue();

Все еще переписывая предыдущий каштан:

<!--communication.vue-->
<communication-sub v-bind="dataProps" >
</communication-sub>
···
beforeDestroy() { <!-- 实例销毁时,需要卸载监听事件 -->
    this.$bus.$off('busClick');
},
created() {  <!-- 监听子组件触发的 Bus 事件-->
    this.$bus.$on('busClick', (data) => {
        this.dataProps.title = data;
    });
}

<!--communication-min-sub.vue-->
<template>
    <div class="communication-min-sub">
        <button @click="busClick">click bus</button>
        <!--子组件触发点击事件-->
    </div>
</template>
<script>
export default{
    methods: {
        busClick() {
            this.$bus.$emit('busClick', 'bus 触发了');
        }
    }
}
</script>

Это базовая реализация EventBus. Теперь давайте представим, что информацию, подобную userInfo, нужно использовать на многих страницах, тогда нам нужно сделать это на многих страницах.$onКонтролируемая операция. Можно ли объединить эти операции? Давайте посмотрим вместе:

 // 新建一个 eventBus.js
import Vue from 'vue';
const bus = new Vue({
    data () {
        return {
            userInfo: {}
        }
    },
    created () {
        this.$on('getUserInfo', val => {
            this.userInfo = val;
        })
    }
});
export default bus;
// main.js
import bus from './eventBus';
Vue.prototype.$bus = bus;
// app.vue
methods: {
    getUserInfo() {
        ajax.post(***).then(data => {
            this.$bus.$emit('getUserInfo', data); // 通知 EventBus 更新 userInfo
        })
    }
}

Таким образом, когда другие страницы используют информацию о пользователе, вам нужно толькоthis.$bus.userInfoВот и все. Обратите внимание, что я не использовал off для удаления монитора только сейчас, потому что на самом деле нет точного времени для уничтожения глобальной информации, такой как userInfo, Когда браузер закрыт, нам не нужно с этим разбираться. Однако, если он используется только определенным компонентом страницы, рекомендуется использовать начальный метод для его удаления при уничтожении страницы.

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

Отправка и вещание: отправка и вещание

На этот раздел ссылаетсяИсходный код элемента

В реализации Vue 1.x есть$dispatchа также$broadcastметод, но устарел в 2.x.$dispatchОсновная роль заключается в отправке событий вышестоящему компоненту,$broadcastОн транслируется на нижний уровень. Их преимущество в том, что все они поддерживают кросс-уровень, а дальше смотрим официальные причины отказа от этих двух методов:

Потому что поток событий, основанный на древовидной структуре компонентов, действительно сложно понять, и он будет становиться все более и более хрупким по мере расширения структуры компонентов. а также$dispatchа также$broadcastЭто также не решает проблему связи между родственными компонентами.

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

Диспетчеризация и трансляция зависят от имени компонента (больше всего боюсь, что кто-то здесь скажет: Если не написать имя, этот метод будет бесполезен? 2333...), чтобы найти соответствующий уровень экземпляра компонента по уровень. В реализации Element ко всем компонентам добавляется атрибут componentName, поэтому он ищется в соответствии с componentName. Мы по-прежнему используем имя напрямую, когда реализуем его.

Давайте сначала посмотрим$dispatchПростое использование, а затем анализировать идеи.

<!--communication-min-sub.vue-->
<template>
  <button @click="handleDispatch">dispatch</button>
</template>
<script>
import Emitter from '../../utils/emitter';
export default {
  mixins: [Emitter], // 混入,方便直接调用
  methods: {
    handleDispatch () {
      this.dispatch('communication', 'onMessage', '触发了dispatch');
    }
  }
}
</script>
<!--communication.vue-->
<script>
  export default {
    beforeDestroy() { // 销毁
        this.$off('onMessage');
    },
    mounted () {
        this.$on('onMessage', (data) => { // 监听
            this.dataProps.title = data;
        })
    }
  }
</script>

Теперь уточним цель.Метод отправки получает три параметра, имя компонента, имя события и основные данные (необязательно). Для рассылки событий по уровням вам нужно найти экземпляр компонента с указанным именем выше и использовать указанный выше$emitМетод выполняет отправку, поэтому его можно использовать в указанном компоненте.$onконтролировать. Таким образом, диспетчеризация, по сути, ищет указанный компонент и запускает свой собственный.$emit, отвечает этим, широковещательная передача делает обратное. Итак, как выполнить межуровневый поиск?

function broadcast(componentName, eventName, params) {
  this.$children.forEach(child => { // 遍历所有的 $children
    var name = child.$options.name; // 拿到实例的name,Element 此处用的 componentName
    if (name === componentName) { // 如果是想要的那个,进行广播
      child.$emit.apply(child, [eventName].concat(params));
    } else { // 不是则递归查找 直到 $children 为 []
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
  methods: {
    dispatch(componentName, eventName, params) {
      var parent = this.$parent || this.$root;
      var name = parent.$options.name;
      while (parent && (!name || name !== componentName)) {
      // 存在 parent 且 (不存在 name 或 name 和 指定参数不一样) 则继续查找
        parent = parent.$parent; // 不存在继续取上级
        if (parent) {
          name = parent.$options.name; // 存在上级 再次赋值并再次循环,进行判断
        }
      }
      if (parent) { // 找到以后 如果有 进行事件派发
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    }
  }
};

Выше приведен подробный пример emitter.js, как видите, это то же самое, о чем мы говорили ранее.$parent,$children,$emit,$onтесно связаны. Это также причина, почему он ставится позже. Как я уже говорил, распространение и широковещание не решают проблему связи между родственными компонентами, поэтому здесь вы можете расшириться и подумать о том, как поддерживать связь между родственными компонентами. все еще зависит от$parent,$children, можно найти любой указанный компонент.

Vuex

Vuex — это шаблон управления состоянием, разработанный для приложений Vue.js. Он использует централизованное хранилище для управления состоянием всех компонентов приложения и использует соответствующие правила, чтобы гарантировать предсказуемое изменение состояния. ---официальная документация

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

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

Суммировать

На этом содержание этой статьи закончено, давайте подведем итоги и повторим:

  • Способ, которым дочерний компонент достигает родительского компонента: Реквизиты,$parent,$attrs,$listeners, предоставлять и вводить,$dispatch
  • Способ, которым родительский компонент достигает дочернего компонента:$emitа также$on,$children,$ref,broadcast
  • Глобальная связь: EventBus, Vuex

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

группа обмена

Группа внешнего обмена QQ: 960807765, приветствуем все виды технического обмена, с нетерпением ждем вашего присоединения

постскриптум

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

Еще статьи:

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