Skip to content

vue2

v-if和v-show

  • v-if是条件渲染,
  • v-show是显示与隐藏

如何理解MVVM

  • M:模型,对应的就是data的数据
  • V:视图,用户界面,DOM
  • VM:视图模型:Vue的实例对象,连接View和Model的桥梁

核心是提供对View和ViewModel的双向数据绑定,当数据改变的时候,ViewModel能监听到数据的变化,自动更新视图,当用户操作视图的时候,ViewModel也可以监听到视图的变化,然后通知数据进行改动,这就实现了双向数据绑定

ViewModel通过双向绑定把View和Model连接起来,他们之间的同步是自动的,不需要认为干涉,所以我们只需要关注业务逻辑即可,不需要操作DOM,同时也不需要关注数据的状态问题,因为她是由MVVM统一管理

v-for中的key值的作用是什么?

key属性是DOM元素的唯一标识

  • 提高虚拟DOM的更新
  • 若不设置key,可能会触发一些bug
  • 为了触发过度效果

vue的生命周期

创建

  • beforeCreat 在这个阶段属性和方法都不能使用
  • created 这里时实例创建完成之后,在这里完成了数据监测,可以使用数据,修改数据,不会触发updated,也不会更新视图

挂载

  • beforeMount 完成了模板的编译,虚拟DOM也完成创建,即将渲染,修改数据,不会触发updated
  • Mounted 把编译好的模板挂载到页面,这里可以发送异步请求也可以访问DOM节点

更新

  • beforeUpdate 组件数据更新之前使用,数据是新的,页面上的数据时旧的,组件即将更新,准备渲染,可以改数据
  • updated render重新做了渲染,这时数据和页面都是新的,避免在此更新数据

销毁

  • beforeDestroy 实例销毁前,在这里实例还可以用,可以清楚定时器等等
  • destroyed 组件已经被销毁了,全部都销毁

使用了keep-alive时多出两个周期:

  • activited 组件激活时
  • deactivited 组件被销毁时

在created和mounted去请求数据,有什么区别?

  • created:在渲染前调用,通常先初始化属性,然后做渲染
  • mounted:在模板渲染完成后,一般都是初始化页面后,在对元素节点进行操作

在这里请求数据可能会出现闪屏的问题,created里不会,一般用created比较多

  • 请求的数据对DOM有影响,那么使用created
  • 如果请求的数据对DOM无关,可以放在mounted

vue中的修饰符有哪些?

  1. 事件修饰符
    • .stop 组织冒泡
    • .prevent 组织默认行为
    • .capture 内部元素触发的事件先在次处理
    • .self 只有在event.target是当前元素时触发
    • .once 事件只会触发一次
    • .passive 立即触发默认行为
    • .native 把当前元素作为原生标签看待
  2. 按键修饰符
    • .keyup 键盘抬起
    • .keydown 键盘按下
  3. 系统修饰符
    • .ctrl
    • .alt
    • .meta
  4. 鼠标修饰符
    • .left 鼠标左键
    • .right 鼠标右键
    • .middle 鼠标中键
  5. 表单修饰符
    • .lazy 等输入完之后再显示
    • .trim 删除内容前后的空格
    • .number 输入是数字或转为数字

##vue如何进行组件通信?

  1. 父传子
    • props 父组件使用自定义属性,然后子组件使用props
    • $ref 引用信息会注册在父组件的$refs对象上
  2. 子传父
    • $emit 子组件绑定自定义事件,触发执行后,传给父组件,父组件需要用事件监听来接收参数
  3. 兄弟传
    • new一个新的vue实例,用on和emit来对数据进行传输
  4. vuex传值

keep-alive

Vue的一个内置组件,包裹组件的时候,会缓存不活跃的组件实例,并不是销毁他们

作用:把组件切换的状态保存在内存里,防止重复渲染DOM节点,减少加载时间和性能消耗,提高用户体验

axios是怎么做封装的

  • 下载
  • 创建实例
  • 接着封装请求响应拦截器
  • 抛出
  • 最后封装接口

vue路由时怎么传参的?

  • params传参
js
this.$router.push({name: 'index', params: {id: item.id}})
this.$route.params.id
  • 路由属性传参
js
this.$router.push({name: '/index/${item.id}'})
  • 路由配置 { path:'/index:id' }

  • query传参(可以解决页面刷新参数丢失的问题)

js
this.$router.push({
    name: 'index',
    query: {id: item.id}
})

vue路由的hash模式和history模式的区别

  1. hash的路由地址上有#号,history模式没有
  2. 在做回车刷新的时候,hash模式会加载对应页面,history会报错404
  3. hash模式支持低版本浏览器,history不支持,因为是H5新增的API
  4. hash不会重新加载页面,单页面应用必备
  5. history有历史记录,H5新增了pushState和replaceState()去修改历史记录,并不会立刻发送请求
  6. history需要后台配置

路由拦截是怎么实现

需要在路由配置中添加一个字段,它是用于判断路由是否需要拦截

json
{
  name: 'index',
  path: '/index',
  component: Index,
  meta: {
    requirtAuth: true
  }
}

而后给router添加一个beforeEach钩子函数,判断路由(token是否需要拦截)是否需要拦截

js
router.beforeEach((to, from, next) => {
    if (to.meta.requirtAuth) {
        if (store.satte.token) {
            next()
        } else {
        }
    }
})

vue的动态路由

  • 要在路由配置里设置meat属性,扩展权限相关的字段,在路由导航守卫里通过判断这个权限标识,实现路由的动态增加和跳转
  • 根据用户登录的账号,返回用户角色
  • 前端再根据角色,跟路由表的meta.role进行匹配
  • 把匹配搭配的路由形成可访问的路由

