1、对于MVVM的理解
Model
:代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View
: 代表UI 组件,它负责将数据模型转化成UI 展现出来。
ViewModel
: 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
2、双向数据绑定原理
https://www.jianshu.com/p/3e6b89d7d7ad
https://my.oschina.net/liuxinzhou/blog/2244630
3、什么是渐进式框架
在我看来,渐进式代表的含义是:主张最少。
每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。
比如说,Angular,它两个版本都是强主张的,如果你用它,必须接受以下东西:
- 必须使用它的模块机制- 必须使用它的依赖注入- 必须使用它的特殊形式定义组件(这一点每个视图框架都有,难以避免)
所以Angular是带有比较强的排它性的,如果你的应用不是从头开始,而是要不断考虑是否跟其他东西集成,这些主张会带来一些困扰。
比如React,它也有一定程度的主张,它的主张主要是函数式编程的理念,比如说,你需要知道什么是副作用,什么是纯函数,如何隔离副作用。它的侵入性看似没有Angular那么强,主要因为它是软性侵入。
Vue可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。
渐进式的含义,我的理解是:没有多做职责之外的事。
4、生命周期的理解
https://www.jianshu.com/p/410b6099be69
https://segmentfault.com/a/1190000008010666
5、组件间通信
(1)、props/$emit
(2)、$emit/on
(3)、vuex
(4)、$attrs
/ $listeners
(5)、Vue.observable/inject
(6)、$ref
/$parent
/$children
https://segmentfault.com/a/1190000019208626?utm_source=tag-newest
6、vuex原理
https://blog.csdn.net/weixin_44667072/article/details/101164766
7、vue-router原理
https://www.jianshu.com/p/4295aec31302
8、router和route的区别
(1).router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。
举例:history对象
$router.push({path:'home'})
:本质是向history栈中添加一个路由,在我们看来是 切换路由,但本质是在添加一个history记录
方法:
$router.replace({path:'home'})
://替换路由,没有历史记录
(2).route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等
$route.path
字符串,等于当前路由对象的路径,会被解析为绝对路径,如 "/home/news" 。
$route.params
对象,包含路由中的动态片段和全匹配片段的键值对
$route.query
对象,包含路由中查询参数的键值对。例如,对于 /home/news/detail/01?favorite=yes ,会得到$route.query.favorite == 'yes' 。
$route.router
路由规则所属的路由器(以及其所属的组件)。
$route.matched
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
$route.name
当前路径的名字,如果没有使用具名路径,则名字为空。
$route.path
, $route.params
, $route.name
, $route.query
这几个属性很容易理解,主要用于接收路由传递的参数
9、路由钩子
1、路由钩子
在某些情况下,当路由跳转前或跳转后、进入、离开某一个路由前、后,需要做某些操作,就可以使用路由钩子来监听路由的变化
全局路由钩子:router.beforeEach
注册一个全局前置守卫
router.beforeEach((to, from, next) => {
//会在任意路由跳转前执行,next一定要记着执行,不然路由不能跳转了
console.log('beforeEach')
console.log(to,from)
//
next()
})
//
router.afterEach((to, from) => {
//会在任意路由跳转后执行
console.log('afterEach')
})
单个路由钩子:
只有beforeEnter
,在进入前执行,to参数就是当前路由
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
路由组件钩子:
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
https://segmentfault.com/a/1190000019635485
10、vue中v-if与v-show的区别以及使用场景
区别
1.手段:v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;
2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
3.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;
4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
使用场景
基于以上区别,因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
总结
v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;v-show调整DOM元素的CSS的dispaly属性,可以使客户端操作更加流畅,但有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
11、vue里边如何让css样式只在当前组件中生效
方法很简单,在组件中的style前面加上scoped就可以了,示例:
什么是 scoped?
scoped
属性是 HTML5 中的新属性,是一个布尔属性,如果使用该属性,则样式仅仅应用到 style 元素的父元素及其子元素。
scoped的实现原理?
vue中的scoped属性的效果主要通过PostCSS转译实现,如下是转译前的vue代码:
转译后:
即:PostCSS给一个组件中的所有dom添加了一个独一无二的动态属性,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom,这种做法使得样式只作用于含有该属性的dom——组件内部dom。
** 为什么需要穿透scoped?**
scoped看起来很美,但是,在很多项目中,会出现这么一种情况,即:引用了第三方组件,需要在组件中局部修改第三方组件的样式,而又不想去除scoped属性造成组件之间的样式污染。此时只能通过特殊的方式,穿透scoped
** scoped 穿透:**
1、使用 >>>
可以穿透 scoped
属性,修改其他第三方组件的样式。
2、使用曲线救国的一个方法,用两个 style
标签,一个带 scoped
属性,一个不带 scoped
属性,用来修改第三方组件的样式。
3、使用 sass 或 less 的样式穿透 /deep/
4、还有一种就是不使用 scoped
属性,通过在最外层加 id
或者 class
的形式进行区分。
不论是使用何种方式,都需要与团队的同事沟通好,统一使用哪种方法,保证项目整合的时候不会出现冲突。
12、keep-alive 的作用
keep-alive是什么
keep-alive是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
一个场景
用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面,我们希望:列表页面可以保留用户的筛选(或选中)状态。
keep-alive就是用来解决这种场景。当然keep-alive不仅仅是能够保存页面/组件的状态这么简单,它还可以避免组件反复创建和渲染,有效提升系统性能。总的来说,keep-alive用于保存组件的渲染状态。
https://www.jianshu.com/p/9523bb439950
13、vue中使用插件的步骤
采用ES6的import ... from ...语法或CommonJS的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })
14、$nextTick
this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
https://www.cnblogs.com/jin-zhe/p/9985436.html
15、vue的优点
低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变
可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写
16、路由跳转
1、
router-link
2、this.$router.push()
(函数里面调用)
3、this.$router.replace()
(用法同上,push)
4、this.$router.go(n) ()
ps : 区别
this.$router.push
跳转到指定url路径,并想history栈中添加一个记录,点击后退会返回到上一个页面
this.$router.replace
跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面 (就是直接替换了当前页面)
this.$router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数
https://www.jb51.net/article/160401.htm
17、vue SSR
其基本实现原理
app.js 作为客户端与服务端的公用入口,导出 Vue 根实例,供客户端 entry 与服务端 entry 使用。客户端 entry 主要作用挂载到 DOM 上,服务端 entry 除了创建和返回实例,还进行路由匹配与数据预获取。
webpack 为客服端打包一个 Client Bundle ,为服务端打包一个 Server Bundle 。
服务器接收请求时,会根据 url,加载相应组件,获取和解析异步数据,创建一个读取 Server Bundle 的 BundleRenderer,然后生成 html 发送给客户端。
客户端混合,客户端收到从服务端传来的 DOM 与自己的生成的 DOM 进行对比,把不相同的 DOM 激活,使其可以能够响应后续变化,这个过程称为客户端激活 。为确保混合成功,客户端与服务器端需要共享同一套数据。在服务端,可以在渲染之前获取数据,填充到 stroe 里,这样,在客户端挂载到 DOM 之前,可以直接从 store 里取数据。首屏的动态数据通过 window.INITIAL_STATE 发送到客户端
Vue SSR 的实现,主要就是把 Vue 的组件输出成一个完整 HTML, vue-server-renderer 就是干这事的
Vue SSR 需要做的事多点(输出完整 HTML),除了 complier -> vnode,还需如数据获取填充至 HTML、客户端混合(hydration)、缓存等等。 相比于其他模板引擎(ejs, jade 等),最终要实现的目的是一样的,性能上可能要差点
18、vue中为何将data写成函数
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。
https://www.cnblogs.com/wangjiachen666/p/9876266.html
19、computed实现
建立与其他属性(如:data、 Store)的联系;
属性改变后,通知计算属性重新计算
实现时,主要如下
1、初始化 data, 使用 Object.defineProperty 把这些属性全部转为 getter/setter。
2、初始化 computed, 遍历 computed 里的每个属性,每个 computed 属性都是一个 watch 实例。每个属性提供的函数作为属性的 getter,使用 Object.defineProperty 转化。
3、Object.defineProperty getter 依赖收集。用于依赖发生变化时,触发属性重新计算。
若出现当前 computed 计算属性嵌套其他 computed 计算属性时,先进行其他的依赖收集
20、complier实现
模板解析这种事,本质是将数据转化为一段 html ,最开始出现在后端,经过各种处理吐给前端。随着各种 mv* 的兴起,模板解析交由前端处理。
总的来说,Vue complier 是将 template 转化成一个 render 字符串。
可以简单理解成以下步骤:
parse 过程,将 template 利用正则转化成 AST 抽象语法树。
optimize 过程,标记静态节点,后 diff 过程跳过静态节点,提升性能。
generate 过程,生成 render 字符串
21、怎么快速定位哪个组件出现性能问题
用 timeline 工具。 大意是通过 timeline 来查看每个函数的调用时常,定位出哪个函数的问题,从而能判断哪个组件出了问题
22、开发中常用到的指令
https://cn.vuejs.org/v2/api/#v-text
v-text
v-html
v-on
修饰符:
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
v-bind
修饰符:
.prop - 作为一个 DOM property 绑定而不是作为 attribute 绑定。(差别在哪里?)
.camel - (2.1.0+) 将 kebab-case attribute 名转换为 camelCase。(从 2.1.0 开始支持)
.sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的v-on
侦听器。
v-if
v-else-if
v-else
v-show
v-for
v-model
修饰符:
.lazy
- 取代input
监听change
事件
.number
- 输入字符串转为有效的数字
.trim
- 输入首尾空格过滤
v-slot
v-pre
v-cloak
v-once
23、vue父子组件生命周期的顺序
父组件beforeCreate > 父组件created > 父组件beforeMount > 子组件beforeCreate > 子组件created > 子组件beforeMount > 子组件mounted > 父组件mounted > 父组件beforeDestroy > 子组件beforeDestroy > 子组件destroyed > 父组件destroyed
销毁的时候,父组件先执行beforeDestroy,然后子组件执行beforeDestroy和destroyed 后,父组件才执行destroyed。
当父组件给子组件传参,进行更新的时候
父组件beforeUpdate > 子组件beforeUpdate > 子组件updated > 父组件updated
24、proxy和object.defineProperty的区别
https://blog.csdn.net/qwe435541908/article/details/107360849
- Proxy使用上比Object.defineProperty方便的多。
- Proxy代理整个对象,Object.defineProperty只代理对象上的某个属性。
- 如果对象内部要全部递归代理,则Proxy可以只在调用时递归,而Object.defineProperty需要在一开始就全部递归,Proxy性能优于Object.defineProperty。
- 对象上定义新属性时,Proxy可以监听到,Object.defineProperty监听不到。
- 数组新增删除修改时,Proxy可以监听到,Object.defineProperty监听不到。
- Proxy不兼容IE,Object.defineProperty不兼容IE8及以下。
25、vue响应式数据-修改对象的属性值,视图不更新
https://blog.csdn.net/qq_36135258/article/details/107586425
https://www.cnblogs.com/lianchenxi/p/11731311.html
原因
vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。对于已经创建的实例,Vue允许动态添加根级别的响应式 property。
26、vue 和react的区别
https://www.jianshu.com/p/b7cd52868e95?from=groupmessage
27、vue中computed和watch的区别
https://www.cnblogs.com/jiajialove/p/11327945.html
28、vue双向数据绑定原理
https://blog.csdn.net/zhangyuea/article/details/89458843
29、ref
https://cn.vuejs.org/v2/api/#ref
ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
30、vue修饰符
详见问题22
vue的性能优化
1、源码方面
2、打包方面
http://baijiahao.baidu.com/s?id=1655581973404072017&wfr=spider&for=pc
31、Vue.extend和Vue.component的区别
https://segmentfault.com/a/1190000021185841?utm_source=tag-newest
vue.extend
:相当于一个扩展实例的构造器, 用于创建一个具有初始化选项的Vue子类,在实例化时可以进行扩展选项,最后使用$mount方法绑定在元素上。
vue.component
:vue.component用于全局注册组件
32、vue.nextTick和vm.$nextTick的区别
相同点:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
不同点:不同的是$nextick回调的 this 自动绑定到调用它的实例上。
33、vueSPA应用优化
1、gzip压缩(https://blog.csdn.net/qq_43363884/article/details/108195408)
方法1:打包的时候通过webpack配置生成对应的 .gz 文件(compression-webpack-plugin),浏览器请求xx.js/css等文件时,服务器返回对应的xxx.js.gz文件;
方法2:浏览器请求xx.js文件时,服务器对xx.js文件进行gzip压缩后传输给浏览器(服务器在线gzip压缩)。
2、cdn缓存(https://www.cnblogs.com/wiliam/p/12587893.html)
https://segmentfault.com/a/1190000013239622
3、减小入口文件体积(路由懒加载)
4、第三方按需加载
5、图片转base64
6、Preload & Prefetch(预加载和预判加载)
34、移动端用vue设计一个比较友好的header组件
当时的思路是头部(Header)一般分为左、中、右三个部分,分为三个区域来设计,中间为主标题,每个页面的标题肯定不同,所以可以通过vue props的方式做成可配置对外进行暴露,左侧大部分页面可能都是回退按钮,但是样式和内容不尽相同,右侧一般都是具有功能性的操作按钮,所以左右两侧可以通过vue slot插槽的方式对外暴露以实现多样化,同时也可以提供default slot默认插槽来统一页面风格
35、既然Vue通过数据劫持可以精准探测数据变化,为什么还需要虚拟DOM进行diff检测差异?
现在前端框架有两种数据变动侦测方式,一种是pull,一种是push.
pull 的代表是React ,在进行 setState 操作后显示更新数据,React 会使用 diff 算法一层层找出差异,然后 patch 到 DOM 树上,React 一开始不知道那里变化了,只是知道变化了,然后暴力进行查找那变化了,另一个代表是 Angular 的脏检查。
Vue 的响应式系统就是 Push 的代表,Vue 初始化的时候就会对 data 的数据进行依赖收集,因此Vue能实时知道那里发生了变化,一般绑定的细粒度过高,会生成大量的Watcher 实例,则会造成过大的内存和依赖追踪的开销,而细粒度过低无法侦测到变化。因此,Vue采用的是中等细粒度的方案,只针对组件级别的进行响应式监听也就是push,这样可以知道那个组件发生了变化,再对组件进行diff算法找到具体变化的位置,这是pull操作,vue是pull + push 结合进行变化侦测的。
36、Vue为什么没有类似于React中shouldComponentUpdate的生命周期?
根本原因是Vue与React的变化侦测方式有所不同:
React
是pull的方式侦测变化,当React知道发生变化后,会使用Virtual Dom Diff进行差异检测,但是很多组件实际上是肯定不会发生变化的,这个时候需要用shouldComponentUpdate进行手动操作来减少diff,从而提高程序整体的性能。
Vue
是pull+push的方式侦测变化的,在一开始就知道那个组件发生了变化,因此在push的阶段并不需要手动控制diff,而组件内部采用的diff方式实际上是可以引入类似于shouldComponentUpdate相关生命周期的,但是通常合理大小的组件不会有过量的diff,手动优化的价值有限,因此目前Vue并没有考虑引入shouldComponentUpdate这种手动优化的生命周期.
37、vue是如何监听数组变化的
https://www.cnblogs.com/ming1025/p/13082822.html
vue源码中重写了数组的push、pop、shift、unshift、splice、sort、reverse七种方法,重写方法在实现时除了将数组方法名对应的原始方法调用一遍并将执行结果返回外,还通过执行ob.dep.notify()将当前数组的变更通知给其订阅者,这样当使用重写后方法改变数组后,数组订阅者会将这边变化更新到页面中。
38、virtual DOM和diff算法
https://segmentfault.com/a/1190000020663531
https://www.cnblogs.com/wind-lanyan/p/9061684.html
https://blog.csdn.net/netox99/article/details/78691571
39、vue模板编译原理
https://segmentfault.com/a/1190000013763590
第一步是将 模板字符串 转换成 element ASTs(解析器)
第二步是对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化(优化器)
第三步是 使用 element ASTs 生成 render 函数代码字符串(代码生成器)
40、delete和vue.delete的区别
delete只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。
Vue.delete直接删除了数组 改变了数组的键值。
var a=[1,2,3,4]
var b=[1,2,3,4]
delete a[1]
console.log(a) //[empty,2,3,4]
this.$delete(b,1)
console.log(b) //[2,3,4]
41、Vue.js介绍
Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API;
Vue.js是一个构建数据驱动的Web界面的库。
Vue.js是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和 Vue生态系统支持的库开发的复杂单页应用。数据驱动+组件化的前端开发。
简而言之:Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API实现响应的数据绑定和组合的视图组件。核心是一个响应的数据绑定系统。
42、请说出vue.cli项目中src目录每个文件夹和文件的用法
assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是一个应用主组件;main.js是入口文件
43、v-on可以监听多个方法吗?
可以。
44、vue如何兼容ie
babel-polyfill插件
45、简述每个周期具体适合哪些场景
beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted : 挂载元素,获取到DOM节点 updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框
46、动态绑定class
对象方法
-最简单的绑定(这里的active加不加单引号都可以,以下也一样都能渲染)
:class="{ 'active': isActive }"
判断是否绑定一个active
:class="{'active':isActive==-1}"
或者
:class="{'active':isActive==index}"
绑定并判断多个
第一种(用逗号隔开)
:class="{ 'active': isActive, 'sort': isSort }"
第二种(放在data里面)
//也可以把后面绑定的对象写在一个变量放在data里面,可以变成下面这样
:class="classObject"
data() {
return {
classObject:{ active: true, sort:false }
}
}
第三种(使用computed属性)
:class="classObject"
data() {
return {
isActive: true,
isSort: false
}
},
computed: {
classObject: function () {
return {
active: this.isActive,
sort:this.isSort
}
}
}
数组方法
单纯数组
:class="[isActive,isSort]"
data() {
return{
isActive:'active',
isSort:'sort'
}
}
数组与三元运算符结合判断选择需要的class
(注意:三元运算符后面的“:”两边的class需要加上单引号,否则不能正确渲染)
:class="[isActive?'active':'']"
或者
:class="[isActive==1?'active':'']"
或者
:class="[isActive==index?'active':'']"
或者
:class="[isActive==index?'active':'otherActiveClass']"
数组对象结合动态判断
//前面这个active在对象里面可以不加单引号,后面这个sort要加单引号
:class="[{ active: isActive }, 'sort']"
或者
:class="[{ active: isActive==1 }, 'sort']"
或者
:class="[{ active: isActive==index }, 'sort']"
47、vue.use()
https://www.jianshu.com/p/7775028cd2f4
48、vue2.x 和vue3.x 的区别
https://www.cnblogs.com/cxddgz/p/13153570.html
49、介绍一下vue.js数据绑定 ,通过对象的set/get属性(闭包的使用)
// Vue.js 数据绑定就是通过对象的set/get属性完成的
// 在vue组件配置对象中声明的数据,会在创建组件对象时,会以set/get属性的方式将数据作为属性添加到组件对象上,在set方法添加了重新渲染组件的代码.所在,每当组件中的数据发生变化,执行set函数,先做属性赋值,然后执行渲染
var main = document.getElementById("main")
let template = main.innerHTML
function initData(){
// 正常的局部变量生命周期, 执行函数创建局部变量->使用局部变量->函数执行结束销毁局部变量
let num = null
let str
Object.defineProperty(window, "num", {
// 外部函数initdata中声明了一个内部函数set,并且在内部函数中使用到了外部函数的局部变量,这个内部函数称之为闭包函数.
// 闭包特点:1.函数套函数 2.内部函数必须使用外部函数的局部变量
// 闭包函数中由于使用了使用了外部函数的局部变量,导致外部函数执行完成后局部变量无法得到及时释放,导致内存泄露
set(v){
num = v
// 同步渲染页面
// 正则表达式
render()
},
get(){
console.log("num属性的get函数被调用了")
return num
}
})
Object.defineProperty(window, "str", {
// 外部函数initdata中声明了一个内部函数set,并且在内部函数中使用到了外部函数的局部变量,这个内部函数称之为闭包函数.
// 闭包特点:1.函数套函数 2.内部函数必须使用外部函数的局部变量
// 闭包函数中由于使用了使用了外部函数的局部变量,导致外部函数执行完成后局部变量无法得到及时释放,导致内存泄露
set(v){
str = v
// 同步渲染页面
// 正则表达式
render()
},
get(){
console.log("num属性的get函数被调用了")
return str
}
})
function render(){
let html = template
var reg = /{{([a-zA-Z0-9_$]+)}}/g
var arr
// 循环查找符合正则的数据
while (arr = reg.exec(html)){
console.log(arr)
// window["num"]
// 取出window中对应的属性值
let v = window[arr[1]]
// 替换对应的属性
html = html.replace("{{"+arr[1]+"}}", v)
}
// html就是替换后的代码
main.innerHTML = html
}
}
initData()
// 设置window的num属性,执行num属性的set函数
num = 10
// 访问window的num属性,执行num属性的get函数
console.log(num)
str = "hello"
// num = 20
str = "word"
function btnClick(){
str = "你好"
num = 23333
}
50、Vue 中 强制组件重新渲染的正确方法
https://segmentfault.com/a/1190000021599461
简单粗暴的方式:重新加载整个页面
不妥的方式:使用 v-if
较好的方法:使用Vue的内置forceUpdate方法
最好的方法:在组件上进行 key 更改(强制 Vue 重新渲染组件的最佳方法是在组件上设置:key。 当我们需要重新渲染组件时,只需更 key 的值,Vue 就会重新渲染组件。)
51、白屏是什么引起的,如何优化
vue 如何优化首页的加载速度?vue 首页白屏是什么问题引起的?如何解决呢?
首先分析原因
VUE首页加载过慢,其原因是因为它是一个单页应用,需要将所有需要的资源都下载到浏览器端并解析。
考虑解决办法
1.使用首屏SSR(服务端渲染,由服务器进行渲染并返回给客户端渲染完成的html) + 跳转SPA(单页面应用)方式来优化
2.改单页应用为多页应用,需要修改webpack的entry
3.改成多页以后使用应该使用prefetch(被标记为prefetch的资源,将会被浏览器在空闲时间加载)的就使用
4.处理加载的时间片,合理安排加载顺序,尽量不要有大面积空隙
5.CDN资源还是很重要的,最好分开,也能减少一些不必要的资源损耗
6.使用Quicklink,在网速好的时候 可以帮助你预加载页面资源
7.骨架屏这种的用户体验的东西一定要上,最好借助stream先将这部分输出给浏览器解析
8.合理使用web worker优化一些计算
9.缓存一定要使用,但是请注意合理使用
SPA(单页面应用)优点
服务器压力小
响应速度快
SPA缺点
SEO, 难以进行搜索引擎优化
首屏打开速度很慢(因为要一次性加载多种依赖和包)
SSR(服务端渲染)优点
超快的响应速度
易做SEO
缺点
增加服务器压力
52、什么是单页面应用(SPA)
什么是单页应用?
单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
单页面应用的优缺点:
优点:
1、用户操作体验好,用户不用刷新页面,整个交互过程都是通过Ajax来操作。
2、适合前后端分离开发,服务端提供http接口,前端请求http接口获取数据,使用JS进行客户端渲染。
缺点:
1、首页加载慢
单页面应用会将js、 css打包成一个文件,在加载页面显示的时候加载打包文件,如果打包文件较大或者网速慢则用户体验不好,首屏时需要请求一次html,同时还要发送一次js请求,两次请求回来了,首屏才会展示出来。相对于多页应用
2、SEO不友好
SEO效果差,因为搜索引擎只认识html里的内容,不认识js的内容,而单页应用的内容都是靠js渲染生成出来的,搜索引擎不识别这部分内容,也就不会给一个好的排名,会导致单页应用做出来的网页在百度和谷歌上的排名差。使用单页面应用将大大减少搜索引擎对网站的收录。
为什么页面切换快?
页面每次切换跳转时,并不需要做html文件的请求,这样就节约了很多http发送时延,我们在切换页面的时候速度很快。
有这些缺点,为什么还要使用Vue呢?
Vue还提供了一些其它的技术来解决这些缺点,比如说服务器端渲染技术(我是SSR),通过这些技术可以完美解决这些缺点,解决完这些问题,实际上单页面应用对于前端来说是非常完美的页面开发解决方案。
以上就是单页面应用的介绍,希望对你有帮助。