Vue发布订阅模式
发布订阅模式是什么
vue-element-plus-admin打包报错:FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed
众所周知,在小程序中跳转页面的方法除了navigateTo,还有redirectTo,reLaunch,switchTab。但是这些方法都有一些限制,比如redirectTo和reLaunch不能打开tabBar页面,navigateTo和switchTab不能打开非tabBar页面。为了解决这个问题,我们需要对小程序的路由进行改造,使其能够满足我们的需求。
应用:单页面应用的 URL 导航
Hash 模式, hash 值变化不会导致浏览器向服务器发出请求,通过监听 URL 中的 hash 值(# 及其后面的部分)来实现 路由切换 和 组件渲染 。
window.addEventListener(‘hashchange’, render)
History 模式利用 History API 中的 pushState 和 replaceState 方法来实现 URL 的导航,无需 # 号
1
2
3
4
5
6
7
8
window.addEventListener('popstate', function (event) {
var state = event.state;
if (state.page === 'about') {
// 显示关于页面内容
} else if (state.page === 'contact') {
// 显示联系页面内容
}
});
类似 get 传参,参数会在 url? 后面拼接,刷新页面参数不会丢失
1
router.push({path: '/user', query: {id: '1'}})
类似 post 传参,需要提前在路由中配置 path: ‘/user/:id’
1
router.push({path: name, params: {id: '1'}})
props 和 emit(最直接的方式)
父传子:父组件在子组件上 v-bind 或者:绑定父组件属性,子组件内部通过 props 获取父组件
子传父:父组件通过 v-on 或者 @监听子组件事件,子组件通过 emit 发送事件
特别的,v-model 是一种语法糖,v-bind 和 v-on 的结合,多用于双向绑定
父组件使用 v-model:xxx 绑定一个变量
子组件通过 props 定义 modelXxx 变量,使用 emit (‘update:modelXxx’, value) 发送事件更新变量
需要注意
也可以使用 defineModel (‘xxx’) 去定义变量
Provide/Inject 依赖注入(多层级透传)
应用与子组件多层次级的透传
父组件通过 provide 提供数据,所有子孙组件都能通过 inject 注入数据
事件总线
适用于共同父组件的子组件之间,使用 eventBus、mitt 库
1
2
3
4
5
6
7
const emitter = new mitt();
// 派发事件
emitter.emit('event-name', data)
// 监听事件
emitter.on('event-name', fn);
// 在组件卸载时移除监听,以免造成性能消耗
onUnmounted(() => { emitter.off('event-name', onFoo) });
Composition API (state)
组合式 API 提供了一种更加灵活的方式使多个组件共享逻辑和状态
1
2
3
// ComponentA
const state = reactive({ count: 0 });
export default () => { return { state } };
1
2
// ComponentB
const { state } = useState();
全局状态管理 stroe(Pinia/Vuex)
1 | // ComponentA |
1 | // ComponentB |
ref 实例(破坏组件封装,侵入性强,不建议使用)
子组件通过 defineExpose 暴露方法,父组件通过子组件的 ref 实例调用子组件方法
1
2
3
4
<div ref="child"></div>
<script>
defineExpose({ xxx:() => {} })
</script>
1
2
const child = ref(null);
child.value.xxx()s
用于持久化数据存储
1 | <template> |
1 | <template> |
3. 插槽透传
Vue 2:需区分 $slots(普通插槽)和 $scopedSlots(作用域插槽)。
Vue 3:所有插槽统一通过 $slots 处理
1 | <template> |
1 | import { ref, onMounted } from 'vue'; |
element-variables.scss
config-provider
el-config-provider
a-config-provider
功能支持:ant-design 开源没有虚拟列表
细节: ant-design 的日期范围组件只能从开始选到结束
自制主题指北
如果仅从能够修改服务器中数据库中的数据层面上讲, 确实只在后端做控制就足够了, 那为什么越来越多的项目也进行了前端权限的控制, 主要有这几方面的好处
降低非法操作的可能性
不怕赃偷就怕贼惦记, 在页面中展示出一个就算点击了也最终会失败的按钮,势必会增加有心者非法操作的可能性
尽可能排除不必要清求, 减轻服务器压力
没必要的请求,操作失败的清求,不具备权限的清求,应该压根就不需要发送,请求少了,自然也会减轻服务器的压力
提高用户体验
根据用户具备的权限为该用户展现自己权限范围内的内容,避免在界面上给用户带来困扰,让用户专注于分内之事
1 | 面试官:说说你在工作中是怎么处理浏览器兼容性 |
1 | .element { |
手动打补丁
根据覆盖率自动打补丁
根据浏览器特性,动态打补丁
JS 代码能够被转化减低,适配了市场占比的浏览器,是不是就已经完成了呢?当然没有。
在 ES6 中出现了 Promise,fetch,以及数组和字符串新的方法,babel 会进行转化吗?会转化成什么呢?肯定不会被转化撒,因为它们都是函数调用,对于 babel 来说就是一个普通的函数调用,只是找不到函数的实现体而已,只是会报错而已。
那么这里也就需要兼容一下,因为新版本的浏览器是认识的,老版本的浏览器是不认识的,那么这里就需要为了兼容了老版浏览器,新部署一个 JS 文件(类似补丁),里面存放了各个函数(promise, fetch)体的实现代码。然后浏览器就能够正常的识别了。