forked from opentiny/tiny-vue
fix(icon): solve the style problem caused by multiple identical ids o… (#2086)
* fix(icon): solve the style problem caused by multiple identical ids of gradient svg * fix: fix vue2 icon error * fix: fix reviews
This commit is contained in:
parent
2dcbfdbb82
commit
8b743d0c39
|
@ -70,7 +70,22 @@ export default defineConfig((config) => {
|
||||||
include: [/\.vue$/, /\.md$/]
|
include: [/\.vue$/, /\.md$/]
|
||||||
}),
|
}),
|
||||||
vueJsx(),
|
vueJsx(),
|
||||||
vue3SvgPlugin(),
|
vue3SvgPlugin({
|
||||||
|
defaultImport: 'component',
|
||||||
|
svgoConfig: {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'preset-default',
|
||||||
|
params: {
|
||||||
|
overrides: {
|
||||||
|
removeViewBox: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'prefixIds'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}),
|
||||||
importPlugin([
|
importPlugin([
|
||||||
{
|
{
|
||||||
libraryName: '@opentiny/vue'
|
libraryName: '@opentiny/vue'
|
||||||
|
|
|
@ -29,7 +29,21 @@ export default defineConfig((config) => {
|
||||||
include: [/\.vue$/, /\.md$/]
|
include: [/\.vue$/, /\.md$/]
|
||||||
}),
|
}),
|
||||||
scriptSetupPlugin(),
|
scriptSetupPlugin(),
|
||||||
vue2SvgPlugin(),
|
vue2SvgPlugin({
|
||||||
|
svgoConfig: {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'preset-default',
|
||||||
|
params: {
|
||||||
|
overrides: {
|
||||||
|
removeViewBox: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'prefixIds'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}),
|
||||||
importPlugin({
|
importPlugin({
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,22 @@ export default defineConfig((config) => {
|
||||||
include: [/\.vue$/, /\.md$/]
|
include: [/\.vue$/, /\.md$/]
|
||||||
}),
|
}),
|
||||||
vue3JsxPlugin(),
|
vue3JsxPlugin(),
|
||||||
vue3SvgPlugin(),
|
vue3SvgPlugin({
|
||||||
|
defaultImport: 'component',
|
||||||
|
svgoConfig: {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'preset-default',
|
||||||
|
params: {
|
||||||
|
overrides: {
|
||||||
|
removeViewBox: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'prefixIds'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}),
|
||||||
importPlugin([
|
importPlugin([
|
||||||
{
|
{
|
||||||
libraryName: '@opentiny/vue'
|
libraryName: '@opentiny/vue'
|
||||||
|
|
|
@ -80,9 +80,15 @@
|
||||||
"type": "component",
|
"type": "component",
|
||||||
"exclude": false,
|
"exclude": false,
|
||||||
"mode": [
|
"mode": [
|
||||||
|
"mobile-first",
|
||||||
"pc"
|
"pc"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"AnchorMobileFirst": {
|
||||||
|
"path": "vue/src/anchor/src/mobile-first.vue",
|
||||||
|
"type": "template",
|
||||||
|
"exclude": false
|
||||||
|
},
|
||||||
"AnchorPc": {
|
"AnchorPc": {
|
||||||
"path": "vue/src/anchor/src/pc.vue",
|
"path": "vue/src/anchor/src/pc.vue",
|
||||||
"type": "template",
|
"type": "template",
|
||||||
|
@ -1464,6 +1470,11 @@
|
||||||
"type": "template",
|
"type": "template",
|
||||||
"exclude": false
|
"exclude": false
|
||||||
},
|
},
|
||||||
|
"Hooks": {
|
||||||
|
"path": "vue-hooks/index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"exclude": false
|
||||||
|
},
|
||||||
"Hrapprover": {
|
"Hrapprover": {
|
||||||
"path": "vue/src/hrapprover/index.ts",
|
"path": "vue/src/hrapprover/index.ts",
|
||||||
"type": "component",
|
"type": "component",
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { isVue2 } from './adapter'
|
||||||
|
|
||||||
|
export const GRADIENT_ICONS_LIST = ['IconLoadingShadow', 'IconNoData']
|
||||||
|
let uniqueId = 0
|
||||||
|
|
||||||
|
const generateId = (vnode, idMaps) => {
|
||||||
|
if (isVue2) {
|
||||||
|
if (vnode.data?.attrs?.id) {
|
||||||
|
const newId = `${vnode.data.attrs.id}${uniqueId}`
|
||||||
|
idMaps[vnode.data.attrs.id] = newId
|
||||||
|
vnode.data.attrs.id = newId
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vnode.props?.id) {
|
||||||
|
const newId = `${vnode.props.id}${uniqueId}`
|
||||||
|
idMaps[vnode.props.id] = newId
|
||||||
|
vnode.props.id = newId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vnode?.children) {
|
||||||
|
vnode.children.forEach((item) => {
|
||||||
|
generateId(item, idMaps)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateUrl = (vnode, idMaps) => {
|
||||||
|
const checkList = ['fill', 'mask', 'filter']
|
||||||
|
|
||||||
|
checkList.forEach((item) => {
|
||||||
|
if (isVue2) {
|
||||||
|
if (vnode.data?.attrs?.[item]?.includes('url(#')) {
|
||||||
|
const oldId = vnode.data.attrs[item].replace('url(#', '').replace(')', '')
|
||||||
|
const newId = idMaps[oldId]
|
||||||
|
if (newId) {
|
||||||
|
vnode.data.attrs[item] = `url(#${newId})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vnode.props?.[item]?.includes('url(#')) {
|
||||||
|
const oldId = vnode.props[item].replace('url(#', '').replace(')', '')
|
||||||
|
const newId = idMaps[oldId]
|
||||||
|
if (newId) {
|
||||||
|
vnode.props[item] = `url(#${newId})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (vnode.children) {
|
||||||
|
vnode.children.forEach((item) => {
|
||||||
|
generateUrl(item, idMaps)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateIcon = (vnode) => {
|
||||||
|
if (!vnode) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 映射老的id和新id的哈希表
|
||||||
|
const idMaps = {}
|
||||||
|
|
||||||
|
generateId(vnode, idMaps)
|
||||||
|
generateUrl(vnode, idMaps)
|
||||||
|
uniqueId++
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import '@opentiny/vue-theme/base/index.less'
|
||||||
import { defineComponent, isVue2, isVue3 } from './adapter'
|
import { defineComponent, isVue2, isVue3 } from './adapter'
|
||||||
import { useBreakpoint } from './breakpoint'
|
import { useBreakpoint } from './breakpoint'
|
||||||
import { useDefer } from './usedefer'
|
import { useDefer } from './usedefer'
|
||||||
|
import { GRADIENT_ICONS_LIST, generateIcon } from './generateIcon'
|
||||||
|
|
||||||
import { useInstanceSlots as createUseInstanceSlots } from '@opentiny/vue-renderless/common/deps/useInstanceSlots'
|
import { useInstanceSlots as createUseInstanceSlots } from '@opentiny/vue-renderless/common/deps/useInstanceSlots'
|
||||||
import { useRelation as createUseRelation } from '@opentiny/vue-renderless/common/deps/useRelation'
|
import { useRelation as createUseRelation } from '@opentiny/vue-renderless/common/deps/useRelation'
|
||||||
|
@ -282,6 +283,18 @@ export function svg({ name = 'Icon', component }) {
|
||||||
extend.nativeOn = context.listeners
|
extend.nativeOn = context.listeners
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解决多个相同的渐变图标svg中有相同id时,在display:none,情况下导致的样式异常问题
|
||||||
|
if (GRADIENT_ICONS_LIST.includes(name)) {
|
||||||
|
const render = component.render
|
||||||
|
component.render = function (...args) {
|
||||||
|
// 指向正确的this对象,保证vue2运行正常
|
||||||
|
const newRender = render.bind(this)
|
||||||
|
const vnode = newRender(args)
|
||||||
|
generateIcon(vnode)
|
||||||
|
return vnode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return renderComponent({
|
return renderComponent({
|
||||||
component,
|
component,
|
||||||
props: mergeProps,
|
props: mergeProps,
|
||||||
|
|
Loading…
Reference in New Issue