Vue框架----原理汇总(纯收藏,方便单页查询)

一、阐述对MVC,MVP,MVVM的理解?

mvc 和 mvvm 其实区别并不大。都是一种设计思想。
主要就是 mvc 中 Controller 演变成 mvvm 中的 viewModel。
mvvm 主要解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。和当 Model 频繁发生变化,开发者需要主动更新到 View 。

1、什么是MVVM?

MVVM 是 Model-View-ViewModel 的缩写。

① Model-View-ViewModel的含义:
     Model 层代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑;
     View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来;
    ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,是一个同步 View 和 Model 的对象,连接Model和View。
② 在 MVVM 架构下,View 和 Model 之间并没有直接的联系,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的, 因此 View 数据的变化会同步到 Model 中,而 Model 数据的变化也会立即反应到 View 上。
③ ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而 View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作 DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

2、相关问题:vue框架是什么?

第一节:Vue.js框架是什么,为什么选择它?_大成子 | 翻身的码农的博客-CSDN博客

3、Vue与Angular以及React的区别?

① Vue与AngularJS的区别

相同点:
都支持指令:内置指令和自定义指令;
都支持过滤器:内置过滤器和自定义过滤器;
都支持双向数据绑定;
都不支持低端浏览器。
不同点:
AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;
在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;
Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。

②Vue与React的区别

相同点:
React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;
中心思想相同:一切都是组件,组件实例之间可以嵌套;
都提供合理的钩子函数,可以让开发者定制化地去处理需求;
都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;
在组件开发中都支持mixins的特性。
不同点:
React采用的 Virtual DOM 会对渲染出来的结果做脏检查;
Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。

二、vue数据绑定和响应式原理

vue MVVM 双向绑定(数据劫持+发布者-订阅者模式) - 简书

vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

解释单向数据流和双向数据绑定

单向数据流:对于 Vue 来说,组件之间的数据传递具有单向数据流这样的特性称为单向数据流,单向数据流(Unidirectional data flow)方式使用一个上传数据流和一个下传数据流进行双向数据通信,两个数据流之间相互独立,单向数据流指只能从一个方向来修改状态。
双向数据绑定:而双向数据绑定即为当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化,两个数据流之间互为影响。

具体步骤:

第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter
这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
① 在自身实例化时往属性订阅器(dep)里面添加自己
② 自身必须有一个update()方法
③ 待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

响应式数据原理:

vue2.x的响应式实现:主要是利用了Object.defineProperty()的方法里面的 setter 与 getter 方法的观察者模式来实现。在组件初始化时,会给每一个data属性注册getter和setter,然后再new 一个自己的Watcher对象,此时watcher会立即调用组件的render函数去生成虚拟DOM。在调用render的时候,就会需要用到data的属性值,此时会触发getter函数,将当前的Watcher函数注册进sub里。当data属性发生改变之后,就会遍历sub里所有的watcher对象,通知它们去重新渲染组件。

 proxy的优势如下:

Proxy 可以直接监听对象而非属性,可以直接监听数组的变化;
Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;

Object.defineProperty 的优势如下: 

兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill(垫片)来弥补

三、Vue生命周期

1、什么是vue生命周期?

Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

2、vue生命周期的作用是?

它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

3、vue生命周期总共有几个阶段?

总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

beforeCreate(创建前) 在数据观测和初始化事件还未开始;
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来;
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上;
mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互;
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程;
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用;
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用;
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用;

4、第一次页面加载会触发:beforeCreate, created, beforeMount, mounted

5、DOM 渲染在 mounted 周期中就已经完成?

四、Vue的路由实现:hash模式 和 history模式

1、hash模式:

在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;
          用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。

2、history模式:

history采用HTML5的新特性;
且提供了两个新方法:pushState(),replaceState()
可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。

3、Vue路由钩子函数

① 全局的钩子

beforeEach(to,from,next)
afterEach(to,from,next)

② 组建内的导航钩子

beforeRouteEnter(to,from,next)进入路由前 
beforeRouteUpdate(to,from,next)路由复用同一个组件时
beforeRouteLeave(to,from,next)离开当前路由时

③ 全局守卫

router.beforeEach 全局前置守卫 进入路由之前
router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
router.afterEach 全局后置钩子 进入路由之后
首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next:
to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由;
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
常用作路由拦截(流程)
1、导航被触发
2、在失活的组件里调用离开守卫
3、调用全局的 beforeEach 守卫
4、在重用的组件里调用 beforeRouteUpdate 守卫
5、在路由配置里调用 beforEnter
6、解析异步路由组件
7、在被激活的组件里调用 beforeRouteEnter
8、调用全局的 beforeResolve 守卫
9、导航被确认
10、调用全局的 afterEach 钩子
11、触发 DOM 更新
12、在创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数

五、Vue 组件

1、组件间的参数传递(bus总线和Vuex状态管理)

