前端面试题(Vue与网络相关)

文章目录

1.Vue

1.1 Vue的最大优势

  • 双向数据绑定,
  • 数据驱动视图,
  • 组件化开发
  • 数据和视图分离
  • 单页面应用可以实现页面数据局部刷新

1.2. v-show与v-if的区别

  • v-if : 条件渲染。 如果不满足条件,则该元素不会添加到DOM树中
    • v-if有更高的切换性能 , 因为当条件为false时v-if不会渲染,当条件为true时才会渲染
  • v-show: 显示与隐藏。 只是修改元素的display属性值
    • v-show有更高的初始渲染消耗 , 因为v-show无条件渲染的,本质只是修改了css的样式

生命周期: v-show由false变为true不会触发组件的生命周期
v-if: 由false变化为true时触发组件的beforeCreate , createbeforeMountmounted钩子,由true变为false的时候触发组件的beforeDestorydestoryed方法

在这里插入图片描述
注意点 v-show 不支持 <template> 元素,也不支持 v-else。

1.3 . v-for与v-if为什么不能同时使用

重点 : v-for的优先级比v-if的优先级高, 如果你有多个元素要进行循环,v-if 就要执行多次

1.4 为啥组件中的data是一个函数而不是一个对象

  • data是对象时报错
    在这里插入图片描述
  • 为啥组件中data是一个函数=>return 相当于=>new Object
    • 当 data 是函数时,组件实例化的时候这个函数将会被调用,返回一个对象,
    • 计算机会给这个对象分配一个内存地址,实例化几次就分配几个内存地址,他们的地址都不一样,所以每个组件中的数据不会相互干扰
    • 保证了组件的独立性和可复用性,

注意根实例对象data可以是对象也可以是函数(根实例是单例),不会产生数据污染情况

1.5 scoped的作用与工作原理

scoped作用:

  • 设置样式的作用域让子组件的样式不会受到父组件样式的影响(只有相同权重的情况下)

scoped工作原理:

  • 给本身的组件添加一个自定义属性 , 通过css属性选择器增加了权重

1.6 什么是单项数据流

  • 单项数据流:就是props传递的数据是只能传不能改
    • (既只能父组件进行修改=>子组件不能进行修改父组件传递的值)

App.vue父组件

 <home
      v-for="item in list"
      :key="item.goodSid"
      :goodSid="item.goodSid"
      :goodsPrice="item.goodsPrice"
      :goodsName="item.goodsName"
      @price="addClick"
    >
    </home>

home.vue子组件进行修改父组件的值

 methods: {
    icreduce() {
      this.goodsPrice--;
    },
  },

在这里插入图片描述

  • 子组件的值发了改变并没有引起父组件的值发生改变=>违反了单一数据流原则
1.6 .1 解决方法 : 子传父进行修改

this.$emit('事件名',事件参数)

在这里插入图片描述
在这里插入图片描述
官网解释 : 关于只改变子组件不改变父组件值的两种方式

  • 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop
    的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
  • 额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变
    prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

1.7 什么是虚拟dom , 虚拟dom是如何工作的

真实dom与虚拟dom对比:

  • (真实dom) : 储存几百个属性

  • (虚拟dom) : 只存储元素中核心的十几个属性

    • 虚拟dom的本质是一个js对象, 与真实dom的区别在于虚拟dom只储存少部分核心的属性, 从而提高的渲染效率

虚拟dom是如何工作的

  • 把页面元素转换为虚拟dom(vNode)
  • 当vue数据变化的时候, 使用diff算法对比新旧vnode
  • 只更新变化的部分

1.8 vue中key值作用

  1. 给元素添加唯一标识符,可以让vue更准确的渲染元素

  2. vue会把页面DOM转换为虚拟dom , 当数据变化的时候,vue会使用diff算法对比新旧虚拟DOM

  3. 当两个盒子元素是一致的时候,vue不会更新元素,而是直接复用

  4. 如果给元素添加唯一标识符key值, vue就会强制更新key值不同的元素

  5. key是每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点

参考有无key的情况下代码更新情况

<div id="app">
    <li v-for="(item, index) in list" >
      <input type="checkbox" :value="item.text" /> {{item.text}}
    </li>
    </ul>
    <button @click="remove"> 删除</button>
  </div>
  <script>
    /* 创建vue实例 */
    let app = new Vue({
      //el:挂载点
      el: "#app",
      //data: 要渲染的数据
      data: {
        list: [{
          id: 1,
          text: '第一个值'
        }, {
          id: 2,
          text: '第二个值'
        }, {
          id: 3,
          text: '第三个值'
        }]
      },
      methods: {
        remove() {
          // shift只做删除第一个数据
          this.list.shift()
        }
      }
    })
  </script>

