1.认识Vue
<div id='root'>
是一个容器,容器中写的是Vue的模版代码。- 模版代码类似于react中的jsx,是html+js的混合体
- {{xxx}},xxx会自动读取data中的xxx属性
<script type="text/javascript">
//创建一个Vue的实例对象,并传入配置对象
const vm=new Vue({ //el只能绑定一个
el:'#root',//el用于指定当前vue实例为哪个容器服务,值是选择器字符串,选择的写法类似与jQuery
data:{//data是存储数据的地方,为root容器提供数据,值为一个对象,相当于React中的state
school:{
name:'nihao',
address:'123456789',
subject: ()=>'前端'//这是箭头指示函数
}
}
})
</script>
2.模版语法
Vue模板语法有2大类:
1.插值语法:
功能:用于解析标签体内容
写法:{{xxxx}},xxx会作为表达式去解析,且可以自动读取到data中的属性
2.指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)
举例:v-bind:href="xxxxxx" 或 简写为:
备注:Vue中有很多的指令,此处我们只是拿v-bind举个例子
只有**v-bind:**可以简写成**:**
备注:v-bind支持的类型html中的属性、css的样式、对象、数组、number 类型、bool类型,它是单向变动
3.数据绑定
1.单向数据绑定(v-bind):数据只能从data流向页面
2.双向数据绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data
备注:
1.双向数据绑定一般都是针对表单类元素
2.v-model:value 可以简写为 v-model,因为v-model默认收集value值。
4.MVVM模型
MVVM的理解:
1. M:模型(Model) :对应data中的数据
2. V:视图(View) :模板代码
3. VM:视图模型(ViewModel) : Vue实例对象vm
data和el的两种写法:
1.el的第一种写法(常用)————new Vue时直接指定el的值
2.el的第二种写法(不常用)————先new Vue,后期通过vm.$mount(el)指定el的值
3.data的第一种写法,data是一个对象
4.data的第二种写法,data是一个函数,且要返回数据对象 (组件中必须用函数式data)
特别注意:
1.若使用函数式data,Vue会帮我们调用data函数,Vue就会得到返回的数据对象,从而使用,this是Vue的实例对象。
2.data不要写成箭头函数,要写成普通函数,否则this的指向就是Window了。
<script type="text/javascript" >
//el的第一种写法(常用)————new Vue时直接指定el的值
new Vue({
el:'#root',
data:{
msg:'123',
address:'456'
}
})
//el的第二种写法(不常用)————先new Vue,后期通过vm.$mount(el)指定el的值
const vm = new Vue({
data:{
msg:'123',
address:'456'
}
})
vm.$mount('#root')
//data的第一种写法,data是一个对象
new Vue({
el:'#root',
data:{
msg:'123',
address:'456'
}
})
//data的第二种写法,data是一个函数,且要返回数据对象 (组件中必须用函数式data)
new Vue({
el:'#root',
data(){
console.log(this)
return {
msg:'123',
address:'456'
}
}
})
</script>
5.数据代理
关于Vue中的数据代理:
1.什么是数据代理?
(1).配置对象data中的数据,会被收集到vm._data中,然后通过,Object.defineProperty让vm上拥有data中所有的属性。
(2).当访问vm的msg时,返回的是_data当中同名属性的值
(3).当修改vm的msg时,修改的是_data当中同名属性的值
2.为什么要数据代理?
为了更加方便的读取和修改_data中的数据。如果不使用数据代理,就要使用:vm._data.xxx访问数据
3. 为什么要先收集在_data中,然后再代理出去呢?
更高效的监视数据(直接收集到vm上会导致监视效率太低)
6.事件处理
事件绑定注意事项:
1.事件的回调都配置在methods对象中
2.methods中的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象
3.methods中的配置的函数,不要用箭头函数!!!!,否则this丢失
<div id="root">
<h2>欢迎来到{{school}}学习</h2>
<!--绑定事件----标准方式-->
<button v-on:click='show1'>点我提示:信息1(v-on绑定)</button><br><br>
<!--绑定事件---简写方式-->
<button @click='show1'>点我提示:信息1(@绑定)</button>
<!--绑定事件---传递参数-->
<button @click='show2($event,666)'>点我提示:信息2 + 传递的参数</button>
<!-- 绑定事件---阻止默认行为,prevent叫事件修饰符 .prevent即阻止-->
<a href="https://www.baidu.com" @click.prevent="show3">点我提示:信息3 (阻止默认行为)</a> <br /><br />
<!-- 绑定事件---阻止冒泡,事件修饰符可以连写,**且顺序可以随意改变** .stop -->
<div @click="show4">
<a href="https://www.baidu.com" @click.stop.prevent="show4">点我提示:信息4 (阻止冒泡)</a>
</div>
</div>
7.计算属性
1.计算属性:要显示的数据不存在,要通过计算得来。
2.fullName函数底层用到的是对象setter和getter方法
3.执行的时机:
(1).初始显示会执行一次,得到初始值去显示。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有**缓存**机制,效率更高。
5.备注:计算属性是用于直接读取使用的,不要加()
<script type="text/javascript" >
const vm = new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
},
computed:{
/*
1.fullName是谁在调用?---Vue
2.fullName什么时候调用?初次渲染会调用、当依赖的属性值发生变化
*/
//简写---相当与只指定了get,没有指定set
fullName(){
console.log('fullName')
return this.firstName + '-' + this.lastName
}
//完整写法----set和get都指定了
fullName:{
set(value){ //fullName被修改时set被调用,set中的this是vm,set会收到修改的值
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
},
get(){ //fullName被读取时get被调用,get中的this是vm
console.log('get')
return this.firstName + '-' + this.lastName
}
}
}
})
console.log(vm)
</script>
8.数据监视
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
computed和watch之间的区别:
1.只要是computed能完成的功能,watch都可以完成
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
备注:
1.所有被Vue所调用(管理)的函数,都不要写箭头函数 ----- 例如:watch中的函数、computed中的函数
2.所有不是被Vue所调(管理)的函数,都要写成箭头函数 --- 例如:定时器的回调、ajax的回调等等
3.watch就是Vue给我提供的一个监测数据改变的手段,至于数据发生改变后,要做什么,得看具体的业务了逻辑。
例如:
需要新的值、旧的值作比较,决定接下来要干什么
不要值,只要数据改变了,就要发请求等等
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三',
fullName: ''
},
watch: {
/*
1.watch中的firstName什么时候调用?data中的firstName被改变的时调用
2.watch中的firstName的this是谁?---vm
*/
//监测姓-----精简写法
firstName(newValue,oldValue){
// console.log('firstName被别人改了',newValue,oldValue)
this.fullName = newValue + '-' + this.lastName
},
//监测姓-----完整写法
firstName:{
immediate:true, //若immediate为true则handler在初始化时,就会调用一次,以后就看firstName的改变了
handler(newValue,oldValue){
this.fullName = newValue + '-' + this.lastName
}
},
//监测名-----精简写法
lastName(newValue, oldValue) {
// console.log('firstName被别人改了',newValue,oldValue)
this.fullName = this.firstName + '-' + newValue
}
}
})
vm.$watch('firstName', {
immediate: true, //若immediate为true则handler在初始化时,就会调用一次,以后就看firstName的改变了
handler(newValue, oldValue) {
setTimeout(() => { //此处定时器的回调一定要写箭头函数
this.fullName = newValue + '-' + this.lastName
}, 1000)
}
})
console.log(vm)
</script>
9.绑定样式
1. 绑定class样式
**:class="xxx"** xxx可以是字符串、对象、数组
2. 绑定style样式
**:style="{fontSize: size + 'px' }"** 其中size是data属性
<div id="root">
<!-- class的字符串写法,适用于:类名不确定,要动态获取 -->
<h2 class="atguigu" :class="myStyle">{{title}}</h2>
<!--class的对象写法,适用于:类名确定,但不确定用不用 -->
<h2 class="atguigu" :class="{classB:hasB,classC:hasC}">{{title}}</h2>
<!--class的三元表达式写法,适用于:类名确定,但不确定用不用 -->
<h2 class="atguigu" :class="hasB ? 'classB' : '' ">{{title}}</h2>
<!--class的数组写法,适用于:同时应用多个class -->
<h2 class="atguigu" :class="[a,b,c]">{{title}}</h2>
<!-- 绑定style -->
<h2 class="atguigu" :class="[a,b,c]" :style="{fontSize:size+'px'}">{{title}}</h2>
</div>
<script type="text/javascript">
new Vue({
el: "#root",
data: {
title: '0922的同学过年好',
myStyle: 'classA',
hasB: true, //标识是否使用classB样式
hasC: true, //标识是否使用classC样式
a: 'classA',
b: 'classB',
c: 'classC',
size: 40
}
})
</script>
10 条件渲染
条件渲染:
v-if:
适用于:切换频率很低的场景
特点:不展示的DOM节点直接被删除
v-show:
适用于:切换频率很高的场景
特点:不展示的DOM节点没有被删除,仅仅是使用样式隐藏掉
严重注意:使用v-if的时,DOM节点可能无法获取到,而使用v-show一定可以获取到DOM节点。