高阶组件
高阶组件是一种在React中用于复用组件逻辑的技术。它本质上是一个函数,接受一个组件作为参数,并返回一个新的增强过后的组件。
高阶组件通过将一些通用的功能逻辑从组件中提取出来,并通过参数或属性的方式传递给被包裹的组件,从而实现代码的复用和逻辑的解耦。它可以用于处理重复的业务逻辑、状态管理、封装第三方库等情况。
功能:
- 属性代理:通过HOC将额外的props传递给被包裹的组件,以增强其功能或修改其行为。
- 渲染劫持:通过HOC修改组件的渲染方式,例如条件渲染、组件替换、渲染包装等。
- 状态提升:通过HOC管理组件的状态,使得多个组件可以共享同一个状态。
- 生命周期扩展:通过HOC对组件的生命周期进行拦截和注入逻辑,以实现各种功能。
高阶组件的优点包括:
- 代码复用:将通用的逻辑抽离出来,提高代码的复用性和可维护性。
- 逻辑解耦:将组件的业务逻辑与其他关注点(如数据获取、状态管理)分离,使得代码更加清晰和可测试。
- 功能增强:通过HOC可以给组件添加额外的功能,提供更多的灵活性和扩展性。
我写过的高阶组件举例
1.在长页面滚动:
当你有一个很长的页面,在用户进行导航或者加载新内容时,希望页面自动滚动到顶部时
在跳转页面加载:当你的应用程序使用跳转页面加载数据,用户浏览不同页面时,希望每次跳转到新页面时自动滚动到顶部,而不是停留在之前的位置。且返回原页面时滚动到原本对应位置时
写了一个高阶组件叫ScrollToTop,是一个接受一个组件和一个配置参数的高阶组件。它返回一个新的组件函数,这个新的组件函数在挂载时会自动滚动到指定参数位置,
具体实现方式,把需要自动滚动到指定位置的组件,即需要滚动到指定位置的参数,传入ScrollToTop组件内部,在ScrollToTop中使用const ref = useRef(null);初始化ref的值,在组件多次被使用时可以保持相同的引用,然后在useEffect中进行滚动高度的计算,用ref.current.offsetTop获取传入的dom元素相对于其上层元素顶部的位置 减去传入的参数,计算出滚动的位置,然后使用window.scrollTo滚动到相应位置。
2. 权限控制
实现方式在登录过后,获取一个身份令牌,根据用户的权限级别或角色,动态决定是否渲染组件、显示不同的内容或禁用某些功能。
3.主题样式切换,这个高阶组件可以将当前主题的样式传递给被包装的组件,实现主题切换的功能,
elementUI input组件的二次封装
当开发时,某些功能需要多次使用elementUl同一个组件时且elementUI 不能满足一些功能样式时,可以对elementUI 进行二次封装,完成特定功能,使用props和插槽功能实现部分功能定制化,实现对代码逻辑简单的复用,减少代码冗余
1.创建一个新的 Vue 组件,作为对 Element UI 组件的二次封装。
2.在该组件中引入需要使用的 Element UI 组件,并根据需求对其样式和功能进行修改和扩展。
3.使用 props 接收外部传入的数据,并将其传递给 Element UI 组件,以实现参数的定制化。
4.利用插槽(slot)功能,在组件的模板中插入内容,使得外部可以自定义组件的部分内容。
5.根据需求,可以添加其他功能或事件处理逻辑,以满足特定的功能要求。
6.将封装好的组件导出,并在需要使用的地方引入并使用该组件
对 ei-input写一个单独组件,需要四个参数(正则,label, 验证提示,el-input配置参数)可传可不传,不传有默认值,当input失去焦点时进行正则验证验证是否通过。通过在input下方显示已通过否则显示未通过,实现对代码逻辑简单的复用,减少代码冗余
在使用的组件中直接导入,通过 props 接收传入参数
项目功能靓点
文字转语音
如何将文字转成音频数据首先考虑到audio.src,如何转wep api浏览器本身有一些api可以去完成音频转文字的效果,但是调用的时操作系统的接口,用这种办法会有很多问题,首先就是浏览器兼容性问题,api肯定是新的api对老版本浏览器兼容性不好,,二就是语音不统一,因为不同的操作系统声音是不一样的,难以统一,功能上也不是特别丰富,比如用户选择不同的播音员。所以使用第三方平台,在上个项目使用的是讯飞,
这个时候因为直接传值会让你传appid,oauth2协议等一些参数放在客户端也是不安全的,还有跨域的原因不能直接向讯飞的接口发送请求,
所以首先要将文本发送到服务器,服务器再去请求第三方平台,因为这边用的是讯飞,这个时候讯飞会把文字转成语音的数据用 wedsocket 传递给我,本地服务器把这个数据转成base64传递给客户端,这个时候使用audio.src绑定base64数据就可以完成文字转换,
这个时候会因为你需要传输数据到服务器在转成语音,在传回来,这个过程是十分耗时的特别是文本过多时,对用户体验特别不好,所以需要优化性能,
- 可以通过断句,把整个文本切成一块一块的小文本,每次只传一个小文本,利用栈原理实现标点分割,利用栈进行双引号和括号的匹配 (栈可用于检查括号是否匹配。当遇到左括号时,将其入栈;当遇到右括号时,检查栈顶元素是否是相应的左括号。如果是,则弹出栈顶元素继续匹配;否则,括号不匹配。)
- 用async/await 和Promise.all()实现同时执行多个并发的异步操作,或者使用WebWorkers进一步提高性能,Promise.all() 接受一个包含多个 Promise 对象的数组,并返回一个新的 Promise 对象,当其中Promise.all()有任何一个Promise 对象出现阻塞情况时,直接返回成功状态,返回一个空数组,防止阻塞。
- 利用缓存原理,相同一篇文章,不同的用户在使用时,只要第一个人请求过后,可以在服务器内部做缓存,其他人在请求时就可以在浏览器直接返回,不需要在进行讯飞转换,前端也可以做缓存,缓存到localstorage中,因为缓存时,健应该存文字的但是文字长度不统一,所以使用md5加密来获取一段等长度的健,值的话就是base64
项目靓点
封装vue指令 resize
这段代码是一个 Vue.js 的自定义指令,用于监听元素的尺寸变化并执行相应的处理函数。
首先,我们创建了一个 WeakMap 对象 map,用于存储元素和对应的处理函数。WeakMap 是一种特殊的 Map 实现,它可以确保在没有其他引用时自动释放存储的键值对,避免了内存泄漏的风险。(WeakMap 是一种弱引用的数据结构,它不会阻止其键(即元素)被垃圾回收。当元素被移除或销毁时,对应的键值对也会被自动清除。这对于监听元素的尺寸变化很有帮助,因为当元素被移除或销毁时,我们可以自动取消对其尺寸变化的监听,避免出现内存泄漏。如果使用普通的 Map 来存储键值对,当元素被移除或销毁时,如果没有手动将其从 Map 中删除,这些键值对会一直存在于内存中,导致内存泄漏。而在使用 WeakMap 的情况下,当元素被移除或销毁时,对应的键值对会被自动清除,不会造成内存泄漏。)
然后,我们创建了一个 ResizeObserver 实例 ob,并通过构造函数传入一个回调函数。这个回调函数会在被观察的元素的尺寸发生变化时被触发。entries 参数是一个数组,包含了所有发生尺寸变化的元素的信息。(ResizeObserver 是一个 Web API,用于监测元素的尺寸变化。它提供了一种简便的方式来检测元素的大小是否发生了改变,并在尺寸变化时触发相应的回调函数,使用 ResizeObserver 的好处是它能在高效地监测大量元素的尺寸变化时提供更好的性能。它可以同时观察多个元素,而无需为每个元素都添加事件监听器。)
接下来,我们在 Vue.js 的自定义指令中定义了两个钩子函数:mounted 和 unmounted。mounted 钩子函数会在指令绑定到元素上时触发,unmounted 钩子函数会在指令与元素解绑时触发。
在 mounted 钩子函数中,我们将元素 el 和处理函数 binding.value 存储到 map 中,以便后续使用。然后,我们调用 ob.observe(el) 开始观察元素的尺寸变化。
(在 Vue.js 的自定义指令中,binding 对象包含了指令的相关信息,其中 binding.value 属性用于获取指令绑定的值。当我们在模板中使用该自定义指令时,可以通过指令的参数来传递一个值,这个值就会被存储在 binding.value 中。在这段代码中,我们将传递给指令的值作为处理函数。)
最后,在 unmounted 钩子函数中,我们调用 ob.unobserve(el) 停止观察元素的尺寸变化,从而避免不必要的资源消耗。
通过使用这个自定义指令,我们可以在 Vue.js 应用中方便地监听元素的尺寸变化,并在变化发生时执行自定义的处理函数。这样可以实现一些响应式的布局或动态适应的效果。
🖊网络请求的封装:
1.定义了一个函数,使用axios方法发送网络请求,并根据请求成功或失败的情况进行相应的处理,设置请求拦截器和响应拦截器。
2.接下来使用Webpack的require.context方法从指定目录中导入多个组件模块。require.context方法接收三个参数,第一个参数是要搜索的目录,第二个参数指定是否还搜索其子目录,第三个参数是一个正则表达式,用于匹配需要导入的文件。这样可以获取到一个包含模块路径的数组。
3.然后(使用reduce方法)对模块路径数组进行遍历和处理。通过正则表达式将路径转换为模块名,并使用moduleFiles获取每个模块的内容。最终得到一个以模块名为属性名、以模块内容为属性值的对象,
4.接下来定义了一个名为proxy的响应式数据,使用ES6的Proxy对象对modules进行代理。通过get方法拦截对proxy对象的属性访问。当访问属性时,会根据属性名获取相应的配置参数,并调用封装的axios函数发送网络请求。根据请求结果,返回相应的数据。
5.最后导出一个异步函数,该函数接收两个参数keyName和meta。如果传入了meta参数,会将meta赋值给proxy对象的meta属性。然后根据keyName从proxy对象中获取对应的数据,并返回该数据。
6,在main.js进行挂载
必背面试题,出现频率超高,几乎每个面试都会问
1.css3新特性
border-radius,box-sizing,媒体查询,transform,弹性盒子布局,选择器
2.浏览器的兼容问题
Es6低版本不兼容
3.Ajax、axios、Fetch区别
Ajax是一种使用原生XMLHttpRequest对象进行异步通信的技术,兼容性好但使用复杂;axios是基于Promise的HTTP客户端,具有简洁的API、更好的错误处理和配置方式;Fetch是现代浏览器提供的新标准,同样基于Promise,但在某些方面可能存在一些限制。根据需求和开发环境选择合适的工具。
4.LocalStorage,SessionStorage,Cookie,Storage四者区别
LocalStorage和SessionStorage5到10mb ,coolie4kb
LocalStorage和SessionStorage是HTML5提供的用于在浏览器端持久化存储和会话期间临时存储数据的机制;Cookie是由服务器发送到浏览器并在每次请求中传递的小型文本文件,用于跟踪用户状态;而Storage是LocalStorage和SessionStorage的共同接口,提供了操作存储的方法和属性。