Vue 高频 API 下

103 阅读8分钟

指令

  • 在 Vue.js 中,指令(Directives)是一种特殊的语法,用于为 HTML 元素添加特定的行为和功能。指令以 v- 作为前缀,通过在 HTML 标签中使用这些指令来操作 DOM,修改元素的属性、样式或行为。
  • Vue.js 提供了一组内置的指令,如 v-model、v-bind、v-if、v-for 等。此外,你也可以自定义指令来满足特定的需求。

常见指令

  1. v-model
    • 用于实现表单元素与 Vue 实例数据的双向绑定。
  2. v-bind
    • 用于动态地将 Vue 实例的数据绑定到 HTML 元素的属性或表达式。
  3. v-if / v-else / v-else-if
    • 根据条件控制元素的显示与隐藏。
  4. v-for
    • 用于根据数据源循环渲染元素列表。
  5. v-on / @
    • 用于监听 DOM 事件,并在触发时执行 Vue 实例中的方法。
  6. v-show
    • 根据条件控制元素的显示与隐藏,通过修改元素的 CSS 属性 display。
  7. v-text
    • 将 Vue 实例的数据绑定到元素的文本内容。
  8. v-html
    • 将 Vue 实例的数据作为 HTML 内容动态渲染到元素中

v-model

1. 概念
  • v-model 指令在 Vue.js 中用于实现表单元素与 Vue 实例数据的双向绑定。当使用 v-model 指令绑定一个表单元素时,它会在底层自动为元素添加一个 value 属性和一个 input 事件监听器
2. 绑定过程
  • 对于表单元素(如<input>、<textarea>、<select>),v-model 会将 value 属性与 Vue 实例中的一个数据属性进行绑定。
  • 在初始化时,Vue 会根据 v-model 指令的绑定值(通常是 Vue 实例的一个属性)将表单元素的初始值赋给该属性。
  • 当用户与绑定了 v-model 的表单元素进行交互(输入、选择等)时,元素的 input 事件会被触发。
  • Vue 会捕获到该事件,并根据表单元素的类型(<input>的 type 属性)来获取新的值。
  • Vue 会将新的值赋给绑定的数据属性,实现从表单元素到 Vue 实例数据的单向绑定。
  • 同时,Vue 会将绑定的数据属性的值反过来赋给表单元素的 value 属性,实现从 Vue 实例数据到表单元素的单向绑定。
  • 这样,无论是表单元素的值变化还是 Vue 实例数据的变化,都会相互影响,实现了双向绑定
3. 示例
```vue
<template>
    <div>
        <div>{{ msg }}</div>
        <!-- <input type="text" :value="msg" @input="inputChange" /> -->
        <!-- 监听表单控件变化,同步每次变化的值到value上 -->
        <input type="text" v-model="msg" />
        <button @click="msg = '张三'">填入张三</button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            arr: [1, 2, 3],
            isRed: false,
            px: 100,
            msg: "aaa",
        };
    },

    methods: {
        inputChange(event) {
            this.msg = event.target.value;
        },
    },
};
</script>

<style scoped>
.red {
    color: red;
}
</style>
```
4. 自定义组件使用 v-model
  1. 子组件
<!-- CustomInput.vue -->
<script>
export default {
    props: ["modelValue"],
    emits: ["update:modelValue"],
};
</script>

<template>
    <input
        :value="modelValue"
        @input="$emit('update:modelValue', $event.target.value)"
    />
</template>
  1. 父组件
<template>
    <div>
        {{ a }}
        <LearnA v-model="a"></LearnA>
    </div>
</template>

<script>
import LearnA from "./learn-a.vue";
export default {
    components: {
        LearnA,
    },
    data() {
        return {
            a: 1,
        };
    },
};
</script>

自定义指令 (了解)

1. 概念

在 Vue 中,你可以使用自定义指令来扩展和修改现有的 DOM 元素行为。自定义指令是一种在 HTML 元素上绑定自定义行为的方式,它们可以用于处理交互、动态样式、事件监听等。

2. 生命周期
  • 在指令定义中指定相应的钩子函数。自定义指令可以定义多个钩子函数,每个钩子函数在指令的生命周期中扮演不同的角色。以下是一些常用的钩子函数:
  • bind: 只调用一次,在指令第一次绑定到元素时调用,可以在这里进行初始设置。
  • inserted: 当被绑定的元素插入到 DOM 中时调用。
  • update: 在组件的 VNode 更新时调用,但可能发生在其子 VNode 更新之前。
  • componentUpdated: 在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind: 只调用一次,在指令与元素解绑时调用
3. 例子

增加 v-color 指令根据传入的参数改变字体颜色

  1. 全局指令
