HTML element could not work in vue js file - vue.js

I am trying to add header division to my vue.js template. but i could not add html tags into the header file. please check my files
App.vue
<template>
<div class="app">
<!-- Sidebar -->
<Header>
</Header>
<Sidebar />
<!-- Content -->
<router-view />
</div>
</template>
<script setup>
import Header from './components/Header.vue'
import Sidebar from './components/Sidebar.vue'
</script>
Header.vue
<div class="page-header">
<ul>
<li>Home</li>
<li>About us</li>
</ul>
</div>
above unorder list consider as a invalid elements. but div tag is valid. Please check the below error during compile
can you help me to solve this problem

maybe miss <template> tag in Header.vue

Related

Nuxtjs Sidebar routing

I'm working on a simple dashboard. trying to make a sidebar static and just the main section dynamic.
Successfully made the sidebar static but the elements on the new page route of the nuxt link appear under the sidebar instead of the main page section.
PS. I'm using bulma as my CSS framework.
Here's the side bar code.
<template>
<div class="ml-6 mt-6">
<div class="columns is-gapless">
<div class="column is-one-fifth">
<aside class="menu">
<ul class="menu-list">
<li class="py-4">
<NuxtLink to="/dashboard">
Dashboard
</NuxtLink>
</li>
<li class="py-4">
<NuxtLink to="/clients">
Clients
</NuxtLink>
</li>
<li class="py-4">
<NuxtLink to="/projects">
Projects
</NuxtLink>
</li>
<li class="py-4">
<NuxtLink to="/invoice">
Invoice
</NuxtLink>
</li>
<li class="py-4">
<a>Proposal</a>
</li>
</ul>
</aside>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SideBar'
}
</script>
And here's the code for one of the pages I'm trying to route to.
<template>
<div>
<h1>
Testing Clients
</h1>
</div>
</template>
<script>
export default {
name: 'ClientS',
layout: 'sidebar'
}
</script>
enter image description here
what do I do to make the contents on the pages show up in the main section area instead of under the sidebar?
Include a <Nuxt /> component in the sidebar layout. It indicates where the page's content is loaded. Learn more on it from the docs.
You need to create a layout file named sidebar in the layouts directory. In this file, you can put your sidebar component and <Nuxt/> component as your page content.
This is the simple example:
/layouts/sidebar.vue
<div>
<Sidebar />
<div>
<Nuxt />
</div>
</div>
In the simplest case, you need three files in nuxt project.
layout file
in /layout/... directory.
the defualt.vue not require to add to project and used by default.
is where the pages run.
page file
in /pages/... directory.
any .vue files in this directory use default.vue layout by default.
component of sidebar or any layout file
in /components/... directory
use can create any .vue file in this directory and use it in layout or page file with syntax
example of layout file with bluma:
(create PanelNavbar and PanelSidebar component With your own taste.)
<template>
<div>
<div class="header has-background-white is-flex is-justify-content-flex-end" >
<PanelNavbar />
</div>
<section class="main-content is-flex is-justify-content-center">
<PanelSidebar />
<div class="column px-0 pt-0">
<div class="navbar header has-background-dark is-flex is-justify-content-flex-end">
</div>
<nuxt />
</div>
</section>
</div>
</template>

Separating start and end tags for conditional rendering

<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?
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>
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.
JSFiddle Demo
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>

Vue add or remove enclosing div

I have a html structure like this:
<template>
<div>
<div class="container">
<somecontent>
<someothercontent>
</div>
</div>
</template>
However, depending on the layout, I want to remove the container div so the structure looks like this:
<template>
<div>
<somecontent>
<someothercontent>
</div>
</template>
Note that the div is completely added or removed, not just the class name. v-if doesn't work here because it would also show or hide the content that is enclosed by the div. What's the simplest solution for that?
You can use
v-if ... v-else
<template>
<div v-if="condition">
<div class="container">
<somecontent>
<someothercontent>
</div>
</div>
<div v-else>
<somecontent>
<someothercontent>
</div>
</template>

Vue bypass html into sub-sub component

Lets say, I have the following vuejs structure:
<!-- MainComponent.vue -->
<template>
<childcomponent></childcomponent>
</template>
<!-- ChildComponent.vue -->
<template>
<div>
<grandchild></grandchild>
</div>
</template>
<!-- GrandchildComponent.vue -->
<template>
<div>
FooBar
<slot name="actions"></slot>
</div>
</template>
If I want to set a value for the grandchild-slot "actions" in the child-component, I have to do this:
<!-- ChildComponent.vue -->
<template>
<div>
<grandchild>
<template slot="actions">Actions from ChildComponent</template>
</grandchild>
</div>
</template>
But how to bypass "actions" from the MainComponent? I tried this, but thats not working:
<!-- MainComponent.vue -->
<template>
<childcomponent>
<template slot="actions" slot-scope="props">
Actions from MainComponent
</template>
</childcomponent>
</template>
<!-- ChildComponent.vue -->
<template>
<div>
<grandchild>
<slot name="actions">
<template slot="actions" slot-scope="props">
Actions from ChildComponent
</template>
</slot>
</grandchild>
</div>
</template>
After a lot of research, I think the only possible way of doing it, is only over the render function (https://v2.vuejs.org/v2/guide/render-function.html).
The main idea behind it is to write instead of html templates for ChildComponent.vue and GrandchildComponent.vue custom render functions.
A complete tutorial for a similar usecase can be found here:
https://github.com/ratiw/vuetable-2-tutorial/wiki

Adding a content inside of a vue component

I have a vue component Jumbotron.vue:
<template lang="html">
<div class="jumbotron" style="border-radius:0px; color:#fff;">
<div class="container">
</div>
</div>
</template>
And other page component Main.vue:
<template>
<div class="root">
<navbar></navbar>
<jumbotron>
<h1 class="display-4">I want to add here, to the jumbotron's div container some h1 and paragraph</h1>
<p class="lead ">Like this paragraph</p>
</jumbotron>
<words></words>
</div>
</template>
But i cant add content to the jumbotron, because its wrong. I dont want to add content(p and h1) inside of the Jumbotron.vue, because i want to use Jumbotron.vue more than 1 time with different content inside it. Is this possible?
This is done with slots.
<template lang="html">
<div class="jumbotron" style="border-radius:0px; color:#fff;">
<div class="container">
<slot></slot>
</div>
</div>
</template>
Everything you put inside the jumbotron component in the parent will be rendered in the slot.