vue概述

文章目录

1、MVC、MVP与MVVM模式

1.1 mvc

一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

  • 组成:模型(model) - 视图(view)-控制器(controller)
  1. 模型:用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法
  2. 视图:渲染页面
  3. 控制器:M和V之间的连接器,用于控制应用程序的流程,及页面的业务逻辑
  • 将模型(M-数据、操作数据)、视图(V-显示数据的HTML元素)之间实现代码分离,松散耦合,使之成为一个更容易开发、维护和测试的客户端应用程序
  • 优点:耦合性低、重用性高、生命周期成本低、部署快、可维护性高、有利软件工程化管理
  • 缺点:无明确定义、不适合小型,中等规模的应用程序、增加系统结构和实现的复杂性、视图与控制器间的过于紧密的连接、视图对模型数据的低效率访问、一般高级的界面工具或构造器不支持模式
    在这里插入图片描述
1.2 mvp

MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

  • 特点:
  1. M、V、P之间双向通信。
  2. View 与 Model之间不通信,都通过 Presenter 传递。Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。
  3. View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
  4. Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,这样就可以重用。不仅如此,还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试–从而不需要使用自动化的测试工具。
  • 优点:
  1. 模型与视图完全分离,我们可以修改视图而不影响模型
  2. 可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
  3. 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
  4. 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)
  • 缺点 :由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。
    在这里插入图片描述
1.3 mvvm

在这里插入图片描述

1.4 区别

mvc可以直接从model中读取数据;
mvp中,model与view的数据通信是通过Presenter来进行的
mvvm采用双向绑定原理

2、常见的mvvm的几种方式

  1. 发布者-订阅者模式: 一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set('property', value)
  2. 脏值检查: angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,在指定的事件触发时进入脏值检测。
  3. 数据劫持: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

3、Object.defineProperty()方法

Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象

  • 参数:
    obj:要在其上定义属性的对象。
    prop:要定义或修改的属性的名称。
    descriptor:将被定义或修改的属性描述符。
  • 返回的值:被传递给函数的对象。

4、构建的 vue-cli 工程都到了哪些技术,它们的作用分别是什么?

1、vue.js:vue-cli工程的核心,主要特点是 双向数据绑定 和 组件系统。
2、vue-router:vue官方推荐使用的路由框架。
3、vuex:专为 Vue.js 应用项目开发的状态管理器,主要用于维护vue组件间共用的一些 变量 和 方法。
4、axios( 或者 fetch 、ajax ):用于发起 GET 、或 POST 等 http请求,基于 Promise 设计。
5、vux等:一个专为vue设计的移动端UI组件库。
6、创建一个emit.js文件,用于vue事件机制的管理。
7、webpack:模块加载和vue-cli工程打包器。

5、vue-cli 工程常用的 npm 命令有哪些?

下载 node_modules 资源包的命令:npm install
启动 vue-cli 开发环境的 npm命令:npm run dev
vue-cli 生成 生产环境部署资源 的 npm命令:npm run build
用于查看 vue-cli 生产环境部署资源文件大小的 npm命令:npm run build–report

6、请说出vue-cli工程中每个文件夹和文件的用处?

1、build文件夹是保存一些webpack的初始化配置。config文件夹保存一些项目初始化的配置。
2、node_modules是npm加载的项目依赖的模块。
3、src目录是我们要开发的目录,
其中assets:用来放置图片
components:用来放组件文件
app.vue:是项目入口文件
main.js是项目的核心文件。代码如下:
import Vue from ‘vue’
import App from ‘./App’
import router from ‘./router’
这三句的意思是首先引入vue,然后引入了./App即App.vue文件。最后一句是引入一段路由配置。
然后是实例化new Vue .el:’#app’意思谁将所有的组件都放在id为app的元素中。components表明引入的文件,此处就是app.vue这个文件,这个文件的内容将以这样的标签写进#app中。
4、static文件夹用来放置静态资源目录
5、index.html是首页入口文件
6、package.json是项目配置文件

7、webpack与gulp的区别?

gulp强调的是前端开发的工作流程,我们可以通过配置一系列的task,定义task处理的事务(例如文件压缩合并、雪碧图、启动server、版本控制等),然后定义执行顺序,来让gulp执行这些task,从而构建项目的整个前端开发流程。
webpack是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。
gulp与webpack上是互补的,还是可替换的,取决于你项目的需求。如果只是个vue或react的单页应用,webpack也就够用;如果webpack某些功能使用起来麻烦甚至没有(雪碧图就没有),那就可以结合gulp一起用。

