本节目标
掌握vue指令
- 定义
- 常用指令
- 案例-小黑记事本
- 指令修饰符
介绍
指令就是带有v-前缀的标签属性, 不同的指令, 可以实现不同的功能
常用指令
渲染指令
语法: v-html
- 动态渲染标签
- 作用: 动态设置元素的innerHTML
- 场景: 用来动态解析标签
语法: v-text
- 动态渲染文本
- 会覆盖标签内部的原本的内容
- 不识别标签
语法: {{ }}
- 插值表达式
- 专门解决内容覆盖问题
显示隐藏
语法: v-show
- 作用: 控制元素显示隐藏
- 示例: v-show="表达式" 表达式值为true显示, false隐藏
- 原理: 切换display:none 控制显示隐藏
- 场景: 频繁切换
动态创建
语法: v-if
- 作用: 控制元素创建或销毁
- 示例: v-if="表达式" 表达式值为true显示,false隐藏
- 原理: 基于条件判断,创建或移除元素
- 场景: 要么显示要么隐藏的场景
- 补充:
- v-else/v-else-if
- 辅助v-if进行复杂的判断渲染
事件绑定
语法: v-on
- 作用: 注册事件 = 添加监听 + 提供处理逻辑
- 语法: v-on:事件名=内联语句
v-on:事件名="methods中的函数名"
- 简写: @事件名="内联语句"
- 区别: 内联语句可以直接访问数据, methods中的方法需要使用this访问实例
- 补充: methods中的方法, this都会指向当前实例
- 传参: @click="fn(参数1, 参数2)"
- 接收: fn(a, b) { ... ... }
- 完整传参: 直接传递参数,会覆盖事件对象, 如果两种参数都需要, 往下看↓
- 方式1: vue提供了内置变量, 名为$event, 就是原生的DOM事件对象
@click="函数名($event, 参数1, 参数2)"
- 方式2: 使用箭头函数包装一层, 可以保留原本的事件对象, 再通过调用函数传参
@click="(value)=> 函数名(value, 参数1, 参数2)"
属性绑定
语法: v-bind:属性名="表达式"
- 作用: 动态的设置html标签的属性( src/ url/ title/)
- 简写: :属性名="表达式"
动态样式
为了方便开发者进行样式控制, Vue扩展了v-bind的语法, 可以针对class类名和style行内样式进行控制
1>class类名
a. 对象写法
语法: :class="{ 类名1: 布尔值, 类名2: 布尔值 }"
场景: 适合一个类名, 来回切换
案例:
<body><!-- 目标:实现tab导航高亮切换思路: 1, 基于数据动态渲染tab2, 准备一个变量, 记录高亮的下标3, 基于高亮标识, 动态控制class类型 4, 高亮切换的核心, 就是切换下标--><div id="app"><ul><li v-for="(item,index) in list" :key="item.id" @click="activeIndex=index"><a :class="{ active: activeIndex===index }" href="#">{{ item.name }}</a></li></ul></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {activeIndex: 0, // 高亮标识list: [{ id: 1, name: '京东秒杀' },{ id: 2, name: '每日特价' },{ id: 3, name: '品类秒杀' }]}})</script>
</body>
b. 数组写法
语法: :class="[类名1, 类名2, 类名3]"
场景: 适合批量添加或删除类名
2>行内style
语法: :style="{ css属性名1: css属性值1, css属性名2: css属性值2, }"
场景: 某个具体属性的控制
补充: 如果是复合属性名( 如background-color), 需要大驼峰或引号包裹, 否则报错
案例:
<body><div id="app"><!-- 外层盒子(黑色容器) --><div class="progress"><!-- 内层盒子(蓝色进度) --><div class="inner" :style="{ width: progress + '%' }"><span>{{progress}}%</span></div></div><button @click="progress=25">设置25%</button><button @click="progress=50">设置50%</button><button @click="progress=75">设置75%</button><button @click="progress=100">设置100%</button></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {progress: 25,}})</script>
</body>
循环渲染
语法: v-for="(item,index) in 数组" :key="唯一标识"
- 作用: 基于数据循环, 多次渲染整个元素
- 范围: 可以循环数组, 对象, 数字
- item是数组元素, index是下标
- key的作用是给元素添加唯一标识, 保证Vue对列表的正确排序和复用
- key的值只能是字符串或数字类型
- key的值必须具有唯一性
- 推荐使用id作为key, 单纯的渲染可以使用index作为key
key的原理
v-for的默认行为会尝试原地修改元素(就地复用)
加key的执行过程
- 要删除第一条数据
- 根据key的值对比ODM,
值相等就删除该DOM,
剩下的DOM复用
- 可以正确的更新DOM,
删除DOM-1,
留下2-3-4
不加key的执行过程
- 要删除第一条数据
- 根据原地复用规则复用DOM
把数据2更新到DOM1中
把数据3更新到DOM2中
把数据4更新到DOM3中
删除DOM4
- 错误的更新DOM,
删除DOM-4,
留下1-2-3
双向绑定
语法: v-model="变量"
- 作用: 给表单元素使用, 快速设置或获取表单元素内容
- 数据变化 -> 视图自会更新
- 视图变化 -> 数据自动同步
其他表单
常见的表单元素都可以使用v-model绑定关联,快速获取和设置表单元素的值
说明
它会根据控件的类型,自定选取正确的方法更新元素
特定修饰符
它们是 v-model 指令的特定修饰符,提供了额外的功能来处理用户输入。
示例 <input type="text" v-model.number="username">
- .number 将用户输入的值变成数值类型
- .trim 去除首位两侧的空格
- .lazy 在'change'时而非'input'时更新(只同步最后的结果,不同步修改的过程)
案例
<body><!-- 目标: 使用v-model收集多种表单类型的值--><div id="app"><h3>小黑学习网</h3>姓名:<input type="text" v-model="name"><br><br>是否单身:<input type="checkbox" v-model="isSingle"><br><br><!-- 前置理解:1. name: 给单选框加上 name 属性 可以分组 → 同一组互相会互斥2. value: 给单选框加上 value 属性,用于提交给后台的数据结合 Vue 使用 → v-model-->性别:<input type="radio" name="gender" value="1" v-model="gender">男<input type="radio" name="gender" value="0" v-model="gender">女<br><br><!-- 前置理解:1. option 需要设置 value 值,提交给后台2. select 的 value 值,关联了选中的 option 的 value 值结合 Vue 使用 → v-model-->所在城市:<select v-model="city"><option value="101">北京</option><option value="102">上海</option><option value="103">成都</option><option value="104">南京</option></select><br><br>自我描述:<textarea v-model="desc"></textarea><button>立即注册</button></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {name: '',isSingle: 'true',gender: '1',city: '101',desc: ''}})</script>
</body>
案例-小黑记事本
需求
- 列表渲染
- 删除功能
- 添加功能
- 统计和清空
<body><!-- 主体区域 --><section id="app"><!-- 输入框 --><header class="header"><h1>小黑记事本</h1><input v-model="newTodo" placeholder="请输入任务" class="new-todo" /><button @click="addTodo" class="add">添加任务</button></header><!-- 列表区域 --><section class="main"><ul class="todo-list"><li class="todo" v-for="(item, index) in list" :key="item.id"><div class="view"><span class="index">{{ index + 1 }}.</span> <label>{{ item.name }}</label><button @click="deleteItem(item.id)" class="destroy"></button></div></li></ul></section><!-- 统计和清空 --><footer class="footer" v-show="list.length>0"><!-- 统计 --><span class="todo-count">合 计:<strong> {{ list.length }} </strong></span><!-- 清空 --><button @click="clear" class="clear-completed">清空任务</button></footer></section><!-- 底部 --><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {newTodo: '',list: [{ id: 1, name: '跑步一公里' },{ id: 2, name: '跳绳500次' },{ id: 3, name: '游泳100米' },]},methods: {// 删除任务deleteItem(id) {this.list = this.list.filter(item => item.id !== id)},// 添加任务addTodo() {if (!this.newTodo.trim()) {alert('请输入任务内容')return}this.list.unshift({ id: + new Date(), name: this.newTodo })this.newTodo = ''},// 清空clear() {this.list = []}}})</script>
</body>
指令修饰符
通过" . " 指明一些指令后缀, 不同后缀封装了不同的处理操作, 帮助我们简化代码
按键修饰符
@Keyup.enter -> 监听键盘回车事件
@keyup.esc -> 监听esc事件
v-model修饰符
v-model.trim -> 去除收尾空格
v-model.number -> 转数字(转换失败保留原值)
事件修饰符
@事件名.stop -> 阻止事件冒泡
@事件名.prevent -> 阻止默认行为
@事件名.once -> 事件只触发一次