vue核心面试题汇总【查缺补漏】(一)

简介: vue核心面试题汇总【查缺补漏】(一)

给大家推荐一个实用面试题库

1、前端面试题库 (面试必备)            推荐:★★★★★

地址:web前端面试题库

很喜欢‘万变不离其宗’这句话,希望在不断的思考和总结中找到Vue中的,来解答面试官抛出的各种Vue问题,一起加油~

一、MVVM原理

Vue2官方文档中没有找到VueMVVM的直接证据,但文档有提到:虽然没有完全遵循MVVM模型,但是 Vue 的设计也受到了它的启发,因此在文档中经常会使用vm(ViewModel 的缩写) 这个变量名表示 Vue 实例。

为了感受MVVM模型的启发,我简单列举下其概念。

MVVM是Model-View-ViewModel的简写,由三部分构成:

  • Model: 模型持有所有的数据、状态和程序逻辑
  • View: 负责界面的布局和显示
  • ViewModel:负责模型和界面之间的交互,是Model和View的桥梁

二、SPA单页面应用

单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML页面并在用户与应用程序交互时动态更新该页面的Web应用程序。我们开发的Vue项目大多是借助个官方的CLI脚手架,快速搭建项目,直接通过new Vue构建一个实例,并将el:'#app'挂载参数传入,最后通过npm run build的方式打包后生成一个index.html,称这种只有一个HTML的页面为单页面应用。

当然,vue也可以像jq一样引入,作为多页面应用的基础框架。

三、Vue的特点

  • 清晰的官方文档和好用的api,比较容易上手。
  • 是一套用于构建用户界面的渐进式框架,将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。
  • 使用 Virtual DOM
  • 提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件。

四、Vue的构建入口

vue使用过程中可以采用以下两种方式:

那么问题来了,使用的或者引入的到底是什么?

答:引入的是已经打包好的vue.js文件,通过rollup构建打包所得。

构建入口在哪里?

答:在vue源码的package.json文件中:

"scripts": {
    // ...
    "build": "node scripts/build.js",
    "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
    "build:weex": "npm run build -- weex",
    // ...
  },

通过执行npm run build的时候,会进行scripts/build.js文件的执行,npm run build:ssr和npm run build:weex的时候,将ssr和weex作为参数传入,按照参数构建出不一样的vue.js打包文件。

所以说,vue中的package.json文件就是构建的入口,具体构建流程可以参考vue2入口:构建入口

五、对import Vue from "vue"的理解

在使用脚手架开发项目时,会有一行代码import Vue from "vue",那么这个Vue指的是什么。

答:一个构造函数。

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

我们开发中引入的Vue其实就是这个构造函数,而且这个构造函数只能通过new Vue的方式进行使用,否则会在控制台打印警告信息。定义完后,还会通过initMixin(Vue)stateMixin(Vue)eventsMixin(Vue)lifecycleMixin(Vue)renderMixin(Vue)的方式为Vue原型中混入方法。我们通过import Vue from "Vue"引入的本质上就是一个原型上挂在了好多方法的构造函数。

六、对new Vue的理解

// main.js文件
import Vue from "vue";
var app = new Vue({
  el: '#app',
  data() {
    return {
      msg: 'hello Vue~'
    }
  },
  template: `<div>{{msg}}</div>`,
})
console.log(app);

new Vue就是对构造函数Vue进行实例化,执行结果如下:

可以看出实例化后的实例中包含了很多属性,用来对当前app进行描述,当然复杂的Vue项目这个app将会是一个树结构,通过$parent$children维护父子关系。

new Vue的过程中还会执行this._init方法进行初始化处理。

七、编译

虚拟DOM的生成必须通过render函数实现,render函数的产生是在编译阶段完成,核心代码如下:

export const createCompiler = createCompilerCreator(function baseCompile (
  template: string,
  options: CompilerOptions
): CompiledResult {
  const ast = parse(template.trim(), options)
  if (options.optimize !== false) {
    optimize(ast, options)
  }
  const code = generate(ast, options)
  return {
    ast,
    render: code.render,
    staticRenderFns: code.staticRenderFns
  }
})

主要完成的功能是:

  • 通过const ast = parse(template.trim(), options)template转换成ast
  • 通过optimize(ast, options)ast进行优化
  • 通过const code = generate(ast, options)将优化后的ast转换成包含render字符串的code对象,最终render字符串通过new Function转换为可执行的render函数

模板编译的真实入口可以参考vue2从template到render:模板编译入口

parse可以参考vue2从template到render:AST

optimize可以参考vue2从template到render:optimize