app.directive("color", {
    mounted(el, binding) {
        el.style.color = binding.value;
        console.log(el, binding);
    },
});
  1. 局部指令
<template>
    <div>
        <input type="text" v-focus="true" />
        <div v-color="`green`">全局指令变红</div>
    </div>
</template>

<script>
export default {
    directives: {
        /**
         * 对象的key是指令的名字
         * 指令 不需要 v- 开头
         * 但是使用的时候 必须要 v- 开头
         */
        focus: {
            /**
             * @param {*} el 当前的dom节点
             * @param {*} binding 相关传值
             */
            mounted(el, binding, vnode, prevVnode) {
                // console.log(el, binding);
                el.focus();
            },
        },
    },
};
</script>

插槽

概念

在 Vue 中,插槽(Slots)是一种用于组件模板中的特殊语法,用于实现组件的内容分发和复用。插槽允许父组件在子组件的模板中插入任意的内容,从而实现更灵活的组件组合和定制

默认插槽 (Default Slot)

默认插槽是最常用的插槽类型。在子组件的模板中,使用 <slot\></slot\> 标签定义默认插槽的位置。父组件在使用子组件时,可以在子组件的标签内放置内容,这些内容将被插入到子组件模板中的默认插槽位置

  1. 父组件
<template>
    <div>
        <LearnSlot2> 任意内容 </LearnSlot2>
    </div>
</template>

<script>
import LearnSlot2 from "./learn-slot2.vue";

export default {
    components: {
        LearnSlot2,
    },
};
</script>
  1. 子组件
<template>
    <div>
        <slot></slot>
    </div>
</template>

具名插槽 (Named Slots)

除了默认插槽,Vue 还支持具名插槽。具名插槽允许在子组件中定义多个命名插槽,父组件可以根据插槽的名称来插入内容。在子组件的模板中,使用 <slot name="slotName"\></slot\> 标签定义具名插槽的位置,并为每个插槽指定一个唯一的名称。在父组件使用子组件时,使用具名插槽的语法来插入相应名称的内容。

  1. 父组件
<template>
    <div>
        <LearnSlot2>
            <!-- <h1>一级标题</h1> -->
            <!-- # 后面是插槽的名字 -->
            <template #footer>
                <div>底部</div>
            </template>
            <template #header>
                <div>头部</div>
            </template>
            <template #content>
                <div>内容</div>
            </template>
        </LearnSlot2>
    </div>
</template>

<script>
import LearnSlot2 from "./learn-slot2.vue";

export default {
    components: {
        LearnSlot2,
    },
};
</script>
  1. 子组件
<template>
    <div>
        一个组件
        <!-- 使用slot这个组件展示组件标签中间的内容-->
        <!-- 使用name跟上插槽的名字 -->
        <slot name="header"></slot>
        <slot name="content"></slot>
        <slot name="footer"></slot>
    </div>
</template>

作用域插槽 (Scoped Slots)

作用域插槽是一种特殊的插槽类型,它允许 slot 组件向子组件传递数据,并且子组件可以在插槽中使用该数据进行渲染。

  1. 父组件
<!-- ParentComponent.vue -->
<template>
    <div>
        <h1>Parent Component</h1>
        <ListComponent>
            <!-- 使用作用域插槽来渲染列表项 -->
            <template v-slot="{ item }">
                <li>{{ item.name }}</li>
            </template>
        </ListComponent>
    </div>
</template>

<script>
import ListComponent from "./ListComponent.vue";

export default {
    components: {
        ListComponent,
    },
};
</script>
  1. 子组件
<!-- ListComponent.vue -->
<template>
    <div>
        <h2>List Component</h2>
        <ul>
            <slot v-for="item in items" :item="item" :key="item.id"></slot>
        </ul>
    </div>
</template>

<script>
export default {
    data() {
        return {
            items: [
                { id: 1, name: "Item 1" },
                { id: 2, name: "Item 2" },
                { id: 3, name: "Item 3" },
            ],
        };
    },
};
</script>

Vue 内置组件

component

1. 概念

<component\> 组件用于动态地渲染组件,根据不同的条件或数据选择性地渲染不同的组件。它可以接收一个组件的名称或组件对象,并根据指定的组件动态地渲染内容

2. 参数
  • is
    • is 属性是 <component\> 组件的一个特殊属性,用于指定要渲染的组件或组件的名称。
    • 通过使用 is 属性,我们可以实现动态组件的渲染,即根据数据的变化在运行时选择不同的组件进行渲染。这对于根据用户的操作或其他条件切换不同的视图非常有用
3. 例子
<template>
    <div>
        <select v-model="selectedComponent">
            <option value="ComponentA">Component A</option>
            <option value="ComponentB">Component B</option>
            <option value="ComponentC">Component C</option>
        </select>
        <component :is="selectedComponent"></component>
    </div>
