web前端Vue面试题目合集(含答案)

2,764 阅读15分钟

Vue的双向绑定原理

Vue的双向绑定原理是采用的订阅者--发布者模式,通过object.defineProperty()来劫持各个
属性身上的getter和setter
,在数据变动时发送消息给订阅者,触发响应的回调函数.
具体步骤:
1.需要observer的数据对象递归遍历,包括子属性对象的属性,都加上getter和setter,
这样的话给每个对象赋值就会触发setter,那么就能监听到数据的变化
2.compile解析模版指令,将模版的变量替换成数据,然后开始初始化渲染页面视图,
并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据发生变化,收到通知更新视图
3.watcher订阅者是observer和compile之间通信的桥梁,主要做的事情:
    1).在自身实例化时,往属性订阅器里面添加自己
    2).自身必须有一个update()方法
    3).待属性变动dep.notice()通知时,能调用自身的update方法,并触发compile中绑定的回调
4.mvvm作为数据绑定的入口,整合observer,compile和watcher三者,通过observer来监听自己的model数据变化,
通过compile来解析编译模版指令,最终利用watcher搭起observer和compile之间的通信桥梁,
达到数据变化->视图更新->数据model变更的双向绑定

object.defineProperty()的作用

主要是用来控制一个对象属性的特有操作,比如说读写权,是否可以枚举等
下面写一下他的get和set属性

varBook= {}
 
       varname= '';
 
       Object.defineProperty(Book, 'name', {
 
           set:function(value) {
 
                name= value;
 
                console.log('你取了一个书名叫做'+ value);
 
           },
 
           get:function() {
 
                return'《'+ name+ '》'
 
           }
 
       })
 
 
 
       console.log(Book)
 
       Book.name= 'vue权威指南'; // 你取了一个书名叫做vue权威指南
 
        console.log(Book.name); // 《vue权威指南》
 
       // get 是在读取那么属性的时候触发的

       // set 是在设置属性值的时候触发的

请详细说下Vue生命周期的理解?

总的生命周期大体主要分为三个阶段(创建阶段,执行阶段,销毁阶段)
创建阶段:
    1)创建前:beforeCreate,vue实例的挂载元素$el和数据对象data都为undefined,还未初始化
    2)创建后:created,vue实例的挂载对象data有了,$el还没有
    3)载入前:beforeMount,vue实例的$el和data都初始化了,但是还是挂载之前为虚拟dom节点,data.message还未替换
    4)载入后:mounted,vue实例挂载完成,data.message成功渲染
执行阶段:
    1)更新前:beforeUpdate,在data发生变化之前发生的事情
    2)更新后:updated,在data数据更新之后做一些事情
销毁阶段:
    1)销毁前:beforeDestroy,销毁之前,正在对页面中监听器等元素进行销毁操作
    2)销毁后:destroyed,执行destroy方法后,对data的改变不会再触发周期函数,
    说明此时vue实例已经解除了事件监听以及dom绑定,但是dom结构依然还在
    这个阶段也不会自动调用,需要使用vm.$destroy()执行
    

请说出vue.cli项目中的src目录每个文件夹和文件的用法?

assets文件夹放置的是静态资源
components是放公共组件
router是定义路由相关的配置
view视图放置单文件组件页面
app.vue是一个应用主组件
main.js是入口文件

怎么定义vue-router的动态路由?怎么获取传过来的参数

下面的这三种是最常用的编程式导航的方式进行路由的动态传参

动态路由就是通过路由传参的方式实现的:
vue路由传参是指嵌套路由时父路由向子路由传递参数,否则操作无效。
传参方式可以划分为params传参和query传参,params传参又可以分为url中显示参数和不显示参数两种方式。

方式一:push方法跳转(最常用)

this.$router.push({path:`/user/${userId}`})

这样传递参数的话,配置路由的时候需要在path上加参数path:user/:userId。
这种接收参数的方式是this.$route.params.userId。

方式二:query方式传参和接收参数

传递参数:
    this.$router.push({
        path:'/xxx',
        query:{
          id:id
        }
      })
