0
点赞
收藏
分享

微信扫一扫

最新面试题目vue

扒皮狼 2021-09-19 阅读 75

vue

1.mvvm 框架是什么?

前端页面中使用MVVM的思想,即MVVM/是整个视图层view的概念,属于视图层的概念。
MVVM是Model-View-ViewModel的简写。即模型-视图-视图模型。
模型指的是后端传递的数据。
视图指的是所看到的页面。
视图模型是mvvm模式的核心,它是连接view和model的桥梁。
它有两个数据传递方向:
一是将模型转化成视图,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。
二是将视图转化成模型,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。
以上两个方向都实现的,我们称之为数据的双向绑定。
总结:在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信
实现了前后端分离

2.vue的优点是什么?(为什么大部分公司选择vue)

体积小:压缩后只有33k;
更高的运行效率:基于虚拟DOM,一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化的技术,由于这种DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM;
双向数据绑定:让开发者不用再去操作DOM对象,把更多的精力投入到业务逻辑上;
生态丰富、学习成本低:市场上拥有大量成熟、稳定的基于vue.js的ui框架及组件,拿来即用实现快速开发;对初学者友好、入门容易、学习资料多;

3.vue的两个核心点是什么?

1.数据驱动

Vue 响应式核心就是,getter 的时候会收集依赖,setter 的时候会触发依赖更新
vue将遍历data中对象的所有property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。
getter 的时候我们会收集依赖,依赖收集就是订阅数据变化watcher的收集,依赖收集的目的是当响应式数据发生变化时,能够通知相应的订阅者去处理相关的逻辑。
setter 的时候会触发依赖更新,之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

2.组件系统

组件的核心选项
1 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。
2 初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。
3 接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。
4 方法(methods):对数据的改动操作一般都在组件的方法内进行。
5 生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。
6 私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用

4.三大框架的优缺点?(vue、Angular、React)

Angular:
优点:
2012年发布版本1.0,后由谷歌接手负责持续的开发维护。Angular是一个比较完善的前端框架,服务、模板、数据双向绑定、模块化、路由、过滤器、依赖注入等功能相当完整,同时模板功能强大,自带丰富的指令,易于操作。此外还引入了一些java的思想,所以有java基础的同学也能够较快上手的。
缺点:
官方文档可操作性不强,缺乏实例,很多功能的使用需要依赖搜索,对自学能力要求较高。入门容易,但是后期学习容易进入瓶颈,概念深入,不易理解。此外版本较多,没有做到很好的兼容,整体较重,渲染初始化慢。
React
优点:
是Facebook的内部项目开源,提出了一种新思路解决Web/Native开发。运用了Virtual Dom技术,比起Angularjs来说,更新dom的次数少,更新内容少,速度会更快。采用声明式设计,可以轻松描述应用,更加灵活,也能和已知的框架或库很好的配合。
缺点:
严格来说可能并不算是一个完整的框架,很多功能无法直接实现,发布较新,很多功能还需要进一步的完善,缺少大项目的实际应用。
Vue
优点:
轻量级!也简单易上手,官方介绍是构建用户界面的渐进式框架,可以灵活选取功能。简洁、轻量、快速、数据驱动、模块友好、组件化,这些特点都有利于更简单的开发页面,同时乘着近些年小程序的热潮,webapp的持续发展,Vue也是广泛使用。
缺点:
相对于家大业大的angular,历史不久的Vue,部分功能还不够完善,支持的库和拓展的丰富性还有待提升,同时对于老浏览器的支持也不太好。数据复杂起来也容易变得不好维护。

5.vue和jQuery的区别?

一、主体不同
1、vue.js:是一套用于du构建用户界zhi面的渐进式JavaScript框架。dao
2、jquery:是一个快速、简洁的JavaScript框架,zhuan是继Prototype之后又一个优shu秀的JavaScript代码库。
二、特点不同
1、vue.js:Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,方便与第三方库或既有项目整合。
2、jquery:具有独特的链式语法和短小清晰的多功能接口;具有高效灵活的css选择器,并且可对CSS选择器进行扩展;拥有便捷的插件扩展机制和丰富的插件。
三、优势不同
1、vue.js:目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
2、jquery:提供了对基本JavaScript结构的增强,比如元素迭代和数组处理等操作。

6.渐进式框架的理解?

主张最少,也就是弱主张,他是在vue核心库(视图模板引擎)的基础上,去逐步添加所需要功能(如,组件系统、路由、状态机等)
vue“渐进式”:是指先使用vue核心库,在vue核心库的基础上,根据自己需要再去逐渐增加功能。
Vue的核心的功能,是一个视图模板引擎,但这不是说Vue就不能成为一个框架。
在声明式渲染(视图模板引擎)的基础上,我们可以通过添加组件系统、客户端路由、大规模状态管理来构建一个完整的框架。
更重要的是,这些功能相互独立,你可以在核心功能的基础上任意选用其他的部件,不一定要全部整合在一起。
所说的“渐进式”,其实就是Vue的使用方式,同时也体现了Vue的设计的理念。

