todo
less
/* @list:0 3 4 5 8 9 10 13 14 15 16 20 24 25 30;
@len:length(@list);
.makeMP(@index) when (@index > 0){ @i:extract(@list,@index); .margin@{i} { margin: @i * 1px; } .makeMP(@index - 1) }
.makeMP(@len); */
Boundless
- 在开发模式下使用.vue后缀会被vite处理成ES模块,所以使用.sfc后缀,并且可能还有其他的解析代码块,可以避免与官方的VueLoader混淆。
- 在编辑sfc文件时,可以手工使用vue的高亮语法。
dev
___VENTOSE_UI_IS_DEV_MODE
Reference
-
- npm update --depth=9999 vue-loader
关于命令式代码,私以为诸如
tips
、popover
、confirm
、dialog
这类的场景都是合适的,一味无脑使用声明,颇有一种手里只有一把锤子的意思。
jsx slot 的写法
const genMenu = () => {
const MenuItemRender = menuInfo => {
if (xU.isArrayFill(menuInfo.children)) {
/* 第一种 */
return (
<SubMenu
v-slots={{
icon: () => <AppleOutlined />,
title: () => menuInfo.label,
default: () => xU.map(menuInfo.children, MenuItemRender)
}}
/>
);
} else {
/* 第二种 */
return (
<MenuItem key={menuInfo.id}>
{{
icon: () => <UserOutlined />,
default: () => <span>{menuInfo.label}</span>
}}
</MenuItem>
);
}
};
return xU.map(props.tree, MenuItemRender);
};
常用函数
$t 多语言转换
- 懒加载,最好是当前模块用到的才加载。
- 如何做到异步?使用 DelayCall function?
单一数据源build/make/language.js
{
"make:language": "node ./build/make.js language"
}
return { label: "显示的对应语言", prop: "key" };
/* main.js 第一行 window._ 工具 常用工具函数 */
import "@ventose/ui/loadCommonUtil.js";
appPlugins
针对 popover 单例的使用,Vue3 以应用为单位配置属性的方式相较于 Vue2 的全局配置,带来了灵活,就需要但对每个应用单独配置,
/* Vue3 组件方式加载 popover content */
if (this.options.component) {
this.$popoverMountDOM = $(
`<div id="${this.id}" class="x-popover-content"/>`
).prependTo($("body"));
const popoverApp = createApp(this.options.component);
/* 独立应用,配置是否共享、同步,可以配置,此处用appPlugins方法,保持一致 */
appPlugins(popoverApp);
const vm = popoverApp.mount(`#${this.id}`);
this.$popoverDOM = $(vm.$el);
this.$popoverDOM.appendTo(this.$popoverMountDOM);
return;
}
与 Vue2 处理方式不同,需要使用 appPlugins 给createApp
返回的app
添加 plugin。应对 app 独立化后,无法共享 component 依赖的特性。
VueX
状态管理 视图归视图,状态归状态
- State_*: 状态(变量)
- Methods_*: 方法
- Cpt_*: 计算属性 .value
Vue2 中的 this 就是用来保存状态,Vue3 的进步之处在于状态的解耦。
xItem 的设计与使用充分基于这种原则,xItem 视图本身,与 configs 相关,状态与 v-model 绑定相关。
xItem value可以直接用configs里面的value 不需要额外的v-model
/* FILE:src\state\State_App.js */
/* state State_App 相当于命名空间*/
export const State_App = reactive({ configs: lStorage.appConfigs });
/* getter 就用computed代替;commit直接修改StateApp */
export const APP_LANGUAGE = computed({
get: () => State_UI.language,
set: lang => (State_UI.language = lang)
});
/* 副作用 effect */
/* 同步AppConfigs 到 localStorage */
watchEffect(() => (lStorage.appConfigs = State_App.configs));
/* actions 异步修改 效果同事务 自己去保证原子性 */
export const Actions_App = {
GetInfo: async () => {},
Login: async () => {},
Logout: async () => {}
};
开发
App.vue 中完成
pro-component
xItem
错误信息可以单独提供,默认是在 formItem 下方展示 tips ,也可以利用错误信息做其他展现方式,比如 popup, 提供 id 定位,方便滑动定位 vModel 与配置信息分开
xItem 作为 controller ,具体的render 如 input 提供具体的处理能力,1,editor(disabled是editor的能力) 2,readonly 模式(只做展示,可以更个性化)itemType接受的是render函数
- 参考
src/views/user/LoginCredentials.vue
src/views/user/State_Login.jsx
import {State_App} from "@ventose/state/State_App";
import {defItem, ITEM_TYPE} from "@ventose/ui";
import {watch} from "vue";
- [ ] 自定义组件的校验如何处理?
const inputConfigs = defItem({
type: ITEM_TYPE.input,
onAfterValueEmit: (configs) => {
State_App.count++;
}
});
const state = reactive({name: ''})
watch(() => State_App.count, (count) => {
State_App.count = count;
});
State_App.count: {{State_App.count}}
<xItem :configs="inputConfigs" v-model="state.name" />
xDataGrid
- 拖动排序 字典下拉顺序=> order 的修改
Utils
- 设置 title
- setDocumentTitle()
- root var css 变量
- setCSSVariables
自定义的折叠按钮(未使用)
<!-- <xRender :render="render.collapsedButton" :collapsed="State_App.collapsed"/>-->
log
-
no-mutating-props
:MutatingProps
-
pickValueFrom
:从 xItem 的 configs 中获取 value; - xItem 错误提示随语言切换变更 涉及到 $t 的配置项都需要 ()=>
- 20211117 登陆框 blur 未触发 update 校验
- 20211127022841 v-uiPopover
- 20220110095314
- xIcon :异步,动态懒加载 src\assets\svg 目录下单个文件,经过插件处理,分别打包成独立文件
- SvgRender: 同步,首页不想让用户看到 loading 状态,可提前加载图标
<!-- src\assets\svg\lockStrok.svg -->
<xIcon
icon="lockStrok"
style="color: red; height: 100px; width: 100px; outline: 1px solid black; margin: 10px; " />
- 20220328210842
国际化,用于内部通信
export const State_UI = reactive({
language: lStorage["language"] || "zh-CN",
/* svg 的路径 */
assetsSvgPath:'',
$t: (prop, payload) => ({
label: prop
})
});
xItem msg 可以是 function 根据传入的参数显示不同信息 raw$Value update:value
动态加载 svg icon
/* 在App中应用,UI lib 中 内置,直接引用 */
const icons = import.meta.glob("../../assets/svg/*.svg");
const modules = {};