1. 指令综合案例-信息表
表单有很多数据,应该在data中定义一个对象
data: {
userInfo:{
username:'',
tel:''
}
},
添加这块使用 … 展开运算符,实现拷贝
let user = {
...this.userInfo,//把userInfo上的数据拷贝到user变量上
}
表单
数据绑定
输入框
姓名:<input v-model="userInfo.username" />
年龄:<input v-model="userInfo.age" type="number" />
单选框
- 单选框 value值会通过v-model被vue获取
- 无value属性会通过v-model被vue获取布尔值
- 如果想要绑定成数字 则 v-bind:value=“1” ;属性加冒号则引号里为js语句,因此为数字。
<input type="radio" value="0" v-model="userInfo.sex"> 男
<input type="radio" :value="1" v-model="userInfo.sex"> 女
<input type="radio" value="2" v-model="userInfo.sex"> 保密
下拉菜单
- 单选
<select v-model="userInfo.jobIndex">
<option value="">请选择</option>
<!-- 0:php工程师 1:java工程师 2:web工程师-->
<option :value="index" v-for="(item,index) in jobs">{{item}}</option>
</select>
- 多选
- multiple属性实现select多选
- 多选数据绑定初始值需要一个数组
<select v-model="userInfo.eatIndex" multiple>
<option value="">请选择</option>
<option :value="index" v-for="(item,index) in eats" :key="index">{{item}}</option>
</select>
多选框
- 多选框 value值会通过v-model被vue获取
- 当要存储多个值,vue内初始值(data的变量值)必须定义为数组
- 无value属性会通过v-model被vue获取布尔值
<!-- 复选框当要存储多个值,初始值必须定义为数组 -->
<input type="checkbox" v-model="userInfo.hobbies" :value="1"> 吃饭
<input type="checkbox" v-model="userInfo.hobbies" :value="2"> 睡觉
<input type="checkbox" v-model="userInfo.hobbies" :value="3"> 打豆豆
<hr>
<!-- 当复选框想得到布尔值,那么初始化需要定义为true或false -->
是否同意协议:<input type="checkbox" v-model="userInfo.isAgree">
技巧:做表单数据交互的时候,前端最好定一个对象,对象的key和后端要求的字段保持一致,这样,后期传参的时候直接传前期定义的那个对象。
addUser() {
//1. 收集数据,指的就是正确的使用v-model
//console.log( this.userInfo )
//2. 判断数据格式
if( !this.userInfo.isAgree ){
alert('请查看协议')
return
}
alert('可以发送ajax请求')
$.ajax({
url:'/添加用户的接口地址',
data:this.userInfo //一定得保证和接口文档需要的键名一致。
})
}
表单修饰符
- .lazy 失去焦点更新数据
- .number 数据为number类型
- .trim 去除左右空格
<div id="app">
<!-- v-model.修饰符 -->
<!-- .lazy: 失去焦点更新数据 -->
<input type="text" v-model.lazy="username">
{{username}}
<!-- .number 保证我们的数据是number类型-->
<input type="number" v-model.number="age"> <button @click="getAge">获取age</button>
<!-- .trim 去除左右空格 -->
<input type="text" v-model.trim="password"><button @click="getPassword">password</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
username:'zs',
age:'',
password:''
},
methods: {
getAge(){
console.log(this.age ,typeof this.age) //number
},
getPassword(){
console.log('---' + this.password + '---')
}
}
})
</script>
表单事件注意事项
单选框、多选框、下拉菜单涉及到选中状态的表单元素如果要绑定事件,都是change,不要使用click。
<div id="app">
<!-- 如果使用clicks事件则选中状态与事件不一致
<input type="checkbox" v-model="isAgree" @click="clickMe"> -->
<input type="checkbox" v-model="isAgree" @change="changeMe">
<div v-show="isAgree">显示与隐藏</div>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
isAgree:true
},
methods: {
clickMe(){
console.log(this.isAgree)
},
changeMe(){
console.log(this.isAgree)
}
}
})
</script>
事件处理及修饰符
事件对象 $event
- 隐式传递事件对象,调用的时候未写小括号,事件对象在接收的时候拿到。
- 显式传递事件对象: 必须第1个参数叫 $event,之后为实参。
<div id="app">
<!-- 绑定、事件对象、冒泡、默认行为、捕获.... 表单的事件、键盘事件 -->
<!-- 1. 隐式传递事件对象,调用的时候未写小括号,接收的时候 -->
<button @click="clickMe1">点击我获取事件对象:隐式传递</button>
<!-- 2. 显式传递事件对象: 必须第1个参数叫 $event -->
<button @click="clickMe2($event)">点击我获取事件对象:显式传递</button>
<!-- 3. 显式传递事件对象: ,同时又想传递其它参数,必须第1个参数叫 $event,其它参数接着往后写 -->
<button @click="clickMe2($event,20,10)">点击我获取事件对象:显式传递</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
},
methods: {
clickMe1(e) {
console.log(e, '隐匿接收事件对象')
},
clickMe2(e,a1,b1) {
console.log(e, '显式接收事件对象',a1,b1)
}
}
})
</script>
事件修饰符
常用事件修饰符
.prevent 阻止默认事件
.stop 阻止事件冒泡
.self 触发的目标元素是自己才执行
.once 一次性事件绑定
.capture 实现事件捕获
//键盘事件 @keydown
.left 左键
.right 右键
.up 上键
.down 下键
.enter 回车
.number 对应键码
阻止默认与冒泡
- 原生写法
阻止默认事件
e.preventDefault() return false:注意写在函数内部的最后一行
阻止冒泡
e.stopPropagation()
e.cancelBubble = true
-
.prevent 阻止默认事件
-
.stop 阻止事件冒泡
-
.self 触发的目标元素是自己才执行,即防止下一级出现事件冒泡。
<!-- 1. .prevent 阻止默认 -->
<div class="box" @contextmenu.prevent="contextmenuHandle"></div>
<!-- 2. .stop 阻止事件冒泡 -->
<div class="box" @click="outerClick">
<button @click.stop="innerClick">按钮</button>
</div>
<!-- .self 触发的是自己才执行,即子元素触发事件不会冒泡到自己 -->
<div class="box" @click.self="outerClick">
.$set
场景:
-
用户在注册时可能只提交了一些信息:用户名、密码
-
用户访问个人中心,要完善信息
-
后端没给全数据,但是前端又要用,并且data未定义,后续又添加或修改某值
-
这个对象中新加的属性不被管理
对象的问题
- this.$set(数据, “新增属性”, “值”): 原型链上的方法
- Vue.set(数据, “新增属性”, “值”):静态方法。
如果定义data的数据时没有某个字段,后面添加数据中的字段改变,页面不会渲染。即无法管理新增字段。
<div id="app">
<h2>用户修改</h2>
用户名: {{user.username}}
<hr>
年龄:{{user.age}}
<hr>
<button @click="changeAge1">修改年龄为20</button>
<button @click="changeAge2">修改年龄为30</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
user: {
username: 'zs'
}
},
methods: {
changeAge1() {
// this.user.age = 20 : 因为datad的user对象上默认没有age属性,视图不会发生变化。
this.$set( this.user,'age',20 )
},
changeAge2() {
Vue.set( this.user,'age',30 )
}
}
})
</script>
数组的问题
- this.$set(原数据, “某一项”, “这一项新数据”): 原型链上的方法
- Vue.set(原数据, “某一项”, “这一项新数据”):静态方法。
- 数组的删除方法 splice() 删、改、加、替换
后端返回了数据,但是前端自己添加了数据中某个字段,该字段改变,页面不会渲染。即无法管理新增字段。
<div id="app">
<div v-for="(item,index) in users" >{{item.username}}--{{item.sex}}
<button @click="editUser(index)">修改成女</button></div>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
users: [
{
username: 'zs',
},
{
username: 'ls',
}
]
},
methods: {
getUsers(){
//后端返回的用户列表中,每一个数据都没有性别,但是又要展示并且并且后续要操作
this.users.forEach(item=>{
item.sex = '男'
})
},
editUser(index){
this.users[index].sex = '女'
this.$set(this.users, index, this.users[index]) //把users数组的index项,换成新的
Vue.set(this.users, index, this.users[index])
//数组的删除方法 splice() 集删、改、加、替换于一身的方法
this.users.splice( index,1,this.users[index] )
}
}
})
</script>
调用下面方法修改数据,视图都会更新。
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
生命周期
面试题
1.vue中检测不到数组或者对象发生改变,如何解决?
2.vue更新数组时触发视图更新的方法
3.Class 与 Style 如何动态绑定?
4.Vue中常用的修饰符有哪些?并简要说明它们的作用。