Vue基础-Day02
模板语法
事件绑定指令
目标:熟悉v-on指令用法
- v-on:具体事件名称=”处理逻辑” 处理逻辑:简单js表达式 或者 methods中的函数
- 表示式用法
<div class="active" v-show='isShow'>测试事件</div>
<button v-on:click='isShow=!isShow'>点击</button>
- 函数用法
<button v-on:click="showInfo">隐藏DIV</button>
new Vue({
el: '#app',
data: {
isShow: false
},
// methods属性专门用于定义函数,
// 1、主要给模板提供事件处理函数
// 2、函数之间也可以相互调用
methods: {
showMsg() {
console.log('nihao')
},
showInfo() {
// 这里的函数中可以操作data中的数据
this.isShow = !this.isShow
// 函数直接也可以相互调用
this.showMsg()
}
}
})
总结:
- methods属性专门用于定义函数,
1、主要给模板提供事件处理函数
2、函数之间也可以相互调用
- 函数传递参数
<div id="app">
<ul>
<li v-on:click='getInfo(item.id, item.uname)' :key='item.id' v-for='item in list'>
{{item.uname}}
</li>
</ul>
</div>
methods: {
getInfo(id, name) {
console.log(id, name)
}
}
总结:绑定函数时,可以直接调用函数并且传递实参,那么事件函数中可以直接获取参数值。
- 访问事件对象
- $event名称是固定的(Vue的API)
<button data-id='123' v-on:click='showInfo'>点击1</button>
<button data-id='456' v-on:click='showInfo'>点击2</button>
<!-- ----------------------------- -->
<!-- 如果需要手动传递事件对象参数,需要使用$event这个名字 -->
<button data-id='789' v-on:click='showInfo("hi", $event)'>点击3</button>
methods: {
showInfo(msg, e) {
console.log(msg)
console.log(e.target.dataset.id)
}
}
总结:
- 如果直接绑定函数名称,那么事件函数的参数中默认得到事件对象
- 如果绑定函数调用showInfo(),那么要想得到事件对象,需要手动传递$event,该参数位置自己决定
- 事件修饰符
- 阻止默认行为
<!-- .prevent事件修饰符的作用:阻止标签的默认行为 -->
<a href="http://itcast.cn" v-on:click.prevent='handleJump'>黑马</a>
- 阻止冒泡
<div v-on:click='showInfo'>
<!-- 事件名称之后.stop为事件修饰符,用于阻止冒泡 -->
<button v-on:click.stop='handleClick'>点击</button>
</div
- 修饰符串联写法:既阻止冒泡又阻止默认行为
<!-- 事件修饰符可以连续使用 -->
<a href="http://itcast.cn" v-on:click.stop.prevent='handleJump'>黑</a>
- 事件绑定简写方式 v-on:可以简写为@
<a @click.stop="doThis"></a>
总结:
- 绑定事件时,最后可以添加事件修饰符
- .stop修饰符用于阻止冒泡
- .prevent修饰符用于阻止默认行为
- 修饰符可以连续使用
- 事件绑定的v-on:可以简化为@
双向数据绑定指令
目标:熟悉v-model指令用法;熟悉双向绑定效果
作用:实现表单元素(视图View)和data当中的数据(数据模型Model)的双向的绑定。
- 双向数据绑定
- data当中的数据需要在表单元素中显示(M—->V)
- 当表单元素的值发生改变,绑定的data当中对应的数据也需要改变(V—->M)
<input type="text" v-model="msg">
总结:
- 双向绑定是哪两个方向?
- V -> M
- M -> V
- 具体使用指令v-model实现双向绑定
- methods中定义的函数中的this指的是vue的实例对象
指令v-model本质分析
目标:熟悉v-model指令的本质(属性绑定和事件绑定)
- 前提 data 当中有数据:
data:{msg:'表单数据'}
<input type="text" :value="msg">
赋值 (M—->V)<input type="text" @input="msg=$event.target.value">
改值 (V—->M)
总结:v-model指令是一个语法糖(简写代码),它简写了 :value 与 @input 两段代码
MVVM:将视图(V)和模型(M)解耦——弱化代码之间的关联;然后制定一套通用的规则再建立两者之间的关联关系:
- 视图———事件监听———->模型
- 模型———数据绑定———->视图
- 关于v-model执行修饰符lazy的用法
<!-- 如果v-model后面添加lazy修饰符,那么底层的事件监听才用change事件(默认使用input事件) -->
<input type="text" v-model.lazy='msg'>
注意:change和input事件的区别:
- change事件在失去焦点时触发
- input事件在有内容变化时触发(按钮按下就触发)
v-once指令用法
目标:知道如何让视图只渲染一次,不受数据变化影响。
作用:优化性能
<div id="app">
<!-- v-once指令会把绑定的数据一次性显示之后,后续就不再更新了 -->
<!-- v-once会把数据绑定变成非响应式的模式 -->
<!-- v-once会提高性能 -->
<!-- 应用场景:一次性展示的内容,后续不需要变更 -->
<div v-once>{{msg}}</div>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: '我是一段信息'
}
})
</script>
注意:【数据】的响应式:数据的变化会导致视图的变化
- 一次性展示的内容,后续不需要变更
- v-once会提高性能
v-pre指令用法
目标:熟悉v-pre指令的用法
作用:跳过这个元素和它的子元素的编译过程,如果跳过某些标签的编译过程,会提高性能,可以显示原始的信息
<!-- v-pre的作用:防止内部的内容被编译 -->
<span v-pre>{{ msg }}</span>
总结:注意的应用场景:显示标签里面的原始信息
案例功能拓展
添加图书
目标:掌握表单的基本操作流程
- 基本布局(表单效果)
- 添加图书按钮的事件绑定
- 实现添加的功能
- 清空表单
<!-- 添加图书表单 -->图书名称:<input type="text" v-model='bookname'>图书作者:<input type="text" v-model='author'><button @click='handleSubmit'>提交</button>
methods: {
handleSubmit() {
// 表单验证
if (!this.bookname) {
alert('请输入图书名称')
return
}
// 获取表单数据,添加到列表中
const book = {
bookname: this.bookname,
author: this.author,
date: new Date()
}
// 动态生成图书的编号id(取当前所有图书的id最大值再加1)
// 把图书的所有的图书id放到数组中
const ids = this.books.map(function (item) {
return item.id
})
book.id = Math.max(...ids) + 1
// 把生成的数据对象book添加到列表books中
this.books.push(book)
// 清空表单
this.bookname = ''
this.author = ''
}
},
总结:表单基本布局;绑定表单提交事件;获取表单数据并完善;添加图书数据到列表中即可。
- 数组相关的操作方法
- forEach 遍历
- sort 排序
- map 处理数组每一项数据
- Math.max方法用法
删除图书
目标:实现删除图书功能
- 绑定删除按钮事件
- 获取要删除的图书的id
- 根据id删除数组中的数据
<td><a @click='handleDelete(item.id)' href="#">删除</a></td>
handleDelete(id) { // 删除图书 // 1、获取要删除的图书id // 2、根据id插值数组中要删除的数据索引 const index = this.books.findIndex(function (item) { // 查找条件 return item.id === id }) // 3、根据索引删除数组中一项数据 this.books.splice(index, 1)},
总结:获取id、更加id获取索引;根据索引删除。 注意:熟悉findIndex方法的使用规则
总结
- 事件处理
- 基本事件绑定 v-on:事件名称=表达式/函数名/函数调用
- 绑定函数名 v-on:click=’showInfo’
- 绑定函数调用 v-on:click=’showInfo()’
- 事件函数如何传递参数v-on:click=’showInfo(123,, 456)’
- 事件对象作为参数传递
- v-on:click=’showInfo’,这种方式默认会传递事件对象
- v-on:click=’showInfo($event)’ $event是vue规定的名称,表示事件对象
- 事件修饰符用法
- 阻止冒泡 .stop
- 阻止默认行为 .prevent
- 事件修饰符可以连续使用
- 双向绑定指令 v-model ,主要用于表单数据项
- 从模型到视图 M -> V (数据绑定)
- 从视图到模型 V -> M (事件监听)
- v-model的底层实际上是两个指令的组合
- v-bind:value=’msg’
- v-on:input=’msg=$event.target.value’
- v-model的修饰符.lazy用于修改事件input为change事件
- v-once 仅仅渲染一次,禁用数据响应式效果,提高性能
- v-pre 不编译模板,显示原始内容
- v-on:可以简写为@
- 图书管理案例
- 添加图书
- 删除图书
- 数组相关的方法
- sort
- findIndex
- map
- some
- every
- filter
- find
- 计算最大值 Math.max(…arr)
- 13个指令(把数据填充到模板中)
- 把数据填充到模板的标签中间
- 插值表达式(v-cloak)
- v-text
- v-html
- v-once
- v-pre
- 把数据填充到模板标签的属性中
- v-bind
- v-bind:class
- v-bind:style
- 条件渲染
- v-if
- v-else
- v-else-if
- v-show
- 列表渲染
- v-for
- key的作用
- 事件监听
- v-on
- v-model
- v-bind:value
- v-on:input
- 把数据填充到模板的标签中间
概念:
- 编译:把vue模板中的代码转换为浏览器可以认识的代码
- 数据绑定:把数据填充到模板的过程
- 数据的响应式:数据的变化会导致页面的自动更新(A的变化会引起B的变化)
- 事件监听:给模板中的标签绑定事件
Vue常用特性
通过案例的相关功能学习这些特性
- 过滤器(格式化日期)
- 自定义指令(获取焦点)
- 计算属性(输入查询)
- 直接操作DOM
过滤器
目标:知道如何定义过滤器和使用过滤器。
作用:在插值表达式中使用,主要用于转换数据格式。
- 定义过滤器
- 全局过滤器(在任何视图中可以使用)
// 实现一个过滤器,用于把图书名称的首字母变成大写
Vue.filter('upcase', function (value) {
// 参数value就表示原始需要处理的数据
// 1、获取原始字符串的首字母
// charAt作用:获取指定索引的单个字符
// toUpperCase作用:把小写字符串转换为大写
const firstLetter = value.charAt(0).toUpperCase()
// 2、截取首字符之外的剩余字符串
const otherLetter = value.substring(1)
// 返回时直接拼接即可
return firstLetter + otherLetter
})
- 局部过滤器(在当前vue实例管理的视图才可以使用)
const vm = new Vue({
el: '#app',
data: {
msg: 'hi vuejs'
},
filters: {
// 实现格式化日期的功能
formatDate: function (date) {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hours = date.getHours()
const minutes = date.getMinutes()
const seconds = date.getSeconds()
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}
},
})
- 使用过滤器
<div id="app"> <!-- 需求:输出的字符串是大写(对现有的数据格式不满意,要进行格式转换,使用过滤器) --> <!-- 使用过滤器, | 术语:管道符 --> {{username|upcase}}</div>
- 基于局部过滤器格式化图书列表中的日期格式
<td>{{item.date | formatDate}}</td>
总结:
- 过滤器的作用:格式化数据
- 两种定义方式:全局过滤器;局部过滤器
- 先定义,再使用(插值表达式中添加【|过滤器名称】)
自定义指令
目标:知道如何定义自定义指令,使用自定义指令。
作用: 我们学过很多vue提供的指令,能够帮助我们实现很多功能,但是不能实现将来我们遇到的所有业务功能,所以vue给你提供了扩展vue指令的方式。(自己封装指令)
- 注册自定义指令
- 全局自定义指令
// Vue.directive('指令的名称','指令的配置对象') 基本语法// 注意:指令的名字在定义时候不需要加v-,在是用的时候才需要加v- Vue.directive('focus', { // 固定属性:inserted 在使用指令的元素渲染完毕后触发的函数 inserted (el) { // 这个函数执行了,代表元素渲染完毕,才可以操作元素。 // 最后根据你指令的需求,实现业务逻辑。el 是使用指令的dom元素 // dom提供的api用了获取焦点 el.focus() }})
- 局部自定义指令
const vm = new Vue({ el: '#app', // key是 指令的名称 要求:定义时候不需要加v-,在是用的时候才需要加v- // value是 指令的配置对象 directives: { // 给使用指令的标签添加背景颜色 color: { inserted: function (el, bindings) { // bindings表示指令使用时相关的信息 // el.style.backgroundColor = '#eee' el.style.backgroundColor = bindings.value } } },})
- 使用指令
<!-- 指令:directive --><div id="app"> <!--需求: v-focus 的指令,自动获取焦点 --> <input type="text" v-focus></div>
- 图书管理案例实现光标定位和背景变色
<input v-color v-focus='bgColor' v-model='bookname' type="text" class="form-control" placeholder="请输入图书名称">
data: {
bgColor: 'pink'
}
总结:
- 内置指令仅仅可以完成一些通用的功能,那么业务相关功能可以通过自定义指令进行扩展
- 定义指令:全局自定义指令和局部自定义指令
- 先定义,在使用
- 处理指令相关信息变更的问题
directives: {
// 给使用指令的标签添加背景颜色
color: {
inserted: function (el, bindings) {
// v-focus='bgColor'
// bindings表示指令使用时相关的信息
// el.style.backgroundColor = '#eee'
el.style.backgroundColor = bindings.value
},
update: function (el, bindings) {
// 更新指令相关信息时触发
el.style.backgroundColor = bindings.value
}
}
},
计算属性
目标:知道如何定义计算属性,以及计算属性和函数的区别。
应用场景:vue不建议在模板中(视图中)使用过于复杂的js表达式,可读性差,不好维护,因此可以使用计算属性进行优化。
- 定义计算属性
new Vue({ el:'#app', data: { message: 'hi vuejs' }, // 计算属性写法,固定的 computed: { // 写函数处理复杂逻辑 handleMsg () { // 反转逻辑,处理之后的结果,是一定要return出去 return this.message.split('').reverse().join('') } }})
- 使用计算属性(注意computed 声明计算属性是函数,当做属性来用了。)
<div id="app">
<!-- 在模板中直接使用计算属性配置对象中声明的函数名称即可(这个函数名称叫计算属性) -->
{{handleMsg}}
</div>
- 基于计算属性的方式计算图书的数量
computed: {
bookTotal() {
// 计算图书的总数
return this.books.length
}
},
<div>图书总数是{{bookTotal}}</div>
总结:基于计算属性的方式实现图书数量的统计
- 计算属性和函数的区别分析
- 计算属性会基于原来的计算结果进行缓存(多次使用计算属性的值,第一次会计算,后续的使用缓存)
- 函数是不会缓存的
总结:
- 计算属性主要解决模板中复杂的js计算(可读性较差)
- 计算属性在使用时不需要添加()
- 计算属性在计算时依赖的数据来源于data,如果data中数据发生改变,那么计算属性是否会重新计算?会的
- 计算数量是有缓存机制的,但是函数没有
操作DOM
目标:知道使用ref获取DOM元素的方法
在Vue中极大的解放了DOM操作(数据驱动视图),但是极端情况下依然需要操作DOM。
- 操作DOM步骤
- 在需要操作的DOM元素上添加ref属性
- 给ref属性加上属性值(保证唯一):
<div ref='userInfo'></div>
- 在vue的方法中,通过this.$refs.userInfo 获取到DOM元素
<div id="app">
<div ref="myDom">我是一个div</div>
<span ref="mySpan">我是一个span</span>
<button @click="fn">获取dom</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
methods: {
fn () {
// this.$refs 是收集了视图中所有加了ref属性的dom元素
// this.$refs = {myDom: 'dom元素',mySpan: 'dom元素'}
const dom = this.$refs.myDom
console.log(this.$refs)
console.log(dom)
}
}
})
</script>
总结:
- 通用ref属性给标签起一个名字,保证唯一性
- 通过
this.$refs.ref起的名字
获取DOM元素