接收参数:
    this.$route.query.id
    注意:传参是this.$router,接收参数是this.$route,这里千万要看清了!!!

方法三:params方式传参和接收参数

传参: 
this.$router.push({
        name:'xxx',
        params:{
          id:id
        }
      })
  
接收参数:
    this.$route.params.id
    注意:params传参,push里面只能是 name:'xxxx',不能是path:'/xxx',因为params只能用name来引入路由,
    如果这里写成了path,接收参数页面会是undefined!!!
    
主要原因:
    如果提供了path,params将会被忽略,但是query不属于这种情况。。。
    如果使用完整路径和query传参,刷新页面时不会造成路由传参的参数丢失。
    另外,二者还有点区别,直白的来说query相当于get请求,页面跳转的时候,
    可以在地址栏看到请求参数,而params相当于post请求,参数不会再地址栏中显示

除了使用编程式导航的方式实现路由传参,我们也可以使用router-link的方式进行路由的传参:

方法一:params传参(url中显示参数)

在子路由中传递参数:

children:[
        {
          path:'/one/log/:num',
          component:Log,
        },
        {
          path:'/one/reg/:num',
          component:Reg,
        },

在父路由组件上使用router-link进行路由导航,传参用<router-link to="/one/login/001">
的形式向子路由组件传递参数。使用router-view进行子路由页面内容渲染,

<template>
  <div style="border:1px solid red;color:red;">
    <p>这是父路由childOne对应的组件页面</p>
    <p>下面可以点击显示嵌套的子路由 </p>
    <router-link to="/one/log/123">显示登录页面</router-link>
    <router-link to="/one/reg/002">显示注册页面</router-link>
    <router-view></router-view>
  </div>
</template>

子路由通过 this.$route.params.num 的形式来获取父路由向子路由传递过来的参数,

<template>
  <div style="border:1px solid orange;color:orange;">
    <p>登录界面:这是另一个嵌套路由的内容</p>
    <h3>{{this.$route.params.num}}</h3>
  </div>
</template>

如上所述路由定义的path: "/one/login/:num"路径和to="/one/login/001"必须书写正确,否则不断点击切换路由,
会因为不断将传递的值显示添加到url中导致路由出错,如下
传递的值存在url中存在安全风险,
为防止用户修改,另一种方式不在url中显示传递的值

方法二:params传参(url中不显示参数)

定义路由时添加name属性给映射的路径取一个别名(name),

 children:[
        {
          path:'/one/log/',
          name:'Log',
          component:Log,
        },
        {
          path:'/one/reg/',
          name:'Reg',
          component:Reg,
        },

在父路由组件上使用router-link进行路由导航,使用 <router-link :to="{name:'home',params:{id:001}}> 形式传递参数。

<template>
  <div style="border:1px solid red;color:red;">
    <p>这是父路由childOne对应的组件页面</p>
    <p>下面可以点击显示嵌套的子路由 </p>
    <router-link :to="{name:'Log',params:{num:666}}">显示登录页面</router-link>
    <router-link :to="{name:'Reg',params:{num:888}}">显示注册页面</router-link>
    <router-view></router-view>
  </div>
</template>

方法三使用query实现路由传参

children:[
        {
          path:'/one/log/',
          component:Log,
        },
        {
          path:'/one/reg/',
          component:Reg,
        },
      ],
    },
    {
      path: '/two',
      name: 'ChildTwo',
      component: ChildTwo
    }
  ]

修改路由导航 <router-link :to="{path:'/one/log',query:{num:123}}"> ,

<template>
  <div style="border:1px solid red;color:red;">
    <p>这是父路由childOne对应的组件页面</p>
    <p>下面可以点击显示嵌套的子路由 </p>
    <router-link :to="{path:'/one/log',query:{num:123}}">显示登录页面</router-link>
    <router-link :to="{path:'/one/reg',query:{num:999}}">显示注册页面</router-link>
    <router-view></router-view>
  </div>
</template>

子路由组件通过 this.$route.query.num 来显示传递过来的参数

