vue3 | slots

vue3,slots · 浏览次数 : 176

小编点评

**插槽介绍** 插槽是一种在子组件中提供给父组件使用的一个占位符,用 `<slot></slot>  表示。父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的 `<slot></slot>`。 **作用域插槽介绍** 作用域插槽可以让父级外层组件能够访问子组件的数据,子组件向将数据提供给插槽,组件 props 传递数据的方式,子组件向插槽传递一个attributes,父组件通过 `v-slot`带的值(任意命名)来获取子组件的数据。 **例子** **方法一:在组件上使用 `v-slot`** ```vue 老板:来 {{ res.data }} 份 {{ res.content }} ~ ``` **方法二:在 template 上使用 `v-slot`** ```vue ``` **方法三:使用具名插槽** ```vue ```

正文

一、什么是插槽

插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot>  表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>标签,父组件填充的内容称为插槽内容

  • 子组件不提供插槽时,父组件填充失效
  • 父组件无填充时,<slot></slot>中的备用内容会启用生效
  • 父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子作用域中编译的,互不影响

二、匿名插槽(默认插槽)

介绍

在外部组件没有提供任何内容的情况下,可以使用匿名插槽提供默认内容。

使用场景

比如
MyComponent.vue

<n-el>
    <slot>这是一个默认展示的内容</slot>
</n-el>

//组件使用
<MyComponent/>

如下:

image.png

如果外部组件提供了插槽内容,我们提供的内容会覆盖掉默认的内容

如下:

<MyComponent>加入一段文字</MyComponent>

image.png

注: 插槽内容可以是任意合法的模板内容,不局限于文本。

如下:

<MyComponent>
  <n-button>加入一个按钮</n-button>
</MyComponent>

image.png

三、具名插槽

介绍

<slot>元素带有 name 属性的插槽被称为具名插槽。

使用场景

作用于一个组件中拥有多个插槽,而name相当于插槽的标识,用来给各个插槽分配唯一的 ID。

MyComponent.vue

<n-el class="flex flex-col justify-center items-center h-[80vh] w-full">
  <n-el class="text-[pink] text-[18px] mb-2">组件相关内容</n-el>
  <slot name="head"></slot>
  <slot name="main"></slot>
  <slot name="footer"></slot>
</n-el>

外部引用该组件

<MyComponent>
  <template v-slot:head>
    <n-el>这是头部内容</n-el>
  </template>
  <template v-slot:main>
    <n-el>这是主体内容</n-el>
  </template>
  <template v-slot:footer>
    <n-el>这是尾部内容</n-el>
  </template>
  <template v-slot:no>
    <n-el>组件中没有可匹配的插槽name,不显示</n-el>
  </template>
</MyComponent>

v-slot可以简写成#

    <MyComponent>
      <template #head>
        <n-el>这是头部内容</n-el>
      </template>
      <template #main>
        <n-el>这是主体内容</n-el>
      </template>
      <template #footer>
        <n-el>这是尾部内容</n-el>
      </template>
      <template #no>
        <n-el>组件中没有可匹配的插槽name,不显示</n-el>
      </template>
    </MyComponent>

现在  <template>  元素中的所有内容都将被传递到相应的插槽。

image.png

image.png

注意: 匿名插槽也有自己的name,只不过 name 会被隐式地命名为default

image.png

上面的写法等价于:

image.png

image.png

四、动态插槽名

<MyComponent>
  <template v-slot:[slotName]>
    ...
  </template>

  <!-- 缩写为 -->
  <template #[slotName]>
    ...
  </template>
</MyComponent>

如下
MyComponent.vue

<n-el>
  <n-el>组件相关内容</n-el>
  <slot name="head"></slot>
</n-el>
<script setup lang="ts">
  const data = 'head'
</script>
<template>
    ......
    <MyComponent>
      <template #[data]> 头部内容 </template>
    </MyComponent>
    .......
</template>

image.png

五、作用域插槽

介绍

作用域插槽可以让父级外层组件能够访问子组件的数据,子组件向将数据提供给插槽,组件 props 传递数据的方式,子组件向插槽传递一个attributes,父组件通过v-slot带的值(任意命名)来获取子组件的数据。

使用场景

(一)、默认插槽

MyComponent.vue

<n-el class="flex flex-col justify-center items-center h-[80vh] w-full">
  <slot content="螺蛳粉" data="10"></slot>
</n-el>

写法一: v-slot 写在组件上

   <MyComponent v-slot="res">
      <n-el>老板:来 {{ res.data }} 份 {{ res.content }} ~</n-el>
    </MyComponent>

image.png

注意: v-slot="res"  可以类比这里的函数签名,和函数的参数类似,我们也可以在  v-slot  中使用解构:

<MyComponent v-slot="{ data, content }">
  <n-el>
    老板:来 {{ data }} 份 {{ content }} ~
  </n-el>
</MyComponent>

写法二: v-slot 写在 template 上

   <MyComponent>
      <template v-slot:default="res">
        <n-el>老板:来 {{ res.data }} 份 {{ res.content }} ~</n-el>
      </template>

      //或者
      <template #default="res">
        <n-el>老板:来 {{ res.data }} 份 {{ res.content }} ~</n-el>
      </template>

    </MyComponent>

(二)、具名插槽

具名作用域插槽的工作方式也是类似的,插槽 props 可以作为  v-slot  指令的值被访问到:v-slot:name="slotProps"。当使用缩写时是这样:

MyComponent.vue

<n-el class="flex flex-col justify-center items-center h-[80vh] w-full">
  <slot content="北京烤鸭" data="5" name="food1"></slot>
  <slot content="长沙臭豆腐" data="15" name="food2"></slot>
</n-el>
   <MyComponent>
      <template #food1="res">
        <n-el>老板:来 {{ res.data }} 份 {{ res.content }} ~</n-el>
      </template>
      <template #food2="res">
        <n-el>老板:来 {{ res.data }} 份 {{ res.content }} ~</n-el>
      </template>
    </MyComponent>

image.png

与vue3 | slots相似的内容:

vue3 | slots

一、什么是插槽 插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签,父组件填充的内容称为插槽内容。 子组件不提供插槽时,父组件填充失效 父组件无填充

vue3 | isRef、unref、toRef、toRefs

isRef 检查某个值是否是ref。是返回true,否则返回false。 const num = ref(10); const num1 = 20; const num2 = reactive({ data: 30 }); console.log(isRef(num)); //true consol

vue3 | shallowReactive 、shallowRef、triggerRef

shallowReactive 使用 reactive 声明的变量为递归监听,使用 shallowReactive 声明的变量为非递归监听(通俗的讲就是 reactive 创建的对象将会被 vue 内部进行递归监听,可以监听到对象中的对象是否发生了改变从而更新视图,而 shallowReactive

vue3 | readonly、shallowReadonly

readonly 接受一个对象(不管是响应式还是普通的)或者是一个ref,返回的是一个原值的只读代理。 {{ data }}<

vue3 | mitt的基本使用

# 一、安装 npm安装 ``` npm i mitt ``` pnpm安装 ``` pnpm i mitt ``` yarn安装 ``` yarn add mitt ``` # 二、使用 ## (一)、当前组件内使用 ```javascript import mitt from 'mitt' //

