文章目录
- 一、概念
- 特点
- 举例
- 二、模板语法
- 插值语法
- 指令语法
- v-bind
- 数据绑定
- 三、组件
- el和data的两种写法
- 四、MVVM模型
- 五、数据代理
- 六、事件处理
- 基本使用
- 事件修饰符
- 键盘按键
- 七、计算属性
- 八、监听属性
- 普通监视
- 深度监视
- 监视简写
- 九、监听与计算总结
一、概念
一套用于构建用户界面的渐进式JavaScript框架
vue2官网
vue3官网
特点
采用组件化模式,提高代码复用率、且让代码更好维护。
一个组件就是一个.vue文件,.vue文件内部包括html,css和javascript三个部分
声明式编码,让编码人员无需直接操作DOM,提高开发效率。
使用虚拟DOM+优秀的Diff算法,尽量复用DOM节点。
举例
动态渲染,需要使用Vue对象将div绑定,此时通过传输的数据动态渲染到页面上
<div id="root"><h1>我的年龄是{{age}}</h1> //{{}}里面写的是Js表达式,如果没和Vue有关,写script一些函数也是可以的
</div>
<script>const x = new Vue({el:‘#root’ //使用document.getElementById('root')//e1用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串data:{age:‘18’}})
</script>
PS:若是两个id为root的盒子,则Vue只会接管第一个容器。多个Vue接管一个容器则会报错。
必须一一对应
二、模板语法
插值语法
上述案例的 { { } } \{\{\}\} {{}}就是插值语法。一般用于标签体内容
指令语法
Vue里面的指令都是v-开头
v-bind
一般管理标签属性的内容
1、<a href="url">></a>
如果正常写,url当成普通字符串执行,写成{{url}}也无法引用Vue的data,因此会解析成字符串
2、<a v-bind:href="url">></a>
加上v-bind后引号里面会被当成js的表达式,此时就可以用Vue里的data
3、v-bind可以简写成:,因此写成<a :href="url">></a>即可
数据绑定
单项数据绑定:v-bind实现单项数据绑定,Vue的值传给容器,容器中值改变不会影响Vue中data值
双向数据绑定:v-model,Vue中data和容器中值互相影响,但V-model只能应用在表单类元素(输入类元素)上
model:value 可以简写为v-model, 因为v-model默认收集的就是value值。
三、组件
el和data的两种写法
1、灵活改变elconst x = new Vue({data:{age:‘18’}})假设不写el,则可用x.$mount('#root')改变
我们console.log(x)后可以得到一个Vue实例对象,里面以$开头的都是可以给用户使用的,其他都是底层使用的,而[[Prototype]]: Object里面是Vue这个对象的一些方法和属性
2、data的函数式写法const x = new Vue({el:"#root",data:function(){return{age:‘18’}}//这么写也可以data(){return{age:‘18’}}/这么写也可以data:()=>{return{age:‘18’}}
组件必须使用data的函数式写法,data函数中的this是vue的实例对象。但注意箭头函数没有自己的this,则它的this指向window.
由Vue管理的函数,一 定不要写箭头函数!一旦写了箭头函数,this就不再是Vue实例了。
四、MVVM模型
- M:模型(Model) :对应data中的数据
data中所有的属性,最后都出现在了Vue实例对象身上。
Vue实例对象身上所有的属性及Vue原型上所有属性,在Vue模板中都可以直按使用。 - V:视图(View) :模板
- VM:视图模型(ViewModel) : Vue 实例对象
五、数据代理
数据代理:通过一个对象代理对另-个对象中属性的操作(读/写)
1、利用 defineProperty给对象添加属性,它有很多选择的功能,可以追加高级的限制Object.defineProperty(对象,'属性名',值)但是这样添加的属性不能被枚举,此时可以通过方法控制。0bject.defineProperty(person, ' age',{value:18,enumerable:true, //控制属性是否可以枚举,默认值是falsewritable:true, //控制属性是否可以被修改,默认值是falseconfigurable:true //控制属性是否可以被删除,默认值是false//当有人读取对象的属性时,get函数(getter)就会被调用,且返回值就是属性的值get: function(){ //可简写成getconsole.log('有人读取age属性了)return 值/变量 }此时变量就可以通过get进行绑定变量,属性值可以根据变量进行改变//当有人修改对象的属性属性时,set函 数(setter)就会被调用,且会收到修改的具体值set(value){console.1og('有人修改了属性属性");变量=value; //这个变量是上述get的return 变量}})
2、通过上述讲解,可以写一个最简单的数据代理
let obj = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{get(){return obj.x},set(value){obj.x = value}
})
在Vue实例对象vm中,data数据存储在_data中,vm解析时还将其数据代理放在外面。通过Object. defineProperty( )把data对象中所有属性添加到vm上。为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写) data中对应的属性。
六、事件处理
基本使用
- 使用v-on:xxx或@xxx绑定事件,其中xxx是事件名;
- 事件的回调需要配置在methods对象中,最终会在vm上;
- methods中配置的函数,不要用简头函数!否则this就不是vm了;
- methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象;
- @click=“demo"和@click=” demo($event)"效果一致, 但后者可以传参;
<button v-on:click="showInfo1">点击1</button>
<button @click="showInfo2($event,66)">点击2</button>
const Vm = new Vue( {el:'#root',data:{name: 'myself'},methods:{showInfo1(event){//target指向按钮对象,按钮对象属性和方法都可以使用,eg.event.target.innnerText可获得点击1// console.log (event.target)// console.log(this) //此处的this是vm,若showInfo1使用(event)=>函数,则this指向window,不太建议使用alert('同学你好1')},showInfo2(event,number){可以传参在括号里传入想要的值,但是一定要加上$event,单独传参event则会消失}}
})
事件修饰符
语法:@xxx.修饰符 eg.@click.stop="showInfo1"
要是需要多个修饰符,可以连这写:@xxx.修饰符.修饰符
- prevent:阻止默认事件(常用) ;
- stop:阻止事件冒泡(常用) ;
- once:事件只触发一次(常用) ;
- capture:使用事件的捕获模式;
- self:只有event.target是当前操作的元素是才触发事件;
- passive:事件的默认行为立即执行,无需等待事件回调执行完毕(用于事件处理很复杂拖慢相应速度的时候);
键盘按键
一些keyup,keydown事件可以有不同修饰符
- Vue中常用的按键别名:
回车=> enter
删除=> delete ( 捕获“删除"和“退格键)
退出=> esc
空格=> space
换行=> tab(特殊,必须配合keydown使用,keyup后会失去焦点,不能用)
上=>up
下=> down
左=> left
右=> right - Vue未提供别名的按键,可以使用按键原始的key值去绑定,可通过e.key,e.keyCode查看按键名字和编码,但注意如果有一个按键名字有两个单词的,比如CapsLock(切换大小写),要转为caps-lock (短横线命名)
- 系统修饰键(用法特殊) : ctrl、alt、 shift、meta(window键)
(1).配合keyup使用:按下F 修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。 - 也可以使用keyCode去指定具体的按键(不推荐,不同键盘不一样) keyup.keyCode
- Vue. config.keyCodes.自定义键名=键码,可以去定制按键别名,然后就可以使用别名
- 当需要多个按键搭配,可以keyup.按键1.按键2,表示只有按下按键1再按下按键2才会触发
七、计算属性
拿着data的属性去计算和加工,得到全新的属性就是计算属性
- 定义:要用的属性不存在,要通过已有属性(只能是属性,即data里面的)计算得来。
- 原理:底层借助了objcet.defineproperty方法提供的getter和Isetter.
- get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。 - 优势:与methods实现相比, 内部有缓存机制(复用),效率更高,调试方便。
- 备注:
1.计算属性最终会出现在vm上,直接读取使用即可。eg.{{fullName}}
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变
const Vm = new Vue( {el:'#root',data:{firstName: '张',lastName:'三'},methods:{}computed:{fullName :{//get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值//get什么时候调用? 1.初次读取fullName时。2. 所依赖的数据发生变化时。get(){console.log('get被调用了')// console.log(this) // 此处的this是vmreturn this.firstName + '-' + this.lastName},//set什么时候调用?当fullName 被修改时。set(value){console.1og( 'set' , value)const arr = value .split('-' )this.firstName = arr[0]this.lastName = arr[1]}}}
})
简写情况:当确定了计算属性只读不改的时候就可以使用简写形式
//function函数当get用
fullName: function(){console.log('get被调用了') return this.firstName +'-' + this.lastName
}
八、监听属性
普通监视
- 当被监视的属性变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视! !
- 监视的两种写法:
(1)new Vue时传入watch配置
(2)通过vm.$watch监视
const Vm = new Vue( {el:'#root',data:{isHot:true,number:{a:1,b:1}},watch:{//其实应该写成'isHot',只不过只有一级被省略了,要是多级结构需要加上''isHot:{immediate:true, // 初始化时让handler调用一下,默认为false//handler什么时候调用?当isHot发生改变时。handler(newValue , oldValue){console.1og( 'isHot被修改了' ,newValue, oldValue )}}}
})
//不通过上述的watch,还可以通过$watch
vm.$watch('isHot',{immediate:true, // 初始化时让handler调用一下,默认为false//handler什么时候调用?当isHot发生改变时。handler(newValue , oldValue){console.1og( 'isHot被修改了' ,newValue, oldValue )}
})
深度监视
- 深度监视:
(1).Vue中的watch默认不监测村象内部值的改变(-层)。
(2).配置deep:true可以监测对象内部值改变(多层)。 - 备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
watch:{//检测多级结构的某个属性'number.a':{}//但是若多级结构很多,写法就很冗余,单独用一级结构number不能监视子结构(存的是地址,地址里值没改变)//此时需要用到深度监视number:{deep:true,handle(newValue, oldValue){}}}
监视简写
当监视只有handle时可以使用简写形式
1、new Vue里简写watch:{//此时相当于handleisHot(newValue, oldValue){}}
2、$watch简写vm.$watch('isHot',function(newValue , oldValue){console.1og( 'isHot被修改了' ,newValue, oldValue )}})
九、监听与计算总结
- computed和Iwatch之间的区别:
1.computed能完成的功能,watch 都可以完成。
2.watch能完成的功能,computed不一 定 能完成,例如: watch以进行异步操作,比如定时等。 - 两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
2.所有不被Vue所管理的函数( 定时器的回调函数、ajax的回调函数等,Promise的回调函数),最好写成箭头函数,
这样this的指向才是vm或组件实例对象。箭头函数没有自己的this,而是往上找this