<template>
  <div style="border:1px solid purple;color:purple;">
    <p>注册界面:这是二级路由页面</p>
    <h3>{{this.$route.query.num}}</h3>
  </div>
</template>

vue-router有哪种导航钩子

全局前置守卫:
    const router = new VueRouter({ ... })

    router.beforeEach((to, from, next) => {
      // ...
    })
全局解析守卫:
你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,
区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

全局后置钩子:
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from) => {
  // ...
})

路由独享的守卫:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})
组件内的守卫:
你可以在路由组件内直接定义以下路由导航守卫:
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

完整的导航解析流程

1.导航被触发。
2.在失活的组件里调用离开守卫。
3.调用全局的 beforeEach 守卫。
4.在重用的组件里调用 beforeRouteUpdate 守卫 
5.在路由配置里调用 beforeEnter。
6.解析异步路由组件。
7.在被激活的组件里调用 beforeRouteEnter。
8.调用全局的 beforeResolve 守卫 (2.5+)。
9.导航被确认。
10.调用全局的 afterEach 钩子。
11.触发 DOM 更新。
12.用创建好的实例调用 beforeRouteEnter 13.守卫中传给 next 的回调函数。

mint-ui是什么?怎么使用?说出至少三个组件使用方法

mint-ui是跟element-ui一样,都是饿了么公司开发的vue组件库,只不过mint-ui主要是移动端的组件开发
使用方法:
Toast('登录成功')
mint-header
mint-swiper

请说一下封装vue组件的过程

首先,组件可以提升整个项目的开发效率,能够把页面抽象成多个相对独立的模块,解决我们传统开发:效率低,难维护,复用性等问题

然后,使用vue.extend方法创建一个组件,然后使用vue.component方法来注册组件,子组件需要数据,,可以在props中接收定义.而子组件修改好数据后,想要把数据传递给父组件,可以采用$emit方法

vue-loader是什么?使用它的用途有哪些?

vue-loader加载器
vue-loader的作用就是告诉webpack如何将vue格式的文件转换成js。主要是因为

vue.cli中怎样使用自定义组件?有遇到过哪些问题吗?

主要分为四个步骤:
创建:在components目录中创建自己的组件文件(smithButton),script一定要export default
引入:在需要的页面中导入import smithButton
注册:注入到vue的子组件的components属性上
使用:在template视图view中使用,<smith-button></smith-button>

问题:使用驼峰命名法,在使用的时候需要smith-button使用连接符进行连接

说下对于mvvm的理解?双向绑定的理解

mvvm就是vm框架视图,m模型就是用来定义驱动的数据,v经过数据变化后html,vm就是用来实现双向绑定

双向绑定:一个变了另一个就跟着变了,例如:视图一个绑定了模型的节点有变化,模型对应的值就会跟着变化

请说下具体使用vue的理解

1.使用vue不必担心布局更改和类名重写导致的js重写,因为他是靠数据驱动双向绑定,底层是通过Object.defineProperty定义的数据,set,get函数原理实现
2.组件化开发,让项目的可扩展性,移植性更好,代码的重用性更高
3.单页面应用的体验零距离接触安卓原生应用,局部组件更新界面,让用户体验更快速省时
4.js的代码无形的规范,团队合作开发代码可阅读性更高

单页面程序的优缺点

单页面应用

单页面的优点:

    1,用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小
    
    2,前后端分离
    
    3,页面效果会比较炫酷(比如切换页面内容时的专场动画)
    
单页面缺点:

    1,不利于seo
    
    2,导航不可用,如果一定要导航需要自行实现前进、后退。
    (由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理)
    
    3,初次加载时耗时多
    
    4,页面复杂度提高很多
    

解决spa首屏加载慢的方法有哪些?

1.将全局引入转换为按需引入文件
2.在 config/index.js 文件中将productionSourceMap 的值设置为false. 不生成映射资源
3.路由懒加载:懒加载即组件的延迟加载,通常vue的页面在运行后进入都会有一个默认的页面
,而其他页面只有在点击后才需要加载出来。

