682 vue3非父子组件的通信之插槽Slot:多个插槽,具名插槽,动态插槽名,渲染作用域

认识插槽Slot


如何使用插槽slot?


插槽的基本使用


插槽的默认内容


多个插槽的效果


App.vue

<template>
  <div>
    <my-slot-cpn>
      <button>我是按钮</button>
    </my-slot-cpn>

    <my-slot-cpn>
      我是普通的文本
    </my-slot-cpn>

    <my-slot-cpn>
      <!-- 也可以插入组件 -->
      <my-button />
    </my-slot-cpn>

    <!-- 没有插入对应的内容,那么会显示插槽默认的内容 -->
    <my-slot-cpn></my-slot-cpn>

    <!-- 插入很多的内容,每个插槽都会获取插入的内容来显示 -->
    <my-slot-cpn>
      <h2>哈哈哈</h2>
      <button>我是按钮</button>
      <strong>我是strong</strong>
    </my-slot-cpn>
  </div>
</template>

<script>
  import MySlotCpn from "./MySlotCpn.vue";
  import MyButton from "./MyButton.vue";
  // C0C8D2  C0C8D2
  export default {
    components: {
      MySlotCpn,
      MyButton,
    },
  };
</script>

<style scoped></style>

MySlotCpn.vue

<template>
  <div>
    <h2>组件开始</h2>
    <slot>
      <i>我是默认的i元素</i>
    </slot>
    <slot>
      <i>我是默认的i元素</i>
    </slot>
    <slot>
      <i>我是默认的i元素</i>
    </slot>
    <h2>组件结束</h2>
    <hr />
  </div>
</template>

<script>
  export default {};
</script>

<style scoped></style>

MyButton.vue

<template>
  <div>
    <button>哈哈哈 我是button组件</button>
  </div>
</template>

<script>
  export default {};
</script>

<style scoped></style>

具名插槽的使用


动态插槽名


具名插槽使用的时候缩写


App.vue

<template>
  <div>
    <nav-bar :name="name">
      <!-- 要用template元素包裹 -->
      <template #left>
        <button>左边的按钮</button>
      </template>
      <template #center>
        <h2>我是标题</h2>
      </template>
      <template #right>
        <i>右边的i元素</i>
      </template>
      <template #[name]>
        <i>why内容</i>
      </template>
    </nav-bar>
  </div>
</template>

<script>
  import NavBar from "./NavBar.vue";

  export default {
    components: {
      NavBar,
    },
    data() {
      return {
        name: "why",
      };
    },
  };
</script>

<style scoped></style>

<template>
  <div class="nav-bar">
    <!-- <slot name="default"></slot> -->
    <div class="left">
      <slot name="left"></slot>
    </div>
    <div class="center">
      <slot name="center"></slot>
    </div>
    <div class="right">
      <slot name="right"></slot>
    </div>
    <div class="addition">
      <slot :name="name"></slot>
    </div>
  </div>
</template>

<script>
  export default {
    props: {
      name: String,
    },
    // data() {
    //   return {
    //     name: "why"
    //   }
    // }
  };
</script>

<style scoped>
  .nav-bar {
    display: flex;
  }

  .left,
  .right,
  .center {
    height: 44px;
  }

  .left,
  .right,
  .addition {
    width: 80px;
    background-color: red;
  }

  .center {
    flex: 1;
    background-color: blue;
  }
</style>

渲染作用域


渲染作用域案例


认识作用域插槽


作用域插槽的案例


独占默认插槽的缩写


默认插槽和具名插槽混合


App.vue

<template>
  <div>
    <!-- 编译作用域 -->
    <!-- <child-cpn>
      <button>{{title}}</button>
    </child-cpn> -->

    <show-names :names="names">
      <template v-slot="hahaha">
        <button>{{ hahaha.item }}-{{ hahaha.index }}</button>
      </template>
    </show-names>

    <!-- 独占默认插槽的缩写 -->
    <!-- 【注意,v-slot是加给组件标签,不是加给其他标签。】 -->
    <show-names :names="names" v-slot="hahaha">
      <button>{{ hahaha.item }}-{{ hahaha.index }}</button>
    </show-names>

    <!-- 注意: 如果还有其他的具名插槽, 那么默认插槽也必须使用template来编写 -->
    <show-names :names="names">
      <template v-slot="hahaha">
        <button>{{ hahaha.item }}-{{ hahaha.index }}</button>
      </template>

      <template v-slot:why>
        <h2>我是why的插入内容</h2>
      </template>
    </show-names>

    <show-names :names="names">
      <template v-slot="slotProps">
        <strong>{{ slotProps.item }}-{{ slotProps.index }}</strong>
      </template>
    </show-names>
  </div>
</template>

<script>
  import ChildCpn from "./ChildCpn.vue";
  import ShowNames from "./ShowNames.vue";

  export default {
    components: {
      ChildCpn,
      ShowNames,
    },
    data() {
      return {
        names: ["why", "kobe", "james", "curry"],
      };
    },
  };
</script>

<style scoped></style>

ChildCpn.vue

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

<script>
  export default {
    data() {
      return {
        title: "我是title",
      };
    },
  };
</script>

<style scoped></style>

ShowNames.vue

<template>
  <div>
    <template v-for="(item, index) in names" :key="item">
      <slot :item="item" :index="index"></slot>

      <slot name="why"></slot>
    </template>
  </div>
</template>

<script>
  export default {
    props: {
      names: {
        type: Array,
        default: () => [],
      },
    },
  };
</script>

<style scoped></style>

posted on 2021-06-10 14:02  冲啊!  阅读(1137)  评论(0编辑  收藏  举报

导航