一.Vue简介
1.什么是Vue
一套构建用户界面(就是将数据展示给用户看得懂的)的渐进式(自底向上逐层应用) JavaScript框架
2.Vue的特点
2.1.采用组件化(new.vue[.vue里面包含html css js])的模式,提高代码的复用率,且让代码更好维护
2.2.声明式编码,让编码人员无需直接操作DOM,提高开发效率
2.3.使用虚拟的DOM+Diff算法(进行虚拟的DOM比较),尽量复用DOM节点
3.vue模板语法
1.要让Vue进行工作,必选先创建一个Vue实例,且传入一个配置对象
2.容器中的代码依然符合html规范,只不过混入一些特殊的Vue语法
3.容器中的模板成为Vue模板
4.一个Vue实例对应一个容器
5.实际开发中只会有一个Vue实例,并且搭配组件进行使用
6.{{XXX}} XXX为js中的表达式,并且可以自动读取到data中的数据
7.当data中的数据发生变化时,页面中的数据也会发生改变
注意:js表达式和js代码(语句)
1.表达式:一个表达式会生成一个值,可以放在任何需要的地方
(1).a a+b demo(1)
2.js代码
(2)if(){} for(){}
Vue模板语法
1.插值语法 用来解析标签体中的内容
{{XXX}} XXX为js中的表达式,并且可以自动读取到data中的数据
2.指令语法
用于解析标签(包括标签属性、标签体内容、绑定事件...)
v-bind:href='xxx' 可以简写成 :href='xxx' xxx同样要写js表达式,且可以读取到data中的所有属性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 容器准备 -->
<div class="root">
<h1>你好,{{name}}</h1>
<a :href="user.url">{{user.name}},去百度学习</a>
</div>
<script type="text/javascript">
new Vue({
el:'.root',
data:{
name:'jack',
user:{
name:'cms',
url:'http://www.baidu.com',
}
}
})
</script>
</body>
</html>
4.数据绑定
数据绑定两种方式:
1.v-bind 单向绑定 数据只能从data流向页面
2.v-model 双向绑定 数据不仅能从data流向页面 也能从页面流向data
2.1双向绑定一般应用在表单元素上 (input select)
2.2v-model:value可以简写成 v-model v-model就是获取value值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<script>Vue.config.productionTip= false </script>
<div class="root">
单向数据绑定:<input type="text" v-bind:value="name">
双向数据绑定:<input type="text" v-model="name">
</div>
<script type="text/javascript">
new Vue({
el:'.root',
data:{
name:'学习',
}
})
</script>
</body>
</html>
5.el和data的两种写法
5.1用el 或者 用$.mount(mount挂载的意思)
5.2data 对象式或者函数式
一个重要原则:由Vue管理的函数,一定不要写箭头函数 一但写了箭头函数就不在是Vue实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>你好,{{name}}</h1>
</div>
<script type="text/javascript">
//el第一种写法
// new Vue({
// el:'#root',
// data:{
// name:'jack',
// }
// })
// 第二种写法
// const x=new Vue({
// data:{
// name:'jack',
// }
// })
// console.log(x)
// //设置1000ms后将Vue实例和容器进行关联
// setTimeout(()=>{
// x.$mount('#root')
// },1000);
//data两种写法
new Vue({
el:'#root',
//data第一种写法 对象式
// data:{
// name:'jack',
// }
//data第二种写法 函数式
//一个重要原则:由Vue管理的函数,一定不要写箭头函数 一但写了箭头函数就不在是Vue实例
data:function(){
console.log(this) //此处表示的是Vue实例对象
return{
name:'jack1',
}
}
})
</script>
</body>
</html>
6. MVVM模型
MVVM模型
1.M 模型:data中的数据
2.V 视图:模板中的代理 就是容器中的模板代码
3.VM 视图模型:Vue实例 以后通过变量接收实例可以用 vm
3.1 data中的所有属性,最终都出现在vm上
3.2vm身上的属性以及Vue原型上的属性都可以在Vue模板中使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
<h1>名称:{{name}}</h1>
<h1>地址:{{address}}</h1>
</div>
<script type="text/javascript">
const vm=new Vue({
data:function(){
return{
name:'Vue',
address:'哔哩哔哩',
}
}
})
vm.$mount('.root')
</script>
</body>
</html>
7.数据代理
7.1Object.defineProperty()原理
传参:传入三个参数,一个是对象,一个是key,一个是value的操作
get:当有人读取person的age的属性,get函数(getter)就会被调用
set:当有人修改person的age的属性,set函数(setter)就会被调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<script type="text/javascript">
let number=18
let person={
name:'张三',
sex:'男',
}
//传入三个参数,一个是对象,一个是key,一个是value的操作
Object.defineProperty(person,'age',{
// value:18,
// enumerable:true,//控制属性是否能够枚举(就是能不能被遍历) 默认false
// writable:true,//控制属性是否能被修改默认值 false
// configurable,//控制属性是否能被删除,默认值false
//当有人读取person的age的属性,get函数(getter)就会被调用,且返回值是age的值
get:function(){
return number
},
//当有人修改person的age的属性,set函数(setter)就会被调用,且收到修改的具体值
set(value){
number=value
}
})
console.log(person)
//将对象中的属性的key值进行遍历
console.log(Object.keys(person))
</script>
</body>
</html>
7.2数据代理
数据代理
1.Vue中的数据代理
通过vm对象来代理data中的属性操作(读/写)
2.Vue中数据代理的好处
更加方便的操作data中的数据
3.基本原理
通过 Object.defineProperty()方法把data中的所有属性添加到vm上
为每一个添加的vm上的属性都指定一个getter和setter
在getter和setter属性内部操作data中的属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>地址:{{name}}</h1>
<h1>区域:{{address}}</h1>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#root',
data () {
return {
name:'长沙',
address:'天心区',
}
}
})
</script>
</body>
</html>
8.事件处理
事件基本使用
1.使用v-on:xxx 或者@xxx 绑定事件,其中xxx是事件名
2.事件的回调配置需要在methods方法中,最终都会出现在vm上
3.methods配置中方法不要使用箭头函数,否则这里的this就不是vm;
4.mthods配置的函数都是被vue所管理的函数 this指向vm或者是组件实例对象
5.@click="demo1" 和@click="demo2($event)"效果一样,后者可以传参
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>你好,{{name}}</h1>
<button v-on:click="showInfo">点我提示信息(不传参)</button>
<button @click="showInfo2($event,11)">点我提示信息(传参)</button>
</div>
<script type="text/javascript">
const vm=new Vue({
data:{
name:'jack'
},
methods: {
showInfo(event){
//获取方法上的按钮
console.log(event)
console.log(this)//这里的this为vm实例
alert("学习Vue")
},
showInfo2(event,number){
console.log(event,number)
console.log(number)
alert("学习Vue2")
},
}
})
vm.$mount('#root')
</script>
</body>
</html>
9.事件修饰符
Vue事件修饰符
prevent 阻止默认事件
stop 阻止冒泡事件
once 事件只触发一次
修饰符可以连续写 eg:@click.stop.prevent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<!-- prevent 阻止跳转到对应页面 -->
<a href="http://www.baidu.com" @click.prevent="show">点我去百度</a>
<!-- stop阻止向上冒泡 -->
<div class="demo" @click="show">
<button @click.stop="show">点我跳转</button>
</div>
<!-- once 用一次之后就失效 -->
<button @click.once="show">按钮只能用一次</button>
</div>
<script>
const vm=new Vue({
methods: {
show(){
alert('点击跳转')
}
}
})
vm.$mount('#root')
</script>
</body>
</html>
10.键盘事件
Vue常用按键
1.enter delete(捕获删除和退格键) esc space
换行 tab(特殊,必须搭配keydown使用) 上下左右
2.系统修饰键(特殊用法)ctrl,alt,shift,meta(win键)
2.1配合keyup使用时,按下修饰键时,在按下其他键,随后释放其他键,事件被触发
2.2配合keydown使用,正常触发事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<input placeholder="点我输入" @keydown.ctrl="show">
</div>
<script>
const vm=new Vue({
el:'#root',
methods: {
show(event){
//获取输入框中的值
console.log(event.target.value)
}
}
})
</script>
</body>
</html>
11.姓名案例
11.1插值语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
姓:<input v-model="firstName" type="text"><br>
名:<input v-model="lastName" type="text"><br>
全名:<span>{{firstName}}-{{lastName}}</span>
</div>
<script>
const vm=new Vue({
el:'.root',
data () {
return {
firstName:'张',
lastName:'三'
}
}
})
</script>
</body>
</html>
11.2methods
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
姓:<input v-model="firstName" type="text"><br>
名:<input v-model="lastName" type="text"><br>
全名:<span>{{fullName()}}</span>
</div>
<script>
const vm=new Vue({
el:'.root',
data () {
return {
firstName:'张',
lastName:'三'
}
},
methods: {
fullName(){
//这里的this就是vm实例 methods被Vue管理
return this.firstName+'-'+this.lastName
}
}
})
</script>
</body>
</html>
11.3计算属性(computed)
计算属性computed
1.要通过已有的属性进行进行计算得来
2.原理:底层借助了Object.defineProperty中的getter和setter
3.get调用时间
3.1.初次读取的时候会被调用 3.2.所依赖的数据发生变化时
4.和methods进行相比,内部有缓存机制
5.计算的属性最终都会到vm上,直接使用即可
如果计算中的属性要被修改,必须要有set函数响应 且set必须要引起依赖的数据发生变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div class="root">
姓:<input v-model="firstName" type="text"><br>
名:<input v-model="lastName" type="text"><br>
全名:<span>{{fullName}}</span>
</div>
<script>
const vm=new Vue({
el:'.root',
data () {
return {
firstName:'张',
lastName:'三'
}
},
computed: {
// fullName:{
// //当fullName被读取时,get就会被调用,且返回值就是fullName的值
// //get啥时候被调用 1.初次读取的时候会被调用 2.所依赖的数据发生变化时
// get(){
// return this.firstName+'-'+this.lastName
// },
// //set啥时候调用,当fullName进行修改时
// set(value){
// //生成数组 按照指定字符串进分割
// const arr=value.split('-')
// this.firstName=arr[0]
// this.lastName=arr[1]
// }
// }
//当只有读取数据,没有修改时,可以简写
fullName:function(){
return this.firstName+'-'+this.lastName
}
}
})
</script>
</body>
</html>
12.监视属性(watch)
1.当被监视的属性发生变化时,回调函数进行调用(handler)
2.监视的属性必须存在,才能进行监视
3.两种方式
(1)new Vue({})中写入watch
(2)vm.$watch
12.1天气案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>今天天气{{info}}</h1>
<button @click="change">点我切换</button>
</div>
<script>
const vm= new Vue({
el:'#root',
data:{
isHot:true
},
computed: {
info(){
//三目运算
return this.isHot ?'炎热' :'凉爽'
}
},
methods: {
change(){
return this.isHot=!this.isHot
}
},
watch:{
// isHot:{
// //immediate:true,//初始化时调用handler
// //当isHot发生变化时,handler被调用
// handler(newValue,oldValue){
// console.log("isHot被修改了",newValue,oldValue)
// }
// }
//简写形式
isHot(){
console.log("isHot被修改了",newValue,oldValue)
}
}
})
//当创建vm实例不知道监听那个属性时,通过后续操作进行
// vm.$watch('isHot',{
// handler(newValue,oldValue){
// console.log("isHot被修改了",newValue,oldValue)
// }
// })
</script>
</body>
</html>
12.2深度监视
深度监视
1.Vue中的watch不默认监视对象内部值的改变 通过配置deep可以监视对象内部值的改变
2.Vue自身是可以监测对象内部值的改变,但vue提供的watch是不可以的
使用watch根据数据结构 是否要进行深度监视
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>{{numbers.a}}</h1>
<button @click="numbers.a++">点我a+1</button>
<h1>{{numbers.b}}</h1>
<button @click="numbers.b++">点我b+1</button>
</div>
<script>
const vm= new Vue({
el:'#root',
data:{
numbers:{
a:1,
b:1
}
},
watch:{
//监视多级结构中某个属性的变化
// 'numbers.a':{
// handler(){
// console.log('a的值被修改了')
// }
// }
//监视多级结构中的所有属性
numbers:{
deep:true,
handler(){
console.log('numbers被修改')
}
}
}
})
</script>
</body>
</html>
12.3watch和computed的区别
1.computed能完成的功能,watch也能完成
2.watch能完成的功能,computed不一定能完成 watch可以进行异步操作
2.1所有被Vue管理的函数,最好写成普通函数,这样this指向的是vm对象或者是组件实例对象
2.2所有不被Vue管理的函数(定时器的回调函数,ajax的回调函数)最好写成箭头函数,这样this的指向才是vm或者组件实例对象
13.条件渲染
1.v-if
(1)v-if="表达式"
(2)v-else-if="表达式"
(3)v-else="表达式"
适用于频率切换低的场景 不展示DOM元素直接被移除
(1)(2)(3)一起使用时,要求结构不要被打断
2.v-show="表达式"
适用于切换频率较高的场景
不展示DOM元素未被移除,只是将DOM元素通过样式进行隐藏
3.使用v-if,元素可能无法获取到 可以使用v-show一定获取到
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>欢迎来到{{name}}</h1>
<h2>当前值是{{count}}</h2>
<button @click="count++">点我值+1</button>
<!-- 使用v-show做条件渲染 -->
<!-- <div v-show="count===1">1</div>
<div v-show="count===2">2</div>
<div v-show="count===3">3</div> -->
<!-- 使用v-if做条件渲染 和v-if-else -->
<!-- <div v-if="count===1">1</div>
<div v-else-if="count===2">2</div>
<div v-else-if="count===3">3</div>
<div v-else>66</div> -->
<!-- 搭配使用 template -->
<template v-if="count===1">
<h2>你好</h2>
<h2>你好</h2>
<h2>你好</h2>
</template>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
name:'德莱联盟',
count:0
}
})
</script>
</body>
</html>
14.基本遍历+key作用原理
v-for
1.用来遍历 可以遍历数组(最多) 对象 字符串 指定次数
2.v-for="(p,index) in persons" :key="index"
key的作用原理
1.作用:key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后将新的虚拟DOM和旧的虚拟DOM进行对比
2.对比规则
(1)新的虚拟DOM和旧的虚拟DOM找到相同的key 如果内容没有改变 就直接复用之前的DOM
内容发生变化就,则生成新的DOM替换页面中的真实DOM
(2)新的虚拟DOM和旧的虚拟DOM没有找到相同key,则直接生成新的真实DOM,渲染到页面中
3.用index作为key会出现的问题
(1)对数据进行逆向的添加,删除等操作 会产生没有必要的真实DOM更新===》页面没问题 但是效率低
(2)如果结构中有输入类的DOM 会产生错误的DOM更新==》页面出现问题
4.如何选择
(1)最好使用每一条数据的唯一标识作为key
(2)不存在逆序的添加,删除操作,仅仅用于页面展示 用index作为key没有问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>人员列表</h2>
<ul>
<button @click.once="add">点我添加人员</button>
<!-- 遍历数组 对象 -->
<li v-for="(p,index) in persons" :key="p.id">
{{p.name}}-{{p.age}}
<input type="text">
</li>
<!-- 遍历对象 -->
<li v-for="(c,key) in car" :key="key">
{{key}}-{{c}}
</li>
</ul>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
persons:[
{id:'01',name:'张三',age:'18'},
{id:'02',name:'李四',age:'19'},
{id:'03',name:'王五',age:'20'}
],
car:{
name:'奔驰',
price:'100万',
address:'上海'
}
},
methods: {
add(){
const p={id:'004',name:'老刘',age:'30'}
return this.persons.unshift(p)
}
}
})
</script>
</body>
</html>
14.1案例---列表过滤
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>人员列表</h2>
<!-- 通过双向绑定获取数据 -->
<input type="text" placeholder="请输入名字" v-model="keyWord">
<ul>
<li v-for="(p,index) in newPersons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.gender}}
</li>
</ul>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
persons:[
{id:'01',name:'马冬梅',age:'18',gender:'女'},
{id:'02',name:'周冬雨',age:'19',gender:'女'},
{id:'03',name:'周杰伦',age:'20',gender:'男'},
{id:'04',name:'温兆伦',age:'21',gender:'男'}
],
// newPersons:[],
keyWord:''
},
//监视已有属性
// watch:{
// keyWord:{
// immediate:true,
// handler(val){
// this.newPersons=this.persons.filter((a)=>{
// return a.name.indexOf(val)!==-1
// })
// }
// }
// }
computed: {
newPersons(){
return this.newPersons=this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord)!==-1
})
}
}
})
</script>
</body>
</html>
14.2案例---列表排序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>人员列表</h2>
<!-- 通过双向绑定获取数据 -->
<input type="text" placeholder="请输入名字" v-model="keyWord">
<button @click="softType=2">年龄升序</button>
<button @click="softType=1">年龄降序</button>
<button @click="softType=0">原顺序</button>
<ul>
<li v-for="(p,index) in newPersons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.gender}}
</li>
</ul>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
persons:[
{id:'01',name:'马冬梅',age:'25',gender:'女'},
{id:'02',name:'周冬雨',age:'19',gender:'女'},
{id:'03',name:'周杰伦',age:'30',gender:'男'},
{id:'04',name:'温兆伦',age:'21',gender:'男'}
],
softType:0, //0原顺序 1降序 2升序
keyWord:''
},
computed: {
newPersons(){
//通过计算得到
const arr=this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord)!==-1
})
//判断是否要进行排序
if(this.softType){
arr.sort((a1,a2)=>{
//前-后 升序 后-前 降序
return this.softType===1 ? a2.age-a1.age : a1.age-a2.age
})
}
return arr
}
}
})
</script>
</body>
</html>
15.vue监视数据原理
Vue监视数据原理
1.vue会监视data中所有层次的数据
2.监测对象中的数据
通过setter实现监视,且在new Vue就传入要监视的数据【就是你的data中放什么数据】
(1)给对象后进行数据添加,不做响应式处理
(2)给后添加的数据进行响应式【data中本来的没有的数据,根据需求 进行数据添加】
Vue.set(target,propertyName/index,value) eg:Vue.set(this.stu,'sex','男')
vm.$set(target,propertyName/index,value) eg: this.$set(this.stu,'sex','男')
3.监测数组中的数据
通过包裹数组更新元素的方法实现
(1)调用原生的数组对应的更新方式(eg:push,unshift...)
(2)进行模板解析,重新更新页面
4.在Vue修改页面中的某个元素要用以下的方法
(1)使用这些API push(),pop(),shift(),unshift(),sort(),reverse(),splice()
使用filter时 会得到新的数组 将新的数组替换原来的数组
(2)使用Vue.set()或者vm.$set
注意:Vue.set()和vm.$set不能给vm或者vm的根属性(data)进行添加属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>{{msg}}</h1>
<button @click="stu.age++">点我年龄+1</button><br>
<button @click="addSex">点我添加性别,默认男</button><br>
<button @click="stu.sex='未知'">点我修改性别</button><br>
<button @click="addFriend">点我添加朋友</button><br>
<button @click="updateFriendFirst">修改列表第一个朋友</button><br>
<button @click="addHobby">添加一个爱好</button><br>
<button @click="updateHobbtFirst">修改第一个爱好为开车</button>
<h2>name:{{stu.name}}</h2>
<h2>age:{{stu.age}}</h2>
<h2 v-if="stu.sex">sex:{{stu.sex}}</h2>
<h2>hobby</h2>
<ul>
<li v-for="(h,index) in stu.hobby" :key="index">
{{h}}
</li>
</ul>
<h2>朋友</h2>
<ul>
<li v-for="(f,index) in stu.friend" :key="index">
{{f.name}}-{{f.age}}
</li>
</ul>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
msg:'学生信息',
stu:{
name:'张三',
age:'18',
hobby:['唱','跳','rap'],
friend:[
{name:'李四',age:'20'},
{name:'王五',age:'23'}
]
},
},
methods: {
addSex(){
//Vue.set(this.stu,'sex','男')
this.$set(this.stu,'sex','男')
},
addFriend(){
this.stu.friend.unshift({name:'jack',age:'20'})
},
updateFriendFirst(){
this.stu.friend[0].name='老樊'
},
addHobby(){
this.stu.hobby.push('学习')
},
updateHobbtFirst(){
// this.$set(this.stu.hobby,0,'开车')
//通过splice引起vm中数组的变化
this.stu.hobby.splice(0,1,'写代码')
}
}
})
</script>
</body>
</html>
15.1Vue.set或者this.$set引起数据改变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>人员列表</h2>
<button @click="updateMei">点我更新马冬梅数据</button>
<ul>
<li v-for="(p,index) in persons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.gender}}
</li>
</ul>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
persons:[
{id:'01',name:'马冬梅',age:'25',gender:'女'},
{id:'02',name:'周冬雨',age:'19',gender:'女'},
{id:'03',name:'周杰伦',age:'30',gender:'男'},
{id:'04',name:'温兆伦',age:'21',gender:'男'}
]
},
methods: {
updateMei(){
//奏效
// this.persons[0].name='马老师'
// this.persons[0].age='50'
// this.persons[0].gender='男'
//不可行
//this.persons[0]={id:'01',name:'马老师',age:'50',gender:'女'}
this.$set(this.persons,0,{id:'01',name:'马老师',age:'50',gender:'女'})
}
}
})
</script>
</body>
</html>
16.收集表单数据
收集表单数据
<input type="text"/> v-model收集的是vlaue值,用户输入的
<input type="radio"/>v-model收集的是value值 但是要在标签中给value值
<input type="checkbox"/>
没有在标签中配置value属性,收集的就是checkbox(布尔值)
配置input中value值(1)v-model初始值是非数组,收集的就是checkbox(布尔值)
(2)v-model初始值是数组,收集的就是value组成的数组
v-model修饰符
lazy 失去焦点时在收集数据
trim 去首尾空格
number 输入字符串转换成有效的数字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<form @submit.prevent="demo">
账号:<input type="text" v-model="account"><br>
密码:<input type="password" v-model="password"><br>
姓别:
男:<input type="radio" name="sex" v-model="sex" value="male">
女:<input type="radio" name="sex" v-model="sex" value="female"><br>
爱好:
学习:<input type="checkbox" v-model="hobby" value="study">
写代码:<input type="checkbox" v-model="hobby" value="write">
打游戏:<input type="checkbox" v-model="hobby" value="game"><br>
所属位置:
<select v-model="city">
<option value="mr">请选择地区</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
</select><br>
其他信息:
<textarea v-model="other"></textarea><br>
<input type="checkbox" v-model="agree">阅读并接受<a href="http://www.baidu.com">用户协议</a><br>
<button>提交</button>
</form>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
account:'',
password:'',
sex:'male',
hobby:[],
city:'mr',
other:'',
agree:''
},
methods: {
demo(){
console.log(JSON.stringify(this._data))
}
}
})
</script>
</body>
</html>
17.v-html指令
1.向指定节点渲染包含html结构的内容
2.和插值语法的区别
(1)v-html会替换掉节点中所有的内容,{{xxxx}}不会
(2)v-html识别html结构
3.安全性问题
在网站上任意渲染html是非常危险,容易遭受攻击
一定要在可信任的内容上使用v-html,用不要在用户提交的内容上
v-cloak指令
1.本质就是一个属性,当Vue创建实例并接管容器后,会删掉v-cloak属性
2.使用css和v-cloak可以解决网速慢时页面展示{{xxx}}问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>{{name}}</h2>
<div v-text="str"></div>
<div v-html="str"></div>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
name:'jack',
str:'<h2>是我</h2>'
}
})
</script>
</body>
</html>
17.1v-once指令和 v-pre指令
v-once指令
v-once所在的节点初次进行动态渲染后,就被当作静态内容
以后数据的变化不会引起v-once所在数据结构的更新,用于优化性能
v-pre指令
跳过所在节点的编译(就是不解析)
可以用在没有实现动态渲染的地方,用于加快解析
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 v-pre>Vue很好学</h2>
<h2 v-once>n的初始值为:{{n}}</h2>
<h2>n的值为:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
<script>
const vm=new Vue({
data:{
n:1
}
})
vm.$mount('#root')
</script>
</body>
</html>
17.2自定义指令
<!-- 指令总结
1.定义语法
(1)局部指令 new Vue({
directives:{指令名:配置对象或者回调函数}
})
(2)全局指令 Vue.directives(指令名,配置对象或者回调函数)
2.常用三个回调
bind 指令和元素进行绑定时
inserted 指令所在的元素被放到页面中
update 指令所在的模板被重新解析
3.指令定义时,不要加v- 使用时要加v-
指令名是多个单词时 中间加- eg: user-name 不要用小驼峰 eg userName
-->
需求1当点击n时,其数值扩大十倍
需求2 自定义指令 进入页面就获取input框的焦点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>n的值为{{n}}</h2>
<!-- <h2>扩大后的值为<span v-big-number="n"></span></h2> -->
<h2>扩大后的值为<span v-big="n"></span></h2>
<button @click="n++">点我n+1</button>
<input type="text" v-fbind="n">
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
n:1
},
directives:{
//elements获取绑定的文本框 binding获取绑定数据的值
//big何时被调用 1.指令和元素成功绑定时 2.指令所在的模板被重新解析时
//函数式
big(element,binding){
console.log('big',this)//这里this是window
element.innerText=binding.value*10
},
// 'big-number'(element,binding){
// console.log('big')
// element.innerText=binding.value*10
// },
//对象式
fbind:{
//指令和元素进行绑定时
bind(element,binding){
element.value=binding.value
},
//指令所在的元素被放到页面中
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析
update(element,binding){
element.value=binding.value
}
}
}
})
</script>
</body>
</html>