长期更新:Vue 知识整理

492 阅读3分钟

如何看待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
// 

为何不监听数组的长度变化和赋值变化

image.png

  • 如果使用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: '商品管理' 
    } 
}