前端面试整理二

vue

组件传值

​           非父子组件之间传递数据     父子 祖孙 兄弟

​                 3.1 引入第三方 new vue 定义为 eventBus 

​                          在组件中 created 中订阅方法 eventBus.$on("自定义事件名",methods 中的方法名) 

​                          在另一个兄弟组件中的 methods 中写函数,在函数中发布 eventBus 订阅的方法 

​                           eventBus.$emit("自定义事件名”) 

​                        在组件的 template 中绑定事件(比如 click) 

​             父组件中通过 provide 来提供变量,然后在子组件中通过 inject 来注入变量。(官方不推荐在实际业务中适用,但是写组件库时很常用。)       祖孙

​                pros 和 $emit  父子组件

​                vuex

​                $refs 父子组件

watch、methods 和 computed 的区别?

怎么认识vuex **vuex 有哪几种属性?**

​          Vuex就是一个仓库,仓库里面放了很多对象。

​         其中state就是数据源存放地,对应于一般Vue对象里面的data
​        
​        它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中

​           vuex的Getter特性
​       A、getters 可以对State进行计算操作,它就是Store的计算属性
​     B、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
​      C、 如果一个状态只在一个组件内使用,是可以不用getters

·        vuex的Mutation特性
        Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。

Vuex 页面刷新数据丢失怎么解决

第一次加载页面会触发那几个钩子函数

父子组件 钩子函数的加载顺序

​        父beforeCreated ->父created ->父beforeMounted ->子beforeCreated ->子created ->子beforeMounted ->子mounted -> 父mounted

实现数据双向绑定的原理

Vue 主要通过以下 4 个步骤来实现数据双向绑定的:

实现一个监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。

实现一个解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。

实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。

实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。

Vue-router 的钩子函数都有哪些?

​    

vue-router 有 3 种路由模式:hash、history、abstract,对应的源码如下所示:

- hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;
- history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式;
- abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式.

​         

路由传值的方式有哪几种

​           Vue-router 传参可以分为两大类,分别是编程式的导航 router.push 和声明式的导航 

​                 1、router.push 

​                          this.$router.push("home")  直接传递路由地址,但是不能传递参数 

​                          this.$router.push({name:"news",params:{userId:123})  这种方式传递参数目标页面刷新会报错 

​                         this.$router.push({path:"/news',query:{uersId:123})   

​                           查询参数 和 name 配对的式 params,和 path 配对的是 query 

​                2、声明式导航 

​                       字符串 <router-link to:"news"></router-link> 

​                     <router-link :to:"{name:'news',params:{userid:1111}}"></route-link>

​                     <router-link :to="{path:'/news',query:{userId:1111}}"></router-link>

query 和 params 之间的区别是什么?(必会) 

​             1、query 要用 path 来引入,params 要用 name 来引入 

​            2、接收参数时,分别是 this.$route.query.name 和 this.$route.params.name(注意:是$route 

​          而不是$router 

​            3、query 更加类似于我们 ajax 中 get 传参,params 则类似于 post,前者在浏览器的地址栏中 显示,params 不显示 

​            4、params 传值一刷新就没了,query 传值刷新还存在

 $route 和$router 的区别是什么?

​              $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由 

信息参数

​             $router 为 VueRouter 的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象, 

​            例如 history 对象,经常用的跳转链接就可以用 this.router.push 会往 history 栈中添加一个新的记 录。返回上一个 history 也是使用$router.go 方法 

路由之间是怎么跳转的?有哪些方式?

​         <router-link to="需要跳转到页面的路径"> 

​          this.$router.push()跳转到指定的 url,并在 history 中添加记录,点击回退返回到上一个页面 

​          this.$router.replace()跳转到指定的 url,但是 history 中不会添加记录,点击回退到上上个页面

​          this.$touter.go(n)向前或者后跳转 n 个页面,n 可以是正数也可以是负数

为什么data是一个函数

​        组件的data写成一个函数,数据以函数返回值形式定义,这样复用一次组件,就会返回一个新的data

​        而单纯的写成对象形式,组件实例共用一份data        

Vue 项目优化的解决方案都有哪些?(必会) 

1、 使用 mini-css-extract-plugin 插件抽离 css 

2、 配置 optimization 把公共的 js 代码抽离出来 

3、 通过 webpack 处理文件压缩 

4、 不打包框架、库文件,通过 cdn 的方式引入 

5、 小图片使用 base64 

6、 配置项目文件懒加载 

7、 UI 库配置按需加载 

​      开启 Gzip 压缩 

​    防抖节流

nextTick

​    在下次dom更新循环结束之后执行的延迟回调,在修改数据之后立即使用这个方法,获取更新后的dom

 怎样理解 Vue 的单项数据流

数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件对原始数据进行修改。这样会防止从子组件意外改变父组件的状态,从而导致你的应用的数据流向难以理解。

**hash 模式**

1、location.has 的值实际就是 URL 中 # 后面的东西。它的特点在于:hash虽然出现 URL 中,但不会被包含在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

2、可以为 hash 的改变添加监听事件
`window.addEventListener("hashchange",funcRef,false)`
每一次改变 hash (window.location.hash),都会在浏览器的访问历史中增加一个记录,利用hash的以上特点,就可以实现前端路由“更新视图但不重新请求页面”的功能了
特点:兼容性好但是不美观

**history 模式**

利用 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。

这两个方法应用于浏览器的历史记录站,在当前已有的 back、forward、go 的基础上,他们提供了对历史记录进行修改的功能。这两个方法有个共同点:当调用他们修改浏览器历史记录栈后,虽然当前 URL 改变了,但浏览器不会刷新页面,这就为单页面应用前端路由“更新视图但不重新请求页面”提供了基础

特点:虽然美观,但是刷新会出现 404 需要后端进行配置。

diff 算法了解吗?

diff算法采用同级比较。

- 1、tag 标签不一致直接新节点替换旧节点。

- 2、tag 标签一样。

  先替换属性

  对比子元素

  - 新老都有子元素,采用双指针方式进行对比

    sameVnode 判断tag和key完全相同为同一节点,进行节点复用

       头和头相等对比

       尾和尾相等对比

       头和尾相等对比

    ------

       sameVnode 的时候传入两个新老子节点patch(oldChild,newChild)

    乱序情况 -- 上面的都不符合,先遍历旧子节点数组形成 key值映射的map对象。

    然后根据新子节点数组循环 按照key值和位置关系移动以及新增节点 最后删除多余的旧子节点 如果移动旧节点同样需要patch(oldChild,newChild)

  - 新的有子元素,老的没有子元素。-- 直接将子元素虚拟节点转化成真实节点插入即可。

  - 新的没有子元素,老的有子元素。 -- 直接清空 innerHtml

- 3、无 tag 标签 -- 文本节点直接比较内容是否一致

this指向 

```
var a=2;
function printA(){
  console.log(this.a);
}
var obj={
  a:10,
  foo:printA,
  bar:function(){
    printA();
  }
}

obj.bar(); 

var f=obj.foo;
f();

var a = 2;
var obj = {
    a:10,
    timer: function () {
    setTimeout(function () {
        console.log(this.a);
        })
      }
    };
obj.timer();   

```

宏任务 微任务

    console.log('script start')
    async function async1() {
       await async2()
       console.log('async1 end')
    }
    async function async2() {
      console.log('async2 end')
    }
    async1()
    
    setTimeout(function() {
       console.log('setTimeout')
    }, 0)
    
    new Promise(resolve => {
        console.log('Promise')
         resolve()
    })
    .then(function() {
        console.log('promise1')
    })
    .then(function() {
        console.log('promise2')
    })
    
    console.log('script end')

//*script start => async2 end =>Promise => script end => async1 end => promise1=> promise2 => setTimeout*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值