8. Vue可复用解决方案
Vue可复用方案是指在Vue.js项目中,通过创建可复用的组件、指令、插件等,来提高代码的复用性和可维护性常见的Vue可复用方案有:组件(Components)、指令(Directives)、插件(Plugins)、混入(Mixins)、高阶组件(Higher-Order Components, HOC)等。通过这些可复用方案,可以有效地减少代码重复,提高开发效率和代码质量。
8.1 自定义指令
自定义指令是Vue.js中一种强大的功能,允许你在DOM元素上绑定特定的行为。通过自定义指令,你可以封装复杂的DOM操作逻辑,并在多个组件中复用。
以下是如何创建自定义指令的详细步骤:
自定义指令可以包含几个钩子函数,例如 bind
、inserted
、update
、componentUpdated
和 unbind
。每个钩子函数都有其特定的用途。
钩子函数
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
- update:所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。
- componentUpdated:指令所在组件的VNode及其子VNode全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
8.1.1 全局指令
<body><div id="app"><div v-date></div><p v-date></p></div><script src="../js/vue3.js"></script><script>let app = Vue.createApp({})// 自定义指令,directive('指令名', {指令的内容})app.directive('date', {// 指令的定义,mounted会返回一个dom对象,el是指令所在的元素mounted(el) {el.innerHTML = new Date()}})app.mount('#app')</script>
</body>
8.1.2 局部指令
<body><div id="app"><div v-date></div><p v-date></p></div><script src="../js/vue3.js"></script><script>let app = Vue.createApp({directives: {date: {mounted(el) {el.innerHTML = new Date()}}}}).mount('#app')</script>
</body>
也可以这么写:
<body><div id="app"><div v-date></div><p v-date></p></div><script src="../js/vue3.js"></script><script>const mydirective = {date: {mounted(el) {el.innerHTML = new Date()}}}let app = Vue.createApp({directives: mydirective}).mount('#app')</script>
</body>
8.1.3 指令参数
<body><div id="app"><img src="../img/jy.jpg" v-imgcir="300"></div><script src="../js/vue3.js"></script><script>const mydirective = {imgcir: {mounted(el,binding) {el.style.width = binding.value + 'px'el.style.height = binding.value + 'px'el.style.borderRadius = (binding.value/2) + 'px'}}}let app = Vue.createApp({directives:mydirective}).mount('#app')</script>
</body>
8.2 Mixin混入
Mixin混入(Mixin Mixins)是一种编程模式,主要用于在面向对象编程中,通过将一个或多个类的功能“混入”到另一个类中,从而实现代码的复用和功能的扩展。Mixin类通常不单独实例化,而是作为其他类的组成部分,为其提供特定的行为或属性。
Mixin混入的主要特点包括:
- 代码复用:Mixin类可以包含一些通用的方法或属性,这些方法或属性可以被多个类共享,从而减少代码重复。
- 灵活性:通过Mixin混入,可以在不修改原有类结构的情况下,为类添加新的功能。
- 多重继承:在支持多重继承的语言中,Mixin类可以被多个类继承,从而实现复杂的功能组合。
8.2.1 基本用法
<body><div id="app">{{ num }}{{ name }}{{ date }}</div><script src="../js/vue3.js"></script><script>const common = {data() {return {name: '张三'}}}const date = {data() {return {date: new Date()}}}let app = Vue.createApp({data() {return {num: 100}},mixins: [common, date]}).mount('#app')</script>
</body>
8.2.2 混入优先级
Vue中Mixin混入的优先级规则如下:
- 数据对象(data):组件自身的数据优先级更高。
- 生命周期钩子函数:Mixin中的钩子函数会在组件自身的钩子函数之前调用。
- 方法(methods)、计算属性(computed)和其他选项:组件自身的定义会覆盖Mixin中的定义。
<body><div id="app">{{ num }}{{ name }}<br><button @click="add">点击</button></div><script src="../js/vue3.js"></script><script>const common = {data() {return {name: '张三',num: 200}},methods: {add() {console.log('这是Mixin混入中的方法');}},created() {console.log('vue实例创建后生命周期函数--Mixin');}}let app = Vue.createApp({data() {return {num: 100}},mixins: [common],methods: {add() {console.log('这是组件中的一个方法');}},created() {console.log('vue实例创建后生命周期函数--组件');}}).mount('#app')</script>
</body>
8.2.3 全局Mixin
<body><div id="app">{{ num }}<button @click="add">点击</button></div><script src="../js/vue3.js"></script><script>let app = Vue.createApp({})app.mixin({data() {return {num: 100}},methods: {add() {console.log('这是Mixin混入中的方法');}},created() {console.log('vue实例创建后生命周期函数--Mixin');}})app.mount('#app')</script>
</body>
8.3 插件
插件(Plugin)是一种扩展Vue功能的方式。插件可以全局地为Vue应用添加一些功能,如添加全局方法或属性、添加全局资源(指令、过滤器、过渡等)、通过全局混入(Mixin)添加一些组件选项,或者向Vue实例添加实例方法。
8.3.1 基本用法
<body><div id="app"></div><script src="../js/vue3.js"></script><script>// 插件声明有两种方式// 1、对象形式/*const MyPlugin = {// app:将使用插件的Vue实例通过app参数传入;options:参数install(app, options) {console.log('hello world');console.log(app);console.log(options);}}*/// 2、函数形式const MyPlugin = (app, options) => {console.log('hello world');console.log(app);console.log(options);}let app = Vue.createApp({})app.use(MyPlugin, { name:'张三' })app.mount('#app')</script>
</body>
8.3.2 给Vue扩展功能
<body><div id="app"><img src="../img/jy.jpg" v-imgcir="300">{{ date }}</div><script src="../js/vue3.js"></script><script>const MyPlugin = {install(app, options) {app.directive('imgcir', {mounted(el, binding) {el.style.width = binding.value + 'px'el.style.height = binding.value + 'px'el.style.borderRadius = (binding.value / 2) + 'px'}})app.mixin({data() {return {date: new Date()}}})}}let app = Vue.createApp({})app.use(MyPlugin)app.mount('#app')</script>
</body>