generate可以参考vue2从template到render:code

八、虚拟DOM

先看浏览器对HTML的理解

<div>  
    <h1>My title</h1>  
    Some text content  
    <!-- TODO: Add tagline -->  
</div>

当浏览器读到这些代码时,它会建立一个DOM树来保持追踪所有内容,如同你会画一张家谱树来追踪家庭成员的发展一样。 上述 HTML 对应的 DOM 节点树如下图所示:

每个元素都是一个节点。每段文字也是一个节点。甚至注释也都是节点。一个节点就是页面的一个部分。就像家谱树一样,每个节点都可以有孩子节点 (也就是说每个部分可以包含其它的一些部分)。

再看VueHTML template的理解

Vue 通过建立一个虚拟 DOM 来追踪自己要如何改变真实 DOM。因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为“VNode”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。

简言之,浏览器对HTML的理解是DOM树,Vue对HTML的理解是虚拟DOM,最后在patch阶段通过DOM操作的api将其渲染成真实的DOM节点。

九、模板或者组件渲染

Vue中的编译会执行到逻辑vm._update(vm._render(), hydrating),其中的vm._render执行会获取到vNodevm._update就会对vNode进行patch的处理,又分为模板渲染和组件渲染。

十、数据响应式处理

Vue的数据响应式处理的核心是Object.defineProperty,在递归响应式处理对象的过程中,为每一个属性定义了一个发布者dep,当进行_render函数执行时会访问到当前值,在get中通过dep.depend进行当前Watcher的收集,当数据发生变化时会在set中通过dep.notify进行Watcher的更新。

数据响应式处理以及发布订阅者模式的关系请参考vue2从数据变化到视图变化:发布订阅模式

十一、this.$set

const app = new Vue({
  el: "#app",
  data() {
    return {
      obj: {
        name: "name-1"
      }
    };
  },
  template: `<div @click="change">{{obj.name}}的年龄是{{obj.age}}</div>`,
  methods: {
    change() {
      this.obj.name = 'name-2';
      this.obj.age = 30;
    }
  }
});

以上例子执行的结果是:

name-1的年龄是

当点击后依然是:

name-2的年龄是

可以看出点击后,objname属性变化得到了视图更新,而age属性并未进行变化。

name属性响应式的过程中锁定了一个发布者dep,在当前视图渲染时在发布者depsubs中做了记录,一旦其发生改变,就会触发set方法中的dep.notify,继而执行视图的重新渲染。然而,age属性并未进行响应式的处理,当其改变时就不能进行视图渲染。

十二、组件注册

组件的使用是先注册后使用,又分为:

  • 全局注册:可以直接在页面中使用
  • 局部注册:使用时需要通过import xxx from xxx的方式引入,并且在当前组件的选项components中增加局部组件的名称。

十三、异步组件

Vue单页面应用中一个页面只有一个

承载所有节点,因此复杂项目可能会出现首屏加载白屏等问题,Vue异步组件就很好的处理了这问题。

十四、this.$nextTick

因为通过new实例化构造函数Vue的时候会执行初始化方法this._init,其中涉及到的方法大多都是同步执行。nextTick在vue中是一个很重要的方法,在new Vue实例化的同步过程中将一些需要异步处理的函数推到异步队列中去,可以等new Vue所有的同步任务执行完后,再执行异步队列中的函数。

nextTick的实现可以参考 vue2从数据变化到视图变化:nextTick

十五、keep-alive内置组件

vue中支持组件化,并且也有用于缓存的内置组件keep-alive可直接使用,使用场景为路由组件动态组件

  • activated表示进入组件的生命周期,deactivated表示离开组件的生命周期
  • include表示匹配到的才缓存,exclude表示匹配到的都不缓存
  • max表示最多可以缓存多少组件

keep-alive的具体实现请参考 vue中的keep-alive(源码分析)

十六、生命周期

vue中的生命周期有哪些?

答案:11个,分别为beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedactivateddeactivatedbeforeDestroydestroyederrorCaptured

具体实现请参考 vue生命周期

十七、v-showv-if的区别

先看v-ifv-show的使用场景:

(1)v-if更多的使用在需要考虑白屏时间或者切换次数很少的场景

(2)v-show更多使用在transition控制的动画或者需要非常频繁地切换的场景

再从底层实现思路上分析:

(1)v-if条件为false时,会生成空的占位注释节点,那么在考虑首页白屏时间时,选用v-if比较合适。条件从false变化为true的话会从空的注释节点变成真实节点,条件再变为false时真实节点又会变成注释节点,如果切换次数比较多,那么开销会比较大,频繁切换场景不建议使用v-if