8、vue渐进式框架的理解?

在我看来,渐进式代表的含义是:主张最少。
每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。
比如说,Angular,它两个版本都是强主张的,如果你用它,必须接受以下东西:

  • 必须使用它的模块机制- 必须使用它的依赖注入;必须使用它的特殊形式定义组件(这一点每个视图框架都有,难以避免)
    比如React,它也有一定程度的主张,它的主张主要是函数式编程的理念
    Vue可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。
    渐进式的含义,我的理解是:没有多做职责之外的事。

9、vue.js的两个核心是什么?

Vue.js是一个提供MVVM数据双向绑定的库,专注于UI层面,核心思想是:数据驱动、组件系统。
数据驱动:Vue.js数据观测原理在技术实现上,利用的是ES5Object.defineProperty和存储器属性: getter和setter(所以只兼容IE9及以上版本),可称为基于依赖收集的观测机制。核心是VM,即ViewModel,保证数据和视图的一致性。
组件系统:
模板(template)
初始数据(data)
接受的外部参数(props)
方法(methods)
生命周期钩子函数(lifecycle hooks)
私有资源(assets)

10、请问 v-if 和 v-show 有什么区别?

都是动态显示DOM元素
v-if是动态的向DOM树内添加或者删除DOM元素;
v-show是通过设置DOM元素的display样式属性控制显隐;
v-if是惰性的,如果初始条件为假,则什么也不做;
v-show是在任何条件下都被编译,然后被缓存,而且DOM元素保留;
v-if有更高的切换消耗;
v-show有更高的初始渲染消耗;
v-if适合运营条件不大可能改变;
v-show适合频繁切换。

11、vue常用的修饰符?

.stop阻止点击事件冒泡
.prevent取消默认事件
.self只会触发自己范围内的事件,不包含子元素
.once只执行一次
.lazy在改变后才触发
.number将输出字符串转为Number类型
.trim自动过滤用户输入的首尾空格
.enter:回车键
.ctrl
.exact修饰符允许你控制由精确的系统修饰符组合触发的事件。

10、v-on可以监听多个方法吗?

<button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来1</button>
<button @mouseenter="onEnter" @mouseleave="onLeave">鼠标进来2</button>
<button @click="a(),b()">点我ab</button>

13、vue中 key 值的作用?

key的作用主要是为了高效的更新虚拟DOM。
需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

14、vue事件中如何使用event对象?

使用不带圆括号的形式,event 对象将被自动当做实参传入;
使用带圆括号的形式,我们需要使用 $event 变量显式传入 event 对象。

15、$nextTick的使用?

this.$ nextTick方法用于更新数据后,马上进行dom操作,获取dom内容。
this.$nextTick是异步的。
更新数据后,视图是更新了,但是获取视图上的新数据的时候,却是原来的。这是就要用nextTick了。

16、Vue 组件中 data 为什么必须是函数?

这都是因为js本身的特性带来的,跟vue本身设计无关。
Object是引用数据类型,如果不用function 返回,每个组件的data 都是内存的同一个地址,一个数据改变了其他也改变了;

17、v-for 与 v-if 的优先级?

当它们处于同一节点,v-for的优先级比v-if更高
这意味着 v-if将分别重复运行于每个 v-for循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用

18、vue中 keep-alive 组件的作用?

通过keep-alive包裹的组件,在不活动时会缓存组件实例,不会对组件进行销毁,再次处于活动状态时,会读取缓存的内容并保存组件状态,不用重复请求接口获取数据。
props:
include - 字符串或正则表达,只有匹配的组件会被缓存
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

19、vue中如何编写可复用的组件?

这次的封装主要涉及的文件是Toast.vue toast.js Hello.vue,主要思路如下:
① Toast.vue是我们要使用的toast组件;
② toast.js里面用Vue.extend()扩展一个组件构造器,然后通过实例化组件构造器,就可创造出可复用的组件。
最后在toast.js里面导出函数myToast,函数myToast里面的逻辑在代码里面有解释;
③ Hello.vue里调用函数,显示组件。

20、什么是vue生命周期和生命周期钩子函数?

vue的生命周期就是vue实例从创建到销毁的过程,vue提供了一系列钩子函数,这些函数和生命周期的各个阶段一一对应

  • beforecreated:el 和 data 并未初始化
  • created:完成了 data 数据的初始化,el没有
  • beforeMount:完成了 el 和 data 初始化
  • mounted :完成挂载
  • beforeUpdate组件更新之前
  • update组件更新之后
  • activated组件被激活时调用
  • deactivated组件被移除时调用
  • beforeDestory组件销毁前调用
  • destoryed组件销毁后调用

