目录
一、初识Vue
1、Vue 的特点
- 采用组件化模式开发——提高了代码的复用率、方便维护
- 声明式编程,无需直接操作DOM——提高开发效率
- 使用虚拟DOM 和 优秀Diff 算法——尽量复用DOM节点
2、Vue 模板语法
<body>
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr>
<h1>指令语法</h1>
<a v-bind:href='school.url'>点我去{{school.name}}学习1</a>
</div>
<script>
new Vue({
el:'#root',
data:{
name:'jack',
school:{
name:'尚硅谷',
url:"http://www.atguigu.com"
}
}
})
</script>
</body>
- el 属性:用css选择器指定要配置那个容器
- data 中存放的是页面中要用到的数据,其中的数据都只是初始值
- data 有两种写法:
- 对象式-常用
- 函数式-这个函数是由Vue管理的函数,不能写成箭头函数,因为箭头函数没有this, 它的指向就不一定是Vue实例了
- {{}}-插值表达式,用于解析标签体内容。里面写data属性或者js表达式,一旦data中的数据发生变化,页面中用到该数据的地方也会自动更新
3、数据绑定
-
单向绑定:v-bind 数据只能从data中流向页面
-
双向绑定:v-model 数据不仅能从data中流向页面,也可以从页面中流向data; 双向绑定一般用于表单类元素(input select)
二、数据代理
1、数据代理
数据代理的底层实现原理是原型链知识,首先回顾一下Object.defineProperty(对象名, "属性名", {配置项})
如果我们要给一个对象新添加一个属性和属性值,直接在原对象中添加,那么这个属性是不参与遍历的,读和写都不方便。所以最好是通过Object.defineProperty(对象名, "属性名", {配置项})这种方式,具体操作:
<script>
let number=19
let person={
name:'andy',
sex:'男'
}
// 我们现在要通过定义属性的方法来添加一个年龄属性
Object.defineProperty(person,'age',{
enumerable:true, // 控制属性是否可枚举,默认是false
writable:true, //控制属性是否可被修改,默认值是false
get(){
return number
},
set(value){
number = value
}
})
</script>
getter 函数 和 setter 函数:
当添加的这个属性被读取时,就调用get 函数,返回这个值;
当这个属性被人改写时,就调用set函数,将新的值赋给原来的值。
何为数据代理?
数据代理就是通过一个对象代理对另一个对象中属性的操作(读 写)
2、Vue中的数据代理
通过vm 来代理对data 对象中属性的操作,具体是:
-
通过Object.definedProperty() 把data对象中所有属性添加到vm上;
-
为每一个添加到vm 上的属性都指定一个getter 和 setter;
-
在 getter 和 setter 内部操作data中对应的属性。
这样做的目的是:更加方便的读写data 中的数据。
这里要把握一个重点:vm._data == data (通过数据代理data中数据全部都添加到了vm下的_data中了)
三、事件处理和事件
1、事件处理
- 使用v-on:xxx 或者 @xxx 绑定事件;事件的回调函数配置在methods对象中,这里面的函数最终也是会在vm上
- methods 中配置的函数都是被vue所管理的函数,指向是vm ,所以不要写成箭头函数。
- methods里面的函数不进行数据代理,因为没有改写的必要,如果写在了data中,也可以,但是会降低性能。
2、事件修饰符(部分)
- prevent : 阻止默认事件
- stop: 阻止事件冒泡
- once : 事件只触发一次
<body>
<div id="root">
// @click.stop.prevent 阻止冒泡和阻止默认行为
<a href="http://www.atguigu.com" @click.stop.prevent ='showInfo'>点我提示信息</a>
</div>
</body>
<script>
const vm = new Vue({
el: '#root',
data: {
name: '尚硅谷'
},
methods: {
showInfo(e) {
alert('同学你好')
}
}
})
</script>
3、键盘事件
- 常用的按键别名
回车 => enter
删除 => delete (捕获 删除 和 退格)
退出 =>esc
空格 =>space
换行 =>tab (特殊:必须配合keydown 使用)
上 =>up
下 =>down
左 =>left
右 =>right
<input type="text" placeholder="按下回车提示输入" @keyup.enter='showinfo'>
四、计算属性和监视属性
1、计算属性
1、定义:就是要用的属性不存在,需要通过已有属性计算得来
2、原理:底层借助了Object.defineproperty 方法提供的getter 和 setter
3、get 函数什么时候执行:
(1)初次读取时会执行一次
(2)当依赖的数据发生变化时会被再次调用
4、优势:与methods相比,内部有缓存机制,效率更高,(methods需要每次调用,而计算属性是有改变的时候才调用)
5、注意:
计算属性最终会出现在vm上,直接读取使用
如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生变化。
<body>
<div id="root">
姓: <input type="text" v-model="firstName"> <br><br>
名: <input type="text" v-model="lastName"> <br><br>
全名:<span>{{fullName}}</span><br>
</div>
<script>
// 全名的拼接
const vm = new Vue({
el:'#root',
data:{
firstName: '张',
lastName: '三',
},
computed:{
fullName:{
get(){
return this.firstName + '-' + this.lastName
}
}
}
})
</script>
</body>
2、监视属性
当被监视的属性发生变化时,回调函数自动调用,进行相关操作。
监视的属性必须存在,才能进行监视
两种写法:
- 在new Vue 中传入watch配置
- vm.$watch 监视: vm.$watch(监视属性名, { handler处理函数})
深度监视:
Vue 中的watch 默认不监测对象内部值的改变(一层)
配置deep:true 可以监测对象内部值改变(多层)
监视多级结构中某个属性的变化,对象里面的属性是字符串。需要加引号
<script>
const vm = new Vue({
el:'#root',
data:{
ishot:true,
numbers:{
a:1,
b:2
}
},
watch:{
//对象里面的属性是字符串。需要加引号
'numbers.a':{
handler(){
console.log('a被改变了');
}
}
}
})
</script>
3、computed 和 watch 属性之间的区别
computed 能完成的功能,watch 都可以完成
watch 能完成的功能,computed 不一定可以,例如watch 可以进行异步操作
两个重要原则:
-
所有Vue管理的函数,最好写成普通函数,这样这里的this的指向才是vm 或组件实例对象
-
所有不被Vue所管理的函数(定时器函数,ajax的回调函数等,Promise的回调函数),最好写成箭头函数,这样这里的this的指向才是vm 或组件实例对象(箭头函数的this是根据上下文确定的)
<body> <div id="root"> 姓: <input type="text" v-model="firstName"> <br><br> 名: <input type="text" v-model="lastName"> <br><br> 全名:<span>{{fullName}}</span><br> </div> <script> const vm = new Vue({ el:'#root', data:{ firstName: '张', lastName: '三', fullName:'张-三' }, watch:{ // 不需要深度监视的时候,可以简写成一个函数 监听属性可以进行异步任务。比如添加一个定时器 firstName(newValue){ // 这里必须使用箭头函数是因为 这里的回调函数不是Vue管理的,是Js引擎 setTimeout(()=>{ this.fullName = newValue + '-'+ this.lastName },1000) }, lastName(newValue){ this.fullName = this.firstName + '-'+ newValue } } }) </script> </body>
明天继续冲鸭~~~~~