(2)v-show条件为false时,会生成真实的节点,只是为当前节点增加了display:none来控制其隐藏,相比v-if生成空的注释节点其首次渲染开销是比较大的,所以不建议用在考虑首屏白屏时间的场景。如果我们频繁切换v-show的值,从display:nonedisplay:block之间的切换比起空的注释节点和真实节点的开销要小很多,这种场景就建议使用v-show

可以通过vue中v-if和v-show的区别(源码分析)了解v-ifv-show详细过程。

十八、v-forkey的作用

v-for进行循环展示过程中,当数据发生变化进行渲染的过程中,会进行新旧节点列表的比对。首先新旧vnode列表首先通过首首尾尾首尾尾首的方式进行比对,如果key相同则采取原地复用的策略进行节点的移动。

如果首尾两两比对的方式找不到对应关系,继续通过keyvnode的对应关系进行寻找。

如果keyvnode对应关系中找不到,继续通过sameVnode的方式在未比对的节点中进行寻找。

如果都找不到,则将其按照新vnode进行createElm的方式进行创建,这种方式是比节点移动的方式计算量更大。

最后将旧的vnode列表中没有进行匹配的vnode中的vnode.elm在父节点中移除。

简单总结就是,新的vnode列表在旧的vnode列表中去寻找具有相同的key的节点进行原地复用,如果找不到则通过创建的方式createElm去创建一个,如果旧的vnode列表中没有进行匹配则在父节点中移除其vnode.elm。这就是原地复用逻辑的大体实现。

具体keydiff算法的关系可以参考vue2从数据变化到视图变化:diff算法图解

十九、v-forv-if能同时使用吗

答案是:用了也能出来预期的效果,但是会有性能浪费。

同时包含v-forv-iftemplate模板在编辑阶段会执行v-forv-if优先级更高的编译流程;在生成vnode的阶段,会包含属性isCommenttrue的空白占位vnode;在patch阶段,会生成真实的占位节点。虽然一个空的占位节点无妨,但是如果数据量比较大的话,也是一个性能问题。

当然,可以在获取到数据(一般是在beforeCreate或者created阶段)时进行过滤处理,也可以通过计算属性对其进行处理。

可以通过v-for和v-if可以一起使用吗?了解v-forv-if的详细过程。

二十、vue中的data为什么是函数

答案是:是不是一定是函数,得看场景。并且,也无需担心什么时候该将data写为函数还是对象,因为vue内部已经做了处理,并在控制台输出错误信息。

场景一new Vue({data: ...})

这种场景主要为项目入口或者多个html页面各实例化一个Vue时,这里的data即可用对象的形式,也可用工厂函数返回对象的形式。因为,这里的data只会出现一次,不存在重复引用而引起的数据污染问题。

场景二:组件场景中的选项

在生成组件vnode的过程中,组件会在生成构造函数的过程中执行合并策略:

// data合并策略
strats.data = function (
  parentVal,
  childVal,
  vm
) {
  if (!vm) {
    if (childVal && typeof childVal !== 'function') {
      process.env.NODE_ENV !== 'production' && warn(
        'The "data" option should be a function ' +
        'that returns a per-instance value in component ' +
        'definitions.',
        vm
      );
      return parentVal
    }
    return mergeDataOrFn(parentVal, childVal)
  }
  return mergeDataOrFn(parentVal, childVal, vm)
};

如果合并过程中发现子组件的数据不是函数,即typeof childVal !== 'function'成立,进而在开发环境会在控制台输出警告并且直接返回parentVal,说明这里压根就没有把childVal中的任何data信息合并到options中去。

可以通过vue中的data为什么是函数?了解详细过程。

二十一、this.$watch

使用场景:用来监听数据的变化,当数据发生变化的时候,可以做一些业务逻辑的处理。

配置参数:

  • deep:监听数据的深层变化
  • immediate:立即触发回调函数

实现思路: Vue构造函数定义完成以后,在执行stateMixin(Vue)时为Vue.prototype上定义$watch。该方法通过const watcher = new Watcher(vm, expOrFn, cb, options)进行Watcher的实例化,将options中的user属性设置为true。并且,$watch逻辑结束的会返回函数function unwatchFn () { watcher.teardown() },用来取消侦听的函数。

可以通过watch选项和$watch方法的区别vue中的watch和$watch监听的事件,执行几次?来了解详细过程。

二十二、计算属性和侦听属性的区别

相同点: 两者都是Watcher实例化过程中的产物