如何解决刷新后二次加载路由

  • window.location.reload()
  • matcher
js
const router = createRouter()

export function resetRouter() {
    const newRouter = creatRouter()
    router.matcher = newRouter.matcher
}

vuex刷新页面数据丢失

  • 把数据直接保存在浏览器缓存里(cookie localstorage sessionStorage)
  • 页面刷新的时候,再次请求数据,达到可以动态更新的方法
    • 监听浏览器的刷新数据,在刷新前把数据保存到sessionStorage里,刷新后请求数据,请求到了用vuex,如果没有那就用sessionStorage里的数据

computed和watch的区别

  • computed是计算属性,watch是监听,监听的是data中数据的变化
  • computed是支持缓存,依赖的属性值发生变化,计算属性才会重新计算,否则用缓存;watch不支持缓存
  • computed不支持异步,watch是可以异步操作
  • computed是第一次加载就监听,watch是不监听
  • computed函数中必须有return watch不用

vuex属性有哪些

  • state 存储变量
  • getters state的计算属性
  • mutations 提交更新数据的方法
  • actions 和mutations差不多,他是提交mutations来修改数据,可以包括异步操作
  • modules 模块化vuex

vue的双向数据绑定原理

通过数据劫持和发布订阅者模式来实现,同时利用Object.defineProperty()劫持各个属性的getter和setter

在数据发生改变的时候发布消息给订阅者,触发对应的监听回调渲染视图,也就是说数据和视图时同步的,数据发生改变,视图跟着发生改变,视图改变,数据也会发生改变。

  • 需要observer的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter

  • compile模板解析指令,把模板中的变量替换成数据,然后初始化渲染视图,同时把每个指令对应的节点绑定上更新函数,添加订阅者,如果数据变化,收到通知,更新视图

  • Watcher订阅者是Observer和Compile之间的通信桥梁。主要是用来做:

    1. 在自身实例化的时候忘订阅器内添加自己
    2. 自身要有一个update()方法
    3. 等待属性变动时,调用自身的update方法,触发compile这种的回调
  • MVVM模式作为数据绑定的入口,整合了observer、compile和watcher三者, 通过observer来监听自己的数据变化,通过compile解析模板指令,最后利用watcher把observer和compile联系起来, 最终达到数据更新视图更新,视图更新数据更新的效果

diff算法和虚拟DOM

  • 虚拟DOM,描述元素和元素之间的关系,创建一个JS对象 如果组件内有响应的数据,数据发生改变的时候,render函数会生成一个新的虚拟DOM,这个新的虚拟DOM会和旧的虚拟DOM进行比对,找到需要修改的虚拟DOM内容,然后去对应的真实DOM中修改
  • diff算法就是虚拟DOM的比对时用的,返回一个patch对象,这个对象的作用就是存储两个节点不同的地方,最后用patch里记录的信息进行更新真实DOM
    • JS对象表示真实的DOM结构,要生成一个虚拟DOM,再用虚拟DOM构建一个真实DOM树,渲染到页面
    • 状态改变生成新的虚拟DOM,跟就得虚拟DOM进行比对,这个比对的过程就是DIFF算法,利用patch记录差异
    • 把记录的差异用在第一个虚拟DOM生成的真实DOM上,视图就更新了。

vue和jq的区别

  • 原理不同 vue就是数据绑定;jq是先获取dom再处理
  • 着重点不同 vue是数据驱动,jq是着重于页面
  • 操作不同
  • 未来发展不同

如何封装一个组件

  • 使用Vue.extend()创建一个组件
  • 使用Vue.components()方法注册组件
  • 如果子组件需要数据,可以在props中接收定义
  • 子组件修改好数据,要把数据传递给父组件,可以用emit()方法

封装一个可复用的组件,需要满足什么条件

  • 低耦合,组件之间的依赖越小越好
  • 最好从父级传入信息,不要在公共组件中请求数据
  • 传入的数据要进行校验
  • 处理事件的方法写在父组件中

vue的过滤器

  • 全局过滤器
js

Vue.filter('add', function (v) {
    return v < 10 ? '0' + v : v
})
  • 本地过滤器:和methods同级
filter:{
   add:function(v){
      return v < 10 ? '0' + v : v
   }
}

在模板中使用

vue

<div>{{33 | add}}</div>

vue强制刷新

  • location.reload()
  • this.$router.go(0)
  • provide和inject

vue的性能优化

  1. 编码优化
    • 不要把所有数据都放在data中
    • v-for时给每个元素绑定事件用事件代理
    • keep-alive缓存组件
    • 尽可能拆分组件,提高复用性、维护性
    • key值要保证唯一
    • 合理使用路由懒加载,异步组件
    • 数据持久化存储的使用尽量用防抖、节流优化
  2. 加载优化
    • 按需加载
    • 内容懒加载
    • 图片懒加载
  3. 用户体验
    • 骨架屏
  4. SEO优化
    • 预渲染
    • 服务端渲染ssr
  5. 打包优化
    • CDN形式加载第三方模块
    • 多线程打包
    • 抽离公共文件
  6. 缓存和压缩
    • 客户端缓存、服务端缓存
    • 服务端Gzip压缩

首屏优化

  • 使用路由懒加载
  • 非首屏组件使用异步组件
  • 首屏不重要的组件延迟加载
  • 静态资源放在CDN上
  • 减少首屏上JS、CSS等资源文件的大小
  • 使用服务端渲染
  • 尽量减少DOM的数量和层级
  • 使用精灵图请求
  • 做一些loading
  • 开启Gzip压缩
  • 图片懒加载

By Modify.