① 父组件与子组件传值(嵌套组件通信):
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数;
② 非父子组件间的数据传递,兄弟组件传值(非嵌套组件通信):
bus总线:eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)
Vuex状态管理

2、Vuex是什么?如何使用?

① 使用:只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
在main.js引入store,注入。新建了一个目录store,….. export 。
② 应用场景有:单页应用中,组件之间的状态、登录状态、加入购物车。
③ 方法:
state   定义共享数据
Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
mutations   同步修改共享数据
mutations  定义的方法动态修改Vuex 的 store 中的状态或数据。
getters    计算属性
类似vue的计算属性,主要用来过滤一些数据。
action   异步修改数据
actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispatch 来分发 action。
modules   独立成模块
项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

3、内置组件

<template> 条件渲染组件


<keep-alive> 对动态组件进行缓存

是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
在vue 2.1.0 版本之后,keep-alive新加入了两个属性: include(包含的组件缓存) 与 exclude(排除的组件不缓存,优先级大于include) 。


<transition> : 动画的内置组件
<transition-group> : 列表动画的内置组件
<component> : 动态组件
<slot> : 插槽

4、全局组件与局部组件

六、Vue指令

全局指令,自定义指令,v-model……

1、vue-cli如何新增自定义指令?

① 创建自定义局部指令( directives)

var app = new Vue({
    el: '#app',
    data: {    
    },
    // 创建指令(可以多个)
    directives: {
        // 指令名称
        dir1: {
            inserted(el) {
                // 指令中第一个参数是当前使用指令的DOM
                console.log(el);
                console.log(arguments);
                // 对DOM进行操作
                el.style.width = '200px';
                el.style.height = '200px';
                el.style.background = '#000';
            }
        }
    }
})

② 全局自定义局部指令(Vue.directive)

Vue.directive('dir2', {
    inserted(el) {
        console.log(el);
    }
})

③ 指令的使用

<div id="app">
    <div v-dir1></div>
    <div v-dir2></div>
</div>

七、vue如何自定义一个过滤器?(filter)

全局定义过滤器:(Vue.filter())
举个小例子:
Html下:
<div id="app">
     <input type="text" v-model="msg" />
     {{msg| capitalize }}
</div>
全局定义过滤器:(Vue.filter)
Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})
局部定义:(filters)
var vm=new Vue({
    el:"#app",
    data:{
        msg:''
    },
    filters: {
      capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
      }
    }
})

八、其他

1.css只在当前组件起作用:
在style标签中写入scoped即可,例如:<style scoped></style>。
2.v-if 和 v-show 区别:
v-if按照条件是否渲染,v-show是display的block或none;
3.$route和$router的区别
答:$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。
4.vue.js的两个核心是什么?
答:数据驱动、组件系统
5.vue几种常用的指令
答:v-for 、 v-if 、v-bind、v-on、v-show、v-else
6.vue常用的修饰符?
答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用
7.v-on 可以绑定多个方法吗?
答:可以
8.vue中 key 值的作用?
答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。
9.什么是vue的计算属性?
答:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。
10.vue等单页面应用及其优缺点
答:优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
active-class是哪个组件的属性?嵌套路由怎么定义?
答:vue-router模块的router-link组件。嵌套路由使用了children属性
11、sass是什么?安装使用的步骤是?有哪几大特性?
sass是css的预编译。
使用步骤:
第一步:用npm 下三个loader(sass-loader、css-loader、node-sass)
第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss
第三步:还是在同一个文件,配置一个module属性
第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”
有哪几大特性:
1、可以用变量,例如($变量名称=值);
2、可以用混合器,例如()
3、可以嵌套
12、axios是什么?怎么使用?描述使用它实现登录功能的流程?
请求后台资源的模块。npm install axios -S装好,然后发送的是跨域,需在配置文件中config/index.js进行设置。后台如果是Tp5则定义一个资源路由。js中使用import进来,然后.get或.post。返回在.then函数中如果成功,失败则是在.catch函数中。
13、Vue里的坑:https://www.jianshu.com/p/64a4fa04b74d
15、使用Vuex只需执行 Vue.use(Vuex),并在Vue的配置中传入一个store对象的示例,store是如何实现注入的?
答:Vue.use(Vuex) 方法执行的是install方法,它实现了Vue实例对象的init方法封装和注入,使传入的store对象被设置到Vue上下文环境的$store中。因此在Vue Component任意地方都能够通过this.$store访问到该store。
16.  问:state内部支持模块配置和模块嵌套,如何实现的?
答:在store构造方法中有makeLocalContext方法,所有module都会有一个local context,根据配置时的path进行匹配。所以执行如dispatch('submitOrder', payload)这类action时,默认的拿到都是module的local state,如果要访问最外层或者是其他module的state,只能从rootState按照path路径逐步进行访问。
17.  问:在执行dispatch触发action(commit同理)的时候,只需传入(type, payload),action执行函数中第一个参数store从哪里获取的?
store初始化时,所有配置的action和mutation以及getters均被封装过。在执行如dispatch('submitOrder', payload)的时候,actions中type为submitOrder的所有处理方法都是被封装后的,其第一个参数为当前的store对象,所以能够获取到 { dispatch, commit, state, rootState } 等数据。
18. 问:Vuex如何区分state是外部直接修改,还是通过mutation方法修改的?
答:Vuex中修改state的唯一渠道就是执行 commit('xx', payload) 方法,其底层通过执行 this._withCommit(fn) 设置_committing标志变量为true,然后才能修改state,修改完毕还需要还原_committing变量。外部修改虽然能够直接修改state,但是并没有修改_committing标志位,所以只要watch一下state,state change时判断是否_committing值为true,即可判断修改的合法性。
20.Vue路由懒加载(解决首页加载过慢)
Vue-router+webpack配合
在路由中
const aaa = () => import(/*webpackChunkName : “随便名字”*/  “@/view/index即路径”)        webpackcName一样的会打包到同一文件中
const bbb= () => import(/*webpackChunkName : “随便名字”*/  “@/view/index即路径”)    
export default new Router({
router : [{
path : “/”,
name : “aaa”,
component:aaa
},
{
path : “/”,
name : “bbb”,
component:bbb
}
]})
或者直接把路由写成resolve
routers = [ { path: '/', name: 'index', component: (resolve) => require(['./views/index.vue'], resolve) } ]
第三种
const Index = r => require.ensure([], () => r(require('./views/index')), 'group-home'); const routers = [ { path: '/', name: 'index', component: Index } ]
group-home是可以将多个组件都放到一个组里
在webpack.base,conf.js文件中的output配置chunkFileName,即最终打包的名字。