计算属性:

  • 使用场景:模板内的表达式主要用于简单运算,对于复杂的计算逻辑可以用计算属性
  • 计算属性是基于它们的响应式依赖进行缓存的,当依赖的数据未发生变化时,多次调用无需重复执行函数
  • 计算属性计算结果依赖于data中的值
  • 同步操作,不支持异步

侦听属性:

  • 使用场景:当需要在数据变化时执行异步或开销较大的操作时,可以用侦听属性
  • 可配置参数:可以通过配置immediatedeep来控制立即执行和深度监听的行为
  • 侦听属性侦听的是data中定义的

计算属性请参考vue2从数据变化到视图变化:计算属性

侦听属性请参考vue2从数据变化到视图变化:侦听器

二十三、v-model

// main.js
new Vue({
  el: "#app",
  data() {
    return {
      msg: ""
    };
  },
  template: `<div>
    <input v-model="msg" placeholder="edit me">
    <p>msg is: {{ msg }}</p>
  </div>`
});

普通input:input中的v-model,最终通过target.addEventListener处理成在节点上监听input事件function($event){msg=$event.target.value}}的形式,当input值变化时msg也跟着改变。

// main.js
const inputBox = {
  template: `<input @input="$emit('input', $event.target.value)">`,
};
new Vue({
  el: "#app",
  template: `<div>
    <input-box v-model="msg"></input-box>
    <p>{{msg}}</p>
  </div>`,
  components: {
    inputBox
  },
  data() {
    return {
      msg: 'hello world!'
    };
  },
});

组件v-model在组件中则通过给点击事件绑定原生事件,当触发到$emit的时候,再进行回调函数ƒunction input($$v) {msg=$$v}的执行,进而达到子组件修改父组件中数据msg的目的。

二十四、v-slot

v-slot产生的主要目的是,在组件的使用过程中可以让父组件有修改子组件内容的能力,就像在子组件里面放了个插槽,让父组件往插槽内塞入父组件中的楔子;并且,父组件在子组件中嵌入的楔子也可以访问子组件中的数据。v-slot的产生让组件的应用更加灵活。

1、具名插槽

let baseLayout = {
  template: `<div class="container">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>`,
  data() {
    return {
      url: ""
    };
  }
};
new Vue({
  el: "#app",
  template: `<base-layout>
    <template v-slot:header>
      <h1>title-txt</h1>
    </template>
    <p>paragraph-1-txt</p>
    <p>paragraph-2-txt</p>
    <template v-slot:footer>
      <p>foot-txt</p>
    </template>
  </base-layout>`,
  components: {
    baseLayout
  }
});

引入的组件baseLayout中的template被添加了属性v-slot:headerv-slot:footer,子组件中定义了对应的插槽被添加了属性name="header"name="footer",未被进行插槽标识的内容被插入到了匿名的中。

2、作用域插槽

let currentUser = {
  template: `<span>
    <slot name="user" v-bind:userData="childData">{{childData.firstName}}</slot>
  </span>`,
  data() {
    return {
      childData: {
        firstName: "first",
        lastName: "last"
      }
    };
  }
};
new Vue({
  el: "#app",
  template: `<current-user>
    <template v-slot:user="slotProps">{{slotProps.userData.lastName}}</template>
  </current-user>`,
  components: {
    currentUser
  }
});

当前例子中作用域插槽通过v-bind:userData="childData"的方式,将childData作为参数,父组件中通过v-slot:user="slotProps"的方式进行接收,为父组件使用子组件中的数据提供了可能。

v-slot的底层实现请参考vue中的v-slot(源码分析)

二十五、Vue.filters

filters类似于管道流可以将上一个过滤函数的结果作为下一个过滤函数的第一个参数,又可以在其中传递参数让过滤器更灵活。

// main.js文件
import Vue from "vue";
Vue.filter("filterEmpty", function(val) {
  return val || "";
});
Vue.filter("filterA", function(val) {
  return val + "平时周末的";
});
Vue.filter("filterB", function(val, info, fn) {
  return val + info + fn;
});
new Vue({
  el: "#app",
  template: `<div>{{msg | filterEmpty | filterA | filterB('爱好是', transformHobby('chess'))}}</div>`,
  data() {
    return {
      msg: "张三"
    };
  },
  methods: {
    transformHobby(type) {
      const map = {
        bike: "骑行",
        chess: "象棋",
        game: "游戏",
        swimming: "游泳"
      };
      return map[type] || "未知";
    }
  }
});

其中我们对msg通过filterEmptyfilterAfilterB('爱好是', transformHobby('chess'))}进行三层过滤。

