vue面试题

vue面试题

1.Vue解决了什么问题:

①虚拟dom:dom操作时非常耗性能的,不再使用原生的dom操作节点,极大的解放dom操作,但具体操作的还是dom,不过是换了一种方式。
②视图、数据、结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作。
③组件化:把一个单页应用中的各种模块拆分到一个一个单独的组件中,便于开发,以及后期的维护

2.MVVM的理解:

MVVM就是Model-View-ViewModel的缩写,MVVM将视图和业务逻辑分开。

View:视图层,Model数据模型,而ViewModel是把两者建立通信的桥梁。

MVVM框架下,View和Model之间没有直接的联系,而是通过ViewModel进行交互。

View和ViewModel之间以及Model和ViewModel之间的交互都是双向的,因此view数据的变化会同步到Model中,而Model数据的变化也会立即反映到View上。可以说它们两者是实时更新的,互相影响。

ViewModel通过双向数据绑定把View层和Model层连接了起来,而View和Model之间的同步工作完全是自动的,因此开发者只需要关注业务逻辑,不需要手动操作DOM,也不需要关注数据状态的同步问题,这些都由MVVM统一管理。

3.如何实现一个自定义组件?不同组件之间是如何通信的?

实现一个自定义组件:
创建子组件的文件,建立组件的模板,把架子搭起来,就是在子组件中写好视图层,

第二种:子传父:主要通过 e m i t 来 实 现 在 父 组 件 中 给 子 组 件 标 签 绑 定 一 个 自 定 义 事 件 , 给 这 个 事 件 挂 载 需 要 调 用 的 方 法 , 在 子 组 件 的 方 法 通 过 t h i s . emit 来实现 在父组件中给子组件标签绑定一个自定义事件,给这个事件挂载需要调用的方法,在子组件的方法通过this. emitthis.emit(‘自定义事件名’)来调用这个方法。

第三种:兄弟之间传值有两种方法: 方法一:通过 event bus 实现
①创建一个空的vue实例eventBUS
②通过BUS. e m i t ( ‘ 事 件 名 ’ ) 传 到 空 的 v u e 实 例 中 ③ 通 过 B U S . emit(‘事件名’)传到空的vue实例中 ③通过BUS. emit()vueBUS.on(‘事件名’,(参数)=>{挂载从子1传来的数据})来接收

