首页 > 其他分享 >Vue笔记 - 插槽(slot) 详解

Vue笔记 - 插槽(slot) 详解

时间:2022-11-21 03:11:06浏览次数:40  
标签:slot Category Vue name 插槽 user 组件

插槽

目录

注意:本篇笔记为方便兼容Vue3,均采用了比较新的v-slot写法,而未采用老式的slot和slot-scope

  • 插槽(slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽,可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

  • 插槽常用于父组件向子组件指定位置插入html结构,也是一种组件间通信方式,适用于父组件→子组件

  • $slots是组件插槽集,是组件所有默认插槽、具名插槽的集合,可以用来获取当前组件的插槽集

1. 默认插槽

  • 父组件:

    <template>
    	<div class="container">
            <!--默认插槽-->
            <!--写在标签上的是父组件以props形式向子组件传递的属性,与插槽无关-->
            <Category title="美食" :listDate="foods">
                <!--希望向子组件中插入的内容-->
        		<img src="img1.jpg">
        	</Category>
        </div>
    </template>
    
    <script>
    	import Category from './components/Category'
        export default{
            name:'App',
            components:{Category}
        }
    </script>
    
  • 子组件:

    <template>
    	<div class="category">
            <slot></slot>
        </div>
    </template>
    <script>
        export default{
            name:'Category'
        }
    </script>
    
  • 解析:

    在父组件调用 子组件Category 时,额外附加了一段代码<img src="img1.jpg">。添加这段代码后,vue会在Category中自动寻找可以插入的地方。

    若Category中定义了插槽<slot></slot>,则这段代码会被替换为<img src="img1.jpg">;若没有,则父组件传入的代码会被自动抛弃

    如果在<slot></slot>之间写入代码,则该段代码将会作为后备内容。即,若父组件没有传入附加代码,该段代码会作为默认值自动渲染

  • 注意:

    • 若父组件需要传入不同的代码,并在子组件不同地方渲染,默认插槽会失效,此时需使用具名插槽

    • 默认插槽是特殊的具名插槽,它具有隐藏的name="default"

    • 默认插槽无法让父组件获取子组件中的变量和值

      <navigation-link url="/profile">
        Logged in as {{ user.name }}
      </navigation-link>
      

      此处user.name在子组件中为undefined。因为插槽会先渲染然后再传递到子组件中,而user.name在父组件中不存在,即便子组件中具有user.name,也不会获取到该变量

      如果要让父组件获取子组件中的变量和值,可以使用作用域插槽

2. 具名插槽

有时候会同时需要多个插槽,并将其渲染到不同的位置上,此时就需要使用具名插槽

  • 父组件:

    <template>
    	<div class="container">
            
            <Category title="美食" :listDate="foods">
                <!--添加名称-->
                <template v-slot:center>
        			<img src="img1.jpg">
      			</template>
                <!--添加名称-->
    			<template v-slot:footer>
        			<a href="www.baidu.com">百度</a>
      			</template>
        	</Category>
            
        </div>
    </template>
    
    <script>
    	import Category from './components/Category'
        export default{
            name:'App',
            components:{Category}
        }
    </script>
    
  • 子组件:

    <template>
    	<div class="category">
            <!--指定名称-->
            <slot name="center"></slot>
            <!--指定名称-->
            <slot name="footer"></slot>
        </div>
    </template>
    <script>
        export default{
            name:'Category'
        }
    </script>
    
  • 解析:指定的代码会渲染到对应名称的slot上

3. 作用域插槽

当数据在组件的自身,而根据数据生成的结构需要组件的使用者来决定时,就要用作用域插槽

假设子组件<current-user>具有user对象数据,此时有如下代码

  • 父组件:

    <current-user>
      {{ user.firstName }}
    </current-user>
    
  • 子组件:

    <span>
      <slot></slot>
    </span>
    

以上代码不会正常工作,因为只有 <current-user> 组件可以访问到 user,而提供的内容是在父级渲染的

此时需要使用作用域插槽

  • 父组件:

    <current-user>
        <template v-slot:default="ScopeData">
    		{{ ScopeData.user.firstName }}
        </template>
    </current-user>
    
    
  • 子组件:

    <span>
      <slot :user="user"></slot>
    </span>
    
  • 解析:

    仔细看看和普通插槽相比,父子组件在使用作用域插槽时分别产生了哪些改变:

    • 父组件

      传统的v-slot:default后添加了="slotScope"

      而这个"slotScope"在插入内容中,用{{ ScopeData.user.firstName }}替代了 {{ user.firstName }}

    • 子组件

      子组件额外添加了一个:user="user"

    • 原理

      实际上在这里,父组件对子组件进行了一次传参,只不过传参与参数的接受仅仅局限于插槽之间

      绑定在 <slot> 元素上的 attribute 被称为插槽 prop,而在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps

      也就是说,子组件用:user="user"user对象绑定在了slotProps上,然后传递了过去,父组件则用slotProps.user.firstName的方式接收到了。

      注意,这并不意味着作用域插槽可以用于子组件→父组件传递数据,实际逻辑为父组件→(需求子组件数据)→(发送请求)→(子组件绑定数据传输到父组件)→(父组件渲染)→(插入到子组件)→子组件。整体仍然是父组件传递数据到子组件

标签:slot,Category,Vue,name,插槽,user,组件
From: https://www.cnblogs.com/Solitary-Rhyme/p/16910208.html

相关文章

  • Vue笔记 - 计算属性(computed)和监视属性(watch)
    计算属性和监视属性目录计算属性和监视属性1.计算属性2.监视属性2.1深度监视3.computed和watch对比1.计算属性定义:使用的属性起初并不存在,要通过已有属性计算得......
  • VueRouter笔记 - 路由传参中query和params的区别
    query和params的区别目录query和params的区别1.书写方式不同2.对path的支持3.url的显示与参数保存1.书写方式不同query<router-link:to="{name:'thisIsAName'......
  • 局部按照vue-cli,实现版本切换
    项目搭建npminit-y#初始化项目依赖文件cnpmi-D@vue/cli#安装脚手架npxvue-V#查看vue-cli版本号npxvuecreateproject-one#创建项目#ornpxv项目启动......
  • vue中控制组件过渡动画
     基本用法首先先要给组件添加自定义名字<button@click="show=!show">Toggle</button><Transitionname="自定义名称"> <pv-if="show">hello</p></Transition>......
  • vue-router全局导航守卫
    实现组件跳转时,浏览器标题更新①router的index.js文件中routes配置添加meta属性 ②router.beforeEach方法importVuefrom'vue'importVueRouterfrom'vue-rout......
  • Vue3 reactive 之源码的实现
    Reflect.get()方法与从对象(target[propertyKey])中读取属性类似,但它是通过一个函数执行来操作的。exportconstreactive=<Textendsobject>(target:T)=>{......
  • Vue3组件Props属性名不能与Setup()中变量名不可重复
    npmrunlint,显示错误点:30:9   error Gettingavaluefromthe`props`inrootscopeof`setup()`willcausethevaluetolosereactivity vue/no-setup-pr......
  • Vue
    1、Vue是一套前端框架,免除原生JavaScript的DOM操作,简化书写。2、基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上。3、官网:https://cn.vue......
  • Vue笔记 - 样式穿透原理及使用方法
    样式穿透目录样式穿透1.为什么需要样式穿透1.1为什么样式会失效2.如何使用样式穿透2.1实例1.为什么需要样式穿透在开发中引入了第三方组件库(如element-ui),但又想......
  • vue组件中插入二维码的操作
    vue组件中插入二维码的操作 引入在public/index.html的head标签中引入:<scriptsrc="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>......