</template>

<script>
import ComponentA from "./ComponentA.vue";
import ComponentB from "./ComponentB.vue";
import ComponentC from "./ComponentC.vue";

export default {
    data() {
        return {
            selectedComponent: "ComponentA",
        };
    },
    components: {
        ComponentA,
        ComponentB,
        ComponentC,
    },
};
</script>

keep-alive

1. 概念

组件用于缓存动态组件,以便在组件切换时保留其状态或避免重新渲染。它会缓存被包裹的组件的实例,并在组件切换时保持实例的状态,以提高应用的性能和响应性

2. 参数
  • include: 缓存 name 为 xxx 的组件
  • exclude: 不缓存 name 为 xxx 的组件
3. 例子
<template>
    <div>
        <select v-model="selectedComponent">
            <option value="ComponentA">Component A</option>
            <option value="ComponentB">Component B</option>
            <option value="ComponentC">Component C</option>
        </select>
        <keep-alive>
            <component :is="selectedComponent"></component>
        </keep-alive>
    </div>
</template>

<script>
import ComponentA from "./ComponentA.vue";
import ComponentB from "./ComponentB.vue";
import ComponentC from "./ComponentC.vue";

export default {
    data() {
        return {
            selectedComponent: "ComponentA",
        };
    },
    components: {
        ComponentA,
        ComponentB,
        ComponentC,
    },
};
</script>
4. 相关生命周期
export default {
    activated() {
        // activated 每次进入缓存都会执行
    },
    deactivated() {
        // 缓存组件被销毁时调用
    },
};

router-view / router-link

详细讲解等学完路由在讲解 <router-view\> 组件用于在 Vue 路由中渲染匹配到的组件,根据当前的路由状态动态地渲染对应的组件内容。<router-link\> 组件用于生成路由链接,提供了一种声明式的方式来导航到不同的路由

slot

详情请看 插槽那节课

teleport (了解)

1. 概念

它可以将一个组件内部的一部分模板 “传送” 到该组件的 DOM 结构外层的位置去。这类场景最常见的例子就是全屏的模态框

2. 参数
  • to: 指定传送的目标。
    • to 的值可以是一个 CSS 选择器字符串,也可以是一个 DOM 元素对象。
3. 例子
<button @click="open = true">Open Modal</button>

<Teleport to="body">
    <div v-if="open" class="modal">
        <p>Hello from the modal!</p>
        <button @click="open = false">Close</button>
    </div>
</Teleport>

transition / transition-group(了解)

1. 概念

<transition/> 组件用于在元素插入或移除时应用过渡效果,例如淡入淡出、滑动等效果。<transition-group/> 组件用于在多个元素同时插入或移除时应用过渡效果,并为每个元素添加唯一的过渡类名。这些组件提供了丰富的过渡效果和过渡钩子函数,使得在 Vue 应用中实现动画效果变得更加容易

2. 参数
  1. name 属性
    • name 属性用于指定过渡的名称,它在定义过渡样式和钩子函数时非常有用。通过为过渡样式类名添加 name 的前缀,可以确保不同过渡之间的样式不会相互冲突。同时,name 也用于在过渡钩子函数中标识当前过渡的名称,以便在需要时进行特定处理。
  2. tag 属性
    • tag 属性用于指定过渡组件渲染的标签。默认情况下,<transition\> 组件渲染为一个 span 标签,而 <transition-group\> 组件渲染为一个 span 包裹的 span 标签。通过设置 tag 属性,你可以指定渲染为其他的标签,如 div、ul、ol 等,以满足你的实际需求
3. 示例
<template>
    <div>
        <button @click="addItem">Add Item</button>
        <button @click="removeItem">Remove Item</button>

        <transition-group name="a" tag="ul">
            <li v-for="item in items" :key="item.id">
                {{ item.text }}
            </li>
        </transition-group>
    </div>
</template>

<script>
export default {
    data() {
        return {
            items: [
                { id: 1, text: "Item 1" },
                { id: 2, text: "Item 2" },
                { id: 3, text: "Item 3" },
            ],
            nextId: 4,
        };
    },
    methods: {
        addItem() {
            this.items.push({
                id: this.nextId,
                text: `Item ${this.nextId}`,
            });
            this.nextId++;
        },
        removeItem() {
            this.items.pop();
        },
    },
};
</script>

<style>
/*
    激活时的过渡效果
    a 为 name定义的值
    -enter-active这部分写死

    过渡效果需要自己写
*/
.a-enter-active,
.a-leave-active {
    transition: opacity 0.5s;
}
.a-enter,
.a-leave-to {
    opacity: 0;
}
</style>