使用懒加载可以将页面中的资源划分为多份,从而减少第一次加载的时候耗时。
4.压缩css和js文件
5.使用cdn托管(就是把原服务器上数据复制到其他服务器上,
用户访问时,哪台服务器近访问到的就是哪台服务器上的数据。)

怎么认识的vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,
并以相应的规则保证状态以一种可预测的方式发生变化。
1.vuex可以理解为一种开发模式或框架
2.通过状态集中管理驱动组件的变化
3.应用级的状态集中放在store中:改变状态的方式是提交mutations,这是同步事物;异步逻辑应该封装在action中

vuex有哪几种属性

state
getter
mutation
action
module

vuex的State(声明数据)特性是?

1.vuex就是一个仓库,仓库里面放了很多对象,其中state就是数据源存放地,对应于一般对象的data

2.state里面存放的数据是响应式的,vue组件从store中读取数据,若是store中的数据发生改变,
依赖这个数据的组件也会发生更新

3.他是通过mapState把全局的state和getters映射到当前组件的computed计算属性中

vuex的getter特性是?

1.getters可以对state进行计算操作,他就是store的计算属性
2.虽然在组件内也可以做计算属性,但是getters可以在多组件之间复用
3.如果一个状态只在一个组件内使用,是可以不用getters

的作用是什么?

<keep-alive></keep-alive>包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染

vue中ref的作用是什么?

ref被用来给DOM元素或子组件注册引用信息,引用信息会根据父组件的$ref对象进行注册.
如果在普通的DOM元素上使用,引用信息就是元素,
如果在子组件上使用,引用信息就是组件实例

vue中组件直接的通信是如何实现的?

juejin.cn/post/684490…

虚拟DOM是什么?

虚拟DOM是对真实DOM的一种描述
​
    VNODE 虚拟节点:描述了真实的DOM节点,本质上就是普通对象
    {
        tagName: 'div'
        attrs: { class: "active", id: "info"}
        content: "hello"
    }
​
 虚拟DOM也会形成一个树状结构,描述了真实的DOM树
 如果数据发生变化,那么就会触发虚拟DOM数的对比(diff算法)
 对比的结果是:有变化的虚拟节点的集合
 上述虚拟节点需要转化为真实的DOM节点
​
    var div = document.createElement(vnode.tagName)
    div.setAttibute(key, value)
    div.innerHTML = vnode.content
​
 最终会把真实的节点更新到页面

为什么vue减少了DOM操作就会提升速率?

通过操作DOM的代价很高,因为会引起页面的重排和重绘,增加浏览器的性能开销,降低页面的渲染速度

$.route 和$.router的区别

1.$.router是路由实例,想要导航跳转,或者是导航不同就使用router.push()方法
2.$route为当前$router的跳转对象,里面可以获取name、path、query、params等

v-if和v-show的区别

v-if是通过动态创建或者移除元素实现动态切换
v-show是通过控制元素的display:none样式实现切换

一般来说,v-if 有更高的切换消耗 而  v-show 有更高的初始渲染消耗。

因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

双向绑定和虚拟DOM

    DOM的更新比较耗时
    尽可能少的更新DOM节点
    为了实现上述需求,发明了虚拟DOM
    虚拟DOM描述了真实DOM(虚拟DOM树---真实DOM树)
    虚拟DOM树本质其实就是普通对象
    当数据发生变化时,会对比变化前后的虚拟DOM树(diff算法)
对比:
    有变化的虚拟节点的集合
    虚拟的节点需要转化成真实DOM节点
    把真实的DOM节点渲染到页面

说一下computed和methods以及watch的区别

1)computed--computed是在HTML DOM加载后马上执行的,如赋值;
computed计算属性是基于它们的依赖进行缓存的,调用函数时,只要依赖的数据没发生改变时,
会直接从缓存中拿数据,不会再次执行函数

