一、列表渲染
(1)遍历数组
<div v-for="item of arr">{{ item }}</div>
<script>
new Vue({
el:"#app",
data:{
arr:[
1,2,3,4,5,6,7,8,9
]
}
})
</script>
此时,item遍历名对是数组的每一个元素
<div v-for="(item,index) of arr">{{index}}----{{ item }}</div>
<script>
new Vue({
el:"#app",
data:{
arr:[
1,2,3,4,5,6,7,8,9
]
}
})
</script>
此时index就是数组每一个元素对象的下标值
(2)遍历对象
<div v-for="item of arr">{{ item }}</div>
<script>
new Vue({
el:"#app",
data:{
arr:{
name:'张飞',
age:20
}
}
})
</script>
此时item是对象的键值
<div v-for="(item,key) of arr">{{ item }}</div>
<script>
new Vue({
el:"#app",
data:{
arr:{
name:'张飞',
age:20
}
}
})
</script>
此key就是对象的键名
<div v-for="(item,key,index) of arr">{{ item }}</div>
<script>
new Vue({
el:"#app",
data:{
arr:{
name:'张飞',
age:20
}
}
})
</script>
此时index是键值对的下标
(3)遍历整数
<标签名 v-for="item in 10">{{ item }}</标签名>
遍历指定次数,item的值从1开始,到10结束
(4)key属性的作用
key属性是一个唯一的能够标识指定标签的属性,它不能重复,在数据发生变化,虚拟DOM重新渲染时,能够明确知道哪个页面结构要被重新渲,从而提升页面渲染的速度和性能。
<ul>
<li v-for="(item,index) of arr" :key="index">
{{ item }}
<button @click="delCon(index)">删除</button>
</li>
</ul>
<script>
new Vue({
el:"#app",
data:{
arr:[]
},
methods:{
addCon(){
this.arr.push('aaaa')
},
delCon(n){
this.arr.splice(n,1)
}
}
})
</script>
二、响应式原理
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data
选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty
把这些 property 全部转为 getter/setter。Object.defineProperty
是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
原生js
<script>
var person = {
wh:"燕人",
get wh(){
console.log("获取外号.....")
return "张飞"
},
set wh(val){
console.log("设置外号...",val)
}
}
console.log(person.wh)//获取对象的属性时,会触发get方法
person.wh = "关羽"//设置对象的属性时,会触发set方法
</script>
三、数据更新后,页面不重新渲染
对象类型和数组类型的数据直接添加新的属性或者通过下标修改数据后,页面不会重新渲染
1.对象类型数据
<div id="app">
{{ info }}
<button @click="addPro">添加属性</button>
<button @click="delPro">删除属性</button>
</div>
<script>
new Vue({
el:"#app",
data:{
info:{
name:'小飞'
}
},
methods: {
addPro(){
// this.info.age = 20//此时页面不会重新渲染
this.$set(this.info,'age',20)
console.log(this)
},
delPro(){
// delete this.info.name;//此时页面不会重新渲染
this.$delete(this.info,'name')
console.log(this.info)
}
},
})
</script>
2.数组类型数据
通过下标直接操作数组中的内容时,数据会变化但是页面不会变化
需要使用数组相关的api方法来进行数组的操作
也可以使用$forceUpdate方法,来强制重新渲染页面
<div id="app">
{{ arr }}
<button @click="addCourse">添加课程</button>
<button @click="delCourse">删除课程</button>
<button @click="editCourse">修改课程</button>
</div>
<script>
new Vue({
el:"#app",
data:{
arr:['web前端','java','python','ui']
},
methods: {
addCourse(){
// this.arr[4] = '测试'
this.arr.push('测试')
console.log(this.arr)
},
delCourse(){
// this.arr[3] = '';
this.arr.splice(3,1)
console.log(this.arr)
},
editCourse(){
this.arr[3] = '测试'
// console.log(this)
this.$forceUpdate();//强制重新渲染页面
}
}
})
</script>
四、表单元素双向绑定
设计模式
后端+前端
MVC设计模式:强制的把用户的输入、输出、处理分开
M model 数据模型层
V view 视图层
C controller 控制器层
MVVM
M model
V view
VM viewmodel 视图模型层
vue中通过v-model可以实现视图模型层数据的双向绑定。
(1)内容输入
①文本框
<input type="text" v-model="msg">
②文本域
<textarea cols="20" rows="20" v-model="msg"></textarea>
(2)选择框
选择框一定要设置value属性,不然会出现选中一个其他的都选中的情况。
①复选
<div id="app">
<!-- 复选框-布尔值 -->
是否同意协议<input type="checkbox" v-model="isagree">
{{isagree}}
<br>
<!-- 复选框-数组 -->
兴趣爱好:
<input type="checkbox" v-model="hobbys" value="打游戏">打游戏
<input type="checkbox" v-model="hobbys" value="看电影">看电影
<input type="checkbox" v-model="hobbys" value="逛街">逛街
<p>{{ hobbys }}</p>
</div>
<script>
new Vue({
el:"#app",
data:{
isagree:true,//布尔值
hobbys:[]//数组
}
})
</script>
②单选
<div id="app">
在籍状态:
<input type="radio" v-model="iszj" value="是">是
<input type="radio" v-model="iszj" value="否">否
<p>{{ iszj }}</p>
</div>
<script>
new Vue({
el:"#app",
data:{
iszj:"是"
}
})
</script>
radio单选框也需要设置value,v-model双向绑定后,会拿初始值与value值进行对比,如果相同,则选中。
(3)下拉菜单
select标签不需要给option标签添加selected属性来控制哪个选项选中,只需要给select添加v-model双向绑定即可。
<div id="app">
<!-- 下拉菜单 -->
期望职位:
<select v-model="job">
<option value="">请选择</option>
<option value="web">web开发工程师</option>
<option value="java">java开发工程师</option>
<option value="ui">ui设计师</option>
</select>
{{ job }}
</div>
<script>
new Vue({
el:"#app",
data:{
job:""
}
})
</script>
五、修饰符
1.事件修饰符
语法格式:
<标签名 @事件名.修饰符=”自定义函数名“></标签名>
(1)prevent
阻止标签的默认事件
<button @contextmenu.prevent="menu">按钮</button>
(2)stop
阻止事件冒泡,写到触发事件冒泡的元素上
<div class="box" @click="boxClick">
<div class="small" @click.stop="smallClick"></div>
</div>
(3)capture
捕获事件冒泡,它会影响事件冒泡的执行顺序,变成了由外向内执行
<div class="box" @click.capture="boxClick">
<div class="small" @click.capture="smallClick"></div>
</div>
(4)self
控制事件只在自己本身的元素上起作用
<div class="box" @click.self="boxClick">
<div class="small" @click="smallClick"></div>
</div>
(5)once
控制事件只起作用一次
<button @contextmenu.prevent.once="menu">按钮</button>
事件修饰符可以连贯使用:事件名.修饰符1.修饰符2
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件修饰符案例</title>
<script src="../../node_modules/vue/dist/vue.js"></script>
<style>
*{
margin:0;
padding:0;
}
html,body,#app,.box,.mask{
width:100%;
height: 100%;
}
.mask{
background-color: rgba(0,0,0,0.5);
position: fixed;
left:-100%;
transition: left 0.5s;
}
.show{
left:0;
}
.content{
width:50%;
height: 100%;
background-color: #fff;
position: fixed;
}
.content a{
display: block;
margin:20px;
}
</style>
</head>
<body>
<div id="app">
<!--
touch
start
move
end
-->
<div class="box"
@touchstart="start"
@touchmove="move"
@touchend="end"
>
<div :class="{ mask:true,show:isshow }" @click.self="isshow=false">
<div class="content">
<a>个人信息</a>
<a>我的好友</a>
</div>
</div>
</div>
</div>
<script>
new Vue({
el:"#app",
data:{
startX:0,//触摸开始的x轴坐标点
endX:0,//触摸移动后结束时的x轴坐标点
isshow:false
},
methods:{
start(e){
this.startX = e.touches[0].clientX;
this.endX = 0;
},
move(e){
this.endX = e.touches[0].clientX;
},
end(e){
console.log(this.startX)
console.log(this.endX)
if(this.endX > this.startX){
this.isshow = true;
}
}
}
})
</script>
</body>
</html>