在这里插入图片描述

1.9 vue中key值为什么不能是下标?

  • 当数组元素发生变化的时候,其他的元素下标也会变化。
  • 如果使用下标作为key值,那么当数组元素发生变化的时候,可能会导致其他元素下标变化从而引起vue的就地更新。
  • 如果使用id作为key值,当数组元素变化的时候,下标变化不会引起vue就地更新。vue会复用相同的id元素,只会更新不同的id元素

1.10 vue有没有遇到数据更新页面不变的情况? vue修改data数据一定会更新吗? vue有没有遇到哪些问题?

  • 数组有些方法不会改变数组自身,而是得到一个新的数组,这种情况数组变化不会引起页面更新
  • 一般遇到这种情况,可以使用 vue.$set()方法强制更新数组 或者 把之前的数组给覆盖掉

值发生了改变但是数据没有做到响应式解决方法

  1. 直接进行赋值处理

  2. 使用 $set解决

    💘target:要更改的数据源(可以是对象或者数组)
    🌹 key:要更改的具体数据
    🌹 value :重新赋的值

   this.$set(this.list, 2, 100)`

1.11 JS数组方法中哪些会改变原数组,哪些不会?

  • v-for更新检测

    数组的方法分为两种
    
  • 第一种: 会改变原数组的元素值, pop(),push(),shift,unshift,sort(),reverse,splice()
    * 这种情况 v-for也会更新

  • 第二种:不会改变原数组的元素值. 例如 slice() 、 filter() 、 concat()等
    * 这种情况 v-for不会更新

具体方法参考

1.12 计算属性computed与methods的区别

  • 计算属性注意点:

    • 这个函数一定要写在vue实例的computed对象中

    • 这个函数一定要有返回值,否则计算属性无法渲染

  • 计算属性特点及原理介绍 :

    • 计算属性本质是一个函数=>但是使用时不能加()=>底层做了一次平铺:既平铺到vue实例当中
    • 计算属性的值就是函数的返回值
  • 缓存机制(提高性能)

(1)计算属性在第一次使用时,vue会调用一次函数,之后就会将返回值缓存起来
(2)下一次使用计算属性的时候,不会执行这个函数,而是直接从缓存中读取
(3)只有当计算属性中的数据发生变化时,这个函数才会重新执行一次

计算属性与mehods的区别在于

  1. 计算属性是基于它们的响应式依赖进行缓存的。
    只在相关响应式依赖发生改变时它们才会重新求值渲染数据,多次访问计算属性会立即返回之前的计算结果,而不必再次执行函数。
  2. methods方法,每当触发重新渲染时,调用方法将总会再次执行函数。

    详细参考计算属性与methods的区别

1.13 计算属性与侦听器的区别

  1. 侦听器没有缓存 , 但是计算属性有缓存

  2. 侦听器可以进行异步操作 ,但是计算属性不能进行异步

  3. 侦听器只能侦听data中的数据 , 计算属性可以不用data中的数据

  4. 侦听器没有返回值 ,但是计算属性必须有返回值

  5. 计算属性默认会执行一次(进行缓存)但是侦听器只有在第一次数据变化的时候才会执行

  6. 侦听可以侦听多个数据的变化但是计算属性只能侦听一个数据的变化

1.14 Vue的生命周期

四大阶段八大方法

阶段方法名方法名
初始化beforeCreatecreated
挂载beforeMountmounted
更新beforeUpdateupdated"
销毁beforeDestroy destroyed

vue初始化阶段执行的四个钩子

阶段名称方法名方法名
初始化阶段beforeCreatecreated
挂载阶段beforeMountmounted

组件生命周期的阶段
在这里插入图片描述
生命周期各个阶段所完成的事情

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMsg">改变</button>
    <p>我的名字是:{{ name }}</p>
    <button @click="doClick">点我改名字</button>
  </div>
</template>

<script>
export default {
  //数据
  data() {
    return {
      name: "ikun",
      age: 12,
      message: "hello word",
    };
  },
  //事件
  methods: {
    changeMsg() {
      this.message = "goodbye world";
    },
    doClick() {
      this.name = "黑马李宗盛";
    },
  },
  //  创建了vue实例,但是没有创建data
  beforeCreate() {
    console.log("----------初始化之前------");
    console.log(this);
    console.log(this.name);
    console.log(this.$el);
  },
  // 创建了data数据对象但是没有挂载=>
  // 可以调用 methods 中的方法,操作 data 中的数据,但 dom 未生成,$el 未存在
  // 最早可以获取data的钩子, 一般在这里发送Ajax请求
  created() {
    console.log("----------初始化完成------");
    console.log(this);
    console.log(this.name);
    console.log(this.$el);
    this.changeMsg();
  },
  // vue 实例的 $el 和 data 都已初始化,但是data没有挂载,data.message 未替换。
  beforeMount() {
    // 创建了`el`但是data还没有挂载
    console.log("----------挂载之前------");
    console.log(this);
    console.log(this.name);
    // 脚手架环境获取的undefined  html环境可以获取挂载点
    console.log(this.$el);
  },
  // 完成初始化渲染 , 挂载data数据(data.messagec成功渲染)
  // 最早可以操作dom的钩子 , 在这里可以进行dom的操作(比如焦点)
  mounted() {
    console.log("----------挂载完成------");
    console.log(this);
    console.log(this.name);
    console.log(this.$el);
  },
  beforeUpdate() {
    //检测data中的数据变化但是data 数据尚未和最新的数据保持同步。
    console.log("--------更新之前------");
  },
  updated() {
    // data中的数据变化,页面和 data 数据已经保持同步了。
    console.log("------更新完成-------");
  },
  beforeDestroy() {
    // 组件销毁之前调用 ,在这一步,实例仍然完全可用。
    console.log("----------销毁之前------");
  },
  // 完成组件实例的销毁(注意不是JS内存的回收 , 如果别的组件对其有引用永远都不会进行销毁)
  destroyed() {
    console.log("-----销毁完成----");
  },
};
</script>

前四个阶段游览器打印结果
在这里插入图片描述
图解
在这里插入图片描述
在这里插入图片描述

1.15 为什么token要存在vuex中还要存本地一份

  • 用户登录后,访问其他页面需要携带token,vuex是储存在内存里面的,而内存的特点就是快,将token存在vuex中可以提高获取token速度。
  • 因为localStorage的读取是一次磁盘读取,读取速度远低于vuex的内存读取,为了避免重复读取localStorage影响性能,需要将localStorage的数据放到vuex里维护。

由于vuex是储存在内存里面的,所以刷新页面就会消失,所以要存本地一份,刷新后token从本地获取。

  • 每次更新token也是修改vuex中的token,然后再覆盖到localstorage中

1.16 template的渲染机制

首先在Vue的生命周期中 , 是否指定el的挂载点 当有template时会直接执行template下的语法 , 在编译的过程中把template渲染成reader函数
在这里插入图片描述
整个渲染机制流程 : 首先借助抽象语法树(AST)解析<template></template>标签中写的模板。然后解析模板为render函数后转化为虚拟dom(VNode)再解析成真实DOM , 这样的一个渲染过程
在这里插入图片描述

1.17为什么vue2的对象新增或者删除不能实时响应-我们是如何处理的

  1. vue2采用的是Object.definerProperty 实现双向数据绑定
  2. 在初始化实例时,对属性执行getter与setter的转化
  3. 所有属性必须在data对象中存在,才能将它转化为响应式的(这也就造成了Vue无法检测到对象属性的添加或者修改)

参考例如: 直接修改数组的某一项(arr[index]='xxx')vue 不能做响应式处理

  • 处理方式
  使用Vue.set(object , propertyName , value) // 当前对象,属性名 属性值  

1.18 $route$router的区别

  • routes : 数组。 路由匹配规则
  • router : 对象。 路由对象
  • $router : 对象。 用于跳转路由 和 传递参数
  • $route :对象。 用于接收路由跳转参数
  1. $route 是路由信息对象,包括 path,params,hash,query ,fullPath,matched,name 等路由信息参数
  2. $router路由实例对象 包括路由的跳转方法,钩子函数

1.19 单页面应用与多页面应用的区别与特点

  1. SPA(单页面应用)
    • 就是指只有 一个主页面的应用,游览器一开始就加载所有的html , css ,js ,所有的界面内容都是包含在这个主页面中,但是在写的时候,还是要分开写,然后在加载的时候由路由动态载入,单页面的跳转只刷新局部资源
  • 优点 :
    • 无刷新界面,用户体验比较好
    • 前后端分离,节省原生开发App的成本
  • 缺点:
    • 不利于首屏优化,搜索引擎抓取
    • 初次加载时,时耗过长,页面复杂度提高很多
  1. 多页面(MPA),就是一个应用中有多个页面,页面跳转时是整页刷新

1.20 Vue数据双向绑定的原理

  • Vue是采用数据劫持,结合发布-订阅者模式,通过Object.defineProperty()来劫持各个属性之间的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调,也就是数据和视图同步,数据变化视图也跟着变化,视图变化数据也跟着变化
    源码详细参考

1.21 Vue2与Vue3双向数据绑定原理的区别

  • Vue在初始化实例时遍历data中的所有属性,并使用Object.defineProperty把所有属性转化为getter/setter。这样当追踪到数据变化时,setter会自动调用

      1. 添加或者删除对象的属性时,Vue检测不到,因为添加或者删除对象没有在初始化进行响应式处理,只能通过Vue.$set来调用Object.defineProperty()处理
      1. 无法监控到数组下标或者长度的变化
  • Vue3使用 Proxy来监控数据的变化,其作用为:用于定义基本操作自定义行为(如:属性查找,赋值,枚举,函数调用等)

    • Proxy直接代理整个对而非对象属性,这样只需要做一层代理就可以监听同级结构下 的所有属性变化
    • Proxy 可以监听数组的变化

1.22 $nextTick

  • 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM,主要思路就是采用微任务优先的方式调用异步方法去执行 nextTick 包装的方法
// 修改数据
this.message = "修改后的值";
this.isShow=true  // 更新视图
// 此时DOM还没有更新
console.log(this.$el.textContent); // => '原始的值'
this.$nextTick(function () {
  // DOM 更新了
  console.log(this.$el.textContent); // => '修改后的值'
});

  • 为啥使用$nexttick()
  1. 因为vue更新dom是异步的,但是我们要操作更新数据之后的视图就需要$nextTcik()

$nextTick原理解答

1.23keep-alive缓存组件

  • keep-alive主要功能是缓存组件,提升性能
  • 应用场景
  1. 可以j减少网络请求,如果当前组件数据量比较大,就可以节省网络请求 >> 提升用户体验
  2. 举例:如果详情页面之间进行切换,就可以使用keep-alive进行缓存组件,防止同样的数据重复请求
  • 他的三个属性

    • include包含要缓存的组件
    • exclude任何名称匹配的组件都不会被缓存
    • max 最多要缓冲多少个组件
  • 在路由中设置keepAlive属性判断是否需要缓存

 meta: {
  keepAlive: true,
  title: '列表页'
 }
  • 两个生命周期钩子
    • activated 激活时会被触发
    • deactivated 不激活,退出时触发

1.24 hash与history模式的区别

  • Hash模式:
  1. url路径会出现#字符
  2. Hash值不包括在HTTP请求中,因此修改当前页面的hash,不需要额外配置
  • History模式:
  1. 游览器自带的API
  2. 整个地址重新加载,可以保存历史记录,方便前进后退
  3. 使用HTML5 API(旧浏览器不支持)和HTTP服务端配置,没有后台配置的话,页面刷新时会出现404
  • 原理
  • 1.hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用 window.location.hash 读取。特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面
  • 2.history模式:history采用HTML5的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更

1.25 Vue常用的修饰符

  • .stop 阻止事件冒泡
  • .prevent 阻止标签默认行为
  • .once 事件只执行一次(Vue3剔除)
  • .enter:监听键盘enter键

1.26 Vue的自定义指令,钩子和参数

  1. 全局指令 :Vue.directive
  2. 局部指令注册:directives
  • 钩子函数有
    • bind 绑定事件的触发
    • inserted 节点插入的时候会触发
    • updata 组件内的相关更新
  • 钩子参数有
    • el:指令所绑定的元素,可以用来直接操作 DOM。

官方具体参考

1.27vuex的五个核心

  1. state: 单一状态树,用来存储变量
  2. getters: 从基本数据(state)派生的数据,相当于state的计算属性
  3. mutations: 提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mution 都有一个字符串的事件类型(type)和一个回调函数(handler)。
    回调函数就是我们实际进行状态更改的地方,并且它会接受 state作为第一个参数,提交载荷作为第二个参数
  4. action: 和mution的功能大致相同,不同之处在于 ①Action提交的是mution,而不是直接变更状态,②Action可以包含任意异步操作
  5. modules: 模块化vuex,可以让每一个模块拥有自己的 state、mutation、action、 getters,使得结构非常清晰,方便管理。

1.28 Vuex的数据传递流程

  1. 当数据进行修改的时候我们需要调用dispatch 来触发actions
  2. actions里面的每一个方法都有一个commit方法,当方法执行的时候会通过commit来触发mutations里面的方法进行数据的修改
  3. mutations里面都有一个state参数,这样就可以进行数据的修改

1.29 路由传值的方式有哪几种

跳转方法传参位置路由规则接收
<router-link to="/path?key=value"></router-link>/path?key=value无特殊$route.query.key
<router-link to="/path/值"></router-link>/path/值/path/:key$route.params.key
this.$router.push({path: “/path”, query: {key: value}})query的对象无特殊$route.query.key
this.$router.push({name: “com”, params: {key: value})params的对象路由规则需要name属性$route.params.key(注意,这种在内存中保存)
  • Vue-router传参可以分为两大类,分别是编程式的导航 router.push和声明式的导航
  • 1.编程式导航:router.push
    • 字符串:直接传递路由地址,但是不能传递参数
      • this.$router.push(“home”)
    • 对象:
      • 命名路由 这种方式传递参数,目标页面刷新会报错 - name+params
      • this.$router.push({name:“news”,params:{userId:123})
    • 查询参数 和path配对的是query
      • this.$router.push({path:"/news’,query:{uersId:123})
    • 接收参数 this.$route.query
  • 2.声明式导航
    • 字符串 <router-link to:“news”>
    • 命名路由 <router-link :to:“{name:‘news’,params:{userid:1111}}”>
    • 还可以to=“/path/值” - 需要提前在路由 规则里值 /path/:key
    • 查询参数
      • 还可以to="/path?key=value

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

  • <router-link to="需要跳转到页面的路径">
  • this.$router.push()跳转到指定的url,并在history中添加记录,点击回退返回到上一个页面
  • this.$router.replace()跳转到指定的url,但是history中不会添加记录,点击回退到上上个页面
  • this.$touter.go(n)向前或者后跳转n个页面,n可以是正数也可以是负数

1.31Vue的Diff算法

简单理解 :

  1. diff算法 采用递归,双指针原理,同级比较,深度优先的准则
  2. 主要就是在虚拟DOM树发生变化后,生成DOM树更新补丁的方式,对比新旧两株虚拟DOM树的变更差异,将更新补丁作用于真实DOM,以最小成本完成视图更新;
  3. 框架会将所有的结点先转化为虚拟节点Vnode,在发生更改后将VNode和原本页面的OldNode进行对比,然后以VNode为基准,在oldNode上进行准确的修改。
  4. 修改准则:原本没有新版有,则增加;原本有新版没有,则删除;都有则进行比较,都为文本结点则替换值;都为静态资源不处理;都为正常结点则替换

参考答案
参考答案

1.32 v-model 与.sync的区别

相同点:都是语法糖,都可以实现父子组件中的数据的双向通信

  • v-model语法糖 = props父传子 + 绑定事件监听@input
  • v-model实现原理 单向绑定默认是表单元素的value属性 + @input事件监听
<input type='text' :value="msg" @input = "msg = $event.target.value"/>
<span>{{msg}}</span>
1.32.1组件上使用v-model
  • v-model 父组件通过子组件标签传值,子组件通过$emit触发
  1. 父组件给子组件传值,并绑定自定义事件,默认传递的属性是value,自定义事件名为input
<!--v-model简写-->
<Son v-model="msg" />
<!--原始写法-->
<Son :value="msg" @input= "val => msg=val "/>

  1. 子组件使用props接收,通过 $emit 修改父组件的数据
props:['value']
1.32.2 sync 修饰符 props传参+ 绑定事件监听@update:属性名/触发事件监听emit 子传父
  • .sync修饰符可以实现和v-model同样的功能,而且它比v-model更加灵活。v-model一个组件只能用一个,sync可以有多个。

xxx.sync的原理
①父组件给字子组件传递props:属性名
②给当前子组件绑定了一个自定义事件,事件名为update:属性名,该事件会更新xxx的值
不同点:

// 正常父传子: 
<son :info="str" :title="str2"></son>

// 加上sync之后父传子(.sync没有数量限制): 
<son :info.sync="str" .title.sync="str2"></son> 

// 它等价于
<son
  :info="str" @update:info="val=>str=val"
  :title="str2" @update:title="val=>str2=val"></son> 

子组件

<template>
  <div>
    <p>{{ info }}</p>
    <button @click="fn">修改数据(子)</button>
  </div>
</template>
<script>
export default {
  props: ["info","title"],
  name:'son',
  methods: {
    fn() {
      // 修改数据:`$emit`所调用的事件名必须是`update:属性名`
      this.$emit('update:info',this.info + ",我现在被子组件emit了")
    },
  },
};
</script>
  1. 格式不同: v-model=“num”, :num.sync=“num”
  2. v-model: @input + value
  3. :num.sync: @update:num
  4. v-model只能用一次;.sync可以有多个

注意点 vue3中取消了修饰符.sync,并且把.sync的功能合并到了v-model上。

1.33 父子组件的加载,更新,销毁顺序

  1. 父组件,beforeCreate ,created ,beforeMount
  2. 子组件,beforeCreate ,created ,beforeMount,mounted
  3. 父组件, mounted

更新循序

  1. 先父组件(beforeUpdata)
  2. 子组件beforeUpdata,Updata
  3. 再父组件 updata

销毁循序

  1. 父组件beforeDestroy
  2. 子组件 beforeDestriy destroyed
  3. 父组件 destroyed

1.34单页面应用首屏优化

  • 缩小项目体积:

    通过webpack 对项目体积进行压缩,开启gizp 压缩文件
    2. 减小图片体积,图标可通过矢量图来代替

  • 减少请求次数
    1. 通过精灵图来减少小图标的总请求数
  • 减少加载模块

    单页面应用的首屏加载较慢主要是因为单页面应用在首屏时,无论是否需要都会加载所有的模块,可通过按需加载、路由懒加载来优化。

1.35 封装Vue组件的过程

  • 组件可以提升整体项目的开发效率,能够把页面抽象成多个相对独立的模块,解决传统项目开发效率低的问题
  • 具体步骤
    • 使用Vue.component方法注册组件,子组件需要数据,可以在props中接受定义,
    • 子组件修改好后,想把数据传递给父组件。可以使用$emit方法向外抛出
    • 如果需要给组件传入模板,这定义为插槽slot
    • 如果需要父组件主动调用子组件的方法可以在methods选项中开放方法

1.36Vue的插件机制(全局注册)

  • Vue.use 注册全局组件

  • Vue 插件机制的原理:本质上插件就是一个对象,在对象里面调用install 方法

import XtxSkeleton from '@/cpn/skeleton/index.vue';
import { App } from 'vue';
export default {
install(app:App){
		app.component('XtxSkeleton', XtxSkeleton)
    }
}

1.37 params与query传参的区别

>路由传参分为 params 传参与 query 传参

params 传参类似于网络请求中的 post 请求,
params 传过去的参数不会显示在地址栏中(但是不能刷新)。
params 只能配合 name 使用,如果提供了 path,params 会失效。

query 传参类似于网络请求中的 get 请求,
query 传过去的参数会拼接在地址栏中(?name=xx)。
query 较为灵活既可以配合 path 使用,也能配合 name 使用(亲测可用)。

参考答案

1.38 组件通信方式

  • 父子组件通信props, e m i t 和 emit和 emiton, p a r e n t 和 parent和 parentchildren,ref, a t t r s 和 attrs和 attrslisteners
  • 兄弟组件通信 p a r e n t , parent, parentroot,eventBus,vuex
  • 跨层级通信 eventBusprovide和injectvuex
    • provide和inject
-  代码执行顺序
data->provide->created->mounted
  * provide 和 inject 绑定并不是可响应的
 //   传入data中的数据必须return  
  //grandpa
 components: { Son },
    provide(){
       return {
        grandpaMsg:this.message
      }
   },
// 要想实现一个响应式 必须reeturn 一个函数
  provide(){
    return {
        grandpaMsg:()=>this.message
    }
  },  

1.39 Vue的内置指令

  1. component组件:有两个属性—is inline-template
    渲染一个‘元组件’为动态组件,按照’is’特性的值来渲染成那个组件

  2. transition组件:为组件的载入和切换提供动画效果,具有非常强的可定制性,支持16个属性和12个事件

  3. transition-group:作为多个元素/组件的过渡效果

  4. keep-alive:包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们

  5. slot:作为组件模板之中的内容分发插槽,slot元素自身将被替换

1.40 vue3 有了解过吗?能说说跟 vue2 的区别吗?

  • 性能更高了,主要得益于响应式的原理换成了 proxy,VNode diff 的算法进行了优化。
  • 体积更小了,删除了一些没必要或不常用到的 API,例如 filter、EventBus 等;按需导入,能配合 Webpack 支持 Tree Shaking。
  • 对 TS 支持更好啦,因为它本身源码就是用 TS 重写的。
  • Composition API(组合 API),相比较 Vue2 的 options api,对于开发大型项目更利于代码的复用和维护。新特性,例如 Fragment、Teleport、Suspense 等。

MVC与MVVM设计模式的区别

MVC : 传统的设计模式。

  • 设计模式: 一套广泛被使用的开发方式
  • M: model 模型
    • 模型:就是数据的意思
  • V : view视图
    • 视图:就是页面的意思
  • C:controller控制器
    • 控制器:在这里写js业务逻辑,把数据M 渲染到 视图 V (有点类似于我们之前学习的,把数据渲染到页面)

在这里插入图片描述

  • MVVM,一种软件架构模式,决定了写代码的思想和层次
    • M: model数据模型 (data里定义)
    • V: view视图 (页面标签)
    • VM: ViewModel视图模型 (vue.js源码)
  • MVVM通过数据双向绑定让数据自动地双向同步 不再需要操作DOM
    • V (修改视图) -> M(数据自动同步)
    • M(修改数据) -> V (视图自动同步)

MVVM是Model-View-ViewModel的简写

  1. MVVM是组织与管理我们代码的方法,在MVVM中View和model不能直接通信,一定要通过ViewModel,
  2. ViewModel实现了一个观察者的角色,每当Model更新的时候ViewModel需要监听他,并通知相应的View做UI更新
  3. 那同样当用户操作View的时候,ViewModel也要
    获取数据上的变化,并通知Model进行数据的更新,这样就实现了数据的双向绑

在这里插入图片描述

3 ajax/计算机网络

3.1常见的HTTP状态码

  1. 2xx(成功)表示成功处理了请求的状态码
    200(成功)服务器已成功处理了请求。
  2. 301 永久重定向
  3. 401 没有认证, 没有登录网站(token过期
  4. 403 禁止访问 ,没有权限
  5. 404 服务器找不到请求网页, 请求地址错误
  6. 500,(服务器内部错误)服务器遇到错误,无法完成请求

3.2讲述XMLHTTPrequest对象及常用方法与属性状态码

  • AJAX的核心技术就是XMLHTTPrequest对象,它是一种支持异步请求的技术
<script>
        /* 学习目标:XMLHttpRequest的两个事件

        1. onload事件 :  接收服务器响应的数(一次请求,只会执行一次)
        2. onreadystatechang事件 : 作用与onload事件一致(一次请求,会执行多次)
            面试点: XMLHttpRequest对象的状态码 (xhr.readyState)
                0: 请求未建立  (创建了xhr对象,但是还没调用open)
                1: 服务器连接已建立 
                2. 请求已接收  (send之后,服务器已经接收了请求)
                3. 请求处理中 
                4. 请求已完成,且响应已就绪 ( 4状态码等同于onload事件 )
        
         */

      //(1).实例化ajax对象
      let xhr = new XMLHttpRequest()
      console.log(xhr.readyState)
      //(2).设置请求方法和地址
      xhr.open("post", "http://www.liulongbin.top:3009/api/login")
      //(3).设置请求头(post请求才需要设置)
      xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
      console.log(xhr.readyState)
      //(4).发送请求 : 参数格式  'key=value'
      xhr.send("username=admin&password=123456")
      //(5).注册回调函数
      //a. onload 是新式浏览器才支持的
      //b. 如果要兼容更早的浏览器,可以使用 onreadystatechange
      //c. onreadystatechange触发时机 : xhr.readState状态变化
      // xhr.onload = function() {};

      xhr.onreadystatechange = function() {
        console.log(xhr.readyState)
        //onreadystatechange会触发多次,一般需要判断xhr.readState == 4 才获取响应数据
        if (xhr.readyState == 4) {
          console.log(xhr.responseText)
        }
      }
    </script>

3.3 get请求与post请求的区别

  1. 传参方式不同,
  • get在url后面拼接(请求行)
  • post 在请求体传参
  1. 大小限制不同
  • get有大小限制(一般在2-5MB)
  • post 没有大小限制
  1. 安全性不同
  • get 传参直接暴露在url中,不安全 (一般查询类都是get)
  • post 参数在请求体重,更加安全(一般用于登录注册必须是post请求)
  1. 传输速度不同

get 传输速度更快 ,post比较慢

3.4 为什么post请求会发送两次请求?

3.5 HTTP 与 HTTPS 的区别

  1. HTTPS 协议需要到 CA (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。(以前的网易官网是http,而网易邮箱是 https 。)

  2. HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。

  3. HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

  4. HTTP 的连接很简单,是无状态的。HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)
    详细参考

3.6 cookie 和session 的区别:

  • 最大的区别在于:cookie相当于前端的token 但是session相当于key,这个key会返回给后端并存储在数据库redis

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

3.7cookie 、localstorage 、 sessionstrorage 之间有什么区别?

  • 与服务器交互:
    • cookie 是网站为了标示用户身份而储存在用户本地终端上的数据(通常经过加密)
    • cookie 始终会在同源 http 请求头中携带(即使不需要),在浏览器和服务器间来回传递
    • sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存
  • 存储大小:

    cookie 数据根据不同浏览器限制,大小一般不能超过 4k
    sessionStorage 和 localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大

  • 有期时间:
    1. localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
    2. sessionStorage 数据在当前浏览器窗口关闭后自动删除
    3. cookie过期时间是后端决定的,与浏览器是否关闭无关

3.8 为什么需要cookie

  1. HTTP是一种无状态的协议,客户端与服务端建立连接并传输数据,数据传输完成后,连接就会关闭,再次交互数据需要建立新的连接,
  2. 因此,服务器无法从连接上跟踪会话,也无法知道用户上次做了什么,这时候就需要借助Cookie。 客户端请求服务器后,如果服务器需要记录用户状态,服务器会在响应信息中包含一个Set-Cookie的响应头,客户端会根据这个响应头存储Cookie信息。再次请求服务器时,客户端会在请求信息中包含一个Cookie请求头,而服务器会根据这个请求头进行用户身份、状态等较验。
    参考答案

3.9 HTTP 请求方式

方法描述
GET请求指定的页面内容,并返回实体主体
HEAD类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据包含在请求体中。POST请求可能会导致新的资源的建立或者已有资源的修改。
PUT从客户端向服务器传送的数据取代指定的文档的内容
DELETE请求服务器删除指定的页面
CONNECTHTTP1.1协议中预留给能够将连接方式改为管道方式的代理服务器
OPTIONS允许客户端查看服务器的性能
TRACE回显服务器收到的请求,主要用于测试或诊断

3.10 三次握手与四次挥手

答案详解

  • 四次挥手过程
    在这里插入图片描述
1. 客户端向服务端发送一个 `FIN`包,自己进入终止等待一状态 (挥手)
2. 服务端向客户端发送`ACK`包,表示自己进行等待关闭状态,客户端进入终止等待二状态  (二次挥手), 此过程中服务端还可以向客户端发送未发送的数据,而客户端还可以接受数据
3. 待客户端接受数据完后,服务端向客户端发送`FIN`包进入最后的确认状态
4. 客户端收到之后回复`ACK`包进入超时登录状态,经过超时时间后关闭连接

 A:分手吧     B:好吧
             B:是我不够帅吗?
A : 是的

3.11 计算机的七层网络模型

七层网络模型

4.项目与优化问题

4.1 下载功能的封装

下载功能的封装问题

4.2 后端返回的字节流(图片 | 文件)处理

  • 1、先把字节流图片转换为base64
 const src =
          "data:image/png;base64," + 
          btoa(
            new Uint8Array(res).reduce(
              (data, byte) => data + String.fromCharCode(byte),
              ""
            )
          );

这样图片可直接使用img标签显示出来
*2 , 然后使用url encode加密base64图片

url encode.encode(src); // 默认是’UTF-8’

4.3 图片懒加载与预加载

  1. 懒加载:也叫延迟加载,就是指在长网页中延迟加载图像,优化网页的性能,(主要是在电商网站中使用,用来减少服务器的负载,常适用图片很多页面很长的情况下)
  • 为啥用懒加载
  1. 提升用户的体验,如果图片数目较多,等待时间较长,严重影响用户的体验
  2. 减少无效资源的加载 这样能明显减少服务器的压力和流量,
  3. 防止资源过多阻塞JS的加载,影响网站的正常使用
  • 懒加载的原理
  1. 首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在data-original属性中,
  2. 当页面滚动的时候需要去监听scroll事件,在scroll事件的回调中,判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内将图片的 src 属性设置为data-original 的值,这样就可以实现延迟加载。
  1. 预加载: 也是一种性能优化的技术,预加载简单的说就是将所需的资源提前请求加载到本地,这样后面就可以直接在缓存中取资源

    • 为什么用预加载

在网页全部加载之前,对一些主要内容进行加载,`以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,直到所有内容加载完毕。

详细参考

4.4 SSR(服务端渲染模式)

SSR是服务端渲染:在后台将vue实例渲染为HTML字符串直接返回,在前端激活为交互程序。

  • 流程
    • 客户端发送请求给服务器
    • 服务器读取模板,解析成dom节点,返回一个完整的首屏html结构
    • 客户端进行首屏激活(把用户写的交互代码,在前端激活,重新变成SPA应用)
    • 这样后续,用户再点击超链接,跳转时,不会再向服务器发送请求,而是使用前端路由跳转,只发送ajax请求数据

优点

  • SEO友好,首屏加载快

缺点 :开发逻辑复杂,服务器负载大

SRR 传统的服务端渲染,SPA 与SSR 的区别

4.5 强缓存与协商缓存的区别

  • 强缓存: 指的是 让浏览器强制缓存服务端提供的资源。 使用Cache-Control 中的 max- age 字段来指定缓存时间

  • 协商缓存,主要由 ETag 和 Last-Modified 两个字段来实现

  • 区别:

    • 当静态资源不改变的时候,强缓存不会发送请求,协商缓存会发送请求
    • 强缓存的状态码是200,协商缓存是304
    • 强缓存发生在客户端,协商缓存发生在服务端
      在这里插入图片描述
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值