vue3 | defineExpose的使用

简介 使用

uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天语音/朋友圈

原创研发uniapp+vue3+pinia2跨三端仿微信app聊天模板Uniapp-Wechat。 uni-vue3-wchat基于uni-app+vue3+pinia2+uni-ui+uv-ui等技术跨端仿制微信App界面聊天项目,支持编译到H5+小程序端+App端。实现编辑框多行消息/emoj混

Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序

基于electron31+vite5+pinia2跨端仿微信Exe聊天应用ViteElectronChat。 electron31-vite5-chat原创研发vite5+electron31+pinia2+element-plus跨平台实战仿微信客户端聊天应用。实现了聊天、联系人、收藏、朋友圈/短

vue3 + mark.js | 实现文字标注功能

页面效果 具体实现 新增 1、监听鼠标抬起事件,通过window.getSelection()方法获取鼠标用户选择的文本范围或光标的当前位置。 2、通过 选中的文字长度是否大于0或window.getSelection().isCollapsed (返回一个布尔值用于描述选区的起始点和终止点是否位于

Vite-Wechat网页聊天室|vite5.x+vue3+pinia+element-plus仿微信客户端

基于Vue3+Pinia+ElementPlus仿微信网页聊天模板Vite5-Vue3-Wechat。 vite-wechat使用最新前端技术vite5+vue3+vue-router@4+pinia+element-plus搭建网页端仿微信界面聊天系统。包含了聊天、通讯录、朋友圈、短视频、我的等功