自定义指令和插槽

169 阅读2分钟

自定义指令

基本语法

image-20240131201111537.png

全局注册指令

import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = false
//全局注册指令
Vue.directive('focus',{
  //inserted会在指令所在的元素,被插入到页面中时触发
  inserted(el){
    //el就是元素所绑定的元素
    el.focus()
​
  }
})
new Vue({
  render: h => h(App),
}).$mount('#app')
​
<template>
<div>
    <h1>自定义属性</h1>
    <input v-focus ref="inp" type="text">
</div>
</template><script>
export default {
mounted(){
  this.$refs.inp>focus()
}
}
</script><style></style>

局部注册指令

<template>
<div>
    <h1>自定义属性</h1>
    <input v-focus ref="inp" type="text">
</div>
</template><script>
export default {
// mounted(){
//   this.$refs.inp>focus()
// }
directives:{
  focus:{
    inserted(el){
      el.focus()
    }
  }
}
}
</script><style></style>

指令的值

image-20240131201111537.png ​ ​

v-loading指令封装

image-20240201152628123.png

1.准备一个loading类,通过伪元素定位,设置宽高,实现蒙层

.loading:before{
    content:'';
    position:absolute;
    left:0;
    top:0;
    width100%;
    height100%;
    background:#fff url();
    
}

2.开启关闭loading状态

directive:{
    loading:{
        inserted(el,binding){
            binding.value?el.classList.add('loading'):el.classList.remove('loading'),
        }
    }
}

3.结合自定义语法进行封装复用

插槽

作用:让组件内部的一些结构支持自定义

默认插槽

image-20240201183717295.png

image-20240201185843661.png

后备插槽

image-20240201190231995.png solt标签中默认为默认内容,若在外部传东西后会被自动代替掉

具名插槽

image-20240201192831809.png

APP

<template>
  <div>
    <!-- 需要通过templte标签包裹 -->
    <MyDialog>
      <template v-slot:head>
        <div>我是大标题</div>
      </template>
      <div>我是大标题</div>
    </MyDialog>
  </div>
</template><script>
import MyDialog from'./component/MyDialog.vue'
export default {
  data(){
    return{
​
    }
  },
  components:{
    MyDialog
  }
​
}
</script><style></style>
<template>
  <div class="dialog">
    <div class="dialog-header">
        <!-- 一旦插槽取了名字,就是具名插槽,只支持定向分发 -->
      <solt name="head"></solt>
    </div>
    <div class="dialog-content">
      <solt name="content"></solt>
    </div>
    <div class="dialog-footer">
      <button>取消</button>
      <button>确认</button>
    </div>
  </div>
</template><script>
export default {};
</script><style>
</style>

作用域插槽

image-20240201195251861.png

image-20240201195355534.png

<template>
  <div>
    <MyTable :data="list"></MyTable>
    <!-- 通过template #插槽名=“变量名” 接收 -->
    <template #default="obj">
      {{ obj }}
      <button @click="del(obj.row.id)">
        删除
      </button>
    </template>
  </div>
</template><script>
import MyTable from "./component/MyTable.vue";
export default {
  data() {
    return {
      list: [
        { id: 1, name: "张小花", age: 18 },
        { id: 2, name: "张小", age: 19 },
        { id: 3, name: "张花", age: 17 },
      ],
      list2: [
        { id: 1, name: "赵小云", age: 18 },
        { id: 2, name: "赵小", age: 19 },
        { id: 3, name: "赵云", age: 15 },
      ],
    }
  },
  methods:{
    del(id){
      this.list=this.list.filter(item=>item.id!==id)
​
    }
  },
  components:{
    MyTable
  }
};
</script><style>
</style>
<template>
  <table class="my-table">
    <thead>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>年纪</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item,index) in data" :key="item.id">
        <td>{{index +1}}</td>
        <td>{{item.name}}</td>
        <td>{{item.age}}</td>
        <td>
          <!-- 给slot标签,添加属性的方式传值 -->
          <slot :row="item" msg="测试文本"></slot>
          <!-- 将所有的属性,添加到一个对象 -->
        </td>
      </tr>
      <tr>
        <td>1</td>
        <td>小米</td>
        <td>8</td>
      </tr>
    </tbody>
  </table>
</template><script>
export default {
  props:{
    data:Array
  }
};
</script><style>
</style>