7.单页面应用和多页面应用区别及优缺点?

单页面应用
一个项目中只有一个完整的html页面,其他的都是部分的html片段组成。页面跳转只是局部刷新,不会重新加载全部资源。片段之间的切换快,比较容易实现转场动画。
多页面应用
一个项目是由多个完整的html页面组成,页面跳转所有的资源都要重新加载,页面之间的切换会出现卡顿空白的问题,不容易实现切换动画等


8.SPA首屏加载慢如何解决?

1.通过Gzip压缩
2.使用路由懒加载
3.利用webpack中的externals这个属性把打包后不需要打包的库文件都分离出去,减小项目打包后的大小
4.使用SSR渲染(服务器渲染)
5.将公用的JS库通过script标签外部引入,减小 app.bundel 的大小,让浏览器并行下载资源文件,提高下载速度;
6.在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;
7.加一个首屏loading图,提升用户体验;

9.scss的安装以及使用?

1.npm来安装 Sass

npm install \-g cnpm \--registry\=https://registry.npm.taobao.org
cnpm install -g sass

2.使用
2.1 首先要建立2个文件夹,文件夹名称可以随便起,再启动以下命令监听。

sass --watch sass:css  //(sass:css为文件夹名称,可以自设定)

2.2 在.scss 文档写入内容,另外一个css文件夹就会自动出现一个css的文档,在写代码时命令窗口不能关闭,负责无法执行css文档代码。

10.vue常用的UI组件库?

PC端:Element UI,iView,Muse-U,Ant Design Vue,AT-UI
移动端:Vant,Mint UI,Vux(微信),Mand Mobile

11.vue构建初始化工程步骤?

搭建Vue项目步骤如下:
①、打开cmd,cd到项目存放路径如:

cd C:\Users\lenovo\Desktop\bus_total

②、全局安装 vue-cli,cmd里输入命令行:

npm install -g vue-cli

③、创建一个基于 webpack 模板的新项目,在项目所在文件夹下,先进行初始化,即当前目录输入:

vue init webpack

根据提示,进行YES/NO,即安装是否安装配置路由之类的。

?Generate project in current directory? Yes
? Project name bus_total
? Project description A Vue.js project
? Author 王利平 <6551469+wang_li_pingping@user.noreply.gitee.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests No
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) npm

④、新建目录:vue init webpack my-project。(该步骤与第3步骤一样,选一即可)
⑤、安装依赖,进入项目所在文件夹,即当前文件夹、输入:

npm install

⑥、启动项目

npm run dev

⑦在浏览器中输入:

http://localhost:8080/

能看到:Welcome to Your Vue.js App页面则表示成功。

1.Vue中双向数据绑定是如何实现的?

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

var obj  = {};
Object.defineProperty(obj, 'name', {
        get: function() {
            console.log('我被获取了')
            return val;
        },
        set: function (newVal) {
            console.log('我被设置了')
        }
})
obj.name = 'fei';//在给obj设置name属性的时候,触发了set这个方法
var val = obj.name;//在得到obj的name属性,会触发get方法

首先我们为每个vue属性用Object.defineProperty()实现数据劫持,为每个属性分配一个订阅者集合的管理数组dep;然后在编译的时候在该属性的数组dep中添加订阅者,v-model会添加一个订阅者,{{}}也会,v-bind也会,只要用到该属性的指令理论上都会,接着为input会添加监听事件,修改值就会为该属性赋值,触发该属性的set方法,在set方法内通知订阅者数组dep,订阅者数组循环调用各订阅者的update方法更新视图。

2.请说出vue.cli项目中src目录每个文件夹和文件的用法?

assets文件夹是放静态资源;
components是放组件;
router是定义路由相关的配置;view视图;
app.vue是一个应用主组件;
main.js是入口文件

3.package.json 里面的配置解释?

默认的package.json文件直接使用命令:npm init --yes生成

