Vue项目实战
构建基础框架
路由
路由分类:
- memoryHistory:内存路由,路由信息记录在内存中,当页面刷新,整个路由记录栈没有了的场景使用内存路由。当做状态用,存在内存中间的历史记录栈。(组件的tabs标签页切换算是内存路由)
- hashHistory:hash模式,通过触发onhashchange方法来监听URL中hash值的变化
- browserHistory/webHistory:web模式,通过popstate和pushState监听和触发来改变历史记录栈里的数据
- 面向ssr的记录模式
区别:跳转路由的方法不一样,监听历史记录栈变更的方法不一样
common-基础封装,负责api协议的约定,在不同端处理实际问题后,在抽象层上一层再做一层封装
hash-
html5-webHistory
memory-memoryHistory
路由
- app 主路由
- dataSource 数据源
- :id 动态路由
- layout 界面组件
- actions
- dataSource 数据源
跟路由相关的组件都放在views,其他普通的组件都放在components中
view:路由组件
components:其他普通组件
blocks:重点组件
项目( v1.0,base-app-layer)
项目分支:第一个和第二个分支是基础的分支(init project,base-config),重点
导航 router
- app
- dataSource 数据源
- layout 布局
- actions 动作
- about
怎么实现切换页面后,标签不同颜色的问题?
在AppNavigator.vue组件中:
- 定义 组件对象,里面包括value,label,bg,color,borderColor属性
- 使用computed对组件对象处理,获取当前的router.name,来看router.name名称和当前激活的内容匹配上
物料
编排选型
考虑技术选型和方案
例如:
- 拖拽,应用拖拽实现
- html5的drag和drop实现
- mousemove事件
编排引擎形式:
流式、流式2
自由拖拽、
grid(仪表盘开发)
vue-grid-layout:底层用什么事件来做的?interactjs库
=>方案调研后,使用的是流式布局的smooth-dnd
- SmoothDnd
- SmoothDndContainer - 负责容器
- SmoothDndDraggable - 负责拖拽的元素
- AppEditorRenderer - 使用的地方,不同端抹平差异的地方
- LaptopPreviewer PC端 - 需要地址栏
- MobilePreviewer 移动端 - simulator模拟器
- AppPreviewer
- LaptopPreviewer - 上层不同的地方,下层-BlocksRenderer 移动端和PC端公用的
- MobilePreviewer
8个组件(物料)需要用8种不同逻辑去渲染,最底层做抽象,向外暴露统一的API;
设计组件的渲染器,需要关注 他向外部暴露了哪些方法、接口、props、事件都有哪些
例如,要封装一个图表渲染的组件,需要考虑
底层封装需要负责哪些内容(负责数据转换、负责图表加载、请求数据出错是否重试等等)
往上封装图表时候,图表不同对应类型的时候,封装 折线图、饼图、旭日图、条形图等等
- blocks
- basic - 基础物料
- View
- Quote - 传进来的blockInfo,拿到props.blockInfo.props.content就能渲染对应的内容
- Image
- HeroTitle
- Chart
- external - 额外物料
- Button
- Form
- Notes
- BlockRenderer.vue - 基础物料+额外物料 加和 统一用这个来渲染
<component :is="blocksMap\[block.type\].material" :blockInfo="block"\>\ block.type -物料类型 material-具体代码在哪 blockInfo 物料信息 blocksMap - 下面setup方法的install中讲述
- basic - 基础物料
插件化
- src
- setup.ts - 定义了很多block(物料),本地物料;
- 使用了插件化机制,整个block要通过BlockSuite底座来维护,添加时候addBlock用数组的格式将物料添加进去。block是一个对象,包含type和material两个属性
- setup方法:
install方法挂载几个东西,
(1)app.provide(blocksMapSymbol,blocksMap)
将blocksMap传到以下所有的内容,通过inject方法插入这些数据,能够把深层状态直接传递进去
(2)app.config.globalProperties.$blocksMap = blocksMap 绑定属性 $blocksMap
插件化物料后,怎么做权限?举例说明
javascript
const blockSuite=new BlockSuite()
const authCode=0b1111
const authMap={
button:0b001,
form:0b0010,
notes:0b0100
}
const auth=authMap
if(authMap.button & authCode){
}
插件化平时写代码场景
配置器开发
基于 key path的动态表单状态管理:vee-validate
- components
- AppRightPanel
-
AppRightPanel.vue - 基础架子
使用策略模式渲染右侧栏的
<component :is="blockSetting" :blockInfo="currentBlockInfo"></component>
blockSetting: quote->QuoteSetting,chart->ChartSetting
-
QuoteSetting.vue
- import {useFieldArray,useForm} from 'vee-validate' - 注册useForm
- useForm->initialValue->content 注入内容
- defineInputBinds - 跟当下的,具体的内容做双向绑定
- watch检测values做到跟页面中数据实时更新
- useFieldArray('block') - 获取fields,push两个方法;按钮直接调用push即可追加quote
-
- AppRightPanel
react中类似:react-hook-form (建议) 或者 formik
对于动态表单的技术选型 为什么选用VeeValidate?
1.设计理念比较好 基于hooks实现的/CompositionAPI实现的,能够解决很多事情,例如,表单类型校验规则,动态表单,表单间联动,统一的表单状态处理等等
2.开源,有人维护
不管是useForm,还是自己去封装表单,表格的插件,都需要将UI层(组件)和状态层(CompositionAPI负责产出的状态数据)分离,在用的地方,使用useForm,useTable等等解构出来
保证数据逻辑和UI逻辑之间解耦
如果组件多了,渲染引擎变得慢或卡,一家公司的商城,首页用了无代码平台来搭建,首页要等一会才出来,这个如何解决?
使用代码分割来解决。在router层就可以做封装,使用defineAsyncComponent动态模块导入,入口将依赖作为标记,接下来内容就会通过动态导入方式来切分掉代码片段,生成新的trunk,通过trunk来处理;所以,如果首页很卡,首页加载资源非常多,将首页不加载的资源进行切掉,切到另外一个包里,就不会加载那么多内容了,等用到这部分内容时候,动态去加载。
- 首页加载优化
- 1.5s,静态资源(chunk【cachegroup 硬缓存】、dynamic import)
- cdn、gzip
- http2