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>