admin 管理员组文章数量: 887021
持续更新中…
前端面试题知识点
- VUE 2.0面试题
- vuex
- router路由
- axios
- webpack
- JS面试题
- ES6面试题
- 其他面试题
- html + css面试题
- UniApp面试题
VUE 2.0面试题
vue的双向数据绑定原理
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过new Proxy()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
vue生命周期的理解
- beforeCreate:实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载,vue实例的挂载元素$el和数据对象data为undefined,还未初始化,无法访问到数据和真实的dom,一般不做操作
- created:这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取,因为这个阶段,数据对象data已经有了,但是挂载元素$el仍为undefined
- beforeMount: 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。在这个阶段,vue实例的挂载元素$el和数据对象data都已经初始化了。
- mounted:接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情…
- beforeUpdate:当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿
- updated:当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom
- beforeDestroy:当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
- destroyed:彻底销毁,在这里做善后工作也可以
vue优点
- 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
- 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
- 双向数据绑定:保留了 angular 的特点,在数据操作方面更为简单;
- 组件化:保留了 react 的优点,实现了 html 的封装和重用,在构建单页面应用方面有着独特的优势;
- 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
- 虚拟DOM: dom 操作是非常耗费性能的, 不再使用原生的 dom 操作节点,极大解放 dom 操作,但具体操作的还是 dom 不过是换了另一种方式;
- 运行速度更快:相比较于 react 而言,同样是操作虚拟 dom ,就性能而言, vue 存在很大的优势。
mvvm是什么?和mvc有什么区别?
- MVVM:是Model-View-ViewModel的简写。即模型-视图-视图模型。模型指的是后端传递的数据。视图指的是所看到的页面。视图模型mvvm模式的核心,它是连接view和model的桥梁。在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。
- MVC:Model-View- Controller的简写。即模型-视图-控制器。M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下。\
- MVC和MVVM的区别并不是VM完全取代了C,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。
Vue 组件data为什么必须是函数?
因为JS本身的特性带来的,如果data是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue实例的数据。如果将data作为一个函数返回一个对象,那么每一个实例的data属性都是独立的,不会相互影响了。
vuex
vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
vuex有哪几种属性?
- state :基本数据(数据源存放地)
- getters :从基本数据派生出来的数据
- mutations :提交更改数据的方法,同步!
- actions :像一个装饰器,包裹mutations,使之可以异步。
- modules :模块化Vue
vuex的原理是什么?
vuex仅仅是作为vue的一个插件而存在,不像Redux,MobX等库可以应用于所有框架,vuex只能使用在vue上,很大的程度是因为其高度依赖于vue的computed依赖检测系统以及其插件系统,vuex整体思想诞生于flux,可其的实现方式完完全全的使用了vue自身的响应式设计,依赖监听、依赖收集都属于vue 对象Property set get方法的代理劫持。
router路由
vue-router是什么?
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用(SPA)变得易如反掌。
vue-router有哪几种路由导航钩子?
- 全局钩子
- router.beforeEach 全局前置守卫 进入路由之前
- router.beforeResolve 全局解析守卫 在beforeRouteEnter调用之后调用
- router.afterEach 全局后置钩子 进入路由之后
- 单个路由独享;
- 组件级
- beforeRouteEnter 进入路由前
- beforeRouteUpdate 路由复用同一个组件时
- beforeRouteLeave 离开当前路由时
路由模式
- hash模式:使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载,其显示的网路路径中会有 “#” 号,有一点点丑。这是最安全的模式,因为他兼容所有的浏览器和服务器。
- history模式
美化后的hash模式,会去掉路径中的 “#”。依赖于Html5 的history,pushState API,所以要担心IE9以及一下的版本,感觉不用担心。并且还包括back、forward、go三个方法,对应浏览器的前进,后退,跳转操作。就是浏览器左上角的前进、后退等按钮进行的操作。 - abstract模式
适用于所有JavaScript环境,例如服务器端使用Node.js。如果没有浏览器API,路由器将自动被强制进入此模式。
路由守卫
- 全局钩子: beforeEach、 afterEach
- 独享守卫(单个路由里面的钩子): beforeEnter、 beforeLeave
- 组件内守卫:beforeRouteEnter、 beforeRouteUpdate、 beforeRouteLeave
怎么定义 vue-router 的动态路由? 怎么获取传过来的值?
在router目录下的index.js文件中,对path属性加上/:id。使用router对象的params.id。
路由的跳转方式有哪些?
- router-link标签会渲染为标签,template中的跳转都是这种;
- 另一种是编程是导航也就是通过js跳转比如router.push(/home)
vue-router怎么实现路由懒加载?
- vue异步组件技术:异步加载,vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件。
- 路由懒加载(使用import)。
- webpack提供的require.ensure(),vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。
route和router的区别
- r o u t e r : V u e R o u t e r 实例,想要导航到不同 U R L ,使用 router:VueRouter实例,想要导航到不同URL,使用 router:VueRouter实例,想要导航到不同URL,使用router.push方法。
- $route:当前router跳转对象,里面可以获取name、path、query、params等。
axios
axios是什么?怎么使用?描述使用它实现登录功能的流程?
- 请求后台资源的模块。
- 安装:npm installaxios-S
- 然后发送的是跨域,需在配置文件中vue.config.js进行设置。js中使用import进来,
然后get或.post。返回在.then函数中如果成功,失败则是在.catch函数中
axios为什么既能在浏览器环境运行又能在服务器(node)环境运行?
因为axios在浏览器端使用XMLHttpRequest 对象发送ajax请求;在node环境使用 http 对象发送ajax请求。XMLHttpRequest 时一个API,它为客户端提供了在客户端和服务器之间传输数据的功能;process对象是一个global(全局变量),提供有关信息,控制当前的node.js进程。通过判断XMLHttpRequest和process 这两个全局变量来判断程序的运行环境,从而在不同的环境提供不同的http请求模块,实现客户端和服务端程序的兼容。
axios的特点
- Axios是一个基于 promise 的HTTP库,支持promise所有的API
- 它可以拦截请求和响应
- 它可以转换请求数据和响应数据,并对响应回来的内容自动转换成JSON类型的数据
- 安全性更高,客户端支持防御XSRF
axios相关的配置属性
- ‘url’是用于请求的服务器url
- ‘method’ 是创建请求时使用的方法,默认是get
- 'baseURL’将自动加在url前面,除非url是一个绝对URL。
- ’transformRequest‘允许在向服务器发送前,修改请求数据,只能用在’put\post\patch’这几个请求方法。
- ‘headers’是即将被发送的自定义请求头。
- ‘params’是即将与请求一起发送的url参数,必须是一个无格式对象或URLSearchParams对象
- ‘auth’表示原告i使用HTTP基础验证,并提供票据,这将设置一个Authorization头,覆写掉现有的热比一使用headers设置的自定义Authorization头
- ‘proxy’定义代理服务器的主机名称和端口
Axios 的请求拦截器和响应拦截器有什么作用?如何使用它们?
- 请求拦截器和响应拦截器是 Axios 提供的两个重要功能,用于在请求发送和响应返回时进行拦截和处理。
- 请求拦截器(Request Interceptors):在请求发送之前可以对请求进行拦截和修改,例如添加请求头、修改请求参数等。
- 响应拦截器(Response Interceptors):在收到响应数据之后可以对响应进行拦截和处理,例如统一处理错误、转换响应数据等。
webpack
webpack的作用是什么,谈谈你对它的理解?
现在的前端网页功能丰富,特别是SPA(single page web application 单页应用)技术流行后,JavaScript的复杂度增加和需要一大堆依赖包,还需要解决Scss,Less……新增样式的扩展写法的编译工作。所以现代化的前端已经完全依赖于webpack的辅助了。现在最流行的三个前端框架,可以说和webpack已经紧密相连,框架官方都推出了和自身框架依赖的webpack构建工具。
webpack的工作原理?
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。在3.0出现后,Webpack还肩负起了优化项目的责任。
webpack打包原理
- 把一切都视为模块:不管是 css、JS、Image 还是 html 都可以互相引用,通过定义entry.js,对所有依赖的文件进行跟踪,将各个模块通过 loader 和 plugins 处理,然后打包在一起。
- 按需加载:打包过程中 Webpack 通过 Code Splitting 功能将文件分为多个 chunks,还可以将重复的部分单独提取出来作为 commonChunk,从而实现按需加载。把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载
webpack的核心概念
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。告诉webpack要使用哪个模块作为构建项目的起点,默认为./src/index.js
- output :出口,告诉webpack在哪里输出它打包好的代码以及如何命名,默认为./dist
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
Webpack的基本功能有哪些?
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
- 文件优化:压缩 JavaScript、CSS、html 代码,压缩合并图片等
- 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
- 模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
- 自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
- 代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
gulp/grunt 与 webpack的区别是什么?
- 三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。grunt和gulp是基于任务和流(Task、Stream)的。
- 类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。webpack是基于入口的。
- webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。
webpack是解决什么问题而生的?
如果像以前开发时一个html文件可能会引用十几个js文件,而且顺序还不能乱,因为它们存在依赖关系,同时对于ES6+等新的语法,less, sass等CSS预处理都不能很好的解决……,此时就需要一个处理这些问题的工具。
vue的响应式原理
- vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 数据劫持,来劫持各个属性的setter,getter,在数据更新时发布消息给订阅者,触发相应监听回调。
- 当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
- vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),
- 最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
组件传参
- 父组件传给子组件
- 在子组件里定义一个props,即props:[‘msg’],msg可以是对象也可以是基本数据类型子组件传给父组件
- 这里需要使用自定义事件,在子组件中使用this.$emit(‘myEvent’) 触发,然后在父组件中使用@myEvent监听
- 兄弟组件间传值
运用自定义事件e m i t 的触发和监听能力,定义一个公共的事件总线 e v e n t B u s ,通过它作为中间桥梁,我们就可以传值给任意组件了。而且通过 e v e n t B u s 的使用,可以加深 emit的触发和监听能力,定义一个公共的事件总线eventBus,通过它作为中间桥梁,我们就可以传值给任意组件了。而且通过eventBus的使用,可以加深emit的触发和监听能力,定义一个公共的事件总线eventBus,通过它作为中间桥梁,我们就可以传值给任意组件了 - 路由间传值,i.使用问号传值
- A页面跳转B页面时使用 this.$router.push(‘/B?name=danseek’)
- B页面可以使用 this.$route.query.name 来获取A页面传过来的值
- 祖传孙
正常情况下需要借助父亲的props作为中间过渡,但是这样在父亲组件就会多了一些跟父组件业务无关的属性,耦合度高,借助$attrs可以简化些,而且祖跟孙都无需做修改 - 孙传祖
借助$listeners中间事件,孙可以方便的通知祖 - sessionStorage传值
sessionStorage 是浏览器的全局对象,存在它里面的数据会在页面关闭时清除 。运用这个特性,我们可以在所有页面共享一份数据。 - vuex
这里我也不打算介绍这个大名鼎鼎的vuex怎么用,因为要把它写清楚篇幅太长了…
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您也许不需要使用 Vuex。
Vue中key的作用
key的特殊属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。在相同父元素的子元素必须有独特的key,重复的key会导致渲染错误。
jQuery和Vue有什么不同?
jQuery专注视图层,通过操作DOM去实现页面的一些逻辑渲染;
Vue专注于数据层,通过数据的双向绑定,最终表现在DOM层面,减少了DOM操作。
Vue使用了组件化思想,使得项目子集职责清晰,提高了开发效率,方便重复利用,便于协同开发。
说出几种vue当中的指令和它的用法
- v-html:渲染文本(能解析 HTML 标签)
- v-text:渲染文本(统统解析成文本)
- v-bind:绑定数据
- v-on:绑定事件
- v-model :双向数据绑定
- v-for: 循环
- v-if v-show: 显示与隐藏
- v-once:只绑定一次
watch和computed的区别
watch是进行数据监听,然后进行相应的操作,执行方法等computed和methods的合体使用,比较耗性能,与vue性能优化相背而驰,尽量减少使用;当一条数据影响多条数据的时候就需要用watch,例子:搜索数据。
computed是数据改变进行相应的数据变化,由老数据迸发新的数据(return返回),会利用缓存机制对数据进行缓存,只有当依赖数据变化的时候才会进行相应的变化;当一个属性受多个属性影响的时候就需要用到computed,最典型的例子: 购物车商品结算的时候。
vue中的v-show和V-if是做什么用的,两者区别是什么
- v-if是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做—直到条件第一次变为真时,才会开始渲染条件块。
- v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS进行切换。
- 一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show较好;如果在运行时条件不太可能改变,则使用v-if较好。
自定义指令的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?
- 全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数。
- 组件内定义指令:directives钩子函数:bind(绑定事件触发)inserted(节点插入的时候触发)、update(组件内相关更新)
- bind 只调用一次,指令第一次绑定到元素时候调用,用这个钩子可以定义一个绑定时执行一次的初始化动作。
- inserted:被绑定的元素插入父节点的时候调用(父节点存在即可调用,不必存在document中)
- update: 被绑定与元素所在模板更新时调用,而且无论绑定值是否有变化,通过比较更新前后的绑定值,忽略不必要的模板更新
- componentUpdate :被绑定的元素所在模板完成一次更新更新周期的时候调用
- unbind: 只调用一次,指令月元素解绑的时候调用
- 钩子函数参数:el、binding
单页面应用(SPA)首屏加载慢怎么办?
- 安装动态懒加载所需插件
- 按需加载
- 使用cdn
store注入的原理?
通过全局引用mixin方法使得所有Vue实例在beforeCreate下执行init方法,这个方法将this.$store绑定vuex对象注入
keep-alive是什么?
- keep-alive 是 vue 中的内置组件,能够在组件切换过程中将状态保留在内存中,防止重复的渲染 DOM;
- keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们;
- 设置了 keep-alive 缓存的组件,会多出两个生命周期钩子(activated 和 deactivated )
监听器watch的6个用法是什么?
- 常见用法
- 绑定方法(字符串)
- deep + handler(一层层遍历,性能一般)
- immediate(马上渲染)
- 绑定多个handler
- 监听对象属性
在vue中怎么获取dom节点?
在元素上使用ref属性:ref=“domName”
用法:this.$refs.domName
vue为什么要求组件模版只能有一个根结点?
因为vue组件最终是要被各种loader打包解析的,而我们必须为loader指定一个入口。而且,模版最终是会被编译成vdom的,所以必须有一个根结点来递归遍历其子节点,渲染成一个“树”。
$nextTick是什么?作用是什么?
$nextTick是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后使用它,可以在回调中获取更新后的DOM
如何给vue定义全局方法?
- 挂载到Vue的原型上:Vue.prototype.methodsName = function(){}。
- 使用mixin:Vue.use(mixins)。
- 在mian.js中写入函数,在所有组件里可调用函数
- 写好自己需要的fun.js文件,main.js 引入并使用,在所有组件里可调用函数
用npm怎么安装、发布一个插件的?
- npm install 插件 --save:安装新插件
- npm发布插件
- npm adduser:登录,添加用户名密码邮箱(需要先在npm官网注册好账号)
- npm publish:发布插件
- npm config set registry https://registry.npm.taobao/:修改下载仓库为淘宝镜像(没有下载cnpm时的用法)
- npm config set registry https://registry.npmjs/:发布前需要修改回来
- npm unpublish[包名] --force:卸载插件
用vue怎么处理本地开发跨域问题?
- 在vue.config.js配置文件中的devServer下配置proxy本地代理
- 前端什么也不用做,后端需要开启cors,CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。
- 实际上就是在响应头添加允许跨域的源Access-Control-Allow-Origin: 字段和值(意思就是允许去哪些源地址去请求这个服务器)
vue cli项目中目录src中的文件夹分别是什么?用来做什么?
- assets:用来放置一些静态资源,如图片,字体图标等
- components:用来放置组件
- router:用来放置一些路由相关的配置
- app.vue:根组件
- main.js:入口文件
v-model的原理是什么?
v-model只是一个语法糖,其内部实现原理就是使用v-bind和input事件监听值的改变。
changeValue(e){
value = e.target.value
}
使用vue后怎么针对搜索引擎做SEO优化?
- SSR服务端渲染
- NUXT同构
- prerender-spa-plugin 预渲染
Vue模版编译原理是什么?
- Vue的编译过程就是将template转化为render函数的过程。会经历以下阶段:
生成AST树 -> 优化 -> codegen - 首先解析模版,生成AST语法树(一种用JavaScript对象的形式来描述整个模板)。 使用大量的正则表达式对模板进行解析,遇到标签、文本的时候都会执行对应的钩子进行相关处理。
- Vue的数据是响应式的,但其实模板中并不是所有的数据都是响应式的。有一些数据首次渲染后就不会再变化,对应的DOM也不会变化。那么优化过程就是深度遍历AST树,按照相关条件对树节点进行标记。这些被标记的节点(静态节点)我们就可以跳过对它们的比对,对运行时的模板起到很大的优化作用。
- 编译的最后一步是将优化后的AST树转换为可执行的代码。
sessionStorage、localStorage和cookie的区别
- 共同点:都是保存在浏览器端、且同源的
- 区别:
- cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
- 存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
- 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
- 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
- web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
- web Storage的api接口使用更方便
Vue中的过滤器如何用
vue中的过滤器可以用在两个地方:双花括号插值和 v-bind 表达式(😃,过滤器应该被添加在 JavaScript表达式的尾部,由“管道”符号指示.
使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
改变this指向call、apply与bind区别
- 前两个可以自动执行,bind不会自动执行,需要手动调用
- call、bind与apply区别:前两个都有无数个参数,apply只有两个参数,而且第二个参数为数组
vue的插槽(slot)主要分三种
- 默认插槽
- 具名插槽
- 作用域插槽
- vue中的插槽,指的是子组件中提供给父组件使用的一个占位符;
- 用标签表示,父组件可以在这个占位符中填充任何模板代码,比如HTML、组件等,填充的内容会替换掉子组件的标签(替换占位符)。
JS面试题
js数据类型
- 基本数据类型:
Number、String、Boolean、Null、Undefined、Symbol、bigInt - 引用数据类型:
object、Array、Date、Function、RegExp
深拷贝和浅拷贝
浅拷贝
- 定义:会在栈中开辟另一块空间,并将被拷贝对象的栈内存数据完全拷贝到该块空间中,即基本数据类型的值会被完全拷贝,而引用类型的值则是拷贝了“指向堆内存的地址。
- 区别:浅拷贝重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互影响。
- 方法:
- Object.assign()
- 扩展运算符(…)
- Array.prototype.concat()
- Array.slice()
深拷贝
- 定义:不仅会在栈中开辟另一块空间,若被拷贝对象中有引用类型,则还会在堆内存中开辟另一块空间存储引用类型的真实数据。
- 区别:深拷贝从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,拷贝前后的两个对象互不影响。
- 方法:
- JSON.parse(JSON.stringify(obj))
- 递归方法
- 函数库 lodash
map与forEach的区别
- forEach 方法,是最基本的方法,就是遍历与循环
- 默认有 3 个传参:分别是遍历的数组内容 item、数组索引 index、和当前遍历数组 Arraymap 方法
- 基本用法与 forEach 一致,但是不同的,它会返回一个新的数组,所以 callback需要有 return 值,如果没有,会返回 undefined
js变量和函数声明的提升
在js中变量和函数的声明会提升到最顶部执行,函数的提升高于变量的提升,函数内部如果用 var 声明了相同名称的外部变量,函数将不再向上寻找。匿名函数不会提升。
闭包
- 闭包就是能够读取其他函数内部变量的函数
- 闭包基本上就是一个函数内部返回一个函数
- 闭包有3个特性:
- 函数嵌套函数
- 函数内部可以引用函数外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
- 好处: 可以读取函数内部的变量;将变量始终保持在内存中;可以封装对象的私有属性和私有方法。
- 坏处: 比较耗费内存、使用不当会造成内存溢出的问题。
== 和 ===的区别
- ==是非严格意义上的相等,值相等就相等
- ===是严格意义上的相等,会比较两边的数据类型和值大小,值和引用地址都相等才相等
this
- this总是指向函数的直接调用者
- 如果有new关键字,this指向new出来的对象
- 在事件中,this指向触发这个事件的对象
map与forEach的区别
- forEach 方法,是最基本的方法,就是遍历与循环,默认有 3 个传参:分别是遍历的数组内容 item、数组索引 index、和当前遍历数组 Array
- map 方法,基本用法与 forEach 一致,但是不同的,它会返回一个新的数组,所以 callback需要有 return 值,如果没有,会返回 undefined
箭头函数与普通函数的区别?
- 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象
- 不可以当作构造函数,也就是说,不可以使用 new 命令,否则会抛出一个错误
- 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 Rest 参数代替
- 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数
防抖和节流,应用场景
- 防抖和节流都是防止某一时间频繁触发,但是原理却不一样。
- 防抖是将多次执行变为只执行一次,节流是将多次执行变为每隔一段时间执行。
- 防抖(debounce):
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
- 节流(throttle):
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
- 防抖(debounce):
继承有哪些方法
- 原型链继承
- 借用构造函数继承(伪造对象、经典继承)
- 实例继承(原型式继承)
- 组合式继承
- 寄生组合继承
- es6继承 extends
JSON字符串和JSON对象转换
- JSON字符串转换为JSON对象:
var obj = str.parseJSON();//将JSON字符串转换为JSON对象
var obj = JSON.parse(str);// 将字符串转换为JSON对象 - 将JSON对象转化为JSON字符串:
var str = JSON.stringify(obj);
var str = obj.toJSONString();
微任务和宏任务的区别
- 宏任务:当前调用栈中执行的代码成为宏任务。(主代码快,定时器等等)。
- 微任务: 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。(promise.then,proness.nextTick等等)。
- 宏任务中的事件放在callback queue中,由事件触发线程维护;微任务的事件放在微任务队列中,由js引擎线程维护。
- 微任务:process.nextTick、MutationObserver、Promise.then catch finally
- 宏任务:I/O、setTimeout、setInterval、setImmediate、requestAnimationFrame
** js 判断数据类型的几种方法**
- typeof str // “string” 字符串
- typeof num // “number” 数值
- typeof array // “object” 对象(可以和函数区别开)
- typeof date // “object” 对象
- typeof func // “function” 函数
- typeof symbol // “symbol”
同步异步
async、await:Promise的语法糖;此处使用async是为了令f()声明为异步函数,await用于等待异步结果。语法上规定await只能出现在async中。通过二者搭配,使得该函数运行完成后才可运行其它函数,即实现同步。
async f() {
var result = {}; var param = #### var url = ####
await axios.post(url, param).then(function (res) {
if (res.status == 200) {
result = res.data.data;//根据接口返回的数据进行赋值
} else {
alert("获取失败!");
}
});
},
Promise优化异步
- Promise对象用于表示一个异步操作的最终完成(或失败)及其结果的返回值
- 用Promise可以避免层层嵌套的回调函数
function A() {
return "成功111";
}
var myFirstPromise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(A()); //代码成功执行
}, 250);
});
- 由于Promise.prototype.then方法返回的是一个新的Promise对象,因此可采用链式写法,按顺序依次调用。
- 如果前一个回调函数返回的是Promise对象,这时后一个回调函数就会等待该Promise对象有了运行结果,才会进一步调用。(横向发展改为向下发展)
ES6面试题
let、const、var的区别
- 变量提升
- var 声明的变量存在变量提升,即变量可以在声明前调用,值为 undefined。
- let 和 const 不存在变量提升,变量一定要声明之后才能使用,否则会报错。
- 暂时性死区
- var 不存在暂时性死区
- let 和 const 存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
- 块级作用域
- var 不存在块级作用域
- let 和 const 存在块级作用域
- 初始值设置
- var 和 let 可以不设置初始值
- const 声明变量必须设置初始值
- 重复声明
- var 允许重复声明变量
- let 和 const 不允许重复声明变量,会抛出 SyntaxError 的错误
- 数据修改
- var 和 let 可以修改数据
- const 定义的常量是基本数据类型,不能修改。定义的常量要是引用数据类型,就可以修改。因为保存在栈内存的数据是不可以被修改的。而基本数据类型是直接存储在栈内存中的,所以不能被修改。引用数据类型在栈内存中存储的是一个指针,真正的数据存储在指针指向的堆地址,不可被修改的是指针,真正的数据是可变的。
- 重新赋值
- var 和 let 声明的变量都可以重新赋值
- const 声明的变量不能重新赋值
解构赋值
- 数组的解构赋值
const arr = ['小1','小2','小3','小泽']
let [b,q,h,ze] = arr // 或者等于 ['小1','小2','小3','小泽']
console.log(b);
console.log(q);
console.log(h);
- 对象的解构赋值
let redian = {
name: '1',
chaozuo: function () {
console.log('1');
},
dance: function () {
console.log('2');
}
}
let {chaozuo,dance} = redian;
chaozuo();
dance();
模板字符串
- ``(反引号)
- 使用回车换行:标签与标签之 间能直接换行使用
- 变量、表达式拼接:直接使用${} 进行字符串拼接
箭头函数
- 箭头函数中的this指向的是外层作用域下this的值
- 没有自己的arguments对象,但是可以访问外围函数的arguments对象
- 不能通过 new 关键字调用
- 适合使用箭头函数的场景: 与this无关的回调设置。定时器、数组方法回调。
- 不适合使用箭头函数的场景: 与this有关的回调设置。事件回调、对象中的方法。
setTimeout(() => {
//箭头函数中的this指向的是外层作用域下this的值
console.log(this.data)
},1000)
rest参数
用来代替arguments,直接获取一个真数组,方便操作 (arguments返回的是伪数组)
// rest 参数用来代替 arguments 的
function main(...args) {
console.log(arguments);
console.log(args);
}
main(1,2,3,4,5,6,7,8);
扩展运算符
…能将「数组」转为逗号分隔的「参数序列] ,是 rest 的逆运算
- 数组的展开
const arr = [1, 2, 3]
function fn () {
console.log(arguments);
}
fn(...arr); //fn(1, 2, 3)
- 对象的展开
const one = {
1: 'one'
}
const two = {
2: 'two'
}
// 进行对象的合并
const hero = {...one,...two}
console.log(hero); // {1: 'one', 2: 'two'}
集合(set)
- Set是es6新增的数据结构,类似于数组,但是成员的值都是唯一的,没有重复的值,我们一般称为集合
- 方法:add()、delete()、has()、clear()
- 应用场景: 数组去重、求交、并、差集。
// 声明集合 自动去重
const s = new Set([1,2,3,41,12,21,1,1,1,2,3,4])
console.log(s); //[1,2,3,41,12,21,4]
// 1.元素个数
console.log(s.size); //7
// 2.添加
s.add(8)
// 3.删除
s.delete(1)
console.log(s);//[2,3,41,12,21,4,8]
// 4.检测是否包含某个元素
console.log(s.has(2)); //true
// 5.清空
// s.clear()
console.log(s); //[]
字典(Map)
- Map类型是键值对的有序列表,而键和值都可以是任意类型
- 属性和方法:size()、set()、get()、has()、delete()、clear()
// 声明Map
let m = new Map()
// 1.添加元素(键值对)
m.set('name','小宝')
m.set('age',18)
// 2.获取元素
console.log(m.get(name)) //小宝
// 3.删除元素
m.delete('name')
// 4.获取元素个数
let size = m.size
console.log(size) //1
// 5.检测是否包含某个元素
console.log(m.has('age')); //true
// 6.清空Map
m.clear()
console.log(m) //0
Promise
- Promise 是ES6引入的异步编程的新解决方案。比传统的解决方案(回调函数)更加合理和更加强大
- 状态:pending(进行时)、fulfilled(已成功)、rejected(已失败)
- 用法: Promise 对象是一个构造函数,会接受一个函数作为参数,这个函数的两个参数分别是 resolve和reject
- resolve 函数的作用是将 Promise 对象的状态从 “未完成” 变为 “成功”
- reject 函数的作用是将 Promise 对象的状态从 “未完成” 变为 “失败”
- const promise = new Promise(function(resolve, reject) {});
- 实例方法:
- then() ---- 实例状态发生变化时,触发的回调函数,第一个参数是 resolved状态的回调函数,第二个参数是 rejected 的回调函数(一般使用 catch 方法来替代第二个参数)
- catch() ---- 用于指定发生错误的回调函数
- finally() — 用于指定 不管 Promise 对象最后状态如何,都会执行的操作
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
- 常用的构造函数方法:
- Promise.all() ----将多个 Promise 实例包装成一个新的 Promise 实例
- 只有 p1,p2,p3 状态全为 fulfilled ,p 的状态才会变成fulfilled。此时,p1,p2,p3 的返回值组成一个数组,传递给 p 的回调函数。
- 只要 p1,p2,p3 有一个状态为 rejected ,那么 p 的状态就变成 rejected。此时第一个被reject的实例的返回值,会传递给p的回调函数。
- Promise.race() ----将多个 Promise 实例包装成一个新的 Promise 实例
- const p = Promise.race([p1, p2, p3]);
- 三者谁先改变状态, p 也就会跟着改变状态。率先改变的会将返回值传递给 p 的回调函数。
- Promise.all() ----将多个 Promise 实例包装成一个新的 Promise 实例
类(class)
ES6 引入了class类这个概念,通过class关键字可以定义类,这就是更符合我们平时所理解的面向对象的语言
- 简单的类
//类的声明
class Phone {
//构造方法 不是必须的,但是constructor名字不能修改
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
//声明成员方法
call(someone) {
console.log(`我可以给${someone}打电话`);
}
sendMessage(someone) {
console.log(`我可以给${someone}打电话`);
}
//声明静态成员
static name = '手机';
static change() {
console.log('吃了吗');
}
}
- 类的继承
//子类继承父类
class SmartPhone extends Phone {
//子类的构造方法
constructor(brand,price,screen,pixel) {
//调用父类的构造方法进行初始化 super
super(brand,price);
this.screen = screen;
this.pixel = pixel;
}
//方法声明
playGame() {
console.log('我可以玩游戏');
}
sw() {
console.log('我可以上网');
}
}
// 子类实例化
const onePlus = new SmartPhone('1+', 3999, 6.5, '4800w');
console.log(onePlus);
console.dir(Phone)
console.log(Phone.name);
- 取值函数getter和存值函数setter
let data=[1,2,3,4]; //放在类外面,属于私有变量,可以只读取
class Phone{
// 构造函数
constructor(x,y){
this.x = x;
this.y = y;
}
get x(){
console.log('获得name');
return this._name; //get读取属性
}
set x(x){
console.log("设置name");
this._name=x; //set给属性赋值
}
get data(){
return data; //只读属性,属性返回的值只能是私有变量
}
}
- 静态属性
- 静态属性不能被子类继承,子类不能调用
- 静态属性只能通过类名来调用,不能通过类的实例来调。
static name = '小宝'; // 静态属性
- 静态方法
- 静态方法不会被子类继承,子类不能调用
- 静态方法中的this,指向的是类class,不是类的实例。因此静态方法只能通过类名来调用,不能通过实例来调用。
static sleep(){
console.log('睡觉')
}
其他面试题
echarts自适应问题
echart图表本身是提供了一个resize的函数的
// 使用刚指定的配置项和数据显示图表。
var myChart = echarts.init(document.getElementById("main"));
myChart.setOption(this.option);
window.onresize = myChart.resize;
http请求过程
浏览器发起请求-> 解析域名得到ip进行TCP连接 ->浏览器发送HTTP请求和头信息发送->服务器对浏览器进行应答,响应头信息和浏览器所需的内容-> 关闭TCP连接或保持-> 浏览器得到数据数据进行操作。
html + css面试题
标准盒模型和怪异盒模型的区别
- 怪异盒模型的宽度变小
- 标准盒大小计算公式:width(content) + padding + border + margin
- 怪异盒大小的计算公式:width(content + padding + border) + margin
Flex容器属性
-
设置主轴的方向-语法:flex-direction:row|row-reverse|column|column-reverse;
row 默认值,主轴在水平方向,起点在左端
row-reverse 主轴在水平方向,起点在右端
column 主轴在垂直方向,起点在上沿
column-reverse 主轴在垂直方向,起点在下沿 -
设置flex项目一行或多行显示-语法:flex-wrap:nowrap|wrap|wrap-reverse;
nowrap 默认值,不换行
wrap 换行
wrap-reverse 换行,但行的顺序是倒过来的 -
flex-direction和flex-wrap简写方式-语法:flex-flow:row nowrap; (默认值)
-
设置主轴对齐方式-语法:justify-content:flex-start|flex-end|center|space-between|space-around;
flex-start 主轴在水平方向时,类似于左浮动
flex-end 主轴在水平方向时,类似于右浮动
center 居中对齐
space-between flex项目两端对齐,中间间隔相等
space-around flex项目两侧间隔相等 -
设置交叉轴对齐方式-语法:align-items:flex-start|flex-end|center|baseline|stretch;
flex-start 对齐交叉轴的起点
flex-end 对齐交叉轴的终点
center 以交叉轴为参考居中对齐
baseline flex项目第一行文字基线对齐
stretch flex项目没有设置高度或者为auto,将占满整个父元素的高度 -
设置多根轴线对齐方式-语法:align-content:flex-start|flex-end|center|space-between|space-around|stretch;
flex-start 对齐交叉轴的起点
flex-end 对齐交叉轴的终点
center 以交叉轴为参考,居中对齐
space-between 交叉轴两端对齐,轴线之间的间隔平均分布
space-around Flex项目(沿交叉轴方向)之间的间隔相等
stretch flex没有设置高度或者为auto,将均分父元素的高度
rem的特点
- rem的大小是根据html根目录下的字体大小进行计算的。
- 当我们改变根目录下的字体大小的时候,下面字体都改变。
- rem不仅可以设置字体的大小,也可以设置元素宽、高等属性。
UniApp面试题
uni-app 生命周期
- 应用生命周期
- onLaunch:当uni-app 初始化完成时触发(全局只触发一次)
- onShow:当 uni-app 启动,或从后台进入前台显示(显示页面的时候触发)
- onHide: 当 uni-app 从前台进入后台(隐藏/退出页面的时候触发)
- onError:当 uni-app 报错时触发
- onUniNViewMessage:对 nvue 页面发送的数据进行监听
- onUnhandledRejection:对未处理的 Promise 拒绝事件监听函数
- onPageNotFound:页面不存在监听函数
- onThemeChange:监听系统主题变化
- 页面生命周期
- onInit:监听页面初始化,其参数同 onLoad 参数,触发时机早于 onLoad
- onLoad:监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参)
- onShow:监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回当前页面
- onReady:监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
- onHide:监听页面隐藏
- onUnload:监听页面卸载
- onResize:监听窗口尺寸变化
- onPullDownRefresh:监听用户下拉动作,一般用于下拉刷新
- onReachBottom:页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据
- onTabItemTap:点击 tab 时触发,参数为Object
- onShareAppMessage:用户点击右上角分享
- onPageScroll:监听页面滚动,参数为Object
- onNavigationBarButtonTap:监听原生标题栏按钮点击事件,参数为Object
- onBackPress:监听页面返回
- onNavigationBarSearchInputChanged:监听原生标题栏搜索输入框输入内容变化事件
- onNavigationBarSearchInputConfirmed:监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发
- onNavigationBarSearchInputClicked:监听原生标题栏搜索输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发)
- onShareTimeline:监听用户点击右上角转发到朋友圈
- onAddToFavorites:监听用户点击右上角收藏
- 组件生命周期(同vue生命周期)
- beforeCreate:在实例初始化之后被调用
- created:在实例创建完成后被立即调用
- beforeMount:在挂载开始之前被调用
- mounted:挂载到实例上去之后调用
- beforeUpdate:数据更新时调用
- updated:数据更新之后时调用
- beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用
- destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁
uniapp优缺点
- 优点
- 一套代码可以生成多端
- 学习成本低,语法是vue的,组件是小程序的
- 拓展能力强
- 使用HBuilderX开发,支持vue语法
- 突破了系统对H5调用原生能力的限制
- 缺点:
- 问世时间短,很多地方不完善
- 社区不大
- 官方对问题的反馈不及时
- 在Android平台上比微信小程序和iOS差
- 文件命名受限
一句话总的形容一下uniapp与vue和微信小程序的异同点
- 简单来讲Uni-app就是 用着vue的指令和小程序的组件和API
- vue和uni-app动态绑定一个变量的值为元素的某个属性的时候,会在属性前面加上冒号":"
- 小程序绑定某个变量的值为元素属性时,会用两个大括号{{}}括起来,如果不加括号,为被认为是字符串
uniapp的配置文件、入口文件、主组件、页面管理部分
- pages.json
配置文件,全局页面路径配置,应用的状态栏、导航条、标题、窗口背景色设置等 - main.js
入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex,注意uniapp无法使用vue-router,路由须在pages.json中进行配置。如果开发者坚持使用vue-router,可以在插件市场找到转换插件。 - App.vue
是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。除此之外,应用生命周期仅可在App.vue中监听,在页面监听无效。 - pages
页面管理部分用于存放页面或者组件 - manifest.json
文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。 - package.json
配置扩展。
Uniapp 中常用的指令语句
- v-for:循环渲染 (注意加:key)
- v-if :控制元素的删除添加
- v-show:控制元素的显示隐藏
- v-model:双向数据绑定
- v-on:事件绑定(简写@)
- v-bind:属性绑定(简写:)
Uniapp中的本地缓存
- 同步存储:uni.setStorageSync,获取:uni.getStorageSync
- 异步存储:uni.setStorage,获取:uni.getStorage
uni-app全局变量怎么定义,怎么获取
- 在app.js中设置globalData设置,在需要的地方的js文件
let app=getApp()
app.globalData.数据
uniapp 中的跳转方式)
- 标签法:
<navigator url="/pages/about/about"></navigator>
跳转tabBar页面加open-type="switchTab"
- 页面跳转
- uni.navigateTo({url: “/路径?参数=参数值”}) 保留当前页面,只能打开非 tabBar 页面。
- uni.redirectTo({})关闭卸载当前页面,只能打开非 tabBar 页面
- tabBar跳转
- uni.switchTab关闭所有非tabbar页面, 只能打开 tabBar 页面,不能url传参
- uni.reLaunch({})关闭卸载所有页面,可以打开任意页面
uniapp项目页面之间传值
- 利用uni.setStorageSync和uni.getStorageSync进行数据的缓存和取出以及最后对缓存数据的销毁
- 传单个或多个参数
方法:直接在地址后面拼接,在将要跳转的页面上地址后面拼接要传递的参数,传递多个时用&符拼接
gettaskList(id){
uni.navigateTo({
url:'gettaskList?id=${id}'
})
}
接收时,在页面的onload函数中接收传递过来的参数
onLoad(option){
console.log('上一个页面传递过来的参数', option)
}
- 利用uni. e m i t 和 u n i . emit 和 uni. emit和uni.on进行跨页面传值
传递值页面(使用uni.$emit传递值的变量名和变量值)
uni.$emit('addUserInfo',this.userInfo)
接收值页面(在onload周期中使用uni.$on接收已经传递的参数)
uni.$on('addUserInfo',res=>{
console.log(res);
})
注意:uni. e m i t 和 u n i . emit 和 uni. emit和uni.on属于全局跨页面传参,在接收值页面要在onUnload周期添加移除监听时间。
onUnload() {
uni.$off('addUserInfo')
}
- 传递对象
如需要传递的参数有很多时,由于uniapp跳转页面api 的 url 有长度限制,使用以下数据传递:
getTaskList(item) {
uni.navigateTo({
url: `getTaskList?item=${encodeURIComponent(JSON.stringify(item))}`,
});
}
接收时
onLoad(option) {
const item = JSON.parse(decodeURIComponent(option.item));
console.log('上一个页面传递过来的参数对象',item );
}
注意:传递数据的时候必须使用 JSON.stringify 将其转为 JSON 字符串,然后接收的时候也必须使用 JSON.parse 来进行解析!
操作数组也是一样的,因为数组也是对象
版权声明:本文标题:前端面试题知识点 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1729001864h1305475.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论