(掌握)用Vue实现样式绑定,可以用class或者内联样式,最少写出2个?
<!-- 第一种绑定class -->
<div :class="['classA', 'classB']"></div>
<!-- 第二种绑定class -->
<div :class="{'classA': true, 'classB' : false}"></div>
<!-- 第一种绑定style -->
<div :style="{fontSize: '16px', color: 'red'}"></div>
<!-- 第二种绑定style -->
<div :style="[{fontSize: '16px', color: 'red'}]"></div>
#(掌握)能说下 vue-router 中常用的路由模式实现原理吗
hash 模式
- location.hash 的值实际就是 URL 中#后面的东西 它的特点在于:hash 虽然出现 URL 中,但不会被包含在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
- 可以为 hash 的改变添加监听事件
window.addEventListener("hashchange", funcRef, false);
复制代码
每一次改变 hash(window.location.hash),都会在浏览器的访问历史中增加一个记录利用 hash 的以上特点,就可以来实现前端路由“更新视图但不重新请求页面”的功能了
特点:兼容性好但是不美观
history 模式
利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。
这两个方法应用于浏览器的历史记录站,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。这两个方法有个共同的特点:当调用他们修改浏览器历史记录栈后,虽然当前 URL 改变了,但浏览器不会刷新页面,这就为单页应用前端路由“更新视图但不重新请求页面”提供了基础。
特点:虽然美观,但是刷新会出现 404 需要后端进行配置
#(掌握)vue-router 有几种导航钩子?
1、全局守卫: router.beforeEach
2、全局解析守卫: router.beforeResolve
3、全局后置钩子: router.afterEach
4、路由独享的守卫: beforeEnter
5、组件内的守卫: beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave
#(掌握)前端路由和后端路由的区别
**什么是路由 **
路由是根据不同的 url 地址展示不同的内容或页面;
前端路由
很重要的一点是页面不刷新,前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,每跳转到不同的URL都是使用前端的锚点路由.
随着(SPA)单页应用的不断普及,前后端开发分离,目前项目基本都使用前端路由,在项目使用期间页面不会重新加载。
优点:
1. 用户体验好,和后台网速没有关系,不需要每次都从服务器全部获取,快速展现给用户
2. 可以再浏览器中输入指定想要访问的url路径地址 3. 实现了前后端的分离,方便开发。有很多框架都带有路由功能模块。
缺点:
1. 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
2. 单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置
后端路由
浏览器在地址栏中切换不同的url时,每次都向后台服务器发出请求,服务器响应请求,在后台拼接html文件传给前端显示, 返回不同的页面,
意味着浏览器会刷新页面,网速慢的话说不定屏幕全白再有新内容。后端路由的另外一个极大的问题就是 前后端不分离。
优点:
- 分担了前端的压力,html和数据的拼接都是由服务器完成。
缺点:
- 当项目十分庞大时,加大了服务器端的压力,同时在浏览器端不能输入制定的url路径进行指定模块的访问。另外一个就是如果当前网速过慢,那将会延迟页面的加载,对用户体验不是很友好。
#(掌握)$refs 和 $el的用法
ref 有三种用法:
1、ref 加在普通的元素上,用this.$refs(ref值) 获取到的是dom元素。
2、ref 加在子组件上,用 this.$refs 获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接this.$refs.XX。
vm.$el:
获取Vue实例关联的DOM元素;
比方说我这里想获取自定义组件tabControl,并获取它的OffsetTop,就需要先获取该组件。
在组件内设置 属性 ref='一个名称(tabControl2)', 然后 this.$refs.tabControl2,就拿到了该组件
切记:ref属性,而获取组件的时候要用$refs
获取 OffsetTop,组件不是DOM元素,是没有OffsetTop的,无法通过.OffsetTop来获取的。就需要通过$el来获取组件中的DOM元素:
this.tabOffsetTop=this.$refs.tabControl2.$el.offsetTop
#(掌握)vue常用的修饰符?
.prevent: 提交事件不再重载页面;
.stop: 阻止单击事件冒泡;
.self: 当事件发生在该元素本身而不是子元素的时候会触发;
.capture: 事件侦听,事件发生的时候会调用;
#(掌握)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-for为什么避免一起用
v-if和v-for一起使用,v-for的优先级要高于v-if,先循环再控制显示隐藏
- 为了过滤一个列表中的项目(比如
v-for = "user in users" v-if = "user.isActive"
)。在这种情况下,请将users
替换为一个计算属性(比如activeUsers
),让其返回过滤后的列表。 - 为了避免渲染本应该被隐藏的列表(比如
v-for = "user in users" v-if = "shouldShowUsers"
)。这种情况下,请将v-if
移动至容器元素上(比如ul
,ol
)。
#Vuex 为什么要分模块并且加命名空间
模块:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
命名空间:默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
#使用过 Vue SSR 吗?说说 SSR
SSR 也就是服务端渲染,也就是将 Vue 在客户端把标签渲染成 HTML 的工作放在服务端完成,然后再把 html 直接返回给客户端。
优点:
SSR 有着更好的 SEO、并且首屏加载速度更快
缺点: 开发条件会受到限制,服务器端渲染只支持 beforeCreate 和 created 两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于 Node.js 的运行环境。
服务器会有更大的负载需求
#vue 中使用了哪些设计模式
1.工厂模式 - 传入参数即可创建实例
虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode
2.单例模式 - 整个程序有且仅有一个实例
vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉
3.发布-订阅模式 (vue 事件机制)
4.观察者模式 (响应式数据原理)
5.装饰模式: (@装饰器的用法)
6.策略模式 策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案-比如选项的合并策略