img

vue3代码笔记

2023-12-08 0条评论 476次阅读 JavaScript


可写的计算属性

<script setup>
// 创建一个响应式变量 count,初始值为 1
const count = ref(2)

// 创建一个计算属性 plusOne,返回 count 的值加 1
const plusOne = computed({
    // get 方法返回 count 的值加 1
    get: () => {
        return count.value + 1
    },
    // set 方法将 count 的值加 1
    set: () => {
        count.value++
    }
})
// 确保 plusOne 可以被写入。
// 最终我们得到的结果应该是 plusOne 等于 3 和 count 等于 2。
plusOne.value++
</script>

<template>
    <div>
        <p>plusOne: {{ plusOne }}</p>
        <p>count: {{ count }}</p>
        <button @click="count++">+</button>
    </div>
</template>

防抖输入框

<script setup>
/**
 * 防抖输入框
 */
function useDebouncedRef(value, delay = 200) {
    let timeout
    return customRef((track, trigger) => {
        return {
            get() {
                track()
                return value
            },
            set(newValue) {
                clearTimeout(timeout)
                timeout = setTimeout(() => {
                    value = newValue
                    trigger()
                }, delay)
            }
        }
    })
}
const text = useDebouncedRef('hello')

/**
 * 确保在输入框快速输入时, 只触发一次回调。
 */
watch(text, value => {
    console.log(value)
})
</script>

<template>
    <input v-model="text" />
</template>

防抖点击指令

<template>
    <button v-debounce-click="onClick">Click on it many times quickly</button>
</template>
<script setup>
// 定义 v-debounce-click 组件
const VDebounceClick = {
    // 当组件创建时,执行以下操作
    created(el, binding) {
        // 从 binding 中获取回调函数
        const { value: callback } = binding
        // 为 button 添加 click 事件监听器
        el.addEventListener('click', deduce(callback))
    }
}
// 定义 deduce 函数
function deduce(fn) {
    let timer = 0

    // 返回一个新的函数,用于处理 click 事件
    return function () {
        // 如果 timer 已被设置,清除之前的定时器
        if (timer) {
            clearTimeout(timer)
        }

        // 设置新的定时器,延迟执行 fn 函数
        timer = setTimeout(fn, 1000)
    }
}
// 定义 onClick 函数
function onClick() {
    console.log('Only triggered once when clicked many times quickly')
}
</script>

激活的样式-指令

<script setup>
/**
 * 实现该指令:
 * 当切换该选项卡时,列表项文本颜色变为红色
 */
const VActiveStyle = {
    mounted: (el, binding) => {
        const style = binding.value[0]
        const fn = binding.value[1]
        watchEffect(() => {
            Object.keys(style).forEach(key => {
                el.style[key] = fn() ? style[key] : ''
            })
        })
    }
}

const list = [1, 2, 3, 4, 5, 6, 7, 8]
const activeTab = ref(0)
function toggleTab(index) {
    activeTab.value = index
}
</script>

<template>
    <ul>
        <li v-for="(item, index) in list" :key="index" v-active-style="[{ color: 'red' }, () => activeTab === index]" @click="toggleTab(index)">
            {{ item }}
        </li>
    </ul>
</template>

自定义元素

<script setup>
import { onMounted, defineCustomElement, h } from 'vue'

/**
 * 实现以下代码创建一个自定义元素.
 *  确保页面输出 "Hello Vue.js".
 */
const VueJs = defineCustomElement({
    props: {
        message: String
    },
    render() {
        return h('div', null, this.message)
    }
})
customElements.define('vue-js', VueJs)
onMounted(() => {
    document.getElementById('app').innerHTML = '<vue-js message="Hello Vue.js"></vue-js>'
})
</script>
<template>
    <div id="app"></div>
</template>
<script setup>
import { onMounted, defineCustomElement, h } from 'vue'

/**
 * 实现以下代码创建一个自定义元素.
 *  确保页面输出 "Hello Vue.js".
 */
const VueJs = defineCustomElement({
    props: {
        message: String
    },
    render() {
        return h('div', null, this.message)
    }
})
customElements.define('vue-js', VueJs)
onMounted(() => {
    document.getElementById('testApp').innerHTML = '<vue-js message="Hello Vue.js"></vue-js>'
})
</script>
<template>
    <div id="testApp"></div>
</template>
🏷️ #vue3#setup

💬 COMMENT


🦄 支持markdown语法

👋友