1.自定义指令
之前我们学习了各种指令:v-model、v-for、v-show等,除了这些指令外,Vue允许我们自定义指令。
什么时候使用自定义指令?
需要对DOM元素进行底层操作,这个时候就会用到自定义指令
。
注意:在Vue中,代码的复用和抽象主要还是通过组件。
自定义指令分为两种:
自定义局部指令:组件中通过directives选项
,只能在当前组件中使用。
自定义全局指令:app的directive方法
,可以在任意组件中使用。
案例:某个元素挂载完成后自动获取焦点。
(1)默认实现,不使用自定义指令.
<template><div><input type="text" ref="input"></div>
</template><script>import {ref,onMounted} from "vue";export default {setup() {const input = ref(null)onMounted(() => {input.value.focus();})return {input}}}
</script>
(2)定义局部指令
<input type="text" v-focus>
export default {// 局部指令directives:{focus:{mounted(el){el.focus()}}}}
(3)定义全局指令
在main.js中定义
const app = createApp(App)
// 定义全局指令
app.directive("focus", {mounted(el) {el.focus()}
})app.mount('#app')
2.指令的生命周期
<template><div><button v-if="counter<2" @click="increment" v-phoebe>当前计数{{counter}}</button></div>
</template><script>import { ref } from "vue"export default {setup(){const counter =ref(0)const increment = ()=>counter.value++return {counter,increment}},directives:{phoebe:{created(){console.log("phoebe created")},beforeMount(){console.log("phoebe beforeMount")},mounted(){console.log("phoebe mounted")},beforeUpdate(){console.log("phoebe beforeUpdate")},updated(){console.log("phoebe updated")},beforeUnmount(){console.log("phoebe beforeUnmounted")},unmounted(){console.log("phoebe unmounted")},}}}
</script>
<style>
</style>
时间戳格式化案例
App.vue
<template><div><!-- 可以传进参数,设置时间的格式 --><h2 v-format-time="'YYYY/MM/DD'">{{timestamp}}</h2></div>
</template><script>export default {setup(){const timestamp = 1669456723return {timestamp}}}
</script>
将自定义指令提取出来
format-time.js文件:
// 引入第三方库dayjs
import dayjs from "dayjs"
export default function(app){app.directive("format-time",{mounted(el,bindings){// 获取app.vue传入参数时间的格式let formatString = bindings.value// 如果没有传入使用默认格式if(!formatString){formatString = "YYYY-MM-DD HH-mm-ss"}const textContent =el.textContent// console.log(typeof textContent) //字符串类型// 转换数据类型let timestamp = parseInt(textContent)//如果时间戳是10为,代表为秒钟;统一单位if(textContent.length === 10){timestamp = timestamp * 1000}el.textContent = dayjs(timestamp).format(formatString);// 使用第三方库 dayjs ;npm install dayjs}})
}
index.js
import registerFormatTime from "./format-time.js"
export default function registerDirectives(app) {registerFormatTime(app);
}
在main.js中使用即可,(定义的全局指令)
import registerDirectives from './directives'const app = createApp(App)
registerDirectives(app);
3.认识Teleport
组件化开发中,我们封装一个组件A,在另一个组件B中使用;那么组件A中的template元素会被挂载到组件B中的template的某个位置,最终应用程序会形成一棵DOM树结构.
某些情况下不希望挂载到这个组件树上,可以移动到Vue app之外的其他位置.通过teleport来完成.
Teleport是Vue提供的内置组件
,翻译后有远程传输的意思.
有两个属性:
to: 指定将其中的内容移动到的目标元素,可以使用选择器;
disabled :是否禁用teleport的功能.
在index.html中添加一个div:
<template><div><teleport to="#phoebe"><h2>Hello teleport</h2></teleport></div>
</template>
还可以移动组件
<template><div><teleport to="#phoebe"><h2>Hello teleport</h2><hello-world></hello-world></teleport></div>
</template><script>import HelloWorld from "./HelloWorld.vue"export default{components:{HelloWorld}}
</script>
4.认识Vue插件
向Vue全局添加一些功能时,会采用Vue的插件模式.
两种编写方式:
对象类型
: 一个对象,但是必须要包含一个install的函数
,该函数会在安装插件时执行;
函数类型
: 一个function
,这个函数会在安装插件时自动执行.
插件可以完成的功能没有限制,以下几种都可以:
- 添加全局方法或者property(属性),通过把他们添加到config.globalproperties上实现.
- 添加全局资源 :指令/过滤器/过渡等;
- 通过全局 mixin来添加一些组件选项;
- 一个库,提供自己的API,同时提供上面提到的一个或多个功能.
//创建一个vue插件 对象方式object
export default{install(app){console.log(app)}
}
或者是用函数的方式创建:
//一个函数的方式
export default function(app){console.log(app)
}
在main.js中使用插件:
//引入插件
import plugin from "./plugins/plugins01.js"
const app = createApp(App)
//使用插件
app.use(plugin)