如何看待Vue的渐进式
个人理解:
- 渐进式就是由浅到深的一个过程 Vue既可以简单的通过CDN引入依赖开发一个.html页面,也可以进行脚手架开发来支撑一个整体独立的项目。
- 在脚手架中也是存在由浅入深的开发思想 当我们需要更多的组件时,我们按照实际需要来进行引入,例如当页面需要router配置路由时引入router,当登录信息或者全局信息需要状态管理时,引入Vuex。而当我们不需要这些功能时,也可以不关注他们的存在。
双向绑定
Vue的双向绑定是通过 Object.defineProperty 给对象添加 getter 和 setter 方法实现的。
var data = { name: 'Kikky', msg: 'hello' }
// 枚举data里的属性并添加getter setter方法
Object.keys(data).forEach(function(key) {
Object.defineProperty(data, key, {
get: function() {
console.log('trigger subscription') },
set: function() {
// 属性变动触发通知
console.log('trigger notify') }
})
})
data.msg = 'hello world' // 输出 trigger notify
vue3 框架下如何是实现双向绑定
vue3 使用proxy代理进行双向数据绑定
let obj = {
a:1,
b:2
}
let proxy = new Proxy(obj, {
get: function(target, prop, reciver) {
return prop in target ? target[prop]:0
},
set: function(target, prop, value, reveiver) {
target[prop] =...
}
})
// proxy.a = 1
// proxy.b = 2
proxy.a = 10
// ...
proxy.b = 10
//
为何不监听数组的长度变化和赋值变化
-
如果使用defineProperty对数组的每个值进行绑定监听,那JS就要爆炸了,一个数组的长度会轻轻松松的撑到好几十或者好几百
-
defineProperty 监听不到数组的长度
Vue 怎么监听数组
- 使用内置的Vue.$set
- Vue 重写了数组的push, pop, shift, unshift, splice, sort, reverse方法
v-for的循环绑定 :key发挥什么作用?
- diff算法 简单说就是虚拟dom的计算方式采用diff算法,这个算法的精髓就在于先查找不同之处,然后把不同之处替换或者增加,同时把相同之处采取复用以节约性能
:key作用就是用于标记,当数组发生变化后,根据标记的key进行dom的更新
<div v-for="(item, index) in list" :key="index">{{item.num}}</div>
list: [{
id: 1,
num: 1
},
{
id: 2,
num: 2
},
{
id: 3,
num: 3
},]
如果list中间插入一个对象
[
{
id: 1,
num: 1
},
{
id: 4,
num: '新增加的数据4'
},
{
id: 2,
num: 2
},
{
id: 3,
num: 3
}
]
之前的数据 之后的数据
key: 0 id: 1 index: 0 num: 1 key: 0 id: 1 index: 0 num: 1
key: 1 id: 2 index: 1 num: 2 key: 1 id: 4 index: 1 num: '新增加的数据4'
key: 2 id: 3 index: 2 num: 3 key: 2 id: 2 index: 2 num: 2
key: 3 id: 3 index: 3 num: 3
根据diff算法 只有第一行没有变化 其他的数据都要重新更新
而如果:key 绑定唯一的主键id
之前的数据 之后的数据
key: 1 id: 1 index: 0 num: 1 key: 1 id: 1 index: 0 num: 1
key: 2 id: 2 index: 1 num: 2 key: 4 id: 4 index: 1 num: '新增加的数据4'
key: 3 id: 3 index: 2 num: 3 key: 2 id: 2 index: 2 num: 2
key: 3 id: 3 index: 3 num: 3
根据diff算法只有新增的第4条需要更新
vue inject provide (一种组件传值的方式?)
- 这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。 provide: Object | ()=> Object
inject: Array | { [key: string]: string | Symbol | Object }
- 以路由刷新功能为例
app.vue
export default {
name: 'App',
components: {
MergeTipDialog,
BreakNetTip
},
data () {
return {
isShow: false,
isRouterAlive: true
},
// 父组件中返回要传给下级的数据
provide () {
return {
reload: this.reload
}
},
methods: {
reload () {
this.isRouterAlive = false
this.$nextTick(() => {
this.isRouterAlive = true
})
}
}
}
在子孙组件中可以使用祖先组件中的reload方法 进行路由刷新
inject: ['reload']
method: {
testReload(){
this.reload()
}
}
vuex 存储状态在页面刷新后状态值丢失
采用localStorage 存储状态(注意cookie 和 localStroage sessionStorage区别)
style 标签下的scoped原理
通过POSTCSS Vue会将把DOM 元素添加data-v-xxxxx,从而能够区分不同的样式
keep-alive 是什么,原理是什么
keep-alive 是一个Vue组件,它不会被渲染成为dom元素,
场景
商品列表页点击商品进入到详情页面, 然后从详情页面退出,回到商品列表页面,这是如果使用了keep-alive组件就能够缓存列表页的信息,避免反复渲染,优化了用户体验
LRU策略
使用keep-alive时,添加prop属性包括include, exclude, max , 既然有max限制,就说明缓存存在上限值。
LRU策略是根据访问频率进行存储的策略,如果一个数据较长时间没有被访问,在添加新数据时,会优先剔除访问最少次数的数据。
缓存组件的实例
被keep-alive包裹的组件,不会触发distroyed方法,因此也监听不到这个周期
使用
- 作为组件标签使用
<keep-alive>
<component>
</keep-alive>
- 作为路由配置选项使用
{
path: 'list',
name: 'itemList', // 商品管理
component: (resolve) => {
require(['@/pages/item/list'], resolve)
},
meta: {
keepAlive: true,
title: '商品管理'
}
}