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$/]
|
||||
}),
|
||||
vueJsx(),
|
||||
vue3SvgPlugin(),
|
||||
vue3SvgPlugin({
|
||||
defaultImport: 'component',
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
removeViewBox: false
|
||||
}
|
||||
}
|
||||
},
|
||||
'prefixIds'
|
||||
]
|
||||
}
|
||||
}),
|
||||
importPlugin([
|
||||
{
|
||||
libraryName: '@opentiny/vue'
|
||||
|
|
|
@ -29,7 +29,21 @@ export default defineConfig((config) => {
|
|||
include: [/\.vue$/, /\.md$/]
|
||||
}),
|
||||
scriptSetupPlugin(),
|
||||
vue2SvgPlugin(),
|
||||
vue2SvgPlugin({
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
removeViewBox: false
|
||||
}
|
||||
}
|
||||
},
|
||||
'prefixIds'
|
||||
]
|
||||
}
|
||||
}),
|
||||
importPlugin({
|
||||
options: [
|
||||
{
|
||||
|
|
|
@ -36,7 +36,22 @@ export default defineConfig((config) => {
|
|||
include: [/\.vue$/, /\.md$/]
|
||||
}),
|
||||
vue3JsxPlugin(),
|
||||
vue3SvgPlugin(),
|
||||
vue3SvgPlugin({
|
||||
defaultImport: 'component',
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
removeViewBox: false
|
||||
}
|
||||
}
|
||||
},
|
||||
'prefixIds'
|
||||
]
|
||||
}
|
||||
}),
|
||||
importPlugin([
|
||||
{
|
||||
libraryName: '@opentiny/vue'
|
||||
|
|
|
@ -80,9 +80,15 @@
|
|||
"type": "component",
|
||||
"exclude": false,
|
||||
"mode": [
|
||||
"mobile-first",
|
||||
"pc"
|
||||
]
|
||||
},
|
||||
"AnchorMobileFirst": {
|
||||
"path": "vue/src/anchor/src/mobile-first.vue",
|
||||
"type": "template",
|
||||
"exclude": false
|
||||
},
|
||||
"AnchorPc": {
|
||||
"path": "vue/src/anchor/src/pc.vue",
|
||||
"type": "template",
|
||||
|
@ -1464,6 +1470,11 @@
|
|||
"type": "template",
|
||||
"exclude": false
|
||||
},
|
||||
"Hooks": {
|
||||
"path": "vue-hooks/index.ts",
|
||||
"type": "module",
|
||||
"exclude": false
|
||||
},
|
||||
"Hrapprover": {
|
||||
"path": "vue/src/hrapprover/index.ts",
|
||||
"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 { useBreakpoint } from './breakpoint'
|
||||
import { useDefer } from './usedefer'
|
||||
import { GRADIENT_ICONS_LIST, generateIcon } from './generateIcon'
|
||||
|
||||
import { useInstanceSlots as createUseInstanceSlots } from '@opentiny/vue-renderless/common/deps/useInstanceSlots'
|
||||
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
|
||||
}
|
||||
|
||||
// 解决多个相同的渐变图标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({
|
||||
component,
|
||||
props: mergeProps,
|
||||
|
|
Loading…
Reference in New Issue