VUE-自定义指令

第一节、概念

<标签  v-xx
v-xx:vue提供了内置指令:v-for、v-if、v-show、v-html....
每一个指令都有自己的功能,实现具体的业务
今后总有一些业务我们通过vue自带的指令是无法实现,那么我们就可以采用自定义指令来实现
所谓的自定义指令本质就是将一段业务封装成一个指令(v-xx)

第二节、分类

1 全局自定义指令(用得较多)

一旦定义后在任意组件中能够使用
js中
import Vue from 'vue'
Vue.directive('自定义指令名字',{功能..})

2 局部自定义指令

只能在当前组件中生效
vue中
  directives:{
    '指令名称1':{
      功能。。。
    }
  }

第三节、自定义指令的三个钩子函数

1  bind(){}  ,只会在初始化时调用一次,当指令绑定到某个元素时生效
2  inserted(){} ,在bind之后执行,当被绑定的元素挂载到页面时才会生效 (可能触发多次)
3  update(){} 元素更新时触发 

第四节、全局自定义指令

demo1:页面上有两个文本框,当页面加载完毕后指定某一个文本框获取焦点

  1. 新建目录和文件:src/directives/index.js
  2. 编辑index.js
import Vue from 'vue'
Vue.directive('getFocus',{
    //参数1:被绑定的原生标签对象
    //参数2:绑定对象.value  获取=后面的值
    inserted(el,binding){
        console.log(el,binding.value);
        //业务 (玩的原生dom方法)
        el.focus()
    }
})
  1. main.js
//自定义指令生效
import '@/directives/index.js'
  1. 把自定义指令绑定到某个标签中
<input type="checkbox"  v-getFocus>

demo2:渲染所有学生的头像,如果某些图片加载失败,则显示默认图

  1. 编辑自定义指令
//让异常图片默认显示
Vue.directive('showIsImgError',{
    //参数1:被绑定的原生标签对象
    //参数2:绑定对象.value  获取=后面的值
    inserted(el,binding){
        // console.log(el,binding.value);
        //业务 (玩的原生dom方法)
        el.onerror=function(){
           el.src=binding.value
        }
    }
})
  1. 编辑vue
<template>
    <div>
  
        <img 
        width="100px" 
        height="100px" 
        v-for="(item,index) in arr"
        :key="index"
        :src="`http://localhost:3000/img/${item}`"
        v-showIsImgError="defaultImg"
        />
    </div>
</template>

<script>
export default {
  data(){
    return{
        arr:[],
        defaultImg:require('@/assets/logo.png')
    }
  },
  async created(){
    let res=await this.$http.stus.getAll()
    console.log(res.result);
    this.arr=res.result.map(item=>item.head)
  }

}
</script>

<style>

</style>

第五节、$nextTick

如果我们需要在元素加载完毕后,操作节点时,需要用到mounted,但是如果节点的内容是异步获取的,那么mount就没意义了,
因为mounted钩子函数是同步代码,同步代码会比异步代码先执行,导致我们在数据返回前就提前操作了,如何解决?
采用 this. n e x t T i c k ( ) , 该 a p i 能够等到全部异步任务都执行完毕后,页面最终挂载完毕后才会执行语法 : t h i s . nextTick() ,该api能够等到全部异步任务都执行完毕后,页面最终挂载完毕后才会执行 语法: this. nextTick(),api能够等到全部异步任务都执行完毕后,页面最终挂载完毕后才会执行语法:this.nextTick(()=>{业务})
注意:该语法必须紧挨着数据变动的后面

<template>
    <div>
          <p id="p">{{name}}</p>
    </div>
</template>

<script>
export default {
  data(){
    return{
        name:""
    }
  },
  created(){
      setTimeout(() => {
          this.name='hello'
          //该语法必须放在赋值数据的后面
          this.$nextTick(()=>{
                console.log(document.getElementById("p").innerHTML);
          })
      },100);
  },
}
</script>

<style>

</style>

虚拟dom概念:

如果我们改变了数据后,vue不会立马渲染,而是异步渲染(中间会等待一定的时间)

第六节、全局注册组件

目前的操作都属于局部注册组件:

1 import 引入组件
2 components注册组件
3 当成标签来使用
  • 局部注册组件的好处
    会随着父组件的销毁而销毁,不会一直占用内存
  • 局部注册组件的坏处
    每次都需要重复注册方可使用

全局组件:

一旦注册完之后,会一直占用内存,以后可以直接把该组件当成标签用于任意组件

全局注册组件的方式:

方式1:直接在main.js中注册

//全局注册组件
import MyTable from '@/globalComponents/MyTable.vue'
Vue.component('globalTable',MyTable)

方式2:直接在main.js中注册

