Reputation: 68680
<template>
<div>
<template v-if="isFieldsetElement">
<fieldset>
<legend>Label Here</legend>
</template>
<template v-else>
<label>Label Here</label>
</template>
<span> Description </span>
<img src="image.png" />
<div>more stuff here </div>
<template v-if="isFieldsetElement">
</fieldset>
</template>
</div>
</template>
I'm unable to do this tag separation. Basically I have a separate header
and footer
(for the lack of better word) but I can't do this in Vue like its possible in server-side generated markup.
Is there a workaround or a more elegant solution for this issue?
Upvotes: 1
Views: 1018
Reputation: 68680
Using Dynamic Components:
<component :is="isFieldsetElement ? 'fieldset' : 'div'">
<component :is="isFieldsetElement ? 'legend' : 'label'">
<span> Description </span>
<img src="image.png" />
<div>more stuff here </div>
</component>
</component>
Upvotes: 3
Reputation: 624
The output for PHP is a string, so you can set it like '' + 'hello' + '', but for JS framework, them used HTMLElement, so you can't do same thing here. I think you need to get used to using the component, also PHP. Example:
<?php
class View() {
public $header; public $footer; public $content;
}
$view = new View(); $view->header = 'Hello';...
?>
<html>
<body>
<header>
<?php echo $view->header?>
</header>
<div id="root">
<?php echo $view->content?>
</div>
<footer>
<?php echo $view->footer?>
</footer>
</body>
</html>
For above source, header, footer, content both mean one component, and the content usually has many child component.
So, tag separation never a good solution, include PHP template.
<template>
<div>
<template v-if="isFieldsetElement">
<fieldset>
<legend>Label Here</legend>
<span> Description </span>
<img src="image.png" />
<div>more stuff here </div>
</fieldset>
</template>
<template v-else>
<label>Label Here</label>
<span> Description </span>
<img src="image.png" />
<div>more stuff here </div>
</template>
</div>
</template>
or the other way same as your did in php:
var app = new Vue({data:{html:'<div>Hello</div>'}});
<template v-html="html"></template>
Upvotes: 1
Reputation: 164832
I'm unable to do this tag separation
That's right because Vue works with a complete document model so you cannot put together elements by parts
I'd go with a custom wrapping component. Something like...
<template>
<div> <!-- single root element required -->
<fieldset v-if="wrap">
<legend>{{ label }}</legend>
<slot></slot>
</fieldset>
<template v-else>
<label>{{ label }}</label>
<slot></slot>
</template>
</div>
</tenmplate>
<script>
export default {
name: 'FieldWrapper',
props: {
wrap: Boolean,
label: String
}
}
</script>
and use it like
<FieldWrapper :wrap="isFieldsetElement" label="Label Here">
<span> Description </span>
<img src="image.png" />
<div>more stuff here </div>
</FieldWrapper>
There's a little repetition of the <slot>
within the component but for your use-case, I'd say that's acceptable.
Upvotes: 1