I want to draw a line in an SVG. This line must be vertical and its length must correspond to the height of the SVG that contains it. As the SVG is responsive I can't use pixel coordinates. Instead I put a rect of width 1px and height 100%. The problem is that when I try to position it on the x axis in relation to a reference, Vue.js gives me an error, (even though it works: the result)
Error: Invalid value for <rect> attribute x="calc( 100% / 5 * 2 )"
The problem comes from:
:x="'calc( 100% / ' props.max ' * ' props.x ' )'"
Code
<script setup lang="ts">
import { defineProps } from "vue";
const props = defineProps<{
x: number,
max: number
}>();
</script>
<template>
<rect :x="'calc( 100% / ' props.max ' * ' props.x ' )'" />
</template>
<style scoped>
rect {
width: 1px;
height: 100%;
stroke: none;
fill: #000000;
}
</style>
I also tried
<script setup lang="ts">
import { defineProps, Ref, ref, onMounted } from "vue";
const props = defineProps<{
x: number,
max: number
}>();
const vertical_line: Ref<HTMLElement | null> = ref(null);
onMounted(() => {
vertical_line.value?.focus();
if (vertical_line.value !== null && typeof vertical_line.value === "object" &&
"setAttribute" in vertical_line.value)
vertical_line.value
.setAttribute("x", "calc( 100% / " props.max " * " props.x " )");
});
</script>
<template>
<rect ref="vertical_line" />
</template>
<style scoped>
rect {
width: 1px;
height: 100%;
stroke: none;
fill: #000000;
}
</style>
CodePudding user response:
Looks like your code works, maybe wrong props?
const { ref } = Vue
const app = Vue.createApp({
setup() {
const x = ref(6)
const max = ref(30)
return { x, max }
}
})
app.component('lineI', {
template: `
<rect :x="'calc( 100% / ' max ' * ' x ' )'" />
`,
props: {
x: { type: Number },
max: { type: Number }
},
})
app.mount('#demo')
rect {
width: 1px;
height: 100%;
stroke: none;
fill: #000000;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
<svg>
<line-i :x="x" :max="max"></line-i>
</svg>
<br>
<input type="number" v-model="x" />
<input type="number" v-model="max" />
</div>