目录
1、自定义切换焦点指令v-focus
原题:
自定义指令:当一个 input 元素被 Vue 插入到 DOM 中后,它会被自动聚焦。
答案:
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。
<script setup>
import { ref } from 'vue'
const state = ref(false)
/**
* 实现一个自定义指令,让元素获取焦点
* 确保当切换`state`时,元素随着状态值获取/失去焦点
*/
const VFocus = {
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(el, binding, vnode, prevVnode) {
console.log(el, binding, vnode, prevVnode)
},
// 在元素被插入到 DOM 前调用
beforeMount(el, binding, vnode, prevVnode) {
console.log('beforeMount')
},
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(el, binding, vnode, prevVnode) {
console.log('mounted')
},
// 绑定元素的父组件更新前调用
beforeUpdate(el, binding, vnode, prevVnode) {
console.log('beforeUpdate')
},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(el, { value }) {
console.log('updated', value)
value ? el.focus() : el.blur()
},
// 绑定元素的父组件卸载前调用
beforeUnmount(el, binding, vnode, prevVnode) {
console.log('beforeUnmount')
},
// 绑定元素的父组件卸载后调用
unmounted(el, binding, vnode, prevVnode) {
console.log('unmounted')
}
}
// Vue3.x不需要这段声明
// const app = createApp({})
// app.directive('focus', VFocus)
setInterval(() => {
state.value = !state.value
}, 2000)
</script>
<template>
<input v-focus="state" type="text" />
</template>
文档:
2、自定义防抖指令 v-debounce-click:ms
原题:
自定义指令:确保在一定时间内当快速点击按钮多次时只触发一次点击事件。
你需要支持防抖延迟时间选项, 用法如 `v-debounce-click:ms`
答案:
函数防抖,在一段连续操作结束后,处理回调,利用
clearTimeout
和setTimeout
实现。函数防抖关注一定时间连续触发的事件只在最后执行一次。
<script setup>
const VDebounceClick = {
mounted(el, { value, arg }) {
const debounce = (fn, delay, ...args) => {
let timer = 0
return () => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, ...args)
}, delay)
}
}
el.addEventListener('click', debounce(value, Number(arg)))
}
}
function onClick() {
console.log('Only triggered once when clicked many times quicky')
}
</script>
<template>
<button v-debounce-click:500="onClick">Click on it many times quickly</button>
</template>
3、自定义节流指令 v-throttle-click:ms
原题:
函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能。
函数节流侧重于一段时间内只执行一次。
答案:
<script setup>
const VThrottleClick = {
mounted(el, { value, arg }) {
const throttle = (fn, delay, ...args) => {
let timer = 0
return () => {
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, ...args)
timer = 0
}, delay)
}
}
el.addEventListener('click', throttle(value, Number(arg)))
}
}
function onClick() {
console.log('Only triggered once when clicked many times quicky')
}
</script>
<template>
<button v-throttle-click:2000="onClick">Click on it many times quickly</button>
</template>
4、函数式组件
原题:
答案:
函数式组件是一种定义自身没有任何状态的组件的方式。
它们很像纯函数:接收 props,返回 vnodes。函数式组件在渲染过程中不会创建组件实例 (也就是说,没有
this
),也不会触发常规的组件生命周期钩子。我们用一个普通的函数而不是一个选项对象来创建函数式组件。该函数实际上就是该组件的渲染函数。
函数式组件可以像普通组件一样被注册和使用。如果你将一个函数作为第一个参数传入
h
,它将会被当作一个函数式组件来对待。
<script setup>
import { ref, h } from 'vue'
/**
* 实现该函数式组件 :
* 1. 使用`list`数据渲染列表元素 (ul/li)
* 2. 当点击列表子元素时,将其文本颜色更改为红色
*/
const ListComponent = (props, { emit }) => {
let content = []
props.list.map((item, index) => {
content.push(
h('li', {
innerText: item.name,
index,
style: props['active-index'] === index ? { color: 'red' } : undefined,
onClick: async () => {
await emit('toggle', index)
}
})
)
})
return h('ul', content)
}
const list = [{name: 'John'}, {name: 'Doe'},{name: 'Smith'}]
const activeIndex = ref(0)
function toggle(index) {
activeIndex.value = index
}
</script>
<template>
<list-component :list="list" :active-index="activeIndex" @toggle="toggle" />
</template>
文档:
5、Vue3 + Vue-cli (1) 基础篇
Vue3 + Vue-cli (1) 基础篇_vue3 vue-cli_小草莓蹦蹦跳的博客-CSDN博客