{
"name": "pingdingshan", //包名字
"version": "1.0.0", //包版本,x.x.x的格式,符合语义化版本规则
"description": "", //一些描述信息
"main": "index.js",  //入口文件,一般是index.js
"module": "./es/index",  //es6编译入口文件
"scripts": {   //指定了运行脚本命令的npm命令行缩写,默认是空的test
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": "http://.../h5-components.git",   //项目代码存放的地方
"homepage": "http://...",   //项目主页url,(包的官网)
"author": "",  //作者信息
"license": "ISC",   //许可证,默认是ISC、有的默认是MIT
"files": [   //包含在项目中的文件(夹)数组,可以声明一个.gitignore来忽略部分文件
"lib",
"es",
"dist",
"assets"
],
"config": {  //字段用于添加命令行的环境变量。
"port": 8089,
"entry": {
"h5-components": [
"./index.js"
]
}
},
"dependencies": {   //在生产环境中需要用到的依赖
"antd-mobile": "^2.2.0",
"classnames": "^2.2.1",
"exif-js": "^2.3.0"
},
"devDependencies": {   //在开发、测试环境中用到的依赖
"file-loader": "^1.1.5",
"less-loader": "^4.1.0",
"lodash": "^4.17.4",
"lodash-webpack-plugin": "^0.11.4",
"mini-css-extract-plugin": "^0.4.1"
},
"sideEffects": [   //如果没有这个值,打包时会出错,参照css issue
"*.scss"
],
"browserslist": [   //指定该模板供浏览器使用的版本
"iOS >= 8",
"Firefox >= 20",
"Android > 4.2",
"> 1%",
"last 2 versions",
"not ie <= 10"
]
}

npm run 可列出package.json中scripts的所有脚本命令
npm run test就会执行:echo “Error: no test specified” && exit 1

3.assets和static的区别?

assets和static两个都是用于存放静态资源文件。
放在static中的文件不会进行构建编译处理,也就不会压缩体积,在打包时效率会更高,但体积更大在服务器中就会占据更大的空间
放在assets中的文件会进行压缩体积、代码格式化,压缩后会放置在static中一同上传服务器。
因此建议样式文件放在assets中进行打包,引入的第三方文件放到static中,因为引入的文件已经做过打包处理

4.你们vue项目是打包了一个js文件,一个css文件,还是有多个文件?

根据vue-cli脚手架规范,一个js文件,一个CSS文件。

5.$nextTick的使用?

this.nextTick()的回调函数中。created()中使用的方法时,dom还没有渲染,如果此时在该钩子函数中进行dom赋值数据(或者其它dom操作)时无异于徒劳,所以,此时this.$nextTick()就会被大量使用,而与created()对应的是mounted()的钩子函数则是在dom完全渲染后才开始渲染数据,所以在mounted()中操作dom基本不会存在渲染问题。

new Vue({
  el: '.app',
  data: {
    msg: 'Hello Vue.',
    msg1: '',
    msg2: '',
    msg3: ''
  },
  methods: {
    changeMsg() {
      this.msg = "Hello world."
      this.msg1 = this.$refs.msgDiv.innerHTML
      this.$nextTick(() => {
        this.msg2 = this.$refs.msgDiv.innerHTML
      })
      this.msg3 = this.$refs.msgDiv.innerHTML
    }
  }
})

6.vue组件中data为什么必须是一个函数?

因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象。
组建中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的data,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了。

7.v-on可以监听多个方法吗?

v-on可以监听多个方法

<button @click="myclick('hello','world','你好世界',$event)">点我text</button>
<!-- v-on在vue2.x中测试,以下两种均可-->
<button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来1</button>
<button @mouseenter="onEnter" @mouseleave="onLeave">鼠标进来2</button>
<!-- 一个事件绑定多个函数,按顺序执行,这里分隔函数可以用逗号也可以用分号-->
<button @click="a(),b()">点我ab</button>
<button @click="one()">点我onetwothree</button>
<!-- v-on修饰符 .stop .prevent .capture .self 以及指定按键.{keyCode|keyAlias} -->
<!-- 这里的.stop 和 .prevent也可以通过传入&event进行操作 -->
<!-- 全部按键别名有:enter tab delete esc space up down left right -->
<form @keyup.delete="onKeyup" @submit.prevent="onSubmit">
<input type="text" placeholder="在这里按delete">
<button type="submit">点我提交</button>

8.为什么使用key?

key在vue中,有跟它意思一样的关键的作用,整个框架对数据的渲染方面,起到了至关重要的作用
当更新数据的过程中,如果没有key的存在,系统会自动默认更新数据之间所要区分的key值为undefined,根据undefined==undefined,所以数据更新时会忽略特殊比对值的情况下自动按照对比为true的情况去更新渲染数据
特别是中途插入删除数据的过程中,会因为中间某条数据的缺少而进行从从数据更新点之后的所有数据的重新更新以及多出数据的重新创建,这跟vue框架的本质原则相违背。
添加key这个唯一标识后,vue中patch算法会按照前后对比的原则,收尾找相同节点,将数据一一比对,相同的节点就会只做循环,不会发生任何更新,减少多余更新渲染,最后只将更改后的数据渲染到框架中。(sameVnode方法来判断节点是否相同)

9.vue初始化页面闪动问题?

根dom上加上 style=“display: none;” :style="{display: ‘block’}"

10.vue禁止弹窗后的屏幕滚动?

methods : {
   //禁止滚动
   stop(){
        var mo=function(e){e.preventDefault();};
        document.body.style.overflow='hidden';
        document.addEventListener("touchmove",mo,false);//禁止页面滑动
    },
    /***取消滑动限制***/
    move(){
        var mo=function(e){e.preventDefault();};
        document.body.style.overflow='';//出现滚动条
        document.removeEventListener("touchmove",mo,false);
    }
}

11.vue如何引进本地背景图片?

第一种,只引入单个图片,这种引入方法在异步中引入则会报错。 比如需要遍历出很多图片展示时
<image :src = require('图片的路径') />
第二种,可引入多个图片,也可引入单个图片。 vuelic3版本没有static文件夹。可将静态图片存放到public目录下,直接引入即可
<image src="/public/image/logo.png"/>

12.vue修改打包后静态资源路径的修改?

1、js,css路径不对
解决办法:打开config/index.js,将其中的assetsPublicPath值改为’./’



2、css中引用的图片资源找不到
我的login.vue文件中有一段css,其中引用了一个背景图片,是这样写的
1.login{height:100%;background: url("../assets/login_bg.jpg") no-repeat; background-size: cover;color: white;}
“src/assets/”文件夹下有这张图片,打包后路径发生变化这个图片就找不到了,stackflow上有一个解决办法,很简单
打开“build/utils.js”,增加一行代码即可


13.vue的属性名称与method的方法名称一样时会发生什么问题?

报错 "Method 'xxx' has already been defined as a data property"
vue会把methods和data的东西,全部代理到vue生成对象中。
会产生覆盖所以最好不要同名
键名优先级:props > data > methods

14.你有使用过babel-polyfill模块吗?主要是用来做什么的?

Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。 举例来说,ES6在Array对象上新增了Array.from方法。Babel就不会转码这个方法。如果想让这个方法运行,必须使用babel-polyfill,为当前环境提供一个垫片。 Babel默认不转码的API非常多,详细清单可以查看babel-plugin-transform-runtime模块的definitions.js文件
在低版本浏览器里不能正常显示

15.vue为什么要求组件模板只能有一个根元素?

Vue其实并不知道哪一个才是我们的入口,因为对于一个入口来讲,这个入口就是一个Vue类,Vue需要把这个入口里面的所有东西拿来渲染,处理,最后再重新插入到dom中。如果同时设置了多个入口,那么vue就不知道哪一个才是这个‘类’。
通过这个‘根节点’,来递归遍历整个vue‘树’下的所有节点,并处理为vdom,最后再渲染成真正的HTML,插入在正确的位置。那么这个入口,就是这个树的‘根’,各个子元素,子组件,就是这个树的‘枝叶’,而自然而然地,这棵‘树’,就是指一个vue实例了

16.v-show和v-if指令的共同点和不同点?

相同点:v-show和v-if都能控制元素的显示和隐藏。
不同点:
实现本质方法不同
v-show本质就是通过设置css中的display设置为none,控制隐藏
v-if是动态的向DOM树内添加或者删除DOM元素
编译的区别
v-show其实就是在控制css
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件
编译的条件
v-show都会编译,初始值为false,只是将display设为none,但它也编译了
v-if初始值为false,就不会编译了
性能
v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
注意点:因为v-show实际是操作display:" "或者none,当css本身有display:none时,v-show无法让显示

17.<keep-alive></keep-alive>的作用是什么?

keep-alive可以实现组件缓存,当组件切换时不会对当前组件进行卸载
<keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染
比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用<keep-alive></keep-alive>进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染
常用的两个属性include/exclude,允许组件有条件的进行缓存
两个生命周期activated/deactivated,用来得知当前组件是否处于活跃状态

18.如何获取dom?

根据ID获取
使用getElementById()方法可以获取带有ID的元素对象
根据标签名获取
使用getElementsByTagName()方法获取元素的标签
通过HTML5新增的方法获取
使用getElementsByClassName()方法获取元素
使用document.querySelector()选择器返回任意元素的第一个元素的对象
使用querySelectorAll()返回指定选择器的所有元素对象集合
特殊元素获取

19.说出几种vue当中的指令和它的用法?

1、v-if:判断是否隐藏
2、v-for:数据循环
3、v-bind:class:绑定一个属性
4、v-model:实现数据双向绑定
这里重点说明一个v-if和v-show的区别:
共同点:都是通过判断绑定数据的true/false来展示的
不同点:v-if只有在判断为true的时候才会对数据进行渲染,如果为false代码删除。除非再次进行数据渲染,v-if才会重新判断。可以说是用法比较倾向于对数据一次操作。
v-show是无论判断是什么都会先对数据进行渲染,只是false的时候对节点进行display:none;的操作。所以再不重新渲染数据的情况下,改变数据的值可以使数据展示或隐藏

20.vue-loader是什么?使用它的用途有哪些?

vue-loader是解析 .vue 文件的一个加载器,跟 template/js/style转换成 js 模块;
用途:js可以写es6、style样式可以scss或less;template可以加jade等;

21.如何让CSS只在当前组件中起作用?

当前组件<style>写成<style scoped>

22.v-if和v-for的优先级?

v-for和v-if不应该一起使用,必要情况下应该替换成computed属性。原因:v-for比v-if优先,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候。

1.vue父组件向子组件传递数据?

1,父传子主要通过在父组件v-model绑定数据,在子组件进行用props进行数据的接收;
2,父组件触发子组件的方法,主要通过$refs来触发,同时传参

2.子组件像父组件传递事件?

1.子组件需要使用this.$emit 将子组件的事件进行上级传递。

  1. 父组件需要使用@事件名的方式,接收子组件的事件。

3.非子组件与父组件通信?

这时可以通过eventHub来实现通信. 所谓eventHub就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件.

4.跨组件双向数据绑定?

5.vue 各种组件通信方法(父子 子父 兄弟 爷孙 毫无关系的组件)?(详解)

一、props / $emit

父组件通过props的方式向子组件传递数据,而通过$emit 子组件可以向父组件通信。

  1. 子组件向父组件传值
    对于emit绑定一个自定义事件, 当这个语句被执行时, 就会将参数arg传递给父组件,父组件通过v-on监听并接收参数
二、 parent

三、provide/ inject

概念:provide/ inject 是vue2.2.0新增的api, 简单来说就是父组件中通过provide来提供变量, 然后再子组件中通过inject来注入变量。
注意: 这里不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中回去数据

四、ref / refs

ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据

五、eventBus

eventBus 又称为事件总线,在vue中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。
eventBus也有不方便之处, 当项目较大,就容易造成难以维护的灾难

六、Vuex
  1. Vuex介绍
    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.
    Vuex 解决了多个视图依赖于同一状态和来自不同视图的行为需要变更同一状态的问题,将开发者的精力聚焦于数据的更新而不是数据在组件之间的传递上
  2. Vuex各个模块
    state:用于数据的存储,是store中的唯一数据源
    getters:如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算
    mutations:类似函数,改变state数据的唯一途径,且不能用于处理异步事件
    actions:类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作
    modules:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护
七、localStorage / sessionStorage

这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护。
通过window.localStorage.getItem(key)获取数据
通过window.localStorage.setItem(key,value)存储数据
注意用JSON.parse() / JSON.stringify() 做数据格式转换
localStorage / sessionStorage可以结合vuex, 实现数据的持久保存,同时使用vuex解决数据和状态混乱问题.

八 listeners

现在我们来讨论一种情况, 我们一开始给出的组件关系图中A组件与D组件是隔代关系, 那它们之前进行通信有哪些方式呢?
使用props绑定来进行一级一级的信息传递, 如果D组件中状态改变需要传递数据给A, 使用事件系统一级级往上传递
使用eventBus,这种情况下还是比较适合使用, 但是碰到多人合作开发时, 代码维护性较低, 可读性也低
使用Vuex来进行数据管理, 但是如果仅仅是传递数据, 而不做中间处理,使用Vuex处理感觉有点大材小用了.
总结
常见使用场景可以分为三类:
父子组件通信: props; children; provide / inject ; ref ; listeners
兄弟组件通信: eventBus ; vuex
跨级通信: eventBus;Vuex;provide / inject 、listeners

6.EventBus注册在全局上时,路由切换时会重复触发事件,如何解决呢?

坑一
正当你开心的准备玩耍的时候却发现好像有哪里不对劲,怎么事件会重复触发了,而且每次切换过路由后,事件执行次数就会加一,这怎么行,假如用户非常频繁的切换页面,那事件执行次数不是会越来越多,到最后不是要爆炸。
一番搜索后终于找到了原因,原来这是因为我们的事件是全局的,它并不会随着组件的销毁而自动注销,需要我们手动调用注销方法来注销。知道了问题原因就好办了,我们可以在组件的 beforeDestroy ,或 destroy 生命周期中执行注销方法,手动注销事件。

 beforeDestroy() {
            //组件销毁前需要解绑事件。否则会出现重复触发事件的问题
            this.bus.$off(this.$route.path);
        },

坑二
你以为这样就可以好好玩耍了吗,NO,NO,NO。
虽然我们在生命周期中注销了事件,然而还是发现事件会多次执行,问题依旧在,那是什么原因呢?
经过打印日志后发现,问题出在事件名上面,由于我是用的 this.route.path作为事件名,在注销的时候也是想当然的用this.toure.path 作为注销事件名。观察日志后发现,在 beforeDestroy 中, this.route.path 获取到的其实是下一个页面的 path ,注意这一点,问题即可解决。解决方案也很简单,就是在当前页面用一个变量将当前路由存下来,用这个变量作为事件名注销事件即可。

1.v-model的使用?

v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:
  1. v-bind绑定一个value属性
  2. v-on指令给当前元素绑定input事件
自定义组件使用v-model,应该有以下操作:

  1. 接收一个value prop
  2. 触发input事件,并传入新值

2.分别简述computed和watch的使用场景?

1、区别
watch中的函数是不需要调用的
computed内部的函数调用的时候不需要加()
watch 属性监听 监听属性的变化
computed:计算属性通过属性计算而得来的属性
watch需要在数据变化时执行异步或开销较大的操作时使用
对于任何复杂逻辑或一个数据属性在它所依赖的属性发生变化时,也要发生变化,这种情况下,我们最好使用计算属性computed。
computed 属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
computed中的函数必须用return返回最终的结果
当computed中的函数所依赖的属性如果没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取
watch 一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;
2、使用场景
computed     
    当一个属性受多个属性影响的时候就需要用到computed
    最典型的例子: 购物车商品结算的时候
watch
    当一条数据影响多条数据的时候就需要用watch
    搜索数据

3.vue事件对象的使用?

1,v-on:click/mouseover
2, 阻止冒泡:
a) ev.cancelBubble=true; (原生js语法)
b) @click.stop="show()" 推荐使用
3,默认行为(默认事件)
阻止默认行为:
a) @contextmenu.prevent="show()" 右键行为事件,但右键有个默认行为;推荐使用
b) ev.preventDefault() (原生js语法,阻止默认行为)
4,键盘事件
@keydown="show(event)" ev.keyCode
@keyup

