Из простого списка, чтобы узнать монтажу Vue сокет

Vue.js

нужно

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

Как только вы увидите этот эффект, некоторые друзья могут сказать: «Это непросто, удар слева — это выброшенный кусок кода».

<template>
  <div>
    <div>{{ title }}</div>
    <hr>
    <div>
      <div v-for="(item, i) in List" :key="i">{{ item }}</div>
    </div>
  </div>
</template>

Затем назовите это так в родительском компонентеokсейчас:

<template>
  <custom-list :title="title" :List="books" />
</template>

<script>
import CustomList from './custom-list.js';

export default {
  components: { CustomList },
  data() {
    return {
      title: '书籍列表',
      books: ['Dom编程艺术', '你不知道的Javascript', 'CSS世界', 'HTML入门教程'],
    };
  },
};
</script>

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

Однако достаточно ли этого? Потребности всегда непостоянны, например, в один прекрасный день, чтобы удовлетворить следующие эффекты?

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

слот

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

нормальный слот

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

<template>
  <div>
    <div>
      <slot></slot>
    </div>
    <hr>
    <div>
      <div v-for="(item, i) in List" :key="i">{{ item }}</div>
    </div>
  </div>
</template>

Затем в вызове родительского компонента:

<template>
  <custom-list :List="books">
    <span><icon type="waves"> 书籍列表</span>
  </custom-list>
</template>

<script>
import CustomList from './custom-list.js';

export default {
  components: { CustomList },
  data() {
    return {
      title: '书籍列表',
      books: ['Dom编程艺术', '你不知道的Javascript', 'CSS世界', 'HTML入门教程'],
    };
  },
};
</script>

В этом случае содержимое, обернутое в родительский компонент, заменит<slot>label, поэтому окончательный результат рендеринга выглядит так:

<template>
  <div>
    <div>
      <span><icon type="waves"> 书籍列表</span>
    </div>
    <hr>
    <div>
      <div v-for="(item, i) in List" :key="i">{{ item }}</div>
    </div>
  </div>
</template>

Кстати рот: в<slot>На этикетке также может быть размещено содержимое, например:<slot> 标题 </slot>, Представляет содержимое слота по умолчанию, которое будет отображаться только в том случае, если родительский компонент не передает содержимое через слот.

Точно так же нашиcontentКонтент тоже нужно распространять, поэтому модифицируем его снова:

<template>
  <div>
    <div>
      <slot></slot>
    </div>
    <hr>
    <slot></slot>
  </div>
</template>

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

именованный слот

Как следует из названия, это слот с именем, по которому легко отличить несколько слотов. Затем продолжаем модифицировать:

<template>
  <div>
    <div>
      <slot name="title"></slot>
    </div>
    <hr>
    <slot name="content"></slot>
  </div>
</template>

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

<template>
  <custom-list>
    <template v-slot:title>
      <span><icon type="waves"> 书籍列表</span>
    <template>
    <template v-slot:content>
      <div>
        <div v-for="(item, i) in book" :key="i">
          <icon :type="item.icon">{{ item.name }}
        </div>
      </div>
    </template>
  </custom-list>
</template>

<script>
import CustomList from './custom-list.js';

export default {
  components: { CustomList },
  data() {
    return {
      title: '书籍列表',
      books: [
        { name: 'Dom编程艺术',icon: 'face' },
        { name: '你不知道的Javascript', icon: 'favorite' },
        { name: 'CSS世界', icon: 'av_timer'},
        { name: 'HTML入门教程', icon: 'star_half' },
      ],
    };
  },
};
</script>

Предоставляя контент в именованные слоты, мы можем<template>использовать на элементахv-slotинструктаж и сv-slotукажите его имя в виде аргумента.

Теперь все хорошо, вам даже не нужно передавать данные,ListДочерний компонент вообще не используется, данные рендерятся непосредственно в родительском компоненте, и их приходится записывать каждый раз, когда компонент используетсяv-for, то почему бы не поставитьv-forКак насчет записи в дочерних компонентах? Это нужно написать только один раз. Затем снова изменим подкомпонент:

<template>
  <div>
    <div>
      <slot name="title"></slot>
    </div>
    <hr>
    <div>
      <div v-for="(item, i) in List">
        <slot name="item"></slot>
      </div>
    </div>
  </div>
</template>

Это еще одна проблема: я хочу отобразитьitemноitemэто данные в дочернем компоненте, когда родительский компонент проходитv-slotДоставка поступающего контента,<slot>{{ item }}</slot>Контент будет заменен входящим контентом. Что тут происходит? Подумайте об этом, если мы отдадим данные родительскому компоненту, разве это не будет решено путем отображения их в родительском компоненте? Тогда пришло время作用域插槽появился.

слот с прицелом

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

<template>
  <div>
    <div>
      <slot name="title"></slot>
    </div>
    <hr>
    <div>
      <div v-for="(item, i) in List">
        <slot name="item" :row="item"></slot>
      </div>
    </div>
  </div>
</template>

В этот момент мы будем каждыйitemзначение черезrowатрибут передан<slot>, а затем получаем это значение в родительском компоненте:

<template>
  <custom-list>
    <template v-slot:title>
      <span><icon type="waves"> 书籍列表</span>
    <template>
    <!--实际传的数据格式为: { row:{ name: xx, icon: xx } },所以这里可以使用结构赋值-->
    <template v-slot:item="{ row }">
      <icon :type="row.icon">{{ row.name }}
    </template>
  </custom-list>
</template>

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