1. 困难
1.1 树组件
在这个挑战中,你需要实现一个树组件,让我们开始吧。
<script setup lang="ts"> interface TreeData { key: string; title: string; children: TreeData[]; } defineProps<{ data: TreeData[] }>(); </script>
<template> <ul> <li :key="item.key" v-for="item in data"> <span>{{ item.title }}</span> <TreeComponent :data="item.children" v-if="item.children && item.children.length" /> </li> </ul> </template>
|
1.2 自定义元素
你听说过 Web Components 吗 ?Vue 能很好地解析和创建 Web Components 。在这个挑战中,我们将尝试了解它,让我们开始吧 👇:
<script setup lang="ts"> import { onMounted, defineCustomElement } from "vue";
const VueJs = defineCustomElement({ props: { message: { type: String, default: "", }, }, template: "<span>{{ message }}</span>", }); 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>
|
1.3 自定义 ref
防抖函数在输入框操作场景中非常有用。一个防抖的 ref 在 Vue.js 更加灵活,让我们开始吧 👇:
<script setup> import { customRef, watch } from "vue";
function useDebouncedRef(value, delay = 200) { let timeoutId;
return customRef((track, trigger) => { return { get() { track(); return value; }, set(newValue) { clearTimeout(timeoutId);
timeoutId = setTimeout(() => { value = newValue; trigger(); }, delay); }, }; }); } const text = useDebouncedRef("hello");
watch(text, (value) => { console.log(value); }); </script>
<template> <input v-model="text" /> </template>
|
1.4 激活的样式-指令
在这个挑战中,我们将实现一个"激活的样式"指令,让我们开始吧 👇:
<script setup lang="ts"> import { ref, watchEffect } from "vue";
const VActiveStyle = { mounted(el, binding) { const [activeStyle, isActive] = binding.value; watchEffect(() => { for (const key in activeStyle) { el.style[key] = isActive() ? activeStyle[key] : ""; } }); }, };
const list = [1, 2, 3, 4, 5, 6, 7, 8]; const activeTab = ref(0); function toggleTab(index: number) { 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>
|
1.5 实现简易版v-model
指令
在这个挑战中,我们将尝试实现一个简单的 v-model 指令,让我们开始吧 👇:
<script setup lang="ts"> import { ref } from "vue";
const VOhModel = { mounted(el: HTMLInputElement, binding: Ref<string>) { el.value = binding.value;
el.addEventListener("input", (e) => { value.value = e.target.value; }); }, };
const value = ref("Hello Vue.js"); </script>
<template> <input v-oh-model="value" type="text" /> <p>{{ value }}</p> </template>
|