0

I'm getting several SVG's that are all structured like this:

<?xml version="1.0" encoding="utf-8"?>
<svg>
    ...
    <g id="cabin">
        <g id="1">
            <g id="a">
                <rect />
                <path />
            </g>
            <g id="b">
                <rect />
                <path />
            </g>
        </g>
        <g id="2">
            <g id="a">
                <rect />
                <path />
            </g>
            <g id="b">
                <rect />
                <path />
            </g>
        </g>
        ...
    </g>
</svg>

I'm loading the SVG via the html-loader

<div ref="plan" v-html="require('!html-loader!../assets/plaene/plan_1.svg')"></div>

I'm trying to access all child notes of cabin to change the style of the rect items. How should I do this? I tried this before in a single html-file with plain javascript

var plan = document.getElementById("plan");
plan.addEventListener("load",function() {
    dom = plan.contentDocument;
    let cabins = dom.getElementById('cabin');
    ...
    and so on

but I don't know how to do this in vue. I have read some articles (e.g. VueJS — Tips & Best Practices) which say that you shold avoid manipulating the DOM directly, so I guess there must be something else.

Has somebody a solution for this? Thank you in advance!

Matthias
  • 3,729
  • 22
  • 37
  • Is it an option to create the SVGs dynamically as Vue components instead of loading them from files? This way, you could render your SVG dynamically using Vue's reactivity. Would give you a lot more flexibility regarding the styling. Example: https://codesandbox.io/s/stack-overflow-q-59031887-z6kd2 – wwerner Nov 25 '19 at 12:58
  • Hey @wwerner, thanks for your answer. The problem is that I'm getting the SVG's from an external source. In your example you already add `attributes` like `width` or `heigth` as `props` in the component, which I am missing in my predetermined SVG's. I need to access the `` and `` somehow, to add my styles. – Matthias Nov 25 '19 at 14:38

1 Answers1

0

I ended up doing this:

let numbers = [1, 2]
let g_tags = this.$el.getElementsByTagName('g')

let svg_root
g_tags.forEach(el => {
    if(el.getAttribute('id') === 'cabin') {
        svg_root = el
    }
})

svg_root.children.forEach(obj => {
     let id = obj.getAttribute('id')

     if (numbers.includes(parseInt(id))) {
         obj.firstElementChild.firstElementChild.setAttribute("style", "fill: green")
         obj.lastElementChild.firstElementChild.setAttribute("style", "fill: green")  
     }
})

I guess by using this.$el I access the virtual and not the real DOM, so it should be "legal". Please let me know if I'm wrong and there is a better solution.

Matthias
  • 3,729
  • 22
  • 37