对象方法 v-bind:class="{'orange': isRipe, 'green': isNotRipe}"
数组方法v-bind:class="[class1, class2]"
行内 v-bind:style="{color: color, fontSize: fontSize+'px' }"
1)定义transition时需要设置对应的name,具体语法为:需要动画的内容或者组件或者页面
2)过渡动画主要包含6个class,分别为:
v-enter:定义元素进入过渡的初始状态,在元素插入前生效,插入后一帧删除,
v-enter-active:在元素插入前生效,在动画完成后删除,
v-enter-to:在元素插入后一帧生效,在动画完成后删除,
v-leave:离开过渡的初始状态,在元素离开时生效,下一帧删除
v-leave-active:在离开过渡时生效,在动画完成后删除
v-leave-to:离开过渡结束状态,在离开过渡下一帧生效,在动画完成后删除
⚠️:v会转化为对应的transition的name值
3)当然我们也可以自定义这六个class 可以直接在transition中设置对应的属性为对应的class名称,属性有:enter-class,enter-active-class,enter-to-class,leave-class,leave-active-class,leave-to-class
4)在同时使用过渡和css动画的时候 可以设置type属性来制定vue内部机制监听transitioned或者animationed事件来完成过渡还是动画的监听
5)如果需要设置对应的过渡时间,可以直接设置属性duration,可以直接接收一个数字(单位为毫秒),也可以接收一个对象{enter:1000,leave:300}
6)也可以设置过渡的钩子函数,具体有:before-enter,enter,after-enter,enter-cancelled,before-leave,leave,after-leave,leave-cancelled
自定义指令分为全局指令和组件指令,其中全局指令需要使用directive来进行定义,组件指令需要使用directives来进行定义,具体定义方法同过滤器filter或者其他生命周期,具体使用方法如下:
全局自定义指令 directive(name,{}),其中name表示定义的指令名称(定义指令的时候不需要带v-,但是在调用的时候需要哦带v-),第二个参数是一个对象,对象中包括五个自定义组件的钩子函数,具体包括:
bind函数:只调用一次,指令第一次绑定在元素上调用,即初始化调用一次,
inserted函数:并绑定元素插入父级元素(即new vue中el绑定的元素)时调用(此时父级元素不一定转化为了dom)
update函数:在元素发生更新时就会调用,可以通过比较新旧的值来进行逻辑处理
componentUpdated函数:元素更新完成后触发一次
unbind函数:在元素所在的模板删除的时候就触发一次
钩子函数对应的参数el,binding,vnode,oldnode,具体参数讲解如下:
```php
a、el指令所绑定的元素 可以直接操组dom元素
b、binding一个对象,具体包括以下属性:
1)name:定义的指令名称 不包括v-
2)value:指令的绑定值,如果绑定的是一个计算式,value为对应计算结果
3)oldvalue:指令绑定元素的前一个值,只对update和componentUpdated钩子函数有值
4)expression:指令绑定的原始值 不对值进行任何加工
5)arg:传递给指令的参数
6)modifiers:指令修饰符,如:v-focus.show.async 则接收的modifiers为{show:true,async:true}
c、vnode:vue编译生成的虚拟dom
d、oldVnode:上一个vnode,只在update和componentUpdated钩子函数中有效
⚠️:如果不需要其他钩子函数,可以直接简写为:directive(“focus”,function(el,binding){})
1)diff算法的作用:用来修改dom的一小段,不会引起dom树的重绘
2)diff算法的实现原理:diff算法将virtual dom的某个节点数据改变后生成的新的vnode与旧节点进行比较,并替换为新的节点,具体过程就是调用patch方法,比较新旧节点,一边比较一边给真实的dom打补丁进行替换
3)具体过程详解:
a、在采用diff算法进行新旧节点进行比较的时候,比较是按照在同级进行比较的,不会进行跨级比较
b、当数据发生改变的时候,set方法会调用dep.notify通知所有的订阅者watcher,订阅者会调用patch函数给响应的dom进行打补丁,从而更新真实的视图
c、patch函数接受两个参数,第一个是旧节点,第二个是新节点,首先判断两个节点是否值得比较,值得比较则执行patchVnode函数,不值得比较则直接将旧节点替换为新节点。如果两个节点一样就直接检查对应的子节点,如果子节点不一样就说明整个子节点全部改变不再往下对比直接进行新旧节点的整体替换
d、patchVnode函数:找到真实的dom元素;判断新旧节点是否指向同一个对象,如果是就直接返回;如果新旧节点都有文本节点,那么直接将新的文本节点赋值给dom元素并且更新旧的节点为新的节点;如果旧节点有子节点而新节点没有,则直接删除dom元素中的子节点;如果旧节点没有子节点,新节点有子节点,那么直接将新节点中的子节点更新到dom中;如果两者都有子节点,那么继续调用函数updateChildren
e、updateChildren函数:抽离出新旧节点的所有子节点,并且设置新旧节点的开始指针和结束指针,然后进行两辆比较,从而更新dom(调整顺序或者插入新的内容 结束后删掉多余的内容)
1)全局过滤器必须写在vue实例创建之前
Vue.filter('testfilter', function (value,text) { // 返回处理后的值
return value+text
})
2)局部写法:在组件实例对象里挂载。
filters: {
changemsg:(val,text)\=>{ return val + text
}
}
3)使用方式:只能使用在{undefined{}}
和:v-bind
中,定义时第一个参数固定为预处理的数,后面的数为调用时传入的参数,调用时参数第一个对应定义时第二个参数,依次往后类推
<h3 :title="test|changemsg(1234)">{{test|changemsg(4567)}}</h3>
//多个过滤器也可以串行使用
<h2>{{name|filter1|filter2|filter3}}</h2>
4)vue-cli项目中注册多个全局过滤器写法:
//1.创建一个单独的文件定义并暴露函数对象
const filter1 = function (val) {
return val + '--1'
}
const filter2 = function (val) {
return val + '--2'
}
const filter3 = function (val) {
return val + '--3'
}
export default {
filter1,
filter2,
filter3
}
//2.导入main.js(在vue实例之前)
import filters from './filter/filter.js'
//3.循环注册过滤器
Object.keys(filters).forEach(key=>{
Vue.filter(key,filters[key])
})
1)路由懒加载
2)vue-cli开启打包压缩 和后台配合 gzip访问
3)进行cdn加速
4)开启vue服务渲染模式
5)用webpack的externals属性把不需要打包的库文件分离出去,减少打包后文件的大小
6)在生产环境中删除掉不必要的console.log
plugins: [
new webpack.optimize.UglifyJsPlugin({ //添加-删除console.log
compress: {
warnings: false,
drop_debugger: true,
drop_console: true
},
sourceMap: true
}),
7)开启nginx的gzip ,在nginx.conf配置文件中配置
http { //在 http中配置如下代码,
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 8; #压缩级别
gzip_buffers 16 8k;
#gzip_http_version 1.1;
gzip_min_length 100; #不压缩临界值
gzip_types text/plain application/javascript application/x-javascript text/css
application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
}
8)添加loading效果,给用户一种进度感受
使用 v-cloak 指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除。
一般用于解决网页闪屏的问题,在对一个的标签中使用v-cloak,然后在样式中设置[v-cloak]
样式,[v-cloak]
需写在 link 引入的css中,或者写一个内联css样式,写在import引入的css中不起作用。
答:就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点),具体为:
首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。
另外compile还负责合并option。
然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)
$emit
触发当前实例上的自定义事件(并将附加参数都传给监听器回调)
$on
监听实例上自定义事件并调用回调函数,监听emit触发的事件
$once
监听一个自定义事件,但是只触发一次,在第一次触发之后移除监听器。
$off
用来移除自定义事件监听器。如果没有提供参数,则移除所有的事件监听器;如果只提供了事件,则移除该事件所有的监听器;如果同时提供了事件与回调,则只移除这个回调的监听器。
这四个方法的实现原理是:通过对vue实例挂载,然后分别使用对象存储数组对应的函数事件,其中emit通过循环查找存储的数组中对应的函数进行调用,once只匹配一次就就结束,on是将对应的函数存储到数组中,off是删除数组中指定的元素或者所有的元素事件。
1、轻量级框架
只关注视图层,是一个构建数据的视图集合,大小只有几十kb
Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统
2、简单易学
国人开发,中文文档,不存在语言障碍,易于理解和学习
3、双向数据绑定
也就是所谓的响应式数据绑定。这里的响应式不是@media 媒体查询中的响应式布局,而是指vue.js会自动对页面中某些数据的变化做出同步的响应。
也就是说,vue.js会自动响应数据的变化情况,并且根据用户在代码中预先写好的绑定关系,对所有绑定在一起的数据和视图内容都进行修改。而这种绑定关系,就是以input 标签的v-model属性来声明的,因此你在别的地方可能也会看到有人粗略的称vue.js为声明式渲染的模版引擎。
这也就是vue.js最大的优点,通过MVVM思想实现数据的双向绑定,让开发者不用再操作dom对象,有更多的时间去思考业务逻辑。
4、组件化
在前端应用,我们是否也可以像编程一样把模块封装呢?这就引入了组件化开发的思想。
Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,我们只要先在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现(填坑),然后整个应用就算做完了。
5、视图,数据,结构分离
使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作
6、虚拟DOM
现在的网速越来越快了,很多人家里都是几十甚至上百M的光纤,手机也是4G起步了,按道理一个网页才几百K,而且浏览器本身还会缓存很多资源文件,那么几十M的光纤为什么打开一个之前已经打开过,已经有缓存的页面还是感觉很慢呢?这就是因为浏览器本身处理DOM也是有性能瓶颈的,尤其是在传统开发中,用JQuery或者原生的JavaScript DOM操作函数对DOM进行频繁操作的时候,浏览器要不停的渲染新的DOM树,导致页面看起来非常卡顿。
而Virtual DOM则是虚拟DOM的英文,简单来说,他就是一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM。最后在计算完毕才真正将DOM操作提交,将DOM操作变化反映到DOM树上。
7、运行速度更快
像比较与react而言,同样都是操作虚拟dom,就性能而言,vue存在很大的优势
一、vue-loader作用:
解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理
二、用途
js可以写es6,style样式可以写scss或less
三、vue-template-compiler:
把vue-loader提取出的HTML模板编译成可执行的jacascript代码
vue-cli 项目中src目录每个文件夹和文件的用法
assets 文件夹是放静态资源
components 是放组件
router 是定义路由相关的配置
view 视图
app.vue 是一个应用主组件
main.js 是入口文件
assets和static两个都是用于存放静态资源文件。
放在static中的文件不会进行构建编译处理,也就不会压缩体积,在打包时效率会更高,但体积更大在服务器中就会占据更大的空间
放在assets中的文件会进行压缩体积、代码格式化,压缩后会放置在static中一同上传服务器。
因此建议样式文件放在assets中进行打包,引入的第三方文件放到static中,因为引入的文件已经做过打包处理。
Vue 包含两种观察数组的方法分别如下
1.变异方法
顾名思义,变异方法会改变被这些方法调用的原始数组,它们也将会触发视图更新,这些方法如下
push() pop() shift() unshift() splice() sort() reverse()
2.非变异方法
非变异方法与变异方法的区别就是,非变异方法不会改变原始数组,总是返回一个新数组,
当使用非变异方法时,可以用新数组替换旧数组,非变异方法大致有:filter(), concat() 和 slice()
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
1.当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
2.当你修改数组的长度时,例如:vm.items.length = newLength
vue针对这两个问题给出了相应的解决办法,使用这两种方法,也会触发状态更新
1.使用vue全局方法Vue.set() 或者使用vm.$set() 实例方法
2.使用 splice,caoncat等修改数组
jQuery是使用选择器($)
选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:$(“lable”).val();,它还是依赖DOM元素的值。
Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。
1)样式污染
答:在编写样式中,如果需要防止样式的污染,可以使用两种方式,一种是在组件的根元素上增加一个唯一的class或者id,然后在编写组件的样式时候在根元素对应的class或者id下进行编写;另一种方式是在对应的style上添加scoped关键字,不过该关键字对引用的框架UI无效
2)router-link在安卓上不起作用
答:不起作用的原因是因为转码编译的问题,可以使用babel来进行处理,安装babel polypill插件解决
3)初始化页面出现闪屏乱码的问题
答:这是因为vue还没有解析的情况下会容易出现花屏现象,看到类似于{undefined{data}}的字样,可以使用两种方式来进行处理,一种为:在设置index.html的根元素的元素的样式为display:none,然后在mounted中的$nextTick函数中display:block展示;另一种方式是使用vue的内置指令:v-cloak,并且在css中设置样式
[v-cloak] {
display: none;
}
4)router-link上事件无效解决方法
答:使用@click.native来进行调用原生的js事件。原因:router-link会阻止click事件,.native指直接监听一个原生事件。
vue.config.js
1.vue-router 中有两种模式 分别使用h5中history新增api来实现,静态跳转,页面不会重新加载,location.href会触发浏览器,页面重新加载一次
2.vue-router使用diff算法,实现按需加载,减少dom操作
3.vue-router是路由跳转或同一个页面跳转;location.href是不同页面间跳转;
4.vue-router是异步加载this.$nextTick(()=>{获取url});location.href是同步加载
从浏览器中创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF
axios中的发送字段的参数是data跟params两个
两者的区别在于params是跟请求地址一起发送的,data的作为一个请求体进行发送
params一般适用于get请求
data一般适用于post put 请求
每个属性都拥有自己的dep
属性,存放他所依赖的watcher
,当属性变化后会通知自 己对应的watcher
去更新
默认在初始化时会调用render
函数,此时会触发属性依赖收集 dep.depend
当属性发生修改时会触发 watcher
更新 dep.notify()