4.vue中过滤器有什么作用及详解?

1.代码运用的地方

<!-- 在双花括号中 -->
{{ date | formatDate}}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="data | formatDate"></div>

2.场景: 时间格式的转化


  1. 注册过滤器函数
    首先定义过滤器有两种方式,第一种是全局过滤器,我们可以直接在vue对象上使用filter方法注册过滤器,这种全局注册的过滤器在任何一个组件内都可以使用。第二种则是组件内部的过滤器,注册组件内部过滤器则只能在当前组件内使用,接下来我们使用这两种方式注册过滤器函数。
// 全局函数
Vue.filter('formatTime', function (value) {
  const date = new Date(val);
  const hour = date.getHours();
  const minutes = date.getMinutes();
  const seconds = date.getSeconds();
  return `${hour} : ${minutes} : ${seconds}`;
})
  1. 过滤器可以串联:
    {{ message | filterA | filterB }}
  2. 接收参数
    {{ message | filterA('arg1', arg2) }}
    filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。

5.列举常用的指令?

  1. 文本插值:{{ }} Mustache
  2. DOM属性绑定: v-bind
  3. 指令绑定一个事件监听器:v-on
  4. 实现表单输入和应用状态之间的双向绑定:v-model
  5. 控制切换一个元素的显示:v-if 和 v-else
  6. 列表渲染:v-for:用 v-for 把一个数组对应为一组元素;一个对象的 v-for
  7. 根据条件展示元素:v-show
  8. v-if vs v-show
    9.v-if 与 v-for 一起使用

