vue3中Slot常见使用

发布时间:2023-11-04 19:00

下面先来认识一下插槽

在开发中,我们会经常封装一个个可复用的组件:

  1. 前面我们会通过props传递给组件一些数据,让组件来进行展示;
  2. 但是为了让这个组件具备更强的通用性,我们不能将组件中的内容限制为固定的div、span等等这些元素;
  3. 我们应该让使用者可以决定某一块区域到底存放什么内容和元素;

如何使用插槽slot?

  1. 插槽的使用过程其实是抽取共性、预留不同
  2. 我们会将共同的元素、内容依然在组件内进行封装;
  3. 同时会将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素;
  4. 在封装组件中,使用特殊的元素就可以为封装组件开启一个插槽;
  5. 该插槽插入什么内容取决于父组件如何使用;

插槽的基本使用

\"在这里插入图片描述\"
App.vue

<template>
  <div>
    <my-slot-cpn>
      <button>我是按钮</button>
    </my-slot-cpn>
    <my-slot-cpn>
      <my-input-cpn />
    </my-slot-cpn>
    <h2>我不是插槽的组件</h2>
    <my-slot-cpn>
      <h4>插槽里面很多内容</h4>
      <i>你信不信我</i>
      <del>啦啦啦啦啦</del>
    </my-slot-cpn>
    <my-slot-cpn></my-slot-cpn>
  </div>
</template>

<script>
import MySlotCpn from \"./MySlotCpn.vue\";
import MyInputCpn from \"./MyInputCpn.vue\";
export default {
  name: \"App\",
  components: { MySlotCpn, MyInputCpn },
  methods: {},
};
</script>

<style scoped>
</style>

MySlotCpn.vue

<template>
  <div>
    <h3>组件的开始</h3>
    <slot>
      <i>我是插槽,没有填写信息,我就是默认的</i>
    </slot>
    <h3>组件的结束</h3>
  </div>
</template>

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

<style lang=\"scss\" scoped>
</style>

MyInputCpn.vue

<template>
  <div>
    <input type=\"text\" placeholder=\"我是输入框\" />
  </div>
</template>

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

<style lang=\"scss\" scoped>
</style>

具名插槽的使用-动态插槽名

  1. 具名插槽顾名思义就是给插槽起一个名字, 元素有一个特殊的 attribute:name;
  2. 一个不带 name 的slot,会带有隐含的名字 default;

我们可以通过 v-slot:[dynamicSlotName]方式动态绑定一个名称;
具名插槽使用的时候缩写:
跟 v-on 和 v-bind 一样,v-slot 也有缩写;
即把参数之前的所有内容 (v-slot:) 替换为字符 #;

<template>
  <div>
    <nar-bar :name=\"name\">
      <template v-slot:left> 我是左边的插槽 </template>
      <template v-slot:center>我是中间的插槽</template>
      <template v-slot:right>我是右边的插槽</template>
      <template #[name]>我是语法糖和动态插槽</template>
    </nar-bar>
  </div>
</template>

<script>
import NarBar from \"./NarBar.vue\";

export default {
  name: \"App\",
  data() {
    return {
      name: \"lisi\",
    };
  },
  components: {
    NarBar,
  },
};
</script>

<template>
  <div>
    <div class=\"nav-bar\">
      <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=\"name\"><slot :name=\"name\"></slot></div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    name: String,
  },
};
</script>

渲染作用域

在Vue中有渲染作用域的概念:

  1. 父级模板里的所有内容都是在父级作用域中编译的;
  2. 子模板里的所有内容都是在子作用域中编译的;

案列

\"vue3中Slot常见使用_第1张图片\"

认识作用域插槽

但是有时候我们希望插槽可以访问到子组件中的内容是非常重要的:

  1. 当一个组件被用来渲染一个数组元素时,我们使用插槽,并且希望插槽中没有显示每项的内容;
  2. 这个Vue给我们提供了作用域插槽;

使用步骤
\"vue3中Slot常见使用_第2张图片\"
ShowNames.vue

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

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

<style scoped>

</style>

App.vue

<template>
  <div>
    <nar-bar :name=\"name\">
      <template v-slot:left> 我是左边的插槽 </template>
      <template v-slot:center>我是中间的插槽</template>
      <template v-slot:right>我是右边的插槽</template>
      <template #[name]>我是语法糖和动态插槽</template>
    </nar-bar>
    <hr />
    <show-names :names=\"names\">
      <template v-slot=\"names\">
        <p>{{ names.item }}-{{ names.index }}</p>
      </template>
    </show-names>
    <hr />
    // 如果我们有默认插槽和具名插槽,那么按照完整的template来编写
    <show-names :names=\"names\">
      <template v-slot=\"slotProps\">
        <span>{{ slotProps.item }}---{{ slotProps.index }}</span>
      </template>
    </show-names>
    <hr />
    // 果我们的插槽只有默认插槽时,组件的标签可以被当做插槽的模板来使用,这样,我们就可以将 v-slot 直 接用在组件上
    <show-names :names=\"names\" v-slot=\"slotProps\">
      <button>{{ slotProps.item }}-{{ slotProps.index }}</button>
    </show-names>
    <hr />
    <show-names :names=\"names\">
      <template v-slot=\"slotProps\">
        <button>{{ slotProps.item }}-{{ slotProps.index }}</button>
      </template>
      //如果我们的插槽是默认插槽default,那么在使用的时候 v-slot:default=\"slotProps\"可以简写为vslot=\"slotProps\":
      <template v-slot:lisi>
        <h2>我是name的插入内容</h2>
      </template>
    </show-names>
  </div>
</template>

<script>
import NarBar from \"./NarBar.vue\";
import ShowNames from \"./ShowNames.vue\";

export default {
  name: \"App\",
  data() {
    return {
      names: [\"张三\", \"李四\", \"王五\", \"赵六\", \"孙七\"],
    };
  },
  components: {
    NarBar,
    ShowNames,
  },
};
</script>

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号