mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-05-21 11:59:20 +08:00
version: v4.9.5
This commit is contained in:
parent
60ed09a0c5
commit
d12fcd18b6
28
CHANGELOG.md
28
CHANGELOG.md
@ -1,5 +1,33 @@
|
||||
# CHANGE LOG
|
||||
|
||||
## 4.9.5
|
||||
|
||||
天元突破,红莲螺岩。
|
||||
|
||||
兼容 `vue3.5` 版本的更新。
|
||||
|
||||
## Feats
|
||||
|
||||
- 更新脚手架依赖为主流依赖
|
||||
- 更新 `vue` 版本至 `3.5.6`
|
||||
- 更新 `vite` 版本至 `5.4.3`
|
||||
- 更新 `pinia-plugin-persistedstate` 版本至 `4.0.1`,并且兼容破坏性更新改动
|
||||
- `RChart` 组件相关
|
||||
- 小重构该组件,移除多个 `echart` 缓存,现在有且仅有一个
|
||||
- 减少 `watch` 监听项
|
||||
- 使用 `useTemplateRef` 方法替代 `ref` 注册 `dom`
|
||||
- 现在预设 `card` 时,`chart` 图会更加的醒目一些
|
||||
- 优化 `demo` 展示
|
||||
- 现在会拦截 `aria` 属性,现在仅允许通过 `showAria` 配置项管理无障碍模式
|
||||
- 优化无障碍模式渲染,现在不会重新渲染整个图表,而是通过 `setOptions` 方式更新图表
|
||||
- `useChart` 方法相关
|
||||
- `isDispose` 方法更名为 `isDisposed`
|
||||
|
||||
## Fixes
|
||||
|
||||
- 修复 `useChart` 方法相关方法中 `dispose` 方法执行不生效的问题
|
||||
- 修复 `RChart` 的 `loading` 不能跟随主题变化的问题
|
||||
|
||||
## 4.9.4
|
||||
|
||||
## Feats
|
||||
|
34
package.json
34
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ray-template",
|
||||
"private": false,
|
||||
"version": "4.9.4",
|
||||
"version": "4.9.5",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": "^18.0.0 || >=20.0.0",
|
||||
@ -46,9 +46,9 @@
|
||||
"mockjs": "1.1.0",
|
||||
"naive-ui": "^2.39.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.0",
|
||||
"pinia-plugin-persistedstate": "^4.0.1",
|
||||
"print-js": "^1.6.0",
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.6",
|
||||
"vue-demi": "0.14.6",
|
||||
"vue-hooks-plus": "2.2.1",
|
||||
"vue-i18n": "^9.13.1",
|
||||
@ -56,26 +56,26 @@
|
||||
"vue3-next-qrcode": "2.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.7.1",
|
||||
"@commitlint/config-conventional": "^17.7.0",
|
||||
"@commitlint/cli": "^17.8.1",
|
||||
"@commitlint/config-conventional": "^17.8.1",
|
||||
"@interactjs/types": "1.10.21",
|
||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/dom-to-image": "2.6.7",
|
||||
"@types/jsbarcode": "3.11.4",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mockjs": "1.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
||||
"@typescript-eslint/parser": "^6.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"@vitejs/plugin-vue": "^5.1.0",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||
"@vitest/ui": "1.4.0",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^12.0.0",
|
||||
"@vue/test-utils": "2.4.3",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"depcheck": "^1.4.5",
|
||||
"eslint": "^8.56.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"depcheck": "^1.4.7",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard-with-typescript": "^43.0.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
@ -83,16 +83,16 @@
|
||||
"eslint-plugin-vue": "^9.25.0",
|
||||
"happy-dom": "14.3.1",
|
||||
"husky": "8.0.3",
|
||||
"lint-staged": "^15.1.0",
|
||||
"postcss": "^8.4.31",
|
||||
"lint-staged": "^15.2.0",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss-px-to-viewport-8-with-include": "1.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "1.71.1",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"typescript": "^5.2.2",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.4.1",
|
||||
"unplugin-auto-import": "^0.18.2",
|
||||
"unplugin-vue-components": "^0.27.4",
|
||||
"vite": "^5.4.3",
|
||||
"vite-bundle-analyzer": "0.9.4",
|
||||
"vite-plugin-cdn2": "1.1.0",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
@ -104,7 +104,7 @@
|
||||
"vite-svg-loader": "^4.0.0",
|
||||
"vite-tsconfig-paths": "4.3.2",
|
||||
"vitest": "1.5.2",
|
||||
"vue-tsc": "^2.0.11"
|
||||
"vue-tsc": "^2.0.13"
|
||||
},
|
||||
"description": "<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->",
|
||||
"main": "index.ts",
|
||||
|
934
pnpm-lock.yaml
generated
934
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,8 @@ import { NSpin } from 'naive-ui'
|
||||
import { spinProps } from 'naive-ui'
|
||||
import { getVariableToRefs } from '@/global-variable'
|
||||
|
||||
import type { SpinProps } from 'naive-ui'
|
||||
|
||||
const GlobalSpin = defineComponent({
|
||||
name: 'GlobalSpin',
|
||||
props: {
|
||||
@ -50,7 +52,7 @@ const GlobalSpin = defineComponent({
|
||||
render() {
|
||||
return (
|
||||
<NSpin
|
||||
{...this.$props}
|
||||
{...(this.$props as SpinProps)}
|
||||
show={this.spinValue}
|
||||
themeOverrides={this.overrides}
|
||||
>
|
||||
|
@ -13,6 +13,8 @@ import { RCollapseGrid, RForm } from '@/components'
|
||||
|
||||
import { collapseGridProps, formProps } from '@/components'
|
||||
|
||||
import type { FormProps, GridProps } from 'naive-ui'
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
@ -38,7 +40,8 @@ export default defineComponent({
|
||||
),
|
||||
render() {
|
||||
const { $slots, $props } = this
|
||||
const { labelPlacement, showFeedback, ...rest } = $props
|
||||
const { labelPlacement, showFeedback, ...rest } = $props as FormProps &
|
||||
GridProps
|
||||
|
||||
return (
|
||||
<RForm {...rest} labelPlacement="top" showFeedback={false}>
|
||||
|
@ -17,7 +17,6 @@ import { call } from '@/utils'
|
||||
import { usePagination } from '@/hooks'
|
||||
|
||||
import type { TablePagination, TableRequestConfig, TableProInst } from './types'
|
||||
import type { Recordable } from '@/types'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RTablePro',
|
||||
@ -162,7 +161,9 @@ export default defineComponent({
|
||||
},
|
||||
render() {
|
||||
const { register, $props, paginationRef, $slots } = this
|
||||
const { onRegister, showPagination, ...rest } = $props
|
||||
const { onRegister, showPagination, ...rest } = $props as ExtractPropTypes<
|
||||
typeof props
|
||||
>
|
||||
|
||||
return (
|
||||
<RTable
|
||||
|
@ -16,6 +16,7 @@ import { NSpin } from 'naive-ui'
|
||||
import barcode from 'jsbarcode'
|
||||
import props from './props'
|
||||
import { completeSize, call } from '@/utils'
|
||||
import { useTemplateRef } from 'vue'
|
||||
|
||||
import type { WatchStopHandle } from 'vue'
|
||||
|
||||
@ -23,7 +24,9 @@ export default defineComponent({
|
||||
name: 'RBarcode',
|
||||
props,
|
||||
setup(props) {
|
||||
const barcodeRef = ref<HTMLCanvasElement | HTMLOrSVGElement>()
|
||||
const barcodeRef = useTemplateRef<HTMLCanvasElement | HTMLOrSVGElement>(
|
||||
'barcodeRef',
|
||||
)
|
||||
const cssVars = computed(() => {
|
||||
const cssVar = {
|
||||
'--r-barcode-width': completeSize(props.width),
|
||||
|
@ -79,10 +79,9 @@ const useChart = () => {
|
||||
*
|
||||
* @description
|
||||
* chart 是否已经销毁。
|
||||
* 如果销毁则返回 true, 否则返回 false。
|
||||
* 如果销毁则返回 true,否则返回 false。
|
||||
*/
|
||||
const isDispose = () =>
|
||||
!(echartInst && getChartInstance().echartInst.getDom())
|
||||
const isDisposed = () => !!getChartInstance().echartInst?.isDisposed()
|
||||
|
||||
/**
|
||||
*
|
||||
@ -102,7 +101,7 @@ const useChart = () => {
|
||||
register,
|
||||
{
|
||||
getChartInstance,
|
||||
isDispose,
|
||||
isDisposed,
|
||||
dispose,
|
||||
render,
|
||||
},
|
||||
|
@ -26,7 +26,7 @@ import { NCard } from 'naive-ui'
|
||||
import props from './props'
|
||||
import { throttle } from 'lodash-es'
|
||||
import { completeSize, downloadBase64File, call, renderNode } from '@/utils'
|
||||
import { setupChartTheme } from './utils'
|
||||
import { getCustomEchartTheme, loadingOptions, setEchartOptions } from './utils'
|
||||
import { APP_THEME } from '@/app-config'
|
||||
import {
|
||||
useResizeObserver,
|
||||
@ -35,6 +35,7 @@ import {
|
||||
} from '@vueuse/core'
|
||||
import { RMoreDropdown } from '@/components'
|
||||
import { useSettingGetters } from '@/store'
|
||||
import { useTemplateRef } from 'vue'
|
||||
|
||||
import type { WatchStopHandle } from 'vue'
|
||||
import type { AnyFC } from '@/types'
|
||||
@ -46,15 +47,8 @@ import type {
|
||||
import type { ECharts, EChartsCoreOption } from 'echarts/core'
|
||||
import type { DropdownProps, DropdownOption } from 'naive-ui'
|
||||
|
||||
// setOption 默认配置项
|
||||
const defaultChartOptions = {
|
||||
notMerge: true,
|
||||
lazyUpdate: true,
|
||||
silent: false,
|
||||
replaceMerge: [],
|
||||
}
|
||||
// 获取 chart 主题
|
||||
const echartThemes = setupChartTheme()
|
||||
const echartThemes = getCustomEchartTheme()
|
||||
// download 下载功能 key
|
||||
const __CHART_DOWN_LOAD_CHART__ = '__R_CHART_DOWN_LOAD_CHART__'
|
||||
|
||||
@ -92,14 +86,21 @@ export default defineComponent({
|
||||
props,
|
||||
setup(props, { expose }) {
|
||||
const { getAppTheme } = useSettingGetters()
|
||||
const rayChartRef = ref<HTMLElement>() // echart 容器实例
|
||||
const rayChartWrapperRef = ref<HTMLElement>() // echart 父容器实例
|
||||
const echartInstanceRef = ref<ECharts>() // echart 实例
|
||||
let resizeThrottleReturn: DebouncedFunc<AnyFC> | null // resize 防抖方法实例
|
||||
let resizeObserverReturn: UseResizeObserverReturn | null // resize observer 实例
|
||||
const { echartTheme } = APP_THEME // 当前配置主题
|
||||
let watchThrottledCallback: WatchStopHandle | null // watch props 回调
|
||||
let echartInst: ECharts | null // 无代理响应式代理缓存 echart inst
|
||||
// echart 容器实例
|
||||
const rayChartRef = useTemplateRef<HTMLElement>('rayChartRef')
|
||||
// echart 父容器实例
|
||||
const rayChartWrapperRef = useTemplateRef<HTMLElement>('rayChartWrapperRef')
|
||||
// echart 实例
|
||||
const echartInstanceRef = shallowRef<ECharts>()
|
||||
// resize 防抖方法实例
|
||||
let resizeThrottleReturn: DebouncedFunc<AnyFC> | null
|
||||
// resize observer 实例
|
||||
let resizeObserverReturn: UseResizeObserverReturn | null
|
||||
// 当前配置主题
|
||||
const { echartTheme } = APP_THEME
|
||||
// watch props 回调
|
||||
let watchThrottledCallback: WatchStopHandle | null
|
||||
// 下拉框配置项
|
||||
const moreDropDownOptions = computed<DropdownProps['options']>(() => [
|
||||
{
|
||||
label: '下载图片',
|
||||
@ -108,22 +109,29 @@ export default defineComponent({
|
||||
echartInstanceRef.value && echartInstanceRef.value.getDom()
|
||||
),
|
||||
},
|
||||
]) // 下拉框配置项
|
||||
])
|
||||
const cssVarsRef = computed(() => {
|
||||
return {
|
||||
'--ray-chart-width': completeSize(props.width),
|
||||
'--ray-chart-height': completeSize(props.height),
|
||||
}
|
||||
})
|
||||
const targetIsVisible = ref(false) // 目标是否可见
|
||||
let intersectionObserverReturn: UseIntersectionObserverReturn | null // intersectionObserver 实例
|
||||
// 目标是否可见
|
||||
const targetIsVisible = ref(false)
|
||||
// intersectionObserver 实例
|
||||
let intersectionObserverReturn: UseIntersectionObserverReturn | null
|
||||
// 缓存一些配置信息
|
||||
const __catch = {
|
||||
aria: props.showAria,
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 注册 `echart` 组件, 图利, 渲染器等
|
||||
* @description
|
||||
* 注册 echart 组件、图利、渲染器等。
|
||||
*
|
||||
* 会自动合并拓展 `echart` 组件
|
||||
* 该方法必须在注册图表之前调用
|
||||
* 会自动合并拓展 echart 组件。
|
||||
* 该方法必须在注册图表之前调用。
|
||||
*/
|
||||
const registerChartCore = async () => {
|
||||
use([
|
||||
@ -156,16 +164,17 @@ export default defineComponent({
|
||||
|
||||
/**
|
||||
*
|
||||
* 更具当前主题渲染 chart
|
||||
* @description
|
||||
* 更具当前主题渲染 chart。
|
||||
*
|
||||
* 如果手动配置了 theme 属性,autoChangeTheme 属性则会失效
|
||||
* 但是,如果配置 theme 属性为 default,则会根据当前主题色渲染 chart 默认主题
|
||||
* 如果手动配置了 theme 属性,autoChangeTheme 属性则会失效;
|
||||
* 但是,如果配置 theme 属性为 default,则会根据当前主题色渲染 chart 默认主题。
|
||||
*
|
||||
* 当 Boolean(theme) 为 false,则会尝试获取 echartTheme 属性
|
||||
* 但是,如果未获取到 echartTheme 属性,则会使用默认样式
|
||||
* 当 Boolean(theme) 为 false,则会尝试获取 echartTheme 属性;
|
||||
* 但是,如果未获取到 echartTheme 属性,则会使用默认样式。
|
||||
*/
|
||||
const updateChartTheme = () => {
|
||||
if (echartInst?.getDom()) {
|
||||
if (echartInstanceRef.value) {
|
||||
destroyChart()
|
||||
}
|
||||
|
||||
@ -199,66 +208,61 @@ export default defineComponent({
|
||||
*/
|
||||
const combineChartOptions = (ops: EChartsCoreOption) => {
|
||||
let options = unref(ops)
|
||||
|
||||
const assign = (opts: object) => Object.assign({}, options, opts)
|
||||
|
||||
if (props.showAria) {
|
||||
// 拦截 aria 配置项
|
||||
options = assign({
|
||||
aria: {
|
||||
enabled: true,
|
||||
enabled: props.showAria,
|
||||
decal: {
|
||||
show: true,
|
||||
show: props.showAria,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 渲染 `echart`
|
||||
*
|
||||
* 缓存两个实例
|
||||
* 直接使用响应式代理实例会出现诡异的问题, 例如 `legend` 点击时报错
|
||||
* @description
|
||||
* 渲染 echart。
|
||||
*/
|
||||
const renderChart = (theme: string = echartTheme) => {
|
||||
/** 获取 dom 容器 */
|
||||
// 获取 dom 容器
|
||||
const element = rayChartRef.value as HTMLElement
|
||||
/** 获取配置项 */
|
||||
// 获取配置项
|
||||
const options = combineChartOptions(props.options)
|
||||
/** 获取 dom 容器实际宽高 */
|
||||
// 获取 dom 容器实际宽高
|
||||
const { height, width } = element.getBoundingClientRect()
|
||||
const { onSuccess, onError } = props
|
||||
|
||||
try {
|
||||
/** 注册 chart */
|
||||
echartInst = init(element, theme, {
|
||||
/** 如果款度为 0, 则以 200px 填充 */
|
||||
// 注册 chart
|
||||
echartInstanceRef.value = init(element, theme, {
|
||||
// 如果款度为 0,则以 200px 填充
|
||||
width: width === 0 ? 200 : void 0,
|
||||
/** 如果高度为 0, 则以 200px 填充 */
|
||||
// 如果高度为 0,则以 200px 填充
|
||||
height: height === 0 ? 200 : void 0,
|
||||
})
|
||||
echartInstanceRef.value = echartInst
|
||||
|
||||
// 渲染成功回调
|
||||
if (onSuccess) {
|
||||
call(onSuccess, echartInst)
|
||||
call(onSuccess, echartInstanceRef.value)
|
||||
}
|
||||
|
||||
// 是否强制下一队列渲染图表
|
||||
if (props.nextTick) {
|
||||
echartInst.setOption({})
|
||||
echartInstanceRef.value.setOption({})
|
||||
|
||||
nextTick(() => {
|
||||
options && echartInst?.setOption(options)
|
||||
options && echartInstanceRef.value?.setOption(options)
|
||||
})
|
||||
} else {
|
||||
options && echartInst?.setOption(options)
|
||||
options && echartInstanceRef.value?.setOption(options)
|
||||
}
|
||||
} catch (e) {
|
||||
/** 渲染失败回调 */
|
||||
// 渲染失败回调
|
||||
if (onError) {
|
||||
call(onError)
|
||||
}
|
||||
@ -279,26 +283,29 @@ export default defineComponent({
|
||||
* chart 是否已经销毁。
|
||||
* 如果销毁则返回 true, 否则返回 false。
|
||||
*/
|
||||
const isDispose = () => !(echartInst && echartInst.getDom())
|
||||
const isDisposed = () => {
|
||||
return !!echartInstanceRef.value?.isDisposed()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 销毁 chart 实例, 释放资源
|
||||
* @description
|
||||
* 销毁 chart 实例,释放资源。
|
||||
*/
|
||||
const destroyChart = () => {
|
||||
if (!isDispose()) {
|
||||
echartInst!.clear()
|
||||
echartInst!.dispose()
|
||||
|
||||
echartInstanceRef.value = void 0
|
||||
echartInst = null
|
||||
if (!isDisposed()) {
|
||||
echartInstanceRef.value?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置 echarts 尺寸 */
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 重置 echarts 尺寸。
|
||||
*/
|
||||
const resizeChart = () => {
|
||||
if (echartInst) {
|
||||
echartInst.resize()
|
||||
if (echartInstanceRef.value) {
|
||||
echartInstanceRef.value.resize()
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,15 +314,16 @@ export default defineComponent({
|
||||
* @param key moreDropDownOptions key
|
||||
* @param option moreDropDownOptions current click option
|
||||
*
|
||||
* 预设 card 风格下拉框点击
|
||||
* 当前仅实现下载图片功能
|
||||
* @description
|
||||
* 预设 card 风格下拉框点击。
|
||||
* 当前仅实现下载图片功能。
|
||||
*/
|
||||
const dropdownSelect = (key: string | number, option: DropdownOption) => {
|
||||
if (key === __CHART_DOWN_LOAD_CHART__ && !isDispose()) {
|
||||
if (key === __CHART_DOWN_LOAD_CHART__ && !isDisposed()) {
|
||||
const { filename, ...args } = props.downloadOptions
|
||||
|
||||
downloadBase64File(
|
||||
echartInst!.getDataURL(args),
|
||||
echartInstanceRef.value!.getDataURL(args),
|
||||
filename ?? `${new Date().getTime()}`,
|
||||
)
|
||||
}
|
||||
@ -327,6 +335,11 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 挂载 chart 方法。
|
||||
*/
|
||||
const mount = () => {
|
||||
// 注册事件
|
||||
if (props.autoResize) {
|
||||
@ -348,7 +361,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
// 避免重复渲染
|
||||
if (echartInst?.getDom()) {
|
||||
if (echartInstanceRef.value?.getDom()) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -357,7 +370,7 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
|
||||
// 渲染 chart
|
||||
// 根据主题渲染 chart
|
||||
updateChartTheme()
|
||||
|
||||
// 初始化完成后移除 intersectionObserver 监听
|
||||
@ -366,21 +379,16 @@ export default defineComponent({
|
||||
// 注册 register,用于 useChart hook
|
||||
const { onRegister } = props
|
||||
|
||||
if (onRegister && echartInst) {
|
||||
call(onRegister, echartInst, mount, unmount)
|
||||
if (onRegister && echartInstanceRef.value) {
|
||||
call(onRegister, echartInstanceRef.value, mount, unmount)
|
||||
}
|
||||
}
|
||||
|
||||
if (props.intersectionObserver) {
|
||||
intersectionObserverReturn = useIntersectionObserver(
|
||||
props.intersectionObserverTarget || rayChartWrapperRef,
|
||||
([entry]) => {
|
||||
targetIsVisible.value = entry.isIntersecting
|
||||
},
|
||||
props.intersectionOptions,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 卸载 chart 方法。
|
||||
*/
|
||||
const unmount = () => {
|
||||
// 卸载 echarts
|
||||
destroyChart()
|
||||
@ -395,15 +403,17 @@ export default defineComponent({
|
||||
resizeObserverReturn = null
|
||||
}
|
||||
|
||||
/** 监听全局主题变化, 然后重新渲染对应主题 echarts */
|
||||
// 监听全局主题变化,然后重新渲染对应主题 echarts
|
||||
watch(
|
||||
() => getAppTheme.value,
|
||||
() => {
|
||||
/**
|
||||
*
|
||||
* Q: 为什么需要重新卸载再渲染
|
||||
* A: 因为 echarts 官方文档并未提供动态渲染方法
|
||||
* A: 虽然原型上有 setTheme 方法, 但是官方标记是仅限于在类 ECharts 中访问
|
||||
* @description
|
||||
* Q: 为什么需要重新卸载再渲染?
|
||||
* A: 因为 echarts 官方文档并未提供动态渲染方法。
|
||||
* 虽然原型上有 setTheme 方法,但是官方标记是仅限于在类 ECharts 中访问。
|
||||
* 所以,只能先卸载后重新渲染。
|
||||
*/
|
||||
if (props.autoChangeTheme) {
|
||||
destroyChart()
|
||||
@ -411,21 +421,19 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
)
|
||||
/**
|
||||
*
|
||||
* 贴花跟随主题渲染
|
||||
*
|
||||
* 自动跟随模板主题或者指定主题皆可
|
||||
*/
|
||||
watch(
|
||||
() => props.showAria,
|
||||
() => {
|
||||
destroyChart()
|
||||
updateChartTheme()
|
||||
},
|
||||
)
|
||||
watchEffect(() => {
|
||||
/** 监听 options 变化 */
|
||||
// 是否启用了可视区域监听
|
||||
if (props.intersectionObserver) {
|
||||
intersectionObserverReturn = useIntersectionObserver(
|
||||
props.intersectionObserverTarget || rayChartWrapperRef,
|
||||
([entry]) => {
|
||||
targetIsVisible.value = entry.isIntersecting
|
||||
},
|
||||
props.intersectionOptions,
|
||||
)
|
||||
}
|
||||
|
||||
// 监听 options 变化
|
||||
if (props.watchOptions) {
|
||||
watchThrottledCallback = watchThrottled(
|
||||
() => props.options,
|
||||
@ -434,12 +442,12 @@ export default defineComponent({
|
||||
const options = combineChartOptions(ndata)
|
||||
const setOpt = Object.assign(
|
||||
{},
|
||||
defaultChartOptions,
|
||||
setEchartOptions(),
|
||||
props.setChartOptions,
|
||||
)
|
||||
|
||||
// 如果 options 发生变动更新 echarts
|
||||
echartInst?.setOption(options, setOpt)
|
||||
echartInstanceRef.value?.setOption(options, setOpt)
|
||||
},
|
||||
{
|
||||
// 深度监听 options
|
||||
@ -453,11 +461,20 @@ export default defineComponent({
|
||||
|
||||
// 监听 loading 变化
|
||||
props.loading
|
||||
? echartInst?.showLoading(props.loadingOptions)
|
||||
: echartInst?.hideLoading()
|
||||
? echartInstanceRef.value?.showLoading(
|
||||
loadingOptions(props.loadingOptions),
|
||||
)
|
||||
: echartInstanceRef.value?.hideLoading()
|
||||
|
||||
// 贴花是否启用
|
||||
if (props.showAria !== __catch.aria && echartInstanceRef.value) {
|
||||
echartInstanceRef.value.setOption(combineChartOptions(props.options))
|
||||
|
||||
__catch.aria = props.showAria
|
||||
}
|
||||
|
||||
// 当前图表容器是否处于可见状态,如果可见则渲染图表
|
||||
if (targetIsVisible.value) {
|
||||
if (targetIsVisible.value && !isDisposed()) {
|
||||
mount()
|
||||
}
|
||||
})
|
||||
@ -504,6 +521,7 @@ export default defineComponent({
|
||||
style={[this.cssVarsRef]}
|
||||
contentStyle={contentStyle}
|
||||
bordered={bordered}
|
||||
embedded
|
||||
>
|
||||
{{
|
||||
default: renderNode(
|
||||
@ -517,7 +535,7 @@ export default defineComponent({
|
||||
<RMoreDropdown
|
||||
iconSize={18}
|
||||
cursor="pointer"
|
||||
options={dropdownOptions ?? moreDropDownOptions}
|
||||
options={dropdownOptions || moreDropDownOptions}
|
||||
trigger="click"
|
||||
onSelect={dropdownSelect.bind(this)}
|
||||
placement="bottom-end"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { loadingOptions } from './utils'
|
||||
import { loadingOptions, setEchartOptions } from './utils'
|
||||
|
||||
import type * as echarts from 'echarts/core' // echarts 核心模块
|
||||
import type { PropType, VNode } from 'vue'
|
||||
@ -192,7 +192,8 @@ const props = {
|
||||
*
|
||||
* @description
|
||||
* 是否启用 chart 无障碍模式。
|
||||
* 启用该配置项后会覆盖 options 中的 aria。
|
||||
* 该组建默认拦截 aria 配置项的 enabled 属性与 decal.show 属性。
|
||||
* 也就意味着,你不能通过配置 options 管理该组件的无障碍模式,只能通过该配置项统一管理。
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
@ -344,6 +345,7 @@ const props = {
|
||||
*
|
||||
* @description
|
||||
* 是否将渲染放置下一个队列。
|
||||
* 该配置项在渲染很多图表的时候可以有很不错的性能提升。
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
@ -360,12 +362,7 @@ const props = {
|
||||
*/
|
||||
setChartOptions: {
|
||||
type: Object as PropType<SetOptionOpts>,
|
||||
default: () => ({
|
||||
notMerge: true,
|
||||
lazyUpdate: true,
|
||||
silent: false,
|
||||
replaceMerge: [],
|
||||
}),
|
||||
default: () => setEchartOptions(),
|
||||
},
|
||||
/**
|
||||
*
|
||||
|
@ -1,95 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
||||
*
|
||||
* @date 2023-07-22
|
||||
*
|
||||
* @workspace ray-template
|
||||
*
|
||||
* @remark 今天也是元气满满撸代码的一天
|
||||
*/
|
||||
|
||||
import { useTheme } from '@/hooks'
|
||||
|
||||
import type {
|
||||
ChartThemeRawArray,
|
||||
ChartThemeRawModules,
|
||||
LoadingOptions,
|
||||
} from '@/components/RChart/src/types'
|
||||
|
||||
/**
|
||||
*
|
||||
* @see https://echarts.apache.org/zh/theme-builder.html
|
||||
*
|
||||
* @description
|
||||
* 自动注册所有主题。
|
||||
*
|
||||
* 默认以文件名当作主题名称。
|
||||
*
|
||||
* 主题编辑器使用方法:
|
||||
* 1. 配置、选择主题
|
||||
* 2. 点击下载主题
|
||||
* 3. 选择 json 类型,然后复制
|
||||
* 4. 在 echart-themes 包中创建对应的 json 文件,文件名为主题名称
|
||||
*/
|
||||
export const setupChartTheme = () => {
|
||||
// 获取所有主题
|
||||
const themeRawModules: Record<string, ChartThemeRawModules> =
|
||||
import.meta.glob('@/app-config/echart-themes/**/*.json', {
|
||||
eager: true,
|
||||
})
|
||||
const regex = /\/([^/]+)\.json$/
|
||||
|
||||
const rawThemes = Object.keys(themeRawModules).reduce((pre, curr) => {
|
||||
const name = curr.match(regex)?.[1]
|
||||
|
||||
if (name) {
|
||||
pre.push({
|
||||
name,
|
||||
theme: themeRawModules[curr].default,
|
||||
})
|
||||
|
||||
return pre
|
||||
} else {
|
||||
throw new Error(`[RChart Theme Error]: name ${curr} is invalid!`)
|
||||
}
|
||||
}, [] as ChartThemeRawArray[])
|
||||
|
||||
return rawThemes
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param options 加载自定义配置项
|
||||
*
|
||||
* @description
|
||||
* chart 加载配置项。
|
||||
*
|
||||
* @see https://echarts.apache.org/zh/api.html#echartsInstance.showLoading
|
||||
*
|
||||
* @example
|
||||
* const options = loadingOptions({ ...LoadingOptions })
|
||||
*/
|
||||
export const loadingOptions = (options?: LoadingOptions) => {
|
||||
const { getAppTheme } = useTheme()
|
||||
const { theme } = getAppTheme()
|
||||
|
||||
return Object.assign(
|
||||
{},
|
||||
{
|
||||
text: 'loading',
|
||||
color: '#c23531',
|
||||
textColor: theme ? '#fff' : '#000',
|
||||
maskColor: theme ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)',
|
||||
zlevel: 0,
|
||||
fontSize: 12,
|
||||
showSpinner: true,
|
||||
spinnerRadius: 10,
|
||||
lineWidth: 5,
|
||||
fontWeight: 'normal',
|
||||
fontStyle: 'normal',
|
||||
fontFamily: 'sans-serif',
|
||||
},
|
||||
options,
|
||||
)
|
||||
}
|
45
src/components/RChart/src/utils/get-custom-echart-theme.ts
Normal file
45
src/components/RChart/src/utils/get-custom-echart-theme.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import type {
|
||||
ChartThemeRawArray,
|
||||
ChartThemeRawModules,
|
||||
} from '@/components/RChart/src/types'
|
||||
|
||||
/**
|
||||
*
|
||||
* @see https://echarts.apache.org/zh/theme-builder.html
|
||||
*
|
||||
* @description
|
||||
* 自动注册所有主题。
|
||||
*
|
||||
* 默认以文件名当作主题名称。
|
||||
*
|
||||
* 主题编辑器使用方法:
|
||||
* 1. 配置、选择主题
|
||||
* 2. 点击下载主题
|
||||
* 3. 选择 json 类型,然后复制
|
||||
* 4. 在 echart-themes 包中创建对应的 json 文件,文件名为主题名称
|
||||
*/
|
||||
export const getCustomEchartTheme = () => {
|
||||
// 获取所有主题
|
||||
const themeRawModules: Record<string, ChartThemeRawModules> =
|
||||
import.meta.glob('@/app-config/echart-themes/**/*.json', {
|
||||
eager: true,
|
||||
})
|
||||
const regex = /\/([^/]+)\.json$/
|
||||
|
||||
const rawThemes = Object.keys(themeRawModules).reduce((pre, curr) => {
|
||||
const name = curr.match(regex)?.[1]
|
||||
|
||||
if (name) {
|
||||
pre.push({
|
||||
name,
|
||||
theme: themeRawModules[curr].default,
|
||||
})
|
||||
|
||||
return pre
|
||||
} else {
|
||||
throw new Error(`[RChart Theme Error]: name ${curr} is invalid!`)
|
||||
}
|
||||
}, [] as ChartThemeRawArray[])
|
||||
|
||||
return rawThemes
|
||||
}
|
3
src/components/RChart/src/utils/index.ts
Normal file
3
src/components/RChart/src/utils/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export { getCustomEchartTheme } from './get-custom-echart-theme'
|
||||
export { loadingOptions } from './loading-options'
|
||||
export { setEchartOptions } from './set-echart-options'
|
35
src/components/RChart/src/utils/loading-options.ts
Normal file
35
src/components/RChart/src/utils/loading-options.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { useTheme } from '@/hooks'
|
||||
|
||||
import type { LoadingOptions } from '@/components/RChart/src/types'
|
||||
|
||||
/**
|
||||
*
|
||||
* @param options 加载自定义配置项
|
||||
*
|
||||
* @description
|
||||
* chart 加载配置项。
|
||||
*
|
||||
* @see https://echarts.apache.org/zh/api.html#echartsInstance.showLoading
|
||||
*
|
||||
* @example
|
||||
* const options = loadingOptions({ ...LoadingOptions })
|
||||
*/
|
||||
export const loadingOptions = (options?: LoadingOptions) => {
|
||||
const { getAppTheme } = useTheme()
|
||||
const { theme } = getAppTheme()
|
||||
|
||||
return Object.assign({}, options, {
|
||||
text: 'loading',
|
||||
color: '#c23531',
|
||||
textColor: theme ? '#fff' : '#000',
|
||||
maskColor: theme ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)',
|
||||
zlevel: 0,
|
||||
fontSize: 12,
|
||||
showSpinner: true,
|
||||
spinnerRadius: 10,
|
||||
lineWidth: 5,
|
||||
fontWeight: 'normal',
|
||||
fontStyle: 'normal',
|
||||
fontFamily: 'sans-serif',
|
||||
})
|
||||
}
|
13
src/components/RChart/src/utils/set-echart-options.ts
Normal file
13
src/components/RChart/src/utils/set-echart-options.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
*
|
||||
* @see https://echarts.apache.org/zh/api.html#echartsInstance.setOption
|
||||
*
|
||||
* @description
|
||||
* 获取 setOptions 方法默认配置规则。
|
||||
*/
|
||||
export const setEchartOptions = () => ({
|
||||
notMerge: true,
|
||||
lazyUpdate: true,
|
||||
silent: false,
|
||||
replaceMerge: [],
|
||||
})
|
@ -27,6 +27,8 @@ import { RIcon } from '@/components'
|
||||
import { call } from '@/utils'
|
||||
import props from './props'
|
||||
|
||||
import type { GridProps } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RCollapseGrid',
|
||||
props,
|
||||
@ -99,7 +101,7 @@ export default defineComponent({
|
||||
default: () => (
|
||||
<NGrid
|
||||
class="ray-collapse-grid"
|
||||
{...$props}
|
||||
{...($props as GridProps)}
|
||||
collapsed={modelCollapsed}
|
||||
xGap={xGap || 12}
|
||||
yGap={yGap || 12}
|
||||
|
@ -13,14 +13,16 @@ import { NForm } from 'naive-ui'
|
||||
|
||||
import props from './props'
|
||||
import { call } from '@/utils'
|
||||
import { useTemplateRef } from 'vue'
|
||||
|
||||
import type { RFormInst } from './types'
|
||||
import type { FormProps } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RForm',
|
||||
props,
|
||||
setup(props, { expose }) {
|
||||
const formRef = ref<RFormInst>()
|
||||
const formRef = useTemplateRef<RFormInst>('formRef')
|
||||
|
||||
onMounted(() => {
|
||||
// 主动调用 register 方法,满足 useForm 方法正常调用
|
||||
@ -41,7 +43,7 @@ export default defineComponent({
|
||||
const { $attrs, $props, $slots } = this
|
||||
|
||||
return (
|
||||
<NForm {...$attrs} {...$props} ref="formRef">
|
||||
<NForm {...$attrs} {...($props as FormProps)} ref="formRef">
|
||||
{{
|
||||
...$slots,
|
||||
}}
|
||||
|
@ -16,6 +16,7 @@ import { NSpin } from 'naive-ui'
|
||||
import { call, completeSize } from '@/utils'
|
||||
import props from './props'
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import { useTemplateRef } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RIframe',
|
||||
@ -30,7 +31,7 @@ export default defineComponent({
|
||||
|
||||
return cssVar
|
||||
})
|
||||
const iframeRef = ref<HTMLIFrameElement>()
|
||||
const iframeRef = useTemplateRef<HTMLIFrameElement>('iframeRef')
|
||||
const spinShow = ref(true)
|
||||
|
||||
const iframeLoadSuccess = (e: Event) => {
|
||||
@ -83,9 +84,7 @@ export default defineComponent({
|
||||
allow={this.allow}
|
||||
name={this.name}
|
||||
title={this.title}
|
||||
{...{
|
||||
loading: this.lazy ? 'lazy' : null,
|
||||
}}
|
||||
loading={typeof this.lazy === 'boolean' ? 'lazy' : this.lazy}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
|
@ -12,6 +12,7 @@
|
||||
import type { PropType } from 'vue'
|
||||
import type { MaybeArray } from '@/types'
|
||||
import type { SpinProps } from 'naive-ui'
|
||||
import type { Lazy } from './types'
|
||||
|
||||
const props = {
|
||||
src: {
|
||||
@ -90,7 +91,7 @@ const props = {
|
||||
},
|
||||
lazy: {
|
||||
/** 是否延迟加载 iframe */
|
||||
type: Boolean,
|
||||
type: [Boolean, String] as PropType<boolean | Lazy>,
|
||||
default: true,
|
||||
},
|
||||
iframeClass: {
|
||||
|
@ -12,3 +12,5 @@
|
||||
export interface RIframeInst {
|
||||
iframe: Ref<HTMLIFrameElement>
|
||||
}
|
||||
|
||||
export type Lazy = 'lazy' | 'eager' | undefined
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
} from './constant'
|
||||
|
||||
import type interact from 'interactjs'
|
||||
import type { ModalProps } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RModal',
|
||||
@ -93,7 +94,7 @@ export default defineComponent({
|
||||
},
|
||||
render() {
|
||||
const { $props, $slots, $attrs } = this
|
||||
const { preset, ...$otherProps } = $props
|
||||
const { preset, ...$otherProps } = $props as ModalProps
|
||||
const { cssVars, uuidEl, isFullscreenCardType } = this
|
||||
|
||||
return (
|
||||
|
@ -15,6 +15,8 @@ import { RIcon } from '@/components'
|
||||
import props from './props'
|
||||
import { renderNode } from '@/utils'
|
||||
|
||||
import type { DropdownProps } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RMoreDropdown',
|
||||
props,
|
||||
@ -23,7 +25,11 @@ export default defineComponent({
|
||||
const { default: $default } = this.$slots
|
||||
|
||||
return (
|
||||
<NDropdown {...this.$props} {...this.$attrs} placement="bottom-start">
|
||||
<NDropdown
|
||||
{...(this.$props as DropdownProps)}
|
||||
{...this.$attrs}
|
||||
placement="bottom-start"
|
||||
>
|
||||
{renderNode($default, {
|
||||
defaultElement: <RIcon name={icon} size={iconSize} cursor={cursor} />,
|
||||
})}
|
||||
|
@ -22,8 +22,9 @@ import props from './props'
|
||||
import { call, renderNode, uuid } from '@/utils'
|
||||
import { config } from './shared'
|
||||
import { pick } from 'lodash-es'
|
||||
import { useTemplateRef } from 'vue'
|
||||
|
||||
import type { DropdownOption, DataTableInst } from 'naive-ui'
|
||||
import type { DropdownOption, DataTableInst, DataTableProps } from 'naive-ui'
|
||||
import type { ComponentSize } from '@/types'
|
||||
import type {
|
||||
C as CType,
|
||||
@ -38,8 +39,8 @@ export default defineComponent({
|
||||
setup(props, ctx) {
|
||||
const { expose, emit } = ctx
|
||||
|
||||
const rTableInst = ref<RTableInst>()
|
||||
const wrapperRef = ref<HTMLElement>()
|
||||
const rTableInst = useTemplateRef<RTableInst>('rTableInst')
|
||||
const wrapperRef = useTemplateRef<HTMLElement>('wrapperRef')
|
||||
|
||||
const uuidWrapper = uuid(16) // wrapper id
|
||||
const uuidTable = uuid(16) // table id
|
||||
@ -278,7 +279,7 @@ export default defineComponent({
|
||||
id: uuidTable,
|
||||
}}
|
||||
{...$attrs}
|
||||
{...$props}
|
||||
{...($props as DataTableProps)}
|
||||
{...propsPopselectValue}
|
||||
rowProps={combineRowProps.bind(this)}
|
||||
size={privateReactive.size}
|
||||
|
@ -8,7 +8,7 @@ import type {
|
||||
DataTableBaseColumn,
|
||||
CardProps,
|
||||
} from 'naive-ui'
|
||||
import type { VNode, CSSProperties } from 'vue'
|
||||
import type { VNode, CSSProperties, ShallowRef } from 'vue'
|
||||
import type { Recordable } from '@/types'
|
||||
import type { PrintDomOptions } from '@/utils/dom'
|
||||
|
||||
@ -34,7 +34,7 @@ export interface PrintTableOptions extends PrintDomOptions {}
|
||||
export interface TableProvider {
|
||||
uuidWrapper: string
|
||||
uuidTable: string
|
||||
wrapperRef: Ref<HTMLElement | undefined>
|
||||
wrapperRef: Readonly<ShallowRef<HTMLElement | null>>
|
||||
}
|
||||
|
||||
export interface C extends DataTableBaseColumn {
|
||||
|
@ -16,6 +16,8 @@ import { RIcon } from '@/components'
|
||||
|
||||
import { tooltipProps } from 'naive-ui'
|
||||
|
||||
import type { TooltipProps } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TooltipIcon',
|
||||
props: {
|
||||
@ -58,7 +60,7 @@ export default defineComponent({
|
||||
const { Icon } = this
|
||||
|
||||
return this.tooltipText ? (
|
||||
<NTooltip {...this.$props}>
|
||||
<NTooltip {...(this.$props as TooltipProps)}>
|
||||
{{
|
||||
trigger: () => <Icon />,
|
||||
default: () => this.tooltipText,
|
||||
|
@ -79,7 +79,7 @@ export const piniaKeepAliveStore = defineStore(
|
||||
persist: {
|
||||
key: APP_CATCH_KEY.appPiniaKeepAliveStore,
|
||||
storage: window.sessionStorage,
|
||||
paths: ['keepAliveInclude'],
|
||||
pick: ['keepAliveInclude'],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -446,7 +446,7 @@ export const piniaMenuStore = defineStore(
|
||||
persist: {
|
||||
key: APP_CATCH_KEY.appPiniaMenuStore,
|
||||
storage: window.localStorage,
|
||||
paths: ['breadcrumbOptions', 'menuKey', 'menuTagOptions', 'collapsed'],
|
||||
pick: ['breadcrumbOptions', 'menuKey', 'menuTagOptions', 'collapsed'],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -104,7 +104,7 @@ export const piniaSigningStore = defineStore(
|
||||
{
|
||||
persist: {
|
||||
key: APP_CATCH_KEY.appPiniaSigningStore,
|
||||
paths: ['signingCallback'],
|
||||
pick: ['signingCallback'],
|
||||
storage: window.localStorage,
|
||||
},
|
||||
},
|
||||
|
@ -10,7 +10,7 @@ import type { RChartType } from '@/components'
|
||||
const Echart = defineComponent({
|
||||
name: 'REchart',
|
||||
setup() {
|
||||
const [register, { getChartInstance, dispose, render, isDispose }] =
|
||||
const [register, { getChartInstance, dispose, render, isDisposed }] =
|
||||
useChart()
|
||||
const [
|
||||
register2,
|
||||
@ -18,7 +18,7 @@ const Echart = defineComponent({
|
||||
getChartInstance: getChartInstance2,
|
||||
dispose: dispose2,
|
||||
render: render2,
|
||||
isDispose: isDispose2,
|
||||
isDisposed: isDisposed2,
|
||||
},
|
||||
] = useChart()
|
||||
|
||||
@ -26,6 +26,7 @@ const Echart = defineComponent({
|
||||
const chartAria = ref(false)
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
loading1: false,
|
||||
})
|
||||
|
||||
const baseOptions = {
|
||||
@ -207,10 +208,10 @@ const Echart = defineComponent({
|
||||
}
|
||||
|
||||
const mountChart = () => {
|
||||
if (isDispose()) {
|
||||
if (isDisposed()) {
|
||||
render()
|
||||
} else {
|
||||
window.$message.warning('不可以重复渲染图表~')
|
||||
window.$message.warning('图表已渲染~')
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,14 +220,20 @@ const Echart = defineComponent({
|
||||
}
|
||||
|
||||
const updateChartOptions = () => {
|
||||
state.loading1 = true
|
||||
|
||||
const createData = () => Math.floor((Math.random() + 1) * 100)
|
||||
|
||||
setTimeout(() => {
|
||||
baseLineOptions.value.series[0].data = new Array(7)
|
||||
.fill(0)
|
||||
.map(() => createData())
|
||||
baseLineOptions.value.series[1].data = new Array(7)
|
||||
.fill(0)
|
||||
.map(() => createData())
|
||||
|
||||
state.loading1 = false
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
return {
|
||||
@ -245,11 +252,12 @@ const Echart = defineComponent({
|
||||
register2,
|
||||
dispose2,
|
||||
render2,
|
||||
isDispose2,
|
||||
isDisposed2,
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { register, register2, dispose2, render2, isDispose2 } = this
|
||||
const { register, register2, dispose2, render2, isDisposed2, loading1 } =
|
||||
this
|
||||
|
||||
return (
|
||||
<div class="echart">
|
||||
@ -266,6 +274,13 @@ const Echart = defineComponent({
|
||||
<NButton onClick={this.updateChartOptions.bind(this)}>
|
||||
更新配置项
|
||||
</NButton>
|
||||
<NButton
|
||||
onClick={() => {
|
||||
this.loading1 = !this.loading1
|
||||
}}
|
||||
>
|
||||
{`${this.loading1 ? '关闭' : '开启'}`}加载动画
|
||||
</NButton>
|
||||
</NFlex>
|
||||
<div class="chart--container">
|
||||
<RChart
|
||||
@ -275,6 +290,7 @@ const Echart = defineComponent({
|
||||
options={this.baseLineOptions}
|
||||
showAria={this.chartAria}
|
||||
preset="card"
|
||||
loading={loading1}
|
||||
/>
|
||||
</div>
|
||||
</NCard>
|
||||
@ -283,7 +299,7 @@ const Echart = defineComponent({
|
||||
<NFlex>
|
||||
<NButton
|
||||
onClick={() => {
|
||||
if (isDispose2()) {
|
||||
if (isDisposed2()) {
|
||||
render2()
|
||||
} else {
|
||||
window.$message.warning('不可以重复渲染图表~')
|
||||
|
@ -27,6 +27,8 @@ import { getStorage } from '@/utils'
|
||||
import { useVueRouter } from '@/hooks'
|
||||
import { APP_CATCH_KEY } from '@/app-config'
|
||||
|
||||
import type { ResultProps } from 'naive-ui'
|
||||
|
||||
const PageResult = defineComponent({
|
||||
name: 'PageResult',
|
||||
props: {
|
||||
@ -56,7 +58,7 @@ const PageResult = defineComponent({
|
||||
return (
|
||||
<div class="error-page">
|
||||
<NResult
|
||||
{...this.$props}
|
||||
{...(this.$props as ResultProps)}
|
||||
status="500"
|
||||
title="404 资源不存在"
|
||||
description="小调皮你走错地方了"
|
||||
|
@ -91,6 +91,7 @@ export default defineComponent({
|
||||
type="password"
|
||||
showPasswordOn="click"
|
||||
placeholder={$t('views.login.index.PasswordPlaceholder')}
|
||||
onKeydown={(e) => e.key === 'Enter' && this.handleLogin()}
|
||||
/>
|
||||
</NFormItem>
|
||||
<NButton
|
||||
|
2
unplugin/components.d.ts
vendored
2
unplugin/components.d.ts
vendored
@ -1,10 +1,10 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
|
Loading…
x
Reference in New Issue
Block a user