6.vue常用的修饰符?

一、v-model修饰符

1、.lazy:
输入框改变,这个数据就会改变,lazy这个修饰符会在光标离开input框才会更新数据:



2、.trim:
输入框过滤首尾的空格:



3、.number:
先输入数字就会限制输入只能是数字,先字符串就相当于没有加number,注意,不是输入框不能输入字符串,是这个数据是数字:

二、事件修饰符

4、.stop:
阻止事件冒泡,相当于调用了event.stopPropagation()方法:
!](https://upload-images.jianshu.io/upload_images/6374688-416c2fd29a93f9ec.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
5、.prevent:
阻止默认行为,相当于调用了event.preventDefault()方法,比如表单的提交、a标签的跳转就是默认事件:


6、.self:
只有元素本身触发时才触发方法,就是只有点击元素本身才会触发。比如一个div里面有个按钮,div和按钮都有事件,我们点击按钮,div绑定的方法也会触发,如果div的click加上self,只有点击到div的时候才会触发,变相的算是阻止冒泡:


7、.once:
事件只能用一次,无论点击几次,执行一次之后都不会再执行


8、.capture:
事件的完整机制是捕获-目标-冒泡,事件触发是目标往外冒泡
9、.sync
对prop进行双向绑定
10、.keyCode:
监听按键的指令,具体可以查看vue的键码对应表

7.数组更新检测?

变异方法(具有更新检测的数组方法)
vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。
这些方法如下:push() 、pop() 、shift() 、unshift() 、splice() 、sort() 、reverse(),只要这些方法操作更新了数据,视图就会跟着更新
这些方法操作的都是原数组,不会返回新数组
变异方法(不具有更新检测的数组方法)
不是所有的方法都可以数据同步更新的,比如下面这几个方法:filter(),concat(),slice()
这几个方法都不是操作的原数组,会返回一个新的数组
还有如果是更改原有数组里面的值也不会更新视图或者改变数据的长度
更新检测数组内的数据变化的方法
如果要使用修改数据内容的方式来更新视图的话,可以使用vue提供的一个set()方法
第一个参数:要修改的那个数组,第二个参数:数组的角标(也就是数组的第几项),第三个参数:新的数据
点击按钮的时候,数据视图会更新,另外需要注意的是,这种方法更改数组的数据,需要写全:比如数组中第一个对象里的属性都要写全,不然会默认为空

8.Vue.set视图更新?

Vue.set() 方法
调用方法:Vue.set( target, key, value )
target:要更改的数据源(可以是对象或者数组)
key:要更改的具体数据
value :重新赋的值

9.vue更新数组时触发视图更新的方法?

10.如何自定义指令?

11.请说下封装 vue 组件的过程?

12.vue封装通用组件?

13.引进组件的步骤?

14.delete和Vue.delete删除数组的区别?

15.vue slot(插槽)?

16.vue渲染模板时怎么保留模板中的HTML注释呢?

17.vue的表单修饰符.lazy?

18.说说你对vue的错误处理的了解?

19.在vue事件中传入$event,使用e.target和e.currentTarget有什么区别?

20.vue怎么实现强制刷新组件?

21.vue给组件绑定自定义事件无效怎么解决?

22.watch的属性用箭头函数定义结果会怎么样?

23.axios及安装?

24.axios解决跨域?

1.什么是 vue 生命周期?

2.vue生命周期的作用是什么?

3.第一次页面加载会触发哪几个钩子?

4.简述每个周期具体适合哪些场景?

5.created和mounted的区别?

6.vue获取数据在哪个周期函数?

7.请详细说下你对vue生命周期的理解?

1.vue-router 是什么?它有哪些组件?

2.active-class 是哪个组件的属性?

3.怎么定义 vue-router 的动态路由? 怎么获取传过来的值?

4.vue-router 有哪几种导航钩子?

5.和router 的区别?

6.vue-router响应路由参数的变化?

7.vue-router传参?

8.vue-router的两种模式(hash,history)?

9.vue-router实现路由懒加载( 动态加载路由 )?

10.vue-router怎么重定向页面?

11.vue-router怎么配置404页面?

12.vue跳转新路由 滚动到固定位置?

13.vue 路由去掉#?

14.Vue-router跳转和location.href有什么区别?

15.Vue里面router-link在电脑上有用,在安卓上没反应怎么解决?

16.Vue2中注册在router-link上事件无效解决方法?

17.RouterLink在IE和Firefox中不起作用(路由不跳转)的问题?

1.vuex是什么?怎么使用?哪种功能场景使用它?

2.vuex有哪几种属性?

3.不使用Vuex会带来什么问题?

4.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?

5.vuex一个例子方法?

6.Vuex中如何异步修改状态?

7.Vuex中actions和mutations的区别?

8.页面刷新后vuex的state数据丢失怎么解决?

9.vuex怎么知道state是通过mutation修改还是外部直接修改的?

1.vue 如何mock数据?

2.顶部悬停效果?

3.电话本列表效果( 右边字母分类 上下滑动 旁边字母显示高亮)?

4.vue做代理解决跨域?

5.Vue路由切换时的左滑和右滑效果示例?

6.vue实现锚点功能(点击导航栏向下滑动到对应位置)

7.Vue和原生(ios和安卓)的交互

vue3.0新特性

1,压缩包体积更小

当前最小化并被压缩的 Vue 运行时大小约为 20kB(2.6.10 版为 22.8kB)。Vue 3.0捆绑包的大小大约会减少一半,即只有10kB!

2,Object.defineProperty -> Proxy

Object.defineProperty是一个相对比较昂贵的操作,因为它直接操作对象的属性,颗粒度比较小。将它替换为es6的Proxy,在目标对象之上架了一层拦截,代理的是对象而不是对象的属性。这样可以将原本对对象属性的操作变为对整个对象的操作,颗粒度变大。
javascript引擎在解析的时候希望对象的结构越稳定越好,如果对象一直在变,可优化性降低,proxy不需要对原始对象做太多操作。

3,Virtual DOM 重构

vdom的本质是一个抽象层,用javascript描述界面渲染成什么样子。react用jsx,没办法检测出可以优化的动态代码,所以做时间分片,vue中足够快的话可以不用时间分片。
传统vdom的性能瓶颈:
虽然 Vue 能够保证触发更新的组件最小化,但在单个组件内部依然需要遍历该组件的整个 vdom 树。
传统 vdom 的性能跟模版大小正相关,跟动态节点的数量无关。在一些组件整个模版内只有少量动态节点的情况下,这些遍历都是性能的浪费。
JSX 和手写的 render function 是完全动态的,过度的灵活性导致运行时可以用于优化的信息不足
那为什么不直接抛弃vdom呢?
高级场景下手写 render function 获得更强的表达力
生成的代码更简洁
兼容2.x
vue的特点是底层为Virtual DOM,上层包含有大量静态信息的模版。为了兼容手写 render function,最大化利用模版静态信息,vue3.0采用了动静结合的解决方案,将vdom的操作颗粒度变小,每次触发更新不再以组件为单位进行遍历,主要更改如下
将模版基于动态节点指令切割为嵌套的区块
每个区块内部的节点结构是固定的
每个区块只需要以一个 Array 追踪自身包含的动态节点
vue3.0将 vdom 更新性能由与模版整体大小相关提升为与动态内容的数量相关

4, 更多编译时优化

Slot 默认编译为函数:父子之间不存在强耦合,提升性能
Monomorphic vnode factory:参数一致化,给它children信息,
Compiler-generated flags for vnode/children types

5,选用Function_based API

为什么撤销 Class API ?
1,更好地支持TypeScript
Props 和其它需要注入到 this 的属性导致类型声明依然存在问题
Decorators 提案的严重不稳定使得依赖它的方案具有重大风险
2,除了类型支持以外 Class API 并不带来任何新的优势
3,vue中的UI组件很少用到继承,一般都是组合,可以用Function-based API
1,vue3.0将组件的逻辑都写在了函数内部,setup()会取代vue2.x的data()函数,返回一个对象,暴露给模板,而且只在初始化的时候调用一次,因为值可以被跟踪。
2,新的函数api:const count = value(0)
value是一个wrapper,是一个包装对象,会包含数字0,可以用count.value来获取这个值。在函数返回的时候会关心是value wrapper,一旦返回给模版,就不用关心了。
优点:即使count包含的是基本类型,例如数字和字符串,也可以在函数之间来回传递,当用count.value取值的时候会触发依赖,改值的时候会触发更新。
3,计算属性返回的也是这个值的包装。
4,onMounted生命周期函数直接注入。
Function-based API 对比Class-based API有以下优点
1,对typescript更加友好,typescript对函数的参数和返回值都非常好,写Function-based API既是javascript又是typescript,不需要任何的类型声明,typescript可以自己做类型推导。
2,静态的import和export是treeshaking的前提,Function-based API中的方法都是从全局的vue中import进来的。
3,函数内部的变量名和函数名都可以被压缩为单个字母,但是对象和类的属性和方法名默认不被压缩(为了防止引用出错)。
4,更灵活的逻辑复用。
目前如果我们要在组件之间共享一些代码,则有两个可用的选择:mixins 和作用域插槽( scoped slots),但是它们都存在一些缺陷:
1,mixins 的最大缺点在于我们对它实际上添加到组件中的行为一无所知。这不仅使代码变得难以理解,而且还可能导致名称与现有属性和函数发生冲突。
2,通过使用作用域插槽,我们确切地知道可以通过 v-slot 属性访问了哪些属性,因此代码更容易理解。这种方法的缺点是我们只能在模板中访问它,并且只能在组件作用域内使用。
高阶组件在vue中比较少,在react中引入是作为mixins的替代品,但是比mixins更糟糕,高阶组件可以将多个组件进行包装,子组件通过props接收数据,多个高阶组件一起使用,不知道数据来自哪个高阶组件,存在命名空间的冲突。而且高阶组件嵌套得越多,额外的组件实例就越多,造成性能损耗。
· 3.0比2.0 快2倍
· 3.0去掉了filter, 么有beforeCreate created,用setup取代
· reactivity是可以单独作为库使用的
· 单独功能可以抽离 取代了mixin 优于mixin 解决上下反复横跳
· 支持多个子节点 fragment
· setup里没有this
· Proxy实现响应式不需要set delete 兼容性并不好
· 响应式方面 性能得到很大提升 不用初始化的时候就递归遍历属性
· 响应式不区分数组和对象
· 3.0兼容IE12以上
· composition api 可以和 options API 同时存在

举报

相关推荐

0 条评论