插值语法 :常用标签体内容
{{...}} ...为js表达式
指令语法:解析标签
v-bind 动态绑定
例:
简写: ====> :
例:
数据绑定
单向数据绑定:v-bind
双向数据绑定:v-model:value
简写: ====> v-model
v-model 只能应用于表单类元素
el与data两种写法
el:'#root'
v.$mount('#root')
对象式:data:{}
函数式:dara:funtion(){return{}}//此处的this是vue实例
MVVM模型
M:模型(Model):对应data中的数据
V:视图(View):模板(DOM页面结构)
VM:视图模型(ViewModel):Vue实例对象
数据代理
Object.defineproperty(x,y,z)
例:let person = {name:'a'}
number = 20
Object.defineproperty(person,age,{
value:'2',
enumerable:ture,
writable:ture,
configurable:ture,
get:function(){return number}})
set:function(value){number = value}
enumerable:控制属性是否可以枚举,默认值为false;
writable:控制属性是否可以修改,默认值为false;
configurable:控制属性是否 可以被删除,默认值为false;
当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
数据代理:通过一个对象代理对另一个对象中的属性的操作(读/写)
事件处理
v-on:click="show"//不传参
简写: ===> @click="show($event,aa)"//传参
new vue({methods:{show(event,aa){}}})
事件修饰符
@click.prevent:阻止默认事件
.stop:阻止事件冒泡
.once:事件只触发一次
.capture:使用事件的捕获模式
.self:只有在event.target是当前操作的元素时才触发事件
.passive:事件的默认行为立即执行,无需等待事件回调执行完毕
键盘事件
常用按键别名:
@keyup.enter:回车
.delete:删除(捕获删除和退格键)
.esc:退出
.space:空格
.up:上
.down:下
.left:左
.right:右
计算属性 computed
get函数执行:初次读取时会执行一次;当依赖的数据发生改变时会被再次调用。
优势:与methods实现相比,内部有缓存机制(复用),效率 更高,调试方便。
计算属性最终会出现在vm上,直接读取使用即可。
计算属性要被修改,必须写set函数去响应修改,且set中要引起计算时依赖的数据发生。
监视属性watch
当被监视的属性发生变化时,回调函数自动调用,进行相关操作;
监视的属性必须存在,才能进行监视;
监视的两种写法:1.new Vue时传入watch配置;2.通过vm.$watch监视
深度监视
vue中的watch默认不监视对象内部值的改变(一层);
配置deep:true可以监视对象内部值改变(多层);
监视多级结构中某个属性的变化:'number.a':{}
监视多级结构中所有属性的变化:number:{deep:true}
简写:ishot(newValue,oldValue){
// console.log('a',newValue,oldValue)
// }
vm.$watch('ishot',function(newValue,oldValue){
// console.log('a',newValue,oldValue)
// })
computed 和 watch 之间的区别:
1.computed能完成的功能,watch也能完成
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
两个重要的原则:1.所被vue管理的函数,最好写成普通函数,这样this的指向才是vm 或组件实例对象;2.所有不被vue所管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象。
绑定样式
1.class样式
字符串写法:适用于样式的类名不确定,需要动态指定;
:class="basic"
basic:'aaa'
数组写法 :适用于要绑定的样式个数不确定,名字也不确定;
:class="classArr"
classArr:[aaa,bbb]
对象写法:适用于要绑定的样式个数确定,名字也确定,但要动态觉得用不用;
:class="classobj"
classobj:{aaa:false,bbb:true}
2.style样式
:style="{fontSize:xxx}";//xxx是动态值
:style="[a,b]";//其中a.b是样式对象
条件渲染
v-show="true"
切换频率较高的场景,不展示的DOM元素未被移除,仅仅是使用样式隐藏;
v-if="true"
v-else-if=""
v-else=""
使用切换频率较低的场景,不展示的DOM元素直接被移除;
使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到;
temple
列表渲染
遍历数组
v-for="(p,index) in persons" :key="index"
遍历对象
v-for="(value,k) of car" :key="k"
遍历字符串
v-for="(cahr,index) of str" :key="index"
key作用与原理
1.虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当状态中的数据发生变化时,vue会根据新数据生成新的虚拟DOM,随后vue进行新虚拟DOM与旧虚拟DOM的差异比较, 比较规则如下:
2.比较规则:
(1)旧虚拟DOM中找到了与新虚拟DOM相同的key:
若虚拟DOM中内容没变,直接使用之前的真实DOM;
若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM;
(2)旧虚拟DOM中未找到与新的虚拟DOM相同的key
创建新的真实DOM,随后渲染到页面;
3.使用index作为key可能会引起的问题:
(1)若对数据进行:逆序添加,删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==>界面效果没有问题,但效率低;
(2)如果结构中还包括输入类的DOM:会产生错误DOM更新 ===>界面没有问题
4.开发中如何选择Key:
(1)最好使用每条数据的唯一标识作为key,比如id,手机号,身份证号
(2)如果不存在对数据的逆序添加删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key没有问题;
列表过滤
监视数据原理
1.vue会监视data中所有层次的数据;
2.如何监视对象中的数据:
通过setter实现监视,且要在new vue时就传入要监视的数据;
(1)对象中后追加的属性,vue默认不做响应式处理;
(2)如需给后添加的属性做响应式,请使用如下API:
vue.set(target,peopertyName/index,value)或vm.$set(target,peopertyName/index,value)
3.如何监测数组中的数据:
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1)调用元素对应的方法对数组进行更新;
(2)重新解析模板,进而更新页面;
4.在vue修改数组中的某个元素一定要用如下方法:
(1)使用这些API:push(),shift(),unshift(),splice(),sort(),reberse()
(2)vue.set()或vm.$set()
vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性。
收集表单数据
若:则v-model收集的是value值,用户输入的就是value值;
若:则v-model收集的是value值,且要给标签配置value值;
若:
1.没有配置input的value属性,那么收集的就是checked(勾选或未勾选,是布尔值);
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选或未勾选,是布尔值);
(2)v-model的初始值是数组,那么收集的就是value组成的数组;
v-model的三个修饰符:
lazy:失去焦点在收集数据;
number:输入字符串转为有效数字;
trim:输入首尾空格过滤;
BootCDN
过滤器
定义:对要显示的数据进行特定格式化后在显示(适用于一些简单逻辑的处理)
语法:1.注册过滤器:vue.filter(name,callback)或new vue(filters:{})
2.使用过滤器:{{xx | 过滤器名}}或 v-bind:属性="xxx | 过滤器名"
过滤器也可以接受额外参数,多个过滤器也可以串联;
斌没有改变原本的数据,是产生新的对应的数据;
v-text指令
v-html指令
作用:向指定节点中渲染包含html结构的内容;
与插值语法的区别:
(1)v-html会替换掉节点中所有的内容,{{}}则不会;
(2)v-html可以识别html结构;
v-html有安全性问题:
(1)在网站上动态渲染任意html是非常危险的,容易导致xss攻击;
(2)不要用在用户提交的内容上;
v-cloak指令
v-once指令
所在节点在初次动态渲染后,就视为静态内容;
以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能;
v-pre指令
跳过其所在节点的编译过程;
可利用它跳过:没有使用指令语法,没有使用插值语法的节点,会加快编译;
自定义指令——函数式——对象式
1.局部指令:
new Vue({directive:{指令名:配置对象})}
或 new Vue({directive(){}})
2.全局指令:
Vue.directive(指令名,配置对象)
或 Vue.directive(指令名,回调函数)
配置对象中常用的三个回调:
(1)bind:指令与元素成功绑定时调用;
(2)inserted:指令所在元素被插入页面时调用;
(3)update:指令所在模板结构被重新解析时调用;
指令定义时不加v-,但使用时要加v-;
指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名;
生命周期
又名:生命周期回调函数,生命周期函数,生命周期钩子;
Vue在关键时刻帮我们调用的一些特殊名称的函数;
生命周期函数的名字不能更改;
生命周期函数的this指向是vm 或组件实例对象;
beforeCreate created
挂载 beforMount mounted
mounted:发生ajax请求,启动定时器,绑定自定义事件,订阅消息等【初始化操作】
Vue完成模板的解析并把初始的真是DOM元素放入页面后(挂载完毕)调用mounted
更新 beforeUpdate updated
beforeUpdate: 数据是新的,但页面是旧的;即:页面尚未和数据保持同步;
updated: 页面和数据同步
销毁 beforeDestroy destroyed
beforeDestroy: 清楚定时器,解绑自定义事件,取消订阅消息等【收尾工作】
关于销毁Vue实例:
1.销毁后借助Vue开发者工具看不到任何信息;
2.销毁后自定义事件会失效,但原生DOM事件依然有效;
3.一般不会在beforeDestroy操作数据,因为即便操作数据也不会触发更新数据
组件
实现应用中局部功能代码和资源的集合
非单文件组件
Vue中使用组件的三大步骤:
1.定义组件(创建组件)2.注册组件3.使用组件(写组件标签)
(1)定义组件:
使用Vue.extend(options)创建,其中options 和 new Vue(options)时传入的那个options几乎一样,但区别如下:
el不要写,最终所有的组件都要经过vm管理,由vm中的el决定服务哪个容器;
data必须写成函数,避免组件被复用时,数据存在引用关系;
使用template可以配置组件结构
2.注册组件:
(1)局部注册:靠new Vue的时候传入components选项
(2)全局注册:靠Vue.componet('组件名',组件)
3.编写组件标签
1.关于组件名:
(1)一个单词组成:school/School;
(2)多个单词组成:my-school/MySchool(需要Vue脚手架支持)
组件名尽可能避免HTML中已有的元素名称;
可以使用name配置项指定组件在开发者工具中呈现的名字;
2.关于组件标签:
(1)
(2)
不用使用脚手架时,
3.简写方式:
const school = Vue.extend(options)可简写:const school = options
组件嵌套
VueCommponet:
1.school组件本质是一个名为VueComponet的构造函数,是Vue.extend生成的;
2.我们只需写
3.每次调用Vue.extend,返回的都是一个全新的VueComponent;
4.关于this指向:
(1)组件配置中:data函数,methods中的函数,watch中的函数,computed中的函数,它们的this均是VueComponent实例对象;
(2)new Vue()配置中:data函数,methods中的函数,watch中的函数,computed中的函数,它们的this均是Vue实例对象;
5.VueComponent的实例对象,以后简称VC,也称组件实例对象;Vue的实例对象简称vm
内置关系
VueComponent.prototype._proto_===Vue.prototype
让组件实例对象(vc)可以访问到Vue原型剩的属性,方法;
单文件组件
School.vue-...-App.vue-main.js-index.html
Vue脚手架
render函数
render(createElement){return creaElement('h1','你好')}
render:h=>h(App)
关于不同版本的Vue
1.vue.js与vue.runtime.xxx.js的区别:
(1)vue.js是完整版的Vue,包含核心功能和模板解析器
(2)vue.runtime.xxx.js是运行版的vue,只包含核心功能,没有模板解析器
2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,
需要使用render函数收到creatElement函数去指定具体内容
修改默认配置
## 脚手架文件结构
|—— node modules
|—— public
| |—— favicon.ico:页面图标
| |—— index.html: 主页面
|—— src
| |—— assets: 存放静态资源
| | |—— logo.png
| |—— component: 存放组件
| | |—— HelloWord.vue
| |—— App.vue: 汇总所有组件
| |—— main.js: 入口文件
|—— .gitignore: git版本管理忽略的配置
|—— babel.config.js: babel的配置文件
|—— jsconfig.json: 应用包配置文件
|—— README.md: 应用描述文件
|—— package-lock.json: 包版本控制文件
ref属性
1.被用来给元素或子组件注册引用信息(id的替代者)
2.应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3.使用方法:
打标识:
props配置
功能:让组件接受外部传过来的数据;
(1)传递数据:
(2)接受数据:
第一种方式(只接受):props:['name'];
第二种方式(限制类型):props:{name:'aaa'};
第三种方式(限制类型,限制必要性,指定默认值):props:{name:'aaa',type:String,default:'bbb',//默认值 required:true//必要性};
props是只读的,Vue底层会监测你对props的修改,如果修改了会发出警告,如果需要修改,需复制props的内容到data中,然后再修改data中的数据
mixin混入
功能:可以吧多个组件公共的配置提取成一个混入对象;
使用方式:
第一步定义混合,例:{data(){...},methods:{}}
第二步使用混合,例:1.全局混入:Vue.mixin(xx);2.局部混入:mixins:['xx']
插件
功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据;
定义插件:
对象:install = function(Vue,options){
//1.添加全局过滤器
Vue.filter(..)
//2.添加全局指令
Vue.directive(..)
//3.配置全局混入
Vue.mixin(..)
//4.添加实例方法
Vue.prototype.$myMethod = function(){..}
Vue.protptype.$myProperty = xxx}
使用插件: Vue.use()
scoped样式
作用:让样式在局部生效,防止冲突;
写法:
1.组件化编码流程
1).实现静态组件:抽取组件,使用组件实现静态页面效果
2).展示动态数据:
(1)数据类型。名称是什么;
(2)数据保存在哪个组件;
3)交互--从绑定事件监听开始
2.prpps适用于:
(1)父组件--->子组件通信
(2)子组件 --->父组件通信(要求父给子一个函数)
3.使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不能修改的;
4.props传过来的若是对象类型的值,修改对象中的属性时VUe不会报错,但不推荐这样做;
webStorage 本地存储
API:localStorage.setItem('key','value')(存储数据)
/.getItem('key')(读取数据)//如果获取不到value返回null
/.removeItem('key')(删除 数据)
/.clear(清空数据)
localStorage:存储的内容需手动清除才会消失;
sessionStorage:存储的内容随着浏览器的关闭而消失
JSON.parse(null)的结果依然是null
组件自定义事件
1。一种组件间通信的方式,适用于:子组件---->父组件
2.使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)
3.绑定自定义事件:
(1)在父组件中:
(2) 在父组件中:
3.若想让自定义事件只能触发一次,可以使用once修饰符,或$once()方法;
4.触发自定义事件:this.$emit('hello',数据)
5.解绑自定义事件:this.$off('hello')
6.组件上也可以绑定原生DOM事件,需要使用native修饰符;
7.注意:通过this.$refs.xxx.$on('hello',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出现问题
全局事件总线:任意组件间通信
(GlobalEventBus)
1.一种组件间通信的方式,适用于任意组件间通信;
2.安装全局事件总线:
new Vue({
...
beforeCreate(){Vue.prototype.$bus = this//安装全局事件总线,$bus就是当前应用的vm},
...
})
3.使用事件总线
(1)接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件回调留在A组件自身;
methods(){
demo(data){...}
},
....
mounted(){
this.$bus.$on('xxx',this.demo)
}
(2)提供数据:this.$bus.$emit('xxx',数据)
4.最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件;
消息订阅与发布(pubsub)
1.一种组件间通信的方式,适用于任意组件间通信
2.使用步骤:
(1)安装pubsub:npm i pubsub-js
(2)引入:import pubsub from 'pibsub-js'
(3)接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
methods(){demo(data){..}}
...
mounted(){this.pid = pubsub.subscribe('xxx',this.demo)}//订阅消息
(4)提供数据:ppubsub.publish('xxx',数据)}
(5)最好在beforDestroy钩子中,用PubSub.unsubscribe(pid)去注销订阅
nextTick
1.语法:this.$nextTick(回调函数)
2.作用:在下一次DOM更新结束后执行其指定的回调函数;
3.什么时候使用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行;
动画效果
过度效果 v-enter-active
集成动画库 npm animate.css
配置代理
npm i axios
vue cli
开启代理服务器
在vue.config.js中添加配置
方式1.devServer:{proxy: 'http://localhost:5000'}
配置简单,请求资源时直接发送给前端8080即可;不能配置多个代理,不能灵活的控制请求是否走代理;工作方式:若按照上述配置代理,当前端不存在的资源时,那么该请求就会转发给服务器(优先匹配前端资源)
方式2.devServer:{
proxy:{
'/api':{ //匹配所有以‘api’开头的请求路径
target:'
ws:true,
changeOrigin:true,//false:服务器收到的请求头中的host为:locallhost:8000;true:服务器收到的请求头中的host为:locallhost:5000;默认为true
pathRewrite:{'^/api':''}},
'/foo':{target:'
可以配置多个代理,且可以灵活的控制请求是否走代理;配置略微繁琐,请求资源时必须加前缀;