Vue项目中的性能优化
- 注意对象层级的嵌套,
- 不需要响应式的数据不放到data中
- v-if和v-show区分使用场景
- computed和watch区分使用场景
- v-for 遍历必须加key,并且是id值,避免同时和v-if一起使用
- 列表数据较多时和表格性能优化-虚拟列表和虚拟表格
- 防止内存泄漏,组件销毁后把全局变量和事件销毁
- 懒加载(图片懒加载、路由懒加载)
- 按需引入第三方插件
- 适当采用 keep-alive缓存组件
- 防抖、节流
- 预渲染
.mixin的使用场景和原理
场景:相同或相似的代码在不同的组件中使用,
原理:类似”对象的继承”,当组件初始化时会调用 mergeOptions 方法进行合并,采用策略模式针对不同的属性进行合并。
keep-alive使用场景和原理
场景:实现组件缓存,当组件切换时不会对当前组件进行卸载。
- 常用的两个属性 include/exclude,允许组件有条件的进行缓存
- 两个生命周期 activated/deactivated,用来得知当前组件是否处于活跃状态。
- keep-alive 中还运用了 LRU(最近最少使用)算法,选择最近最久未使用的组件予以淘汰。
.set 方法原理
- 修改数据 不会触发视图更新的两种情况分别是:
- 在实例创建之后添加新的属性到实例上(给响应式对象新增属性)
- 直接更改数组下标来修改数组的值
原理:
- 当给对象新增不存在的属性时,首先会把新的属性进行响应式跟踪,vue给对象和数组本身都增加了__ob__属性,是Observer实例
- 触发对象__ob__的dep收集到的 watcher 去更新
- 修改数组索引时 调用数组本身的 splice 方法去更新数组
Vue.extend 作用和原理
- 创建一个“子类”。参数是一个包含组件选项的对象。
- 子类构造器是 Vue组件的核心 api 实现思路就是使用原型继承的方法返回了 Vue的子类 并且利用 mergeOption 把传入组件的options和父类的options进行了合并。
自定义指令、原理
本质是装饰器
,是vue对于HTML元素的扩展,给HTML元素增加自定义功能。vue 编译DOM时,会找到指令对象
,执行指令的相关方法。
自定义指令有五个生命周期,bind、inserted、update、componentUpdated、unbind
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
- componentUpdated被绑定元素所在模板完成一次更新周期时调用
- unbind只调用一次,指令与元素解绑时调用
原理:
- 1.在生成 ast 语法树时,遇到指令会给当前元素添加 directives 属性
- 2.通过 genDirectives 生成指令代码
- 3.在 patch 前将指令的钩子提取到 cbs 中,在 patch 过程中调用对应的钩子
- 4.当执行指令对应钩子函数时,调用对应指令定义的方法
生命周期钩子是如何实现的
核心是利用订阅发布模式先把用户传入的周期钩子订阅好,然后在创建组件实例的过程中会一次执行对应的钩子方法(发布)
vue-router 如何响应路由参数的变化
什么是路由参数的变化:当使用路由参数时,从 /user/foo导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。
watch:{
$route(to,from){
console.log(to);
console.log(from)
}
}
// 导航守卫
beforeRouterEnter(to,from,next){
next()
}
Vue中 data中变量的数据值发生改变,界面没有跟着更新,原因?
- 1.如果data里面定义了对象,对象里面的键值没有,getter/setter函数没法监听到属性值的数据变化,会导致此现象的发生。
- 解决方法:Vue.set(obj,key,value)
- this,$set(obj,key,value)
多层父子组件通讯
需要通讯的组件不是直接的父子组件,而是祖父和孙子,嵌套的层级比较多的情况下,需要传递的事件和属性比较多,会导致代码混乱,这个时候就需要用到Vue提供的更高阶方法:provide/inject
父子组件通讯方式有哪些?
- 父组件–>子组件:自定义属性 props
- 子组件–>父组件:自定义事件 $emit
- EventBus
- Vuex
- v-model
v-model的方式:
我们都在表单中使用过 v-model 来绑定数据,其实组件之间也是可以用 v-model 进行双向绑定的
v-model 的本质就是绑定一个属性和事件
// 父组件
<aa class="abc" v-model="test" ></aa>
// aa子组件实现一:
<template>
<div>
<ul>
<li>{{'里面的值:'+ msg}}</li>
<button @click="fn2">里面改变外面</button>
</ul>
</div>
</template>
<script>
export default{
model:{
prop:'msg',
event:'cc'
}
},
props:{
msg:''
},
methods:{
fn2(){
this,$emit('cc',this,msg+2)
}
}
</script>
简述Vue的生命周期(vue2.0)
- 常用8个
- beforeCreate阶段、create阶段
- beforeMounted、mounted
- beforeUpdate、update
- beforeDestroy、destroy
- 分别为:创建前/后,载入前/后,更新前/后,销毁前/后。
第一次页面加载会触发哪几个钩子
- beforeCreate、create、beforeMount、mounted
Vue实现数据双向绑定的原理
- 采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
- 当把普通javascript对象传给Vue实例来作为他的data选项时,Vue将遍历它的属性,用Object.defineProperty将它们转为getter/setter。
- 用户看不到getter/setter,但是在内部它们让Vue追踪依赖,在属性被访问和修改时通知变化。
- 数据双向绑定 将MVVM作为数据绑定的入口,整合 Observer,Compile和Watcher三者,通过Observer来监听数据变化,通过 Compile来解析模板指令,最终利用 watcher搭起二者的通信桥梁,达到数据变化–>视图更新;视图交互变化–>数据model变更双向绑定效果。
简单实现双向数据绑定
<body>
<div>
<input type="text" id="txt"
<p id= "show"></p>
</div>
</body>
<script type="text/javascript">
var obj = {}
Object.defineProperty(obj,'txt',{
get:function(){
return obj
},
set:function(newValue){
document.getElementById('txt'),value= newValue
document.getElementById('show'),innerHTML = newValue
}
})
document.getElementById('txt').addEventListener('keyup',function(e){
obj.txt = e.target.value
})
<script>
Vuex刷新页面数据丢失怎么解决?
- 1.将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie)
- 2.在页面刷新时再次请求数据,使之动态更新vuex数据
- 3.在父页面向后台请求远程数据,并且在页面刷新前将vuex的数据先保存到 sessionStorage(以防请求数据量过大页面加载时拿不到返回的数据)
简单讲述 vuex
- 1.vuex是专门为vue.js提供的一种
状态``管理模式
,它采用的是集中式储存
和管理所有组件的状态和数据
。 - Vue Component–>Dispatch–>Actions–>Commit–>Mutations–>Mutate–>State–>Render–>Vue Component
有5种属性,state
、mutation
、action
、getter
、module
- state: vuex使用单一状态树,即每个应用将仅仅包含一个store实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
- getters:类似vue的计算属性,主要用来过滤一些数据。
- mutations:定义的方法动态修改Vuex的store中的状态或数据。
- actions:可以理解为通过将mutations里面的处理数据的方法变成可异步的处理数据的方法,view层通过 store.dispath来分发action
const store = new Vuex.Store({
state:{
count:0
},
mutations:{
increment(state){
state.count++
}
},
actions:{
increment(context){
context.commit('increment')
}
}
})
- modules:当项目复杂时,可以让每一个模块拥有自己的state、mutation、action、getters
const moduleA = {
state:{...},
mutations:{...},
actions:{...},
getters:{...}
}
const moduleB = {
state:{...},
mutations:{...},
actions:{...},
}
const store = new Vuex.Store({
modules:{
a:moduleA,
b:moduleB
}
})
vue如何自定义一个过滤器
<div id="app">
<input type= "text" v-model="msg" />
{{msg | userFilters(过滤器名称)}}
</div>
<script>
var vm = new Vue({
el:"el",
data:{
msg:''
},
filters:{
userFilters:function(v){
if(!v) return ''...
return v
}
}
})
//全局过滤器
Vue.filter('userFilter',function(v){
if(!v)return ''
...
return v
}
</script>
对keep-alive的了解?
- keep-alive 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染
- 使用方法:
<keep-alive>
<component>
<!-- 该组件将被缓存! -->
</component>
</keep-alive>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/163325.html