destroy只是销毁一个实例,清理它与其它实例的连接,解绑它的全部指令及事件监听器,并不会清除data的数据或者清除dom。

21、vue如何监听键盘事件中的按键?

在Vue中,已经为常用的按键设置了别名,这样我们就无需再去匹配keyCode,直接使用别名就能监听按键的事件。
但是,如果是在自己封装的组件或者是使用一些第三方的UI库时,会发现并不起效果,这时就需要用到.native修饰符了
如果遇到.native修饰符也无效的情况,可能就需要用到$listeners了

22、vue更新数组时触发视图更新的方法?

push(); pop(); shift(); unshift(); splice(); sort(); reverse();

22、解决非工程化项目初始化页面闪动问题?

vue页面在加载的时候闪烁花括号{ {}},v-cloak指令和css规则如[v-cloak]{display:none}一起用时,这个指令可以隐藏未编译的Mustache标签直到实例准备完毕。

23、v-for产生的列表,实现active的切换?

@click="currentIndex = index"//点击时获取当前的索引值。
v-bind:class="{active: index === currentIndex}"//绑定点击后的样式为active类,且当前索引值等于几就是在第几个添加active类。
data中设置currentIndex: 0,默认给第一个绑定active类。

24、十个常用的自定义过滤器?

https://www.webge.net/?id=58

25、过滤器?

双花括号插值和 v-bind 表达式
2.0将1.0所有自带的过滤器都删除了,也就是说,在2.0中,要使用过滤器,则需要我们自己编写。
2.0过滤器的传参方式不是以前的方式,是以函数传参的方式

  • 注册在全局的fliter
    Vue.filter(‘过滤器名称’,function(管道符传递的数据){})
    (1)全局方法 Vue.filter() 注册一个自定义过滤器,必须放在Vue实例化前面
    (2) 过滤器函数始终以表达式的值作为第一个参数。带引号的参数视为字符串,而不带引号的参数按表达式计算
    (3)可以设置两个过滤器参数,前提是这两个过滤器处理的不冲突
    (4)用户从input输入的数据在回传到model之前也可以先处理
  • 局部注册是在vue实例实例中添加一个filters属性进行注册的

26、vue等单页面应用及其优缺点?

优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。

27、什么是vue的计算属性?

  1. 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护,所以遇到复杂逻辑时应该使用Vue特带的计算属性computed来进行处理。
  2. 在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。
  3. 计算属性还可以依赖多个Vue 实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新。
  4. 计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。
  5. 计算属性还有两个很实用的小技巧容易被忽略:一是计算属性可以依赖其他计算属性; 二是计算属性不仅可以依赖当前Vue 实例的数据,还可以依赖其他实例的数据,

28、计算属性的缓存和方法调用的区别?

  1. 我们可以将同一函数定义为一个方法或是一个计算属性。两种方式的最终结果确实是完全相同的。不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
  2. 使用计算属性还是methods取决于是否需要缓存,当遍历大数组和做大量计算时,应当使用计算属性,除非你不希望得到缓存。
    我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
  3. 计算属性是根据依赖自动执行的,methods需要事件调用。

29、vue-cli提供的几种脚手架模板

可选用模板常用的是webpack与webpack-simple。
browserify也只是在这两个模板的基础上移植的一个版本
其中,最大的区别是webpack-simple没有vue-router的中间件,不需要路由时推荐使用;
同时webpack-simple没有格式的检测。

30、vue-cli开发环境使用全局常量?vue-cli生产环境使用全局常量?

1 创建普通全局变量 .env
2 创建开发环境变量 .env.development
3 创建生产环境变量 .env.production

31、vue弹窗后如何禁止滚动条滚动?

添加一个遮罩层,给遮罩层加@touchmove.prevent

32、vue-cli中自定义指令的使用?

  • 全局注册:Vue.directive
  1. 使用Vue.directive(‘指令名称’,{}) 定义全局指令
  2. 定义时,指令名称不加 ‘v-’ 前缀,但是在调用的时候要加 ‘v-’ 前缀
  3. 参数2为一个对象,对象身上有一些指令相关处理函数,这些函数可以在特定阶段执行相关操作
    (1). bind:当指令绑定到元素上时,立即执行 bind 函数,只执行一次
    (2). inserted:被绑定元素插入到DOM中时执行 inserted 函数,只执行一次
    (3). update:当组件更新的时候执行 update,可能会出发多次
    (4). componentUpdated:所在组件的VNode及其海自VNode全部更新时调用,
    (5). unbind:只调用一次,指令与元素解绑时调用
  4. 每个函数中,第一个参数永远是 el,表示被绑定指令的那个元素,这个 el 参数,是一个原生的 js 对象
  5. 第二个参数,binding,是一个对象
  • 局部注册:在vue实例的directives属性中定义

