vue的指令
1.什么是指令
在Vue.js中,指令(Directive)是一种带有"v-"前缀的特殊属性,用于为DOM元素添加特殊行为或响应数据的变化。指令以一种声明式的方式将DOM元素与Vue实例的数据绑定起来。
2.常见指令
2.1.属性绑定指令和事件绑定指令
v-bind
vue3的属性绑定v-bind,将表达式的值绑定到页面元素的属性上面插值表达式{{}}不能在 HTML 的标签上面中使用。想要响应式地给标签绑定一个属性,应该使用 v-bind 指令。
语法: v-bind:属性名称=”变量名”可以简写成: :属性名称=”变量名”
示例: <input v-bind:value="value">
<input :value="value">
v-on
vue3的事件绑定v-on ,用于监听DOM事件,并在触发事件时执行相应的方法或逻辑。它的作用是将事件与Vue实例中的方法进行绑定,实现事件处理和响应。
语法:<div v-on:事件名称=”方法名称”></div> 简写为 @事件名称=”方法名称”
示例: <div v-on:click="test">
<div @click="test">
v-model
用于实现表单元素和Vue实例中数据的双向绑定。
语法:<input v-model="响应式变量名称"></div>
示例:<input v-model="message">
v-on和v-bind就实现了v-model
input实现双向绑定
v-bind和v-on可以实现简单的双向绑定示例
input框通过value属性和输入事件的绑定,可以实现数据与视图的双向绑定
<template>
<input type="text"
:value="value"
@input="changValue">
</template>
<script>
export default {
data() {
return {
value: "默认值",
};
},
methods: {
changValue(e) {
console.log(e);
// console.log(value);
//this表示value实例,data定义的属性都挂在vue实例上面,
//不能直接访问
this.value = e.target.value;
console.log("value的值:", this.value);
//多次触发的时候,如果值没有发生改变就不会触发页面更新
// 双向绑定 需要将视图输入的值赋值给数据
},
},
};
</script>
v-model 是Vue框架的一种内置的API指令,本质是一种语法糖写法。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理
什么场景下会使用v-model?
表单提交是开发中非常常见的功能,也是和用户交互的重要手段:比如用户在登录、注册时需要提交账号密码;比如用户在检索、创建、更新信息时,需要提交一些数据
v-model示例
<template>
<!-- <input type="text"
:value="value"
@input="changValue"> -->
<input type="text"
v-model="value"
@input="showValue">
</template>
<script>
export default {
data() {
return {
value: "默认值",
};
},
methods: {
showValue() {
console.log("value的值:", this.value);
},
changValue(e) {
console.log(e);
// console.log(value);
//this表示value实例,data定义的属性都挂在vue实例上面,
//不能直接访问
this.value = e.target.value;
console.log("value的值:", this.value);
//多次触发的时候,如果值没有发生改变就不会触发页面更新
// 双向绑定 需要将视图输入的值赋值给数据
},
},
};
</script>
2.2条件渲染指令
v-if
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染
与js的if判断类似
语法:<div v-if="表达式"></div>
每一次显示和隐藏会创建或者销毁页面元素,支持在 <template> 元素上使用
v-else 可以为 v-if 添加一个“else 区块”,必须挨着一个v-if指令才能使用,不需要表达式
与js的else条件语句类似
语法:<div v-else></div>
每一次显示和隐藏会创建或者销毁页面元素,支持在 <template> 元素上使用
v-else-if 提供的是相应于 v-if 的“else if 区块”。它可以连续多次重复使用,使用于多个判断场景的判断
与javascript 的else if判断一样,可以存在多个
语法:<div v-else-if="表达式"></div>
每一次显示和隐藏会创建或者销毁页面元素,支持在 <template> 元素上使用
v-show
v-show按条件显示一个元素的指令
v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性
语法:<div v-show="表达式"></div>
不支持在 <template> 元素上使用,也不能和 v-else 搭配使用
代码示例
<template>
<div>
<!-- 使用v-if -->
<div v-if="score >= 90">
成绩优秀,分数为:{{ score }}
</div>
<!-- 使用v-else-if -->
<div v-else-if="score >= 60">
成绩合格,分数为:{{ score }}
</div>
<!-- 使用v-else -->
<div v-else>
成绩不合格,分数为:{{ score }}
</div>
<hr>
<!-- 使用v-show -->
<div v-show="isVisible">
这是通过v-show控制显示隐藏的元素,当前显示状态由isVisible决定。
</div>
<button @click="toggleVisible">点击切换显示隐藏(v-show)</button>
<hr>
<!-- 在template元素上使用v-if等(常用于包裹多个元素做整体条件判断) -->
<template v-if="showAllDetails">
<div>详细信息1:这是一些具体的内容1。</div>
<div>详细信息2:这是一些具体的内容2。</div>
</template>
<button @click="toggleShowAllDetails">点击切换显示所有详细信息(v-if)</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 模拟成绩分数,可自行修改数值查看不同条件判断的渲染效果
const score = ref(80);
// 用于控制v-show元素的显示隐藏
const isVisible = ref(true);
// 用于控制template包裹元素的整体显示隐藏(v-if相关)
const showAllDetails = ref(false);
// 点击事件函数,用于切换v-show元素的显示隐藏
const toggleVisible = () => {
isVisible.value =!isVisible.value;
};
// 点击事件函数,用于切换template包裹元素的显示隐藏(v-if相关)
const toggleShowAllDetails = () => {
showAllDetails.value =!showAllDetails.value;
};
</script>
2.3循环渲染指令
v-for
v-for循环渲染数组或对象中的子元素,页面元素的循环生成
v-for 指令的值需要使用 item in items 形式的特殊语法,其中 items 是源数据的数组,而 item 是循环项的别名:
语法:<h1 v-for="(item) in arr">type{{item}}</h1>
示例代码
<template>
<div>
<!-- 循环渲染简单数组 -->
<ul>
<li v-for="(fruit, index) in fruits" :key="index">
{{ index + 1 }}. {{ fruit }}
</li>
</ul>
<!-- 循环渲染包含对象的数组 -->
<ul>
<li v-for="(person, index) in people" :key="index">
姓名:{{ person.name }}, 年龄:{{ person.age }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 简单数组示例
const fruits = ref(['苹果', '香蕉', '橙子']);
// 包含对象的数组示例
const people = ref([
{ name: '张三', age: 25 },
{ name: '李四', age: 30 },
{ name: '王五', age: 28 }
]);
</script>
2.4 页面内容指令
v-html
v-html
是Vue.js指令之一,用于将绑定的数据作为HTML解释而不是纯文本。它允许在页面上动态渲染包含HTML标签的字符串,但潜在的安全风险需要谨慎使用。
语法:<div v-html="htmlContent"></div>
v-text
v-text指令:用于更新页面元素的文本内容(等价于{{}})。
语法:<div v-text="text"></div>
v-pre
v-pre指令:不对{{}}内容进行解析。用于跳过元素和它的子元素的编译过程,显示原始的Mustache({})标签。也就是正常显示‘{}’。
语法:<div v-pre>{}</div>
3.练习
练习一:
动态更新元素
页面中创建一个列表,列表数据如下:
const menu = [
'宫保鸡丁', '鱼香肉丝', '麻辣香锅', '回锅肉', '北京烤鸭',
'红烧肉', '小龙虾', '酸菜鱼', '辣子鸡', '蒜蓉粉丝蒸虾'
];
const name = [
'张三', '李四', '王五', '赵六', '孙七',
'周八', '吴九', '郑十', '冯十一', '陈十二'
];
页面中有两个按钮,一个按钮名为“显示菜单”,一个按钮名为“显示姓名”,当点击【显示菜单】按钮时,展示menu中的菜单数据;当点击【显示姓名】按钮时,展示name中的姓名数据
示例代码
<template>
<div class="container">
<button v-on:click="menu()">显示菜单</button>
<button v-on:click="name()">显示姓名</button>
</div>
<div>
<div v-for="(item) in show":key="item">
{{ item }}
</div>
{{ show }}
</div>
</template>
<script setup >
import { ref } from 'vue'
const show = ref()
const menu1 = ref([
'宫保鸡丁', '鱼香肉丝', '麻辣香锅', '回锅肉', '北京烤鸭',
'红烧肉', '小龙虾', '酸菜鱼', '辣子鸡', '蒜蓉粉丝蒸虾'
])
const name1 = ref([
'张三', '李四', '王五', '赵六', '孙七',
'周八', '吴九', '郑十', '冯十一', '陈十二'
])
const menu = ()=>{
show.value = menu1.value
}
const name = ()=>{
show.value = name1.value
}
</script>
练习二:
点菜
- 点击新增,新增菜到下面的列表中
- 点击列表中的删除,删除当前菜(补充一下数组的删除方法)
补充需求:
- 输入菜名后,按enter可以直接将菜名添加到下面,并且清除input中的内容
- 必须要有菜名才能添加
制作一个菜名管理程序,可以在程序中新增菜名和删除菜名
示例代码
<template>
<div class="container"></div>
<input type="text" v-model="value"/>
<button @click="add">新增菜</button>
<div>
<div v-for="(item,index) in arr" :key="index">
{{ item }}
<button @click="del(index)">删除</button>
</div>
</div>
</template>
<script setup >
import {ref} from 'vue'
const arr = ref([])
const value = ref('')
const add = ()=>{
//拿到input框的值,然后添加到数组中
// v-model双向绑定指令
console.log('输入框的值',value);
if(value.value!=''){
arr.value.push(value.value);
value.value=''
}
}
const del = (index) =>{
console.log('删除的索引',index);
//数组方法 splice:用于删除指定位置的指定长度的元素,并将删除的元素返回
//splice(参数1,参数2) 参数1表示删除的索引起始位置,参数2表示删除的元素个数
arr.value.splice(index,1)
}
</script>
<style scoped>
练习三:
使用前面所学的知识,使用vue的setup语法糖、v-for,将以下数据渲染成上图中的表格形式(不用在意样式,只要是表格即可)
const dataArray = [
{ account: 'YZ0001', name: '系统管理员', 手机号: '18000000000', role: '系统管理员', 用户状态: '启用' },
{ account: 'YZ0002', name: '用户2', 手机号: '18011111111', role: '记录员', 用户状态: '启用' },
{ account: 'YZ0003', name: '用户3', 手机号: '18022222222', role: '畜牧管理员', 用户状态: '禁用' },
{ account: 'YZ0004', name: '用户4', 手机号: '18033333333', role: '系统管理员', 用户状态: '启用' },
{ account: 'YZ0005', name: '用户5', 手机号: '18044444444', role: '记录员', 用户状态: '禁用' },
{ account: 'YZ0006', name: '用户6', 手机号: '18055555555', role: '畜牧管理员', 用户状态: '启用' },
{ account: 'YZ0007', name: '用户7', 手机号: '18066666666', role: '系统管理员', 用户状态: '禁用' },
{ account: 'YZ0008', name: '用户8', 手机号: '18077777777', role: '记录员', 用户状态: '启用' },
{ account: 'YZ0009', name: '用户9', 手机号: '18088888888', role: '畜牧管理员', 用户状态: '禁用' },
{ account: 'YZ0010', name: '用户10', 手机号: '18099999999', role: '系统管理员', 用户状态: '启用' }
];
示例代码
<template>
<table>
<thead>
<tr>
<th>账号</th>
<th>姓名</th>
<th>手机号</th>
<th>角色</th>
<th>用户状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item) in dataArray" :key="item.account">
<td>{{ item.account }}</td>
<td>{{ item.name }}</td>
<td>{{ item.手机号 }}</td>
<td>{{ item.role }}</td>
<td>{{ item['用户状态'] }}</td>
<td>
<button>操作</button>
<button>重置密码</button>
</td>
</tr>
</tbody>
</table>
</template>
<script setup>
import { ref } from 'vue';
const dataArray = ref([
{ account: 'YZ0001', name: '系统管理员', 手机号: '18000000000', role: '系统管理员', 用户状态: '启用' },
{ account: 'YZ0002', name: '用户2', 手机号: '18011111111', role: '记录员', 用户状态: '启用' },
{ account: 'YZ0003', name: '用户3', 手机号: '18022222222', role: '畜牧管理员', 用户状态: '禁用' },
{ account: 'YZ0004', name: '用户4', 手机号: '18033333333', role: '系统管理员', 用户状态: '启用' },
{ account: 'YZ0005', name: '用户5', 手机号: '18044444444', role: '记录员', 用户状态: '禁用' },
{ account: 'YZ0006', name: '用户6', 手机号: '18055555555', role: '畜牧管理员', 用户状态: '启用' },
{ account: 'YZ0007', name: '用户7', 手机号: '18066666666', role: '系统管理员', 用户状态: '禁用' },
{ account: 'YZ0008', name: '用户8', 手机号: '18077777777', role: '记录员', 用户状态: '启用' },
{ account: 'YZ0009', name: '用户9', 手机号: '18088888888', role: '畜牧管理员', 用户状态: '禁用' },
{ account: 'YZ0010', name: '用户10', 手机号: '18099999999', role: '系统管理员', 用户状态: '启用' }
]);
</script>
<style scoped>
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
font-size: 14px;
text-align: left;
min-height: 500px; /* 设置最小高度 */
}
thead {
background-color: #f4f4f4;
}
th, td {
padding: 12px;
border: 1px solid #ddd;
}
th {
font-weight: bold;
color: #333;
}
tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
tbody tr:hover {
background-color: #f1f1f1;
}
th:last-child,
td:last-child {
text-align: center;
}
</style>