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