33、vue-router如何响应 路由参数 的变化?

当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。

  • 方法一:watch监听
  • 方法二:导航守卫:beforeRouteUpdate

34、完整的 vue-router 导航解析流程?

1.导航被触发;

2.在失活的组件里调用beforeRouteLeave守卫;

3.调用全局beforeEach守卫;

4.在复用组件里调用beforeRouteUpdate守卫;

5.调用路由配置里的beforeEnter守卫;

6.解析异步路由组件;

7.在被激活的组件里调用beforeRouteEnter守卫;

8.调用全局beforeResolve守卫;

9.导航被确认;

10.调用全局的afterEach钩子;

11.DOM更新;

12.用创建好的实例调用beforeRouteEnter守卫中传给next的回调函数。

35、vue-router有哪几种导航钩子( 导航守卫 )?

vue-router 的导航钩子,主要用来作用是拦截导航,让他完成跳转或取消。

  • 组件实例的导航守卫:beforeRouteLeave、beforeRouteEnter、beforeRouteUpdate
  • 全局导航守卫:beforeEach、beforeResolve、afterEach
  • 路由配置(独享)守卫:beforeEnter

beforeRouteEnter 不能获取组件实例 this,因为当守卫执行前,组件实例被没有被创建出来,剩下两个钩子则可以正常获取组件实例 this

36、vue-router的几种实例方法以及参数传递?

编程式的导航 router.push
声明式的导航

  • 使用冒号(:)的形式传递参数 或者说 采用url传参
    路由列表的 path 是可以带参数的,我们在路由配置文件(router/index.js)里以冒号的形式设置参数。
    path: '/hello/:id/:userName',
    <router-link to="/hello/123/hangge">跳转到 hello</router-link>
    this.$router.push("/hello/123/hangge");
    页面中通过 $route.params.xxx获取传递过来的数据。
  • 使用 query 方式传递参数
    query 方式类似 get 传参,即通过 URL 传递参数。而路由列表的 path 不需要配置参数
    <router-link :to="{path:'/hello', query:{id:123, userName:'hangge'}}">
    this.$router.push({'path:'/hello',query:{id:123, userName:'hangge'}});
    页面中通过 $route.query.xxx 获取传递过来的数据。
  • 使用 params 方式传递参数
    params 方式类似于 post 传参,即传递的参数不会显示在 URL 上。同上面的 query 方式一样,路由列表的 path 不需要配置参数
    params 只能用 name 来引入路由,而不能用 path。
    <router-link :to="{name:'hello', params:{id:123, userName:'hangge'}}">
    this.$router.push({name:'hello',params:{id:123, userName:'hangge'}});
    页面中通过$route.params.xxx 获取传递过来的数据。

37、vue-router的动态路由匹配以及使用?

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果
一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。

38、vue-router如何定义嵌套路由?

嵌套路由主要是通过 children
children: [{path: 'file',component: File}]

39、vue-router实现路由懒加载( 动态加载路由 )?

vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出啊先长时间的白屏,即使做了loading也是不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时。
vue异步组件
es提案的import()
webpack的require,ensure()

40、vue-router路由的两种模式?

  • hash模式(默认)hash模式背后的原理是onhashchange事件。
  • history模式 history模式利用了H5中新增的pushState()和replaceState()方法
  • 对比:
  1. pushState()设置新的url可以是和当前url同源的任意url;hash只可修改#后面的部分,只能设置当前url同文档的url。
  2. pushState()设置的新url可与当前url一致,这样也会把记录添加到栈中;hash必须设置与当前url不同的url的,才会触发动作将记录添加到栈中。
  3. pushState()通过stateObject参数可以添加任意类型的数据到记录中;hash只可添加短字符串。
  4. pushState()可额外设置title属性供后续使用。
  • 不过,hash模式也有比history模式优势的地方。
  1. hash模式下,仅hash符号之前的url会被包含在请求中,后端如果没有做到对路由的全覆盖,也不会返回404错误。
  2. history模式下,前端的url必须和实际向后端发起请求的url一致,否则将返回404错误。

猜你喜欢

转载自blog.csdn.net/BookstoreSpirit/article/details/103327184