如何准备vue相关的知识点

Vue组件data为什么必须是个函数?

  • 根实例对象data可以是对象也可以是函数 (根实例是单例),不会产生数据污染情况
  • 组件实例对象data必须为函数 一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数,

简版理解

// 1.组件的渲染流程 调用Vue.component -> Vue.extend -> 子类 -> new 子类
// Vue.extend 根据用户定义产生一个新的类
function Vue() {
   }
function Sub() {
    // 会将data存起来
    this.data = this.constructor.options.data();
}
Vue.extend = function(options) {
   
    Sub.options = options; // 静态属性
    return Sub;
}
let Child = Vue.extend({
   
    data:()=>( {
    name: 'zf' })
});

// 两个组件就是两个实例, 希望数据互不感染
let child1 = new Child();
let child2 = new Child();

console.log(child1.data.name);
child1.data.name = 'poetry';
console.log(child2.data.name);

// 根不需要 任何的合并操作   根才有vm属性 所以他可以是函数和对象  但是组件mixin他们都没有vm 所以我就可以判断 当前data是不是个函数

相关源码

// 源码位置 src/core/global-api/extend.js
export function initExtend (Vue: GlobalAPI) {
   
  Vue.extend = function (extendOptions: Object): Function {
   
    extendOptions = extendOptions || {
   }
    const Super = this
    const SuperId = Super.cid
    const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {
   })
    if (cachedCtors[SuperId]) {
   
      return cachedCtors[SuperId]
    }

    const name = extendOptions.name || Super.options.name
    if (process.env.NODE_ENV !== 'production' && name) {
   
      validateComponentName(name)
    }

    const Sub = function VueComponent (options) {
   
      this._init(options)
    }
    // 子类继承大Vue父类的原型
    Sub.prototype = Object.create(Super.prototype)
    Sub.prototype.constructor = Sub
    Sub.cid = cid++
    Sub.options = mergeOptions(
      Super.options,
      extendOptions
    )
    Sub['super'] = Super

    // For props and computed properties, we define the proxy getters on
    // the Vue instances at extension time, on the extended prototype. This
    // avoids Object.defineProperty calls for each instance created.
    if (Sub.options.props) {
   
      initProps(Sub)
    }
    if (Sub.options.computed) {
   
      initComputed(Sub)
    }

    // allow further extension/mixin/plugin usage
    Sub.extend = Super.extend
    Sub.mixin = Super.mixin
    Sub.use = Super.use

    // create asset registers, so extended classes
    // can have their private assets too.
    ASSET_TYPES.forEach(function (type) {
   
      Sub[type] = Super[type]
    })
    // enable recursive self-lookup
    if (name) {
    
      Sub.options.components[name] = Sub // 记录自己 在组件中递归自己  -> jsx
    }

    // keep a reference to the super options at extension time.
    // later at instantiation we can check if Super's options have
    // been updated.
    Sub.superOptions = Super.options
    Sub.extendOptions = extendOptions
    Sub.sealedOptions = extend({
   }, Sub.options)

    // cache constructor
    cachedCtors[SuperId] = Sub
    return Sub
  }
}

Vue-router 路由有哪些模式?

一般有两种模式:
(1)hash 模式:后面的 hash 值的变化,浏览器既不会向服务器发出请求,浏览器也不会刷新,每次 hash 值的变化会触发 hashchange 事件。
(2)history 模式:利用了 HTML5 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。

前端vue面试题详细解答

对keep-alive的理解,它是如何实现的,具体缓存的是什么?

如果需要在组件切换的时候,保存一些组件的状态防止多次渲染,就可以使用 keep-alive 组件包裹需要保存的组件。

(1)keep-alive

keep-alive有以下三个属性:

  • include 字符串或正则表达式,只有名称匹配的组件会被匹配;
  • exclude 字符串或正则表达式,任何名称匹配的组件都不会被缓存;
  • max 数字,最多可以缓存多少组件实例。

注意:keep-alive 包裹动态组件时,会缓存不活动的组件实例。

主要流程

  1. 判断组件 name ,不在 include 或者在 exclude 中,直接返回 vnode,说明该组件不被缓存。
  2. 获取组件实例 key ,如果有获取实例的 key,否则重新生成。
  3. key生成规则,cid +“∶∶”+ tag ,仅靠cid是不够的,因为相同的构造函数可以注册为不同的本地组件。
  4. 如果缓存对象内存在,则直接从缓存对象中获取组件实例给 vnode ,不存在则添加到缓存对象中。 5.最大缓存数量,当缓存组件数量超过 max 值时,清除 keys 数组内第一个组件。

(2)keep-alive 的实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值