2)methods--methods则必须要有一定的触发条件才能执行,如点击事件;
只要发生重新渲染,method 调用总会执行该函数。
3)watch--检测一个数据的变化;对应一个对象,键是观察表达式,
值是对应回调。值也可以是方法名,或者是对象,包含选项。
4)执行顺序--先computed再watch,不执行methods;等触发某一事件后,则是:先methods再watch。

vue有哪些指令

参考博客基础知识一:

juejin.cn/post/684490…

vue和jQuery的区别

区别一:
    1).jQuery是一个类库,提供了很多的方法,不能算框架,在过去和现在Jquery是最流行的web前端js库,可是现在无论国内还是国外,
    他的使用率正在渐渐被其他的js库所替代。随着浏览器厂商对H5规范统一遵循以及ECMA6在浏览器端的实现,
    jquery的使用率会越来越低。
    2).vue的介绍:vue是一个刚兴起不久的前端框架,有一套完整的体系,是一个精简的MVVM。从技术角度讲,vue.js专注于MVVM模型的ViewModel层,通过双向数据绑定把view层和Model层连接起来,通过对数据的操作就可以完成对页面视图的渲染。vue以它独特的优势简单、快速、组合、紧凑、强大而迅速崛起。
区别二:
    1).jQuery是直接操作DOM的;使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作;
    和原生的js区别只在于可以更方便的选取和操作DOM对象;
    数据和界面是在一起,比如获取input标签的内容
    2)vue基于一种MVVM模式,使用数据驱动的方式,通过Vue对象将数据和View完全分离开来。
    对数据进行操作,不在需要引用相应的DOM对象,通过vue对象,将数据和相应的DOM对象相互绑定起来。
区别三
    1).Jquery适用的场景:jquery侧重样式操作,比如一些H5的动画页面;需要js来操作页面样式的页面

    2).Vue适用的场景:vue侧重数据绑定,比如复杂数据操作的后台页面;表单填写页面

说一下你在vue中踩过的坑

1.路由变化页面数据不刷新,解决方法:使用watch监听路由的变化
2.异步回调函数中使用this无法指向vue实例对象,解决:使用箭头函数
3.setInterval路由跳转继续运行并没有及时进行销毁,解决:在组件声明周期beforeDestroy停止setInterval
4.vue注册组件的时候驼峰命名要使用连字符的形式使用

你是怎么考虑vue不利于seo优化问题的

 1.搜索引擎的基础爬虫的原理就是抓取你的url,然后获取你的html源代码并解析。
 而你的页面通常用了vue等js的数据绑定机制来展示页面数据,
 爬虫获取到的html是你的模型页面而不是最终数据的渲染页面,
 所以说用js来渲染数据对seo并不友好。
 
  2.seo 本质是一个服务器向另一个服务器发起请求,解析请求内容。
  但一般来说搜索引擎是不回去执行请求到的js的。也就是说,如果一个单页应用,html在服务器端还没有渲染部分数据数据,
  在浏览器才渲染出数据,而搜索引擎请求到的html是没有渲染数据的。 这样就很不利于内容被搜索引擎搜索到。
  所以服务端渲染就是尽量在服务器发送到浏览器前 页面上就是有数据的。

 3.一般的数据逻辑操作是放在后端的。排序这个如果仅仅是几条数据,前后端排序开起来是一样的,
 如果是有1000条数据,前端要排序就要都请求过来。这样显然是不合理的

vue全家桶

vue vue-router vuex axios vue-cli 

编程式导航的实现

使用push跳转:
router.push(location, onComplete?, onAbort?)
使用replace跳转
router.replace(location, onComplete?, onAbort?)
使用go方式跳转:
router.go(n)

vue为什么在new实例化的时候data是一个对象,在组件中是一个函数

如果两个实例引用同一个对象,当其中一个实例的属性发生改变时,另一个实例属性也随之改变,
只有当两个实例拥有自己的作用域时,才不会相互干扰。

    这是因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象。

    组建中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的data,
    相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。
    而单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了。

说一下mvvm和mvc的区别

