Vue中的插槽和自定义指令

目录

一、插槽

1.默认插槽

2.具名插槽

3.作用域插槽

二、自定义指令

全局注册自定义指令

执行一次性初始化设置

组件vnode更新触发

局部注册自定义指令


一、插槽

父组件传递模板给子组件,子组件使用插槽声明slot元素承载分发内容出口。


1.默认插槽

父组件提供给子组件模板,默认会填充到默认插槽中

slot不设置name会隐式创建一个name为default的插槽

diff 复制代码
<slot name='default'></slot>
2.具名插槽

父组件提供了具体的模板,填充到具名插槽中

指定模板填充到具名插槽中 v-slot绑定具名插槽名称 可以简写为#

diff 复制代码
<template v-slot:header></template>

<slot name='header'></slot>

默认插槽和具名插槽的使用:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <my-child>
      <div>我是父组件提供的模板{{msg}}</div>
      <img width="150px" src="../../Axure/swipe/1.jpeg" alt="">
      <!-- <template v-slot:header> -->
      <template #header>
        <div>
          我是头部的内容
        </div>
      </template>
      <template v-slot:footer>
        <div>
          我是底部的内容
        </div>
      </template>
    </my-child>
  </div>
  <script>
    let myChild = {
      data(){
        return {
          child:'我是子组件',
          user:{
            firstName:'zhao',
            lastName:'terry'
          }
        }
      },
      template:`
        <div>
          {{child}}
          <slot name='default'></slot>  
          <header>
            <slot name='header'></slot>  
          </header>
          <footer>
            <slot name='footer'></slot>  
          </footer>
        </div>
      `
    }
    new Vue({
      el:"#app",
      // 局部注册组件
      components:{
        'my-child':myChild
      },
      data:{
        msg:'hello vue2'
      },
      methods:{

      }
    })
  </script>
</body>
</html>
3.作用域插槽

父组件作用域使用子组件数据

父级作用域模板中获取子组件中数据 子组件向父组件传值 第二种方式

1.在子组件默认插槽中动态绑定插槽prop

diff 复制代码
<slot v-bind:user='user'>

2.在父组件模板中使用v-slot='插槽prop'接收子组件数据

diff 复制代码
<template v-slot='scope'>

{{scope.user.xxxx}}

</template>
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <my-child>
      <template v-slot="scope">
        <div>
          {{scope.user.lastName}}
        </div>
      </template>
    </my-child>
  </div>
  <script>
    /**
     * 作用域插槽:
     *  父级作用域模板中获取子组件中数据 子组件向父组件传值 第二种方式
     *  1.默认插槽使用v-bind绑定插槽prop
     *  2.在父组件作用域中使用v-slot接收插槽prop
    */
    let myChild = {
      data(){
        return {
          child:'我是子组件',
          user:{
            firstName:'zhao',
            lastName:'terry'
          }
        }
      },
      template:`
        <div>
          {{child}}
          <slot v-bind:user='user'>{{user.firstName}}</slot>
        </div>
      `
    }
    new Vue({
      el:"#app",
      // 局部注册组件
      components:{
        'my-child':myChild
      },
      data:{
        msg:'hello vue2'
      },
      methods:{

      }
    })
  </script>
</body>
</html>

二、自定义指令

v-xxx

全局注册自定义指令
diff 复制代码
Vue.directive('指令名称',{

当被绑定元素插入到父节点调用

inserted(el,binding,vnode,oldNode){

el---->绑定指令dom元素

binding---->元素数据 value

vnode 虚拟节点 dom对象内存中数据表示

},
javascript 复制代码
    // 注册自定义指令
    Vue.directive('focus',{
      // 指令绑定dom元素执行钩子函数 调用一次
      bind(el,binding,vnode){
        console.log(el,binding);
        el.style.backgroundColor = binding.value;
      },
      // 当被绑定元素插入到父节点中
      inserted(el,binding,vnode){
        // console.log(el,binding,vnode,'2222');
        el.focus();
      }
    })
执行一次性初始化设置
diff 复制代码
bind(el,binding,vnode,oldNode){

}
组件vnode更新触发
diff 复制代码
update(el,binding,vnode,oldNode){

}

})
局部注册自定义指令
javascript 复制代码
      // 局部注册自定义指令
      directives:{
        myshow:{
          inserted(){

          },
          bind(el,binding){
            el.innerHTML = binding.value;
          },
          // 指令所在组件更新vnode调用
          update(el,binding,vnode){
            console.log(el,binding,vnode,'4444');
            el.innerHTML = binding.value;
          }
        }
      },
相关推荐
kyriewen2 分钟前
Next.js部署:从本地跑得欢,到线上飞得稳
前端·react.js·next.js
Moment6 分钟前
面试官:给 llm 传递上下文,有哪几个身份 role ❓❓❓
前端·后端·面试
跨境数据猎手16 分钟前
跨境独立站系统技术拆解(附带源码)
服务器·前端·php
豹哥学前端27 分钟前
用猜数字游戏,一口气掌握 JavaScript 核心知识点(附完整代码)
前端·javascript
忆往wu前1 小时前
从0到1一步步拆解搭建,梳理一个 Vue3 简易图书后台全开发流程
前端·javascript·vue.js
木斯佳1 小时前
前端八股文面经大全:字节抖音前端三面(2026-04-27)·面经深度解析
前端·面试·笔试·八股·面经
shao9185161 小时前
第3章(2)——使用Gradio JavaScript Client
javascript·node.js·cdn·gradio·job·events·playcode
光影少年1 小时前
大屏页面,一次多个请求,请求加密导致 点击 全局时间选择器 时出现卡顿咋解决(面板收起会延迟1~2秒)
前端·javascript·vue.js·学习·前端框架·echarts·reactjs
Mr.mjw2 小时前
vue中封装一个环形进度条组件,根据外部盒子大小自适应变化
前端·javascript·vue.js
无心使然2 小时前
Openlayers调用ArcGis影像服务之一动态地图、地图切片(/exportImage)
前端·javascript·数据可视化