//全局注册组件
import MyTable from '@/globalComponents/MyTable.vue'
Vue.use({
  install:function(){
    Vue.component('globalTable',MyTable);
  }
})

第七节、excel导出

参考:

https://blog.csdn.net/m0_59023970/article/details/123427008

步骤:

  1. 下载插件
npm install vue-json-excel --save
  1. 全局注册组件
import JsonExcel from 'vue-json-excel'
Vue.component('downloadExcel', JsonExcel)
  1. 使用
    <download-excel
      class="export-excel-wrapper"
      :data="DetailsForm"
      :fields="json_fields"
      :header="title"
      name="web89_stu_list.xls"
    >
      <!-- 上面可以自定义自己的样式,还可以引用其他组件button -->
      <el-button type="success">导出</el-button>
    </download-excel>
     //导出excel相关
      DetailsForm: [
        {
          date: "2022-3-10",
          details: "卸油区过路灯损坏",
          measure: "更换灯泡",
          timeLimit: "2022-3-21",
          plan: "先使用充电灯代替,贴好安全提醒告示",
          personInCharge: "王xx",
          preparer: "王xx",
          fund: "20元",
          complete: "已完成整改",
          remark: "重新更换了灯泡",
        },
      ],
       json_fields: {
        "排查日期":'date',
        "整改隐患内容":'details',
        "整改措施":'measure',
        "整改时限":'timeLimit',
        "应急措施和预案":'plan',
        "整改责任人":'personInCharge',
        "填表人":'preparer',
        "整改资金":'fund',
        "整改完成情况":'complete',
        "备注":'remark',
      },
    title: "沙皮狗集团",

作用:点击按钮,导出当前页的学生记录(除了头像都需要导出)

第八节、vue中的过渡动画

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果

在以下情况方可使用动画

  1. 条件渲染(v-if/v-show)
  2. 动态组件

Demo 点击按钮,以动画的形式隐藏显示元素

<template>
    <div>
      <button @click="flag=!flag">点击</button>
      <transition enter-active-class="xx-enter-active" leave-active-class="xx-leave-active">
         <span v-show="flag">沙皮狗</span>
      </transition>
    </div>
</template>

<script>
export default {
  data(){
    return{
      flag:true
    }
  }
}
</script>

<style scoped>
  @keyframes change{
    0%{
        opacity: 0;
    }
    100%{
        opacity: 1;
    }
  }
  .xx-enter-active{
      animation: change 2s 
  }
  .xx-leave-active{
       animation: change 2s  reverse
  }
</style>

Demo 点击按钮,以动画的形式隐藏显示元素 --简化

<template>
    <div>
      <button @click="flag=!flag">点击</button>
      <transition name="xx">
         <span v-show="flag">沙皮狗</span>
      </transition>
    </div>
</template>

<script>
export default {
  data(){
    return{
      flag:true
    }
  }
}
</script>

<style scoped>

  @keyframes change{
    0%{
        opacity: 0;
    }
    100%{
        opacity: 1;
    }
  }
  .xx-enter-active{
      animation: change 2s 
  }
  .xx-leave-active{
       animation: change 2s  reverse
  }
</style>

demo2: 点击按钮以动画的方式来改变内容时

<template>
    <div>
      <button @click="flag=!flag">点击</button>
      <transition name="xx">
         <span v-if="flag" key="1">张三</span>
         <span v-else key="2">李四</span>
      </transition>
     
    </div>
</template>
<script>
export default {
  data(){
    return{
      flag:true
    }
  }
}
</script>

<style scoped>

  @keyframes change{
    0%{
        opacity: 0;
    }
    100%{
        opacity: 1;
    }
  }
  .xx-enter-active{
      animation: change 1s 
  }

  .xx-leave-active{
       animation: change 0s  reverse
  }

</style>

demo3: 列表过度

<template>
  <div>
    <input type="text" v-model="t" @keyup.enter="add" />
    <ul style="margin-left: 80px">
      <transition-group name="xx">
        <li v-for="item in arr" :key="item.id">
          {{ item.title }}
          <button @click="del(item.id)">删除</button>
        </li>
      </transition-group>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      t: "",
      arr: [
        { id: 1, title: "aa" },
        { id: 2, title: "bb" },
        { id: 3, title: "cc" },
      ],
      id: 4,
    };
  },
  methods: {
    add() {
      this.arr.push({
        id: this.id++,
        title: this.t,
      });
    },
    del(id) {
      this.arr = this.arr.filter((item) => item.id != id);
    },
  },
};
</script>
<style scoped>
@keyframes change {
  0% {
    opacity: 0;
    transform: translateX(-80px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}
.xx-enter-active {
  animation: change 1s;
}
.xx-leave-active {
  animation: change 1s reverse;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值