2. 模板语法 {{ }}

3. 如何创建vm对象和配置写法?

  el : -> 
  data : ->
  methods : -> 
  computed :  ->  区别:可缓存数据,建议:methods给事件用,computed给模板语法用
  watch :  -> 

4. vm对象的属性和方法,面向对象的基本操作
  vm.$el 
  vm.$data 
  vm.xxx

5. 指令,是一种vue提供的功能
 
v-model : 数据视图双向绑定,一般用在表单中

  v-if
  v-for

6. Vue如何操作样式?
  class 
  style

7. Vue事件?
  事件修饰符
  按键修饰符
  鼠标修饰符
  v-on -> methods下的方法

8. v-model主要就是处理表单操作的?
  输入框
  单选框
  复选框
  下拉菜单

9. Vue操作DOM元素?
  ref属性
  nextTick()方法

11. Vue中的组件?
  页面中的一块独立的功能
  根组件和普通组件
  data(){}
  父子通信
  正确的嵌套方式与is属性
  单向数据流
  数据的作用域
  原生事件.native
  props数据规范
  动态组件
  组件上的v-model
  provide inject通信

14. Vue的脚手架
  如何安装
  如何编写组件
  如何处理eslint错误
  样式如何解决冲突
  vsCode -> Vetur插件 
  chrome -> vue devtools插件

Vue2

Vue3

九、Vue3和Vue2对比: 

1、Vue3的体积更小。在脚手架打包的时候,如果vue3中没有使用到的语法,是不会最终进行合并打包的,所以vue3的体积会更小。 tree-shaking(摇树优化)。
2、Vue3的性能更好。Vue3的diff算法比2的diff算法更好。
 Vue2是采用  Object.defineProperty() 数据监听的,只能监听对象的一层,如果要监听多层,就得递归对每一层进行监听;
Vue3是采用  proxy 数据监听的,可以直接对对象整体进行监听,不需要递归。
3、Vue的源码不同。Vue的源码 Vue2使用JS去写的 ;Vue3使用TS去写的,所以Vue3 + TypeScript开发更好。
4、编写代码的风格不同。
      ① Vue2是 选项式风格( option api )

new Vue({
    data,
    methods,
    computed,
    watch
    ....
})

       ② Vue3不仅支持选项式风格(option api ), 还支持 组合式风格(composition api)。


//Vue3中要求,不管是跟组件还是普通组件,data必须是一个函数
    //Vue3脚手架中的tmeplate可以有多个跟标签
    //Vue2 -> vetur插件
    //Vue3 -> Vue Language Features (Volar)插件
vue3 ->  vue-router4 -> 没有大的区别
      1. 格式上做了微调
      2. 提供了两个新的 use函数 useRoute -> this.$route  useRouter -> this.$router
    vue3 -> vuex4 -> 没有大的区别 
      1. 格式上左了微调
      2. use函数 useStore 

  2. Vue3中组合式API的语法?

  3. 组合式API中的use函数是什么?

  4. 路由4和状态管理4有哪些新的变化?

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值