指令
- 在 Vue.js 中,指令(Directives)是一种特殊的语法,用于为 HTML 元素添加特定的行为和功能。指令以 v- 作为前缀,通过在 HTML 标签中使用这些指令来操作 DOM,修改元素的属性、样式或行为。
- Vue.js 提供了一组内置的指令,如 v-model、v-bind、v-if、v-for 等。此外,你也可以自定义指令来满足特定的需求。
常见指令
- v-model
- 用于实现表单元素与 Vue 实例数据的双向绑定。
- v-bind
- 用于动态地将 Vue 实例的数据绑定到 HTML 元素的属性或表达式。
- v-if / v-else / v-else-if
- 根据条件控制元素的显示与隐藏。
- v-for
- 用于根据数据源循环渲染元素列表。
- v-on / @
- 用于监听 DOM 事件,并在触发时执行 Vue 实例中的方法。
- v-show
- 根据条件控制元素的显示与隐藏,通过修改元素的 CSS 属性 display。
- v-text
- 将 Vue 实例的数据绑定到元素的文本内容。
- 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
- 子组件
<!-- CustomInput.vue -->
<script>
export default {
props: ["modelValue"],
emits: ["update:modelValue"],
};
</script>
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</template>
- 父组件
<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 指令根据传入的参数改变字体颜色
- 全局指令
app.directive("color", {
mounted(el, binding) {
el.style.color = binding.value;
console.log(el, binding);
},
});
- 局部指令
<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\> 标签定义默认插槽的位置。父组件在使用子组件时,可以在子组件的标签内放置内容,这些内容将被插入到子组件模板中的默认插槽位置
- 父组件
<template>
<div>
<LearnSlot2> 任意内容 </LearnSlot2>
</div>
</template>
<script>
import LearnSlot2 from "./learn-slot2.vue";
export default {
components: {
LearnSlot2,
},
};
</script>
- 子组件
<template>
<div>
<slot></slot>
</div>
</template>
具名插槽 (Named Slots)
除了默认插槽,Vue 还支持具名插槽。具名插槽允许在子组件中定义多个命名插槽,父组件可以根据插槽的名称来插入内容。在子组件的模板中,使用 <slot name="slotName"\></slot\> 标签定义具名插槽的位置,并为每个插槽指定一个唯一的名称。在父组件使用子组件时,使用具名插槽的语法来插入相应名称的内容。
- 父组件
<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>
- 子组件
<template>
<div>
一个组件
<!-- 使用slot这个组件展示组件标签中间的内容-->
<!-- 使用name跟上插槽的名字 -->
<slot name="header"></slot>
<slot name="content"></slot>
<slot name="footer"></slot>
</div>
</template>
作用域插槽 (Scoped Slots)
作用域插槽是一种特殊的插槽类型,它允许 slot 组件向子组件传递数据,并且子组件可以在插槽中使用该数据进行渲染。
- 父组件
<!-- 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>
- 子组件
<!-- 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 属性,我们可以实现动态组件的渲染,即根据数据的变化在运行时选择不同的组件进行渲染。这对于根据用户的操作或其他条件切换不同的视图非常有用
- 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. 参数
- name 属性
- name 属性用于指定过渡的名称,它在定义过渡样式和钩子函数时非常有用。通过为过渡样式类名添加 name 的前缀,可以确保不同过渡之间的样式不会相互冲突。同时,name 也用于在过渡钩子函数中标识当前过渡的名称,以便在需要时进行特定处理。
- tag 属性
- tag 属性用于指定过渡组件渲染的标签。默认情况下,
<transition\>组件渲染为一个 span 标签,而<transition-group\>组件渲染为一个 span 包裹的 span 标签。通过设置 tag 属性,你可以指定渲染为其他的标签,如 div、ul、ol 等,以满足你的实际需求
- tag 属性用于指定过渡组件渲染的标签。默认情况下,
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>