Vue.filters的底层实现请查看vue中的filters(源码分析)

二十六、Vue.use

  • 作用:Vue.use被用来安装Vue.js插件,例如vue-routervuexelement-ui
  • install方法:如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为install方法。install方法调用时,会将Vue作为参数传入。
  • 调用时机:该方法需要在调用 new Vue() 之前被调用。
  • 特点:当 install 方法被同一个插件多次调用,插件将只会被安装一次。

二十七、Vue.extend和选项extends

1、Vue.extend

Vue.extend使用基础Vue构造器创建一个“子类”,参数是一个包含组件选项的对象,实例化的过程中可以修改其中的选项,为实现功能的继承提供了思路。

new Vue({
  el: "#app",
  template: `<div><div id="person1"></div><div id="person2"></div></div>`,
  mounted() {
    // 定义子类构造函数
    var Profile = Vue.extend({
      template: '<p @click="showInfo">{{name}} 喜欢 {{fruit}}</p>',
      data: function () {
        return {
          name: '张三',
          fruit: '苹果'
        }
      },
      methods: {
        showInfo() {
          console.log(`${this.name}喜欢${this.fruit}`)
        }
      }
    })
    // 实例化1,挂载到`#person1`上
    new Profile().$mount('#person1')
    // 实例化2,并修改其`data`选项,挂载到`#person2`上
    new Profile({
      data: function () {
        return {
          name: '李四',
          fruit: '香蕉'
        }
      },
    }).$mount('#person2')
  },
});

在当前例子中,通过Vue.extend构建了子类构造函数Profile,可以通过new Profile的方式实例化无数个vm实例。我们定义初始的templatedatamethodsvm进行使用,如果有变化,在实例的过程中传入新的选项参数即可,比如例子中实例化第二个vm的时候就对data进行了调整。

2、选项extends

extends允许声明扩展另一个组件 (可以是一个简单的选项对象或构造函数),而无需使用 Vue.extend。这主要是为了便于扩展单文件组件,以实现组件继承的目的。

const common = {
  template: `<div>{{name}}</div>`,
  data() {
    return {
      name: '表单'
    }
  }
}
const create = {
  extends: common,
  data() {
    return {
      name: '新增表单'
    }
  }
}
const edit = {
  extends: common,
  data() {
    return {
      name: '编辑表单'
    }
  }
}
new Vue({
  el: "#app",
  template: `<div>
    <create></create>
    <edit></edit>
  </div>`,
  components: {
    create,
    edit,
  }
});

当前极简demo中定义了公共的表单common,然后又在新增表单组件create和编辑表单组件edit中扩展了common

二十八、Vue.mixin和选项mixins

全局混入和局部混入视情况而定,主要区别在全局混入是通过Vue.mixin的方式将选项混入到了Vue.options中,在所有获取子组件构建函数的时候都将其进行了合并,是一种影响全部组件的混入策略。

而局部混入是将选项通过配置mixins选项的方式合并到当前的子组件中,只有配置了mixins选项的组件才会受到混入影响,是一种局部的混入策略。

二十九、Vue.directivedirectives

1、使用场景

主要用于对于DOM的操作,比如:文本框聚焦,节点位置控制、防抖节流、权限管理、复制操作等功能

2、钩子函数

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

3、钩子函数参数

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
  • name:指令名,不包括 v- 前缀。
  • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
  • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
  • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
  • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
  • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

4、动态指令参数

指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value" 中,argument 参数可以根据组件实例数据进行更新!这使得自定义指令可以在应用中被灵活使用。

vue核心面试题汇总【查缺补漏】(二):https://developer.aliyun.com/article/1415698

相关文章
|
3月前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
3月前
|
JavaScript
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
这篇文章深入探讨了Vue中的`slot`概念,包括它的定义、使用场景和分类(默认插槽、具名插槽和作用域插槽),并通过代码示例展示了如何在组件中使用插槽来实现内容的分发和自定义。同时,文章还对插槽的工作原理进行了分析,解释了`renderSlot`函数和`$scopedSlots`对象的角色。
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
|
3月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
3月前
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
3月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
2月前
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
165 64
|
1月前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
40 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
3月前
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
|
3月前
|
JavaScript 前端开发 编译器
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
这篇文章介绍了Vue 3相对于Vue 2的改进和新增特性,包括性能提升、体积减小、更易维护、更好的TypeScript支持、新的Composition API、新增的Teleport和createRenderer功能,以及Vue 3中的非兼容性变更和API的移除或重命名。
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
|
3月前
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?

热门文章

最新文章