MVC 主要是后端的分层开发思想;把 一个完整的后端项目,分成了三个部分:

    Model:(数据层)主要负责 数据库的操作;
    View:(视图层)所有前端页面,统称为 View 层
    Controller:(业务逻辑层)主要处理对应的业务逻辑;(对于后台来说,这是开发的重点)
        MVVM是前端页面的分层开发思想,主要关注于 视图层 分离,也就是说:MVVM把前端的视图层,分为了 三部分
        Model, View,  ViewModel

Model 是 页面中,需要用到的数据
View 是页面中的HTML结构;
ViewModel 是 一个 中间的调度者,提供了双向数据绑定的概念;

为什么有了mvc还要有mvvm?

因为 MVC是后端的开发思想,并没有明确定义前端的页面该如何开发;

MVVM 是前端的页面的开发思想,把每个页面,分成了三个部分,同时 VM 作为 MVVM 的核心,
提供了双向数据绑定的概念,前端程序员,不需要手动渲染页面了,
而且,页面数据发送变化,也不需要程序员手动把 数据的变化同步到Model中;这所有的操作,都是 VM 自动完成的!
有了 MVVM 的思想以后,前端只关心 页面交互逻辑,不关心页面如何渲染

vue-router路由的两种实现模式,但是vue-router默认的是hash模式

hash模式(默认):
    hash模式背后的原理是onhashchange事件,可以在window上监听这个事件,这种模式的路由只能改变(#)之后的路由,当hash发生变化的url都会被浏览器记录下来
    ,从而你会发现浏览器的前进后退都可以用了,
    同时点击后退时,页面字体颜色也会发生变化。这样一来,尽管浏览器没有请求服务器,
    但是页面状态和url一一关联起来,后来人们给它起了一个霸气的名字叫前端路由,成为了单页应用标配。
history模式:
    随着history api的到来,前端路由开始进化了,前面的hashchange,
    你只能改变(#)后面的url片段,而history api则给了前端完全的自由
    1)使用back forward go三个方法对应浏览器的前进,后退,跳转操作
    2)修改历史状态包括了pushState、replaceState两个方法,

使用场景:
    1) hash模式url里面永远带着#号,我们在开发当中默认使用这个模式。那么什么时候要用history模式呢?
    2) 如果用户考虑url的规范那么就需要使用history模式,因为history模式没有#号,是个正常的url适合推广宣传。
    3) 当然其功能也有区别,比如我们在开发app的时候有分享页面,那么这个分享出去的页面就是用vue或是react做的,
    4) 咱们把这个页面分享到第三方的app里,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式,
    5)但是使用history模式还有一个问题就是,在访问二级页面的时候,做刷新操作,会出现404错误,
    6)那么就需要和后端人配合让他配置一下apache或是nginx的url重定向,重定向到你的首页路由上就ok啦。
    

vue怎么实现组件缓存

1)可以在router中设置router的元信息meta,列如:routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello,
      meta: {
        keepAlive: true // 需要缓存
      }
    },
2) 在页面中判断是否有$route.meta.keepAlive是否是true,如果是true,则进行缓存
给组件添加<keep-alive></keep-alive>

axios怎么实现同步的请求

一般使用axios进行数据请求就是要使用异步请求,一些需求可以写在回调里面。

如果一定要同步使用数据的话,可以使用 async+await

methods: {
    async funA(){
        var res =  await axios.post('') //这里的res就是axios请求回来的结果
    }
}

vue打包出现空白Index.html,这个怎么解决

1)vue-cli 3.0 项目文件打包后,在dist文件打开index.html页面是空白的,
修改方法是在项目文件夹里找到vue.config.js(如果没有vue.config.js文件请自行添加一个),添加如下所示内容:
module.exports={
    publicPath:'./'
}
2)第二个是路由模式改为history的问题--src里边router/index.js路由配置里边默认模式是hash,
如果你改成了history模式的话,打开也会是一片空白。所以改为hash或者直接把模式配置删除,让它默认的就行 。

vue怎么实现跨域