具体实现:创建一个空的 vue 并暴露出去,这个作为公共的 bus,即当作两个组件的桥梁,在两个兄弟组件中分别引入刚才创建的bus,在组件 A 中通过 bus. e m i t ( ’ 自 定 义 事 件 名 ’ , 要 发 送 的 值 ) 发 送 数 据 , 在 组 件 B 中 通 过 b u s . emit(’自定义事件名’,要发送的值)发送数据,在组件 B中通过 bus. emitBbus.on(‘自定义事件名‘,function(v) { //v 即为要接收的值 })接收数据。

//首先在src中创建一个Bus文件夹 => index.js
import Vue from "vue";
export default new Vue({  
})
//子组件1(发送数据的组件)
<button @click="add()">点击</button>
import Bus from "@/Bus"
add(){
    Bus.$emit("add",this.content);
}

//子组件2(接受数据的组件)
<p>{{tit}}</p>
import Bus from "@/Bus";
created(){
    Bus.$on("add",(data) => {
        this.tit = data;
    })
}

第四种:$children / $parent

this.$children[0].msg = "hello world" //父组件修改子组件data中的数据
this.$parent.mag //子组件拿到父组件data中的数据

c h i l d r e n 的 值 是 数 组 , children的值是数组, childrenparent的值是个对象
复制代码注意: p a r e n t , parent, parentchildren它们的目的是作为访问数组的应急方法,更推荐用props和events实现父子组件通信。

第五种:provide / inject
这是vue2.2.0新增的api,简单来说就是父组件中通过provide来提供变量,然后再子组件中通过inject来注入变量。

//父组件
export default{
    name:"A",
    provide:{
        for:"demo"
    },
    components:{
        comB
    }
}

//子组件
export default{
    name:"B",
    inject:["for"],
    data(){
        demo:this.for
    }
}

第六种:ref / refs
ref如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向组件实例,可通过实例直接调用组件的方法或访问数据。

//父组件
<template>
    <component-a ref="comA"></component-a>
</template>
<script>
    export default{
        mounted(){
            const comA = this.$refs.comA;
            console.log(comA.name)//Vue.js
            comA.sayHello() //hello
        }
    }
</script>复制代码//子组件
export default{
    data(){
        return {
            name:"Vue.js"
        }
    },
    methods:{
        sayHello(){
            console.log("hello")
        }
    }
}

第七种:$attrs / l i s t e n e r s 将 数 据 挂 在 到 子 组 件 的 标 签 上 去 后 , 在 子 组 件 中 使 用 t h i s . listeners 将数据挂在到子组件的标签上去后,在子组件中使用this. listeners使this.attrs直接获取到所有挂载的数据,返回的是一个对象。

第八种.Vuex;

第九种:LocalStorage;

4.nextTick的理解:

使用nextTick的原因:
Vue是异步修改DOM的,并且不鼓励开发者直接接触DOM,但是有时候需要必须对数据更改后的DOM元素做相应的处理,但是获取到的DOM数据并不是更改后的数据,这时候就需要this.$nextTick();
原理:
Vue通过异步队列控制DOM更新和nextTick回调函数先后执行的方式。
使用:

//HTML
<button @click="change()">按钮</button><h1 ref="gss">{{msg}}</h1>
//JS
export default{
    name:"app",
    data(){
        return {
            msg:"123"
        }
    },
    methods:{
        change(){
            this.msg = "456";
            console.log(this.refs["gss"].innerHTML)//123
            this.$nextTick(function(){
                console.log(this.refs["gss"].innerHTML)//456
            })
        }
    }
 }

5.Vue的生命周期(11个钩子函数)

⑴beforeCreate(创建前):在此生命周期函数执行的时候,data和methods中的数据都还没有初始化。
⑵created(创建后):在此生命周期函数中,data和methods都已经被初始化好了,如果要调用 methods中的方法,或者操作data中的数据,最早只能在created中操作。
⑶beforeMount(载入前):在此生命周期函数执行的时候,模板已经在内存中编译好了,但是尚未挂载到页面中去,此时页面还是旧的。
⑷mounted(载入后):此时页面和内存中都是最新的数据,这个钩子函数是最早可以操作dom节点的方法。
⑸beforeUpdate(更新前):此时页面中显示的数据还是旧的,但是data中的数据是最新的,且页面并未和最新的数据同步。
⑹Updated(更新后):此时页面显示数据和最新的data数据同步。
⑺beforeDestroy(销毁前):当执行该生命周期函数的时候,实例身上所有的data,所有的methods以及过滤器…等都处于可用状态,并没有真正执行销毁。
⑻destroyed(销毁后):此时组件以及被完全销毁,实例中的所有的数据、方法、属性、过滤器…等都已经不可用了。
//下面两个钩子函数一般配合使用
⑼activated(组件激活时):和上面的beforeDestroy和destroyed用法差不多,但是如果我们需要一个实例,在销毁后再次出现的话,用beforeDestroy和destroyed的话,就太浪费性能了。实例被激活时使用,用于重复激活一个实例的时候
⑽deactivated(组件未激活时):实例没有被激活时。
⑾errorCaptured(错误调用):当捕获一个来自后代组件的错误时被调用

6.虚拟DOM原理:

虚拟dom是什么
1.用javaScript对象结构表示DOM树的结构;然后用这个树构建一个 真正的DOM树,插到文档当中。
2.当状态变更的时候,重新构造一棵树的对象树。然后用新的树和旧 的树进行较比记录两棵树差异。
3.把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。

Virtual DOM本质上就是在JS和DOM之间做了一个缓存,可以类比CPU和硬盘,既然 硬盘这么慢,我们就在它们之间加个缓存。CPU(JS)只操作内存(virtual DOM),最后的 时候再把变更写入硬盘(DOM)。
使用虚拟DOM的好处
操作数据要大大的减少性能损耗,提高渲染效率越多的真实dom 操作,越损耗性能。
**diff算法是什么:**比较两棵DOM树的差异是Virtual DOM算法中最核心的部分,这也是所谓的Virtual DOM的diff算法。在前端中,你会很少跨层地移动DOM元素,所以真实的DOM算法会对同一个层级的元素进行对比。
(diff算法用来做什么)vue的diff算法用于视图更新,也可以说是dom更新。

7.双向绑定的原理?数据劫持?

双向绑定的原理:
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时。Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器 Compile[kang mu pai ao],对每个元素节点的指令进行扫描和解析,替换数据,绑定更新函数
3、实现一个 Watcher,作为连接 Observer 和 Compile 的桥梁,能够收到每个属性变动的通知,绑定的相应回调函数,从而更新视图

数据劫持:
当我们访问或设置对象的属性的时候,都会触发相对应的函数,然后在这个函数里返回或设置属性的值。我们可以在触发函数的时候动一些手脚做点我们自己想做的事情,这也就是“劫持”操作。

8.Proxy相比于defineProperty的优势:

Vue3.0摒弃了Object.defineProperty,改为基于Proxy的观察者机制探索。
Object.defineProperty的缺点:
①Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实施响应。
②Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue2.X里,是通过递归 + 遍历data对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象才是更好的选择。
Proxy两个优点:
①可以劫持整个对象,并返回一个新对象。
②有多种劫持操作(13种)。

9.watch、computed和methods的区别:

watch:监听属性,一个值的改变需要另一个值的改变而改变,结果不会缓存。可以影响数据的变化,当绑定的数据方法变化时触发响应的函数,需要在数据变化时执行异步或开销较大的操作时使用watch。
computed: 计算属性,计算结果会缓存,只有当依赖值改变才会重新计算。自动监听依赖值的变化,从而动态返回内容,主要目的是简化模板内的复杂运算。所以区别来源于用法,只是需要动态值,那就用 computed ;需要知道值的改变后执行业务逻辑,才用 watch。
methods 事件方法,调用一次,执行一次,结果不会缓存。在重新渲染的时候每次都会被重新的调用。

10.virtual-dom原理实现(虚拟dom):

virtual-dom(简称vdom)的概念大规模的推广还是得益于react的出现,virtual-dom也是react这个框架的非常重要的特性之一。相比于频繁的手动去操作dom而带来性能问题,vdom很好的将dom做了一层映射关系,进而将在我们本需要直接进行dom的一系列操作,映射到了操作vdom,而vdom上定义了关于真实dom进行的创建节点,删除节点,添加节点等一系列复杂的dom操作,并将这些操作放到vdom中进行,这样就通过操作vdom来提高直接操作的dom的效率和性能。
在vue的整个应用生命周期当中,每次需要更新视图的时候便会使用vdom,vdom算法是基于snabbdom算法所做的修改。
实现:
①用js对象构造一个虚拟的dom树,插入到文档中;
②状态变更时,记录新树和旧树的差异;
③把上面的差异构建到真正的dom中。

12.vue-router

vue路由:
是指vue-router,其中router是指根据url分配到对应的处理程序,所以说路由就是用来解析url以及调用对应的控制器并返回从视图对象中提取好的网页代码给web服务器,最终返回给客户端。

vue路由优点缺点:
优点:.不需要每次都从服务器获取,渲染页面更快速。
缺点:.不利于SEO;
.使用浏览器前进,后退按键时重新发送请求,未合理利用缓存;
.单页面无法记住之前滚动的位置;

vue-router的实现原理(核心):
更新视图但不重新请求页

单页面路由跳转的方式:
①hash(哈希默认)模式:使用 URL hash 值来作路由。默认模式。
特点:.hash虽然在url中,但不会被包括在HTTP请求中,用来指导浏览器动作,对服务端安全无用,hash不会重新加载页面;
.在hash模式下,仅hash符号之前的内容会被包含在请求中,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回404错误;

②history(mode:history)模式:前端的url必须和后端发起请求的URL一致, 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。

③abstract模式(严格模式):支持所有 JavaScript 运行环境,如 Node.js 服务器端。
根据mode参数来决定采用哪一种方式。

vue-router登陆权限的判断 :
vue-router的登陆权限判断主要是在全局钩子函数中进行的,我们在router.js文件中的定义路由里,将需要登陆权限的页面加上meta属性,值是对象的形式,然后在该对象中自定义一个属性,属性值就是一个Boolean值,这时候在main.js文件的全局钩子函数中进行判断,如果需要跳转的页面的自定义属性值为true,那么将进行判断其是否登录,如果没有登录,则告诉用户登录,如果有登录,那么进行页面跳转。

routes:[
    {
        path:"/home",
        name:"Home",
        components:Home
        meta:{requireAuth:true}
    }
]

router.beforeEach((to,from,next) => {
    if(to.meta.requireAuth){//判断该路由是否需要登录权限
        if(store.state.token){//通过vuex的state获取当前的token是否存在
            next()
        }else{
            next({
                path:"/one",
                query:{redirect:to.fullPath}
                //将跳转的路由path作为参数,登陆成功后跳转到该路由
            })
        }
    }else{
        next();
    }    
})

## 路由嵌套:

routes:[
    {
        path:"/home",
        name:"Home",
        components:Home,
       children:[
            {
                path:"child",
                name:"Child",
                components:"Child"
            }
        ]
    }
]

13. Vuex的理解:

定义:
Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式储存管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

使用场景:
需要构建一个中大型单页应用,您很可能会考虑如何更好的在组件外部管理状态,Vuex将会成为自然而然的选择。

优点:
当你在state中定义了一个数据之后,可以在所在项目中的任何一个组件里进行获取、进行修改、并且你的修改可以得到全局的响应变更。

Vuex的运行机制:
Vuex提供数据(state)来驱动试图(vue components),通过dispath派发actions,在其中可以做一些异步的操作,然后通过commit来提交mutations,最后mutations来更改state。

核心:
①state:定义初始数据。
②mutations:更改Vuex的store中的状态的唯一方法是提交mutation
③getters:可以对
state 进行计算操作,它就是 store 的计算属性虽然在组件内也可以做计算属性,但是 getters 可以在多给件之间复用如果一个状态只在一个组件内使用,是可以不用 getters。
④actions:异步操作初始数据,其实就是调用mutations里面的方法。
⑤module:面对复杂的应用程序,当管理的状态比较多时;我们需要将vuex的store对象分割成模块(modules)。

14.描述下vue从初始化页面–>修改数据–>刷新页面UI过程:

当Vue进入初始化阶段时,一方面Vue会遍历data中的属性,并用Object.defineProperty将它转化成getter/setterd的形式,实现数据劫持;

另一方面,Vue的指令编译器Compiler对元素节点的各个指令进行解析,初始化视图,并订阅Watcher来更新视图,此时Watcher会将自己添加到消息订阅器Dep中,此时初始化完毕。

当数据发生变化时,触发Observer中setter方法,立即调用Dep.notify( ),Dep这个数组开始遍历所有的订阅者,并调用其update方法,Vue内部再通过diff算法,patch相应的更新完成对订阅者视图的改变。

15、Vue的响应式原理 ?

当一个Vue实例创建时,vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。
每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

16、Vue.js的特点?

简洁页面由HTML模板+Json数据+Vue实例组成
数据驱动:自动计算属性和追踪依赖的模板表达式
组件化:用可复用、解耦的组件来构造页面
轻量:代码量小,不依赖其他库
快速:精确有效批量DOM更新模板
友好:可通过npm,bower等多种方式安装,很容易融入

17.插槽的理解 ?

插槽用于决定将所携带的内容,插入到子组件指定的某个位置,但内容必须在父组件中子组件的标签内定义,在子组件中用标签接收。slot是组件内部的占位符。

18.路由守卫有哪几种?

原理:
如果没有权限不让进入,有权限才可以进入
守卫方法接受三个参数:
to:即将进入的目标
from:导航正要离开的路由
next:执行下一步
扩展:
next()进入下一个组件的钩子函数
next(false)阻止跳转终端导航
next(“/login”)进入指定组件的钩子函数

1.全局路由守卫:
定义在router对象上
绝大部分页面需要跳转用全局路由守卫
router.beforeEach 全局前置守卫
router.beforeResolve 全局解析守卫
Router.afterEach 全局后置守卫 (定义在router对象上)
2.路由独享守卫
路由独享守卫:
beforeEnter 路由跳转之前 (定义在路由配置上)
3.组件内守卫
定义在组件内的,相当于组件的methods等属性,
beforeRouterEnter 在渲染该组件的对应路由被confirm前调用
beforeRouterUpdate 在当前路由发改变,但是该组件被复用时调用
beforeRouterLeave 导航离开该组件的对应路由时调用 (定义在组件内)
应用场景:
1.验证用户登录,没有登录无法进入
2.清除当前组件内定时器,以免占内存
3.当前页面有未关闭的窗口阻止页面跳转

执行顺序:
1.导航被触发
2.在失活的组件里调用离开守卫
3.调用beforeach守卫
4.在重用的组件里面调用beforerouterupdate守卫
5.在路由里调用beforeenter
6.解析异步路由组件
7.在被激活的组件里调用beforerouterenter
8.调用全局的beforereslove守卫
9.导航被确认
10.调用全局的aftereach钩子
11.触发dom更新
12.用创建好的实例调用beforerouteenter守卫中传给next回调函数

19、vue组件中的data为什么是一个函数?

data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。
Object是引用数据类型,如果不用function返回,每个组件的data都是内存的同一个地址,一个数据改变了其他也改变了。

20、路由懒加载 ?

使用原因:
在单页应用中,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时。

原理:
vue异步组件技术:异步加载,vue-router配置路由 , 使用vue的异步组件技术 , 实现按需加载。

① 第一种:component:(resolve) => {
    require(["@/components/HelloWorld"],resolve);
}
② 第二种:const info = () => import("@/components/info");
③ 第三种:const info = (resolve) => {
    import("@/components/info").then(modul => {
        resolve(modul);
    })
}
④ 第四种:const info = r => require.ensure([],() => r(
    require("@/components/info")
),"info");

21、Vue.js介绍?

Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API;

Vue.js是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,
Vue采用自底向上增量开发的设计。

Vue的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。

数据驱动+组件化的前端开发。通过尽可能简单的 API实现响应的数据绑定和组合的视图组件。核心是一个响应的数据绑定系统。

22、scoped原理及穿透方法?

vue中的scoped通过在DOM结构以及css样式上加唯一不重复的标记:data-v-hash的方式,以保证唯一(通过PostCSS转译),达到样式私有模块化的目的。
scoped的3条渲染规则:
① 给HTML的DOM节点加一个不重复的data属性,来表示它的唯一性;
② 在每句css选择器末尾(编译后的生成的css语句)加一个当前组件的data属性选择器来私有化样式;
③ 如果组件内部包含有其他组件,只会给其他组件的最外层标签加上ddan当前组件的data属性。
补充:
在做项目中,会遇到这么一个问题,即:引用了第三方组件,需要在组件中局部修改第三方组件的样式,而又不想去除scoped属性造成组件之间的样式污染。
那么有哪些解决办法呢?
①不使用scopeds省略(不推荐);
② 在模板中使用两次style标签。
③scoped穿透:/deep/ PostCSS:使用JS插件转换CSS的工具。这些插件可以支持变量和mixins,转换将来的css语法,内联图像等。Autoprefixer是一种非常流行的PostCSS插件。

23、请说出vue.cli项目中src目录每个文件夹和文件的用法assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是一个应用主组件;main.js是入口文件

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

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

24.Vue中key值的作用?

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟DOM。

key 值:用于管理可复用的元素。
(1)key会使Vue会记住元素们的顺序,并根据这个顺序在适当的位置插入/删除元素来完成更新,这种方法比没有key属性时的就地复用策略效率更高。
(2)使用key属性强制替换元素,因为当key改变时,Vue认为一个新的元素产生了,从而会新插入一个元素来替换掉原有的元素

25、Vue怎么重置data ?

使用Object.assign(),vm. d a t a 可 以 获 取 当 前 状 态 下 的 d a t a , v m . data可以获取当前状态下的data,vm. datadatavm.options.data可以获取到组件初始化状态下的data。Object.assign(this. d a t a , t h i s . data, this. data,this.options.data())

26、组件中写name选项有什么作用?

①项目使用keep-alive时,可搭配组件的name进行缓存过滤。
②DOM做递归组件时需要调用自身name
③vue-devtools调试工具里显示的组件名称是由vue中组件name决定的

27.route和router?

route:
是“路由信息对象”包括path,params,hash,query,fullPath,matched,name等路由信息参数。
router:
是“路由实例对象”,包括了路由的跳转方法(push、go),钩子函数等。

28.Vue和React的区别监听数据变化的实现原理不同?

Vue 通过 getter/setter 以及一些函数的劫持,能精确快速的计算出 vdom 的差异。这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。

React 默认是通过比较引用的方式进行的,如果不优化,每当应用的状态被改变时,全部子组件都会重新渲染,可能导致大量不必要的 VDOM 的重新渲染。

数据流的不同:Vue 中默认支持双向绑定,组件与 DOM 之间可以通过 v-model 双向绑定。但是,父子组件之间,props 在 2.x 版本是单向数据流。React 一直提倡的是单向数据流。

模板渲染方式的不同:React 是通过 JSX 渲染模板,而 Vue 是通过一种拓展的 HTML 语法进行渲染

29.Vue3.0的了解:

1、性能提升
一句话简介:更小巧,更快速;支持摇树优化;支持 Fragments 和跨组件渲染;支持自定义渲染器。
2、API 变动
一句话介绍:除渲染函数 API 和 scoped-slot 语法之外,其余均保持不变或者将通过另外构建一个兼容包 来兼容 2.x。
模板语法的 99% 将保持不变。除了 scoped slot 语法可能会有一些微调之外变动最大的部分将是渲染函数 (render) 中的虚拟 DOM 的格式。
3、重写虚拟 DOM (Virtual DOM Rewrite)
随着虚拟 DOM 重写,减少 运行时(runtime)开销。重写将包括更有效的代码来创建虚拟节点。
第一个是关于提出的新API setup()函数;
第二个说了对于Typescript的支持,最后说了关于替换Object.defineProperty为 Proxy 的支持。详细说了下关于Proxy代替带来的性能上的提升,因为传统的原型链拦截的方法,无法检测对象及数组的一些更新操作,但使用Proxy又带来了浏览器兼容问题。
30.vue-cli替我们做了哪些工作:
vue-cli是基于 Vue.js 进行快速开发的完整系统,也可以理解成是很多 npm 包的集合。
vue-cli完成的功能:
.vue 文件 --> .js 文件
ES6 语法 --> ES5 语法
Sass,Less,Stylus --> CSS
对 jpg,png,font 等静态资源的处理
热更新定义环境变量,区分 dev 和 production 模式
如果开发者需要补充或修改默认设置,需要在 package.json 同级下新建一个 vue.config.js 文件

31.vue的指令

⑴v-bind:给元素绑定属性
⑵v-on:给元素绑定事件
⑶v-html:给元素绑定数据,且该指令可以解析html标签
⑷v-text:给元素绑定数据,不解析标签
⑸v-model:数据双向绑定
⑹v-for:遍历数组
⑺v-if:条件渲染指令,动态在DOM内添加或删除DOM元素
⑻v-else:条件渲染指令,必须跟v-if成对使用
⑼v-else-if:判断多层条件,必须跟v-if成对使用
⑽v-cloak:解决插值闪烁问题
32.v-for 与 v-if 的优先级:
当v-if和v-for一起使用时,v-for的优先级更高;
v-for比v-if优先,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候。

33.axios拦截:

//请求拦截器
axios.interceptors.request.use(function(config){
 return config;
},function(error){
 return promise.reject(error)
})
//响应拦截器
axios.interceptors.response.use(function (response){
    // 对响应数据做点什么
    return response;
  }, function (error){
    // 对响应错误做点什么
    return Promise.reject(error);
  });

是什么:
axios是一个基于promise的HTTP库,可以在浏览器和node.js中。
axios拦截分为请求拦截和响应拦截,在请求或响应被then或catch处理前拦截它们。
应用场景:
1.loading加载在请求拦截的时候将loading的状态改为true, 显示loading动画,在响应拦截的时候将loading的状态改为false,隐藏loading动画
2.token验证:在请求拦截 的时候将每一次判断是否有token,如果token存在,则在请求头加上这个token; 在响应拦截的时候header中是否存在token,在重新设置下token,将本地的token值替换掉。

34.vue怎么兼容IE?

方法一:
1.原因是Vue使用了ES6 Promise的问题,而IE浏览器不支持,解决方法是:使用babel-polyfill转换安装命令代码。
2.使用vue-cli项目在webpack.config.js中添加以下代码:
require(‘babel-polyfill’);
ebtry:{app:[‘babel-polyfill’,’./src/main.js’]}

方法二:
1.解决IE不显示内容代码。
2.在需要兼容的代码添加即可

3.如果出现语法不支持,比如 includes , 那么使用 babel-polyfill 解决方法代码:npm install babel-ployfill --save -g 4.main.js中引入 babel-polyfill 对象方法代码:引入后就兼容了。 import 'babel-ployfill'

35.什么情况下使用$set?

由于 Vue 会在初始化实例时进行双向数据绑定,使用Object.defineProperty()对属性遍历添加 getter/setter 方法,所以属性必须在 data 对象上存在时才能进行上述过程 ,这样才能让它是响应的。如果要给对象添加新的属性,此时新属性没有进行过上述过程,不是响应式的,所以会出现数据变化,页面不变的情况。此时需要用到$set。

35、$set是干嘛用的?

<template>
    <h1>{{arr}}</h1>
    <button @click="change()">点击</button>
</template>

<script>
export default {
    data(){
        return {
            arr:[1,2,3]
        }
    },
    methods:{
        change(){
            this.arr[1]=0;
            console.log(this.arr);  //[1,0,3]
        }
    }
}

复制代码上面就是一个典型的例子,当我们点击按钮想要根据数组arr的下标改变其元素的时候,你会发现data中的数据改变了,但是页面中的数据并没有改变。这时候就需要$set出场了。

change(){this.KaTeX parse error: Expected 'EOF', got '}' at position 20: …this.list,1,0);}̲复制代码改变/添加 对象属性的…set(data实例,“属性名(添加的属性名)”,“属性值(添加的属性值)”)
改变/添加 数组属性的时候:this.$set(data实例,数组下标,“改变后的元素(添加的元素)”)
原因:vue在创建实例的时候把data深度遍历所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。让 Vue 追踪依赖,在属性被访问和修改时通知变化。所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

当你在对象上新加了一个属性newProperty,当前新加的这个属性并没有加入vue检测数据更新的机制(因为是在初始化之后添加的),vue.$set是能让vue知道你添加了属性, 它会给你做处理。

36.vue中"dependencies",

"devDependencies"是什么?

dependencies:生产环境
devDependencies:开发环境,测试环境。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值