尝试用自定义指令实现以下方法
一. 首先显示模板
<template> <div class="navBar" > <div @click="changeIndex(index)" v-for="(item, index) in list" :class="['item']">{{ item }}</div> </div> </template> <script setup> import { reactive, toRefs, toRef } from "vue"; let state = reactive({ curIndex: 0, list: ['选项1', '选项2', '选项3', '选项4' ] }) let { list } = toRefs(state) let curIndex = toRef(state, 'curIndex') let changeIndex = (index) => { //点击改变当前下标 curIndex.value = index } </script> <style> .navBar { margin: 0 auto; width: 400px; height: 100px; display: flex; } .item { width: 100px; border: 1px solid red; line-height: 100px; text-align: center; } .active { background-color: pink; } </style>
复制
二.用插件的形式准备注册一个自定义指令
参考文档:插件 | Vue.js
他会执行install方式,把app实例传进来,这时候可以在app上挂载一些实例了,这时候顺便在main.js中注册先
三.注册一个全局自定义指令
参考文档:自定义指令 | Vue.js
export default { install(app) { app.directive('clickAndAddClass', { }) } }
复制
添加上代码
export default { install(app) { app.directive('clickAndAddClass', { mounted(el, binding) { //拿到自定义指令传过来的配置项 const option = binding.value //拿到child const child = el.getElementsByClassName(option.className) //点击谁,就把最新的下标传进来,并且添加上active类名 child[option.curIndex].className += ` ${option.avtiveClass}` }, // 在绑定元素的父组件 // 及他自己的所有子节点都更新后调用 updated(el, binding) { const option = binding.value //获取旧的配置项 const oldOption = binding.oldValue const child = el.getElementsByClassName(option.className) //把上一个item的类名还原 child[oldOption.curIndex].className = oldOption.className //再把新的item添加上active,记得别忘了不加空格 child[option.curIndex].className += ` ${option.avtiveClass}` }, }) } }
复制
四.传入自定义指令的配置项
<template> <div class="navBar" v-clickAndAddClass="{ curIndex, avtiveClass: 'active', className: 'item' }"> <div @click="changeIndex(index)" v-for="(item, index) in list" :class="['item']">{{ item }}</div> </div> </template>
复制
搞定