1.在config/index.js配置文件中配置proxyTable

 proxyTable: {
      '/apis': {
        // 测试环境
        target: 'http://www.thenewstep.cn/',  // 接口域名
        changeOrigin: true,  //是否跨域
        pathRewrite: {
            '^/apis': ''   //需要rewrite重写的,
        }              
    }
    },
    
2.fetch实现跨域

 //实现跨域请求
  created(){
    //fetch实现跨域请求
    fetch("/apis/test/testToken.php",{
      method:"POST",
      headers:{
        token:"f4c902c9ae5a2a9d8f84868ad064e706"

      },
      body:JSON.stringify({username:"lgs",password:"123"})
    }).then(result=>{
      // console.log(result)
      //解析数据
      return result.json()
    }).then(data =>{
      //打印数据
      console.log(data);
    })

Vue.$nextTick的作用及执行

当我们修改了data中的数据之后,如果要操作文本框,必须等页面重新渲染完毕之后才可以,
所以必须把操作文本框的代码,放在$nextTick中,当做回调去执行

// 修改数据
vm.msg = 'Hello'
// DOM 还没有更新
Vue.nextTick(function () {
  // DOM 更新了
})

// 作为一个 Promise 使用 (2.1.0 起新增,详见接下来的提示)
Vue.nextTick()
  .then(function () {
    // DOM 更新了
  })

对于webpack的认识?

webpack是把项目当做一个整体,通过一个给定的主文件,webpack将从这个文件开始找到你的项目的所有依赖,
使用loaders处理他们,最后打包成一个或多个浏览器可以识别的js文件

webpack中entry是做什么的?

entry:用来写入口文件,他将是整个依赖关系的根,当我们需要多个入口文件的时候,可以把entry写成一个对象

webpack中output是做什么的?

output:即使入口文件有多个,但是只有一个输出配置,如果你定义的入口文件有多个,
那么我们使用占位符来确保输出文件的唯一性

webpack中的loader的作用是什么?

1.实现对不同格式文件的处理,比如说将scss转换成css,或者是typescript转换为js
2.转换这些文件,从而使使其能够被添加到依赖图中
这里介绍几个常用的loader:
    1)babel-loader:让下一代的js文件转换成现代浏览器能够支持的js文件
    2)babel有些复杂,所以大多数都会新建一个.babelrc进行配置
    3)css-loader,style-loader:两个建议配合使用,用来解析css文件,
    能够解释@import,url()如果需要解析less就在后面加一个less-loader
    4)file-loader:生成的文件名就是文件内容的MD5哈希值并会保留所引用资源的原始扩展名
    5)url-loader:功能类似file-loader,但是文件大小低于指定的限制时,
    可以返回一个DataURL,在使用less,scss,stylus这些的时候npm会提示你差什么插件,差什么,你就安上就行了
    

webpack中plugins的作用是什么?

loaders负责的是处理源文件的如css,jsx,一次性处理一个文件,
而plugins并不是直接操作单个文件,他直接对整个项目构建起到作用

webpack中什么是bundle,什么是chunk,什么是module?

1.bundle是由webpack打包出来的文件
2.chunk是指webpack在进行模块的依赖分析的时候,代码分割出来的代码块
3.module是开发中的单个模块
4.chunk打包后变成bundle

webpack-dev-server和http服务器如nginx有什么区别?

webpack-dev-server使用内存来存储webpack开发环境下的打包文件,
并且可以使用模块热更新,他比传统的http服务开发更加有效

什么是模块热更新?

模块热更新,是webpack的一个功能,他可以使得代码通过修改后,不用刷新浏览器就可以更新,
是高级版的自动刷新浏览器

什么是长缓存?在webpack中如何做到长优化缓存?

浏览器在用户访问页面额时候,为了加快加载速度,会对用户访问的静态资源进行存储,但是每一次代码升级或者是更新,
都需要浏览器去下载新的代码,最方便和最简单的更新方式就是引入新的文件名称.在webpack中,
可以在output给出的文件制定chunkhash,
并且分离经常更新的代码和框架代码,通过NamedModulesPlugin或者是HashedMoudulesIdsPlugins
使得再次打包文件名不变