逻辑复用

67 阅读2分钟

1. 组合式函数

组合式函数

组合式函数式一个利用vue组合式API来封装和复用的,有状态逻辑的函数

使用

// useFetch.js
import { ref } from 'vue'
import axios from 'axios'

export function useFetch(url) {
    const data = ref(null)
    const error = ref(null)

    axios.get(url)
        .then(res => {
            console.log(res);
            data.value = res.data;
        })
        .catch((e) => {
            error.value = e
        })
    return { data, error }
}
<script setup>
import { ref } from 'vue'
import { useFetch } from './useFetch'

const url = 'http://jsonplaceholder.typicode.com/todos/1'
const { data, error } = useFetch(url)
</script>

<template>
    <div>组合式API</div>
    <div v-if="error">{{error}}</div>
    <div v-else-if="data">{{data}}</div>
    <div v-else>loading</div>
</template>

组合式函数的优点

  • 代码复用, 功能组合, 代码结构完好
  • 数据来源清晰, 优于mixins

2. 自定义指令

定义

const vFocus = {
    // 在绑定元素的 attribute 前
    // 或事件监听器应用前调用
    created(el, binding, vnode, prevVnode) {
        // 下面会介绍各个参数的细节
        console.log('created', el, binding, vnode, prevVnode);
    },
    // 在元素被插入到 DOM 前调用
    beforeMount(el, binding, vnode, prevVnode) {
        console.log('beforeMount', el, binding, vnode, prevVnode);
    },
    // 在绑定元素的父组件
    // 及他自己的所有子节点都挂载完成后调用
    mounted(el, binding, vnode, prevVnode) {
        console.log('mounted', el, binding, vnode, prevVnode);
        el.focus();
    },
    // 绑定元素的父组件更新前调用
    beforeUpdate(el, binding, vnode, prevVnode) {
        console.log('beforeUpdate', el, binding, vnode, prevVnode);
    },
    // 在绑定元素的父组件
    // 及他自己的所有子节点都更新后调用
    updated(el, binding, vnode, prevVnode) {
        console.log('updated', el, binding, vnode, prevVnode);
    },
    // 绑定元素的父组件卸载前调用
    beforeUnmount(el, binding, vnode, prevVnode) {
        console.log('beforeUnmount', el, binding, vnode, prevVnode);
    },
    // 绑定元素的父组件卸载后调用
    unmounted(el, binding, vnode, prevVnode) {
        console.log('unmounted', el, binding, vnode, prevVnode);
    }
}



template

<input type="text" v-focus>

3. 插件

插件定义

插件是为了给vue提供全局性功能的代码工具. 定义时提供一个install函数

export default {
    install: (app, options) => {
        app.config.globalProperties.$translate = (key) => {
            return key.split('.').reduce((o, i) => {
                if (o) return o[i]
            }, options)
        }
    }
}

使用

<div>plugins, my-i18n: {{$translate('greetings.hello')}}</div>

插件中使用provide和inject

provide注入的资源可以被全局使用

export default {
    install: (app, options) => {
        app.config.globalProperties.$translate = (key) => {
            return key.split('.').reduce((o, i) => {
                if (o) return o[i]
            }, options)
        }

        app.provide('i18n', options);
    }
}

使用

// some child component
<script setup>
import { inject } from 'vue'

const i18n = inject('i18n')
console.log(i18n.greetings);
</script>

插件的其他用途

  1. 通过 app.component() 和 app.directive() 注册一到多个全局组件或自定义指令。

  2. 通过 app.provide() 使一个资源可被注入进整个应用。

  3. 向 app.config.globalProperties 中添加一些全局实例属性或方法