pass component according to v-if - Vue.JS - javascript

I am trying to create a parent component with all kinds of graphics, and depending on what I need to pass on a specific graphic (raise a child) to another component, but I don't necessarily know how I would dynamically do it for the user.
my html charts (chart.vue)
<template>
<div >
<bars v-if="type == 'bar'">
<div class="row gutter-sm">
<div class="col-md-3">
<apexchart ref="chart1" type="bar" :options="options" :series="updatedData"></apexchart>
</div>
</div>
<div class="col-md-3">
<apexchart ref="chart3" type="bar" :options="options3" :series="updatedData"></apexchart>
</div>
</bars>
<lines v-if="type == 'line'">
<div class="row gutter-sm">
<div class="col-md-3">
<apexchart ref="chart4" type="line" :options="options4" :series="updatedData"></apexchart>
</div>
</div>
</lines>
</div>
<template>
If I wanted to pass on bar graphics to my menu.vue, would it be like this?
my html menu
<template>
<div >
<table class="data-table-2" style="min-width: 800px">
<charts type="bar"/>
</table>
</div>
<template>
scripts menu
<script>
import charts from "./charts.vue"
export default {
name: 'menu',
components: {
charts
}
}
</script>

The way you pass values from the parent component to the child component is wrong
<template>
<div >
<table class="data-table-2" style="min-width: 800px">
<charts :type='bar'/>
<charts :type='line'/>
<charts />
</table>
</div>
<template>
child component receiving value, and you can set a default value:
// init in child component
props: {
type: {
type: String,
default: 'bar' // set a default value
}
},
data(){
...
}
then you can use type in child component
<template>
<div >
<bars v-if"type == 'bar'">
<div class="row gutter-sm">
<div class="col-md-3">
<apexchart ref="chart1" type="bar" :options="options" :series="updatedData"></apexchart>
</div>
</div>
<div class="col-md-3">
<apexchart ref="chart3" type="bar" :options="options3" :series="updatedData"></apexchart>
</div>
</bars>
<lines v-if"type == 'line'">
<div class="row gutter-sm">
<div class="col-md-3">
<apexchart ref="chart4" type="line" :options="options4" :series="updatedData"></apexchart>
</div>
</div>
</lines>
</div>
<template>

You need to define a Props in child component.
//Child Component Script
export default ChildComponent {
data() {
return {}
},
props: {
type: string,
}
}
In parent component you need to call child component and pass type data like this
//parent component
<template>
<div>
<child-component :type="line"/>
</div>
</template>

Related

How to replace parent view with child route component in Vue

I have a Vue routes setup with the following parent and child routes:
{
path: '/dashboard', component: dashboard,
children: [
{
path:'report', component: report
}
]
},
And in the parent component I have some card menus to navigate to the child component and also a router-view:
<template>
<div class="container mt-5">
<div class="row mt-0 h-100">
<!-- menu item-->
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 my-auto" id="report-card">
<router-link to="/dashboard/report" class="card2">
<div class="d-flex flex-column justify-content-center">
<div class="card-icon p-3">
<img :src="icons[0]"/>
</div>
<h3>Make a Report</h3>
<p class="small">Make a report of a crime or suspicious activities</p>
</div>
</router-link>
</div>
</div>
<router-view></router-view>
</div>
</template>
When I click on the router link, it does render the child component, but in the parent view.
Is there a way in which I could replace the parent view entirely with the child route instead of rendering or appending to the parent?
I am not sure if this is the right way to do it but you can use v-if with this.$route.name to check router name and render what you want to render.
For example your router will be like:
{
path: '/dashboard',
name: "Dashboard",
component: dashboard,
children: [
{
path:'report',
name: "Report",
component: report
}
]
},
and you can simply check if you are on parent route or not like this:
<template>
<div>
<div v-if="this.$route.name === 'Dashboard' ">
<!-- your homepage component -->
</div>
<router-view></router-view>
</div>
</template>

React - How to resolve: "JSX expression must have parent and expression expected" error in vs code

I have a simple App.js file which is rendering fine in the browser but I am getting some problems or errors in the VS code editor.
I am getting these errors -
My App.js:
import React, { Component } from "react";
import css from "./App.less";
import DonutChart from "./DonutChart";
import TimeLineChart from "./TimeLineChart";
import DataTable from "./DataTable";
import SidebarSample from "./SidebarSample";
class App extends Component {
constructor(props) {
super(props);
}
render() {
let panelLeftCss = css.panel;
panelLeftCss += " " + css.leftPanel;
let panelRightCss = css.panel;
panelRightCss += " " + css.rightPanel;
return (
<div>
<div className="header">
<div>
<h1>Welcome Admin, My Dashboard</h1>
</div>
</div>
<div>
<SidebarSample />
</div>
<div className={css.main}>
<div className={panelLeftCss}>
<div className={css.panelHeader}>Donut Chart</div>
<div className={css.panelBody}>
<div>
<DonutChart />
</div>
</div>
</div>
<div className={panelRightCss}>
<div className={css.panelHeader}>Line Chart</div>
<div className={css.panelBody}>
<div>
<TimeLineChart />
</div>
</div>
</div>
</div>
<div>
<div className={css.panelHeader}>Data Table</div>
<div>
<DataTable />
</div>
</div>
</div>
);
}
}
export default App;
I have tried to add a <React.Fragment> also but it's not resolving the errors in the VS code editor.
Is there any tool that I can use which solves this automatically, like prettier etc?
Please guide me.
Prettier or any other code formatting tools won't help you if you do not enclose your div with tags properly.
You forgot your closing </div> tag at the end of your code.
Also you have an extra </div> tag near your <TimeLineChart> there.
Check the formatted codes here as below. It should work.
You just need to be more careful in placing the tags.
<div>
<div className="header">
<div>
<h1>Welcome Admin, My Dashboard</h1>
</div>
</div>
<div>
<SidebarSample />
</div>
<div className={css.main}>
<div className={panelLeftCss}>
<div className={css.panelHeader}>Donut Chart</div>
<div className={css.panelBody}>
<div>
<DonutChart />
</div>
</div>
</div>
<div className={panelRightCss}>
<div className={css.panelHeader}>Line Chart</div>
<div className={css.panelBody}>
<div>
<TimeLineChart />
</div>
</div>
</div>
<div>
<div className={css.panelHeader}>Data Table</div>
<div>
<DataTable />
</div>
</div>
</div>
</div>
Check your file extension its .ts
It must be .tsx(if you're using TypeScript)
Same for App.js change it to App.jsx (if you're using JavaScript)
then,
try this,
all your code must be in single parent tag, like i did inside <div>
as when render method returns only single parent, so you must careful while writing elements having only one parent or you wrap your code inside parent <div>
import React, { Component } from "react";
import css from "./App.less";
import DonutChart from "./DonutChart";
import TimeLineChart from "./TimeLineChart";
import DataTable from "./DataTable";
import SidebarSample from "./SidebarSample";
class App extends Component {
constructor(props) {
super(props);
}
render() {
let panelLeftCss = css.panel;
panelLeftCss += " " + css.leftPanel;
let panelRightCss = css.panel;
panelRightCss += " " + css.rightPanel;
return (
<div>
<div className="header">
<div>
<h1>Welcome Admin, My Dashboard</h1>
</div>
</div>
<div>
<SidebarSample />
</div>
<div className={css.main}>
<div className={panelLeftCss}>
<div className={css.panelHeader}>Donut Chart</div>
<div className={css.panelBody}>
<div>
<DonutChart />
</div>
</div>
</div>
<div className={panelRightCss}>
<div className={css.panelHeader}>Line Chart</div>
<div className={css.panelBody}>
<div>
<TimeLineChart />
</div>
</div>
</div>
<div>
<div className={css.panelHeader}>Data Table</div>
<div>
<DataTable />
</div>
</div>
</div>
</div>
);
}
}
export default App;

How to pass a dynamic variable to a 'component' and then display it - VueJS

I can not display a variable (which is the link of an image) in my component I am lost ...
(To help you, I'm in a table and click on the icon that opens a pdf)
Thanks you !
Vue.component('modal', {
template: '#modal-template-pdf',
props: {
lien: String
}
});
let appCompta = new Vue({
data: {
showModalActive: false,
currentModalPdfLink: '',
}
}).$mount('#'+id+' #app-compta')
<img slot="apercu" slot-scope="props" class="iconeged main" src="images/ico_pdf.png"
v-bind:currentModalPdfLink='props.row.imglien'
#click="showModalActive = true"
>
<modal v-if="showModalActive" #close="showModalActive = false" v-bind:lien="currentModalPdfLink">
<h3 slot="header">Aperçu PDF</h3>
</modal>
<script type="text/x-template" id="modal-template-pdf">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
default header
</slot>
</div>
<div class="modal-body">
<slot name="body">
{{currentModalPdfLink}}
<iframe height='100%' width='100%' frameborder='0' :src="currentModalPdfLink"/>
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
<button class="modal-default-button" #click="$emit('close')">
FERMER
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>
I assume that currentModalPdfLink is your pdf-link?
The name of the prop that you are passing is src so you need to refer to it in your component with the same name:
Vue.component('modal', {
template: '#modal-template-pdf',
props: ['src']
});

Dynamically add a child component in Vue JS

I need some help in Vue JS and Laravel with adding a child vue component.
I have a parent component called "wrapper" and some child components called like "show-1", "show-2", "show-3" ... etc.
Parent component:
<template>
<div class="card border-light">
<div class="card-header">
<h5 class="title">{{ title }}</h5>
</div>
<div class="card-body">
<component
is="view"
></component >
</div>
<div class="card-footer"></div>
</div>
</template>
<script>
export default {
props : ['title'],
data() {
return {
view : ''
}
}
}
</script>
An exmaple child component like "show-1":
<template>
<div> show-1 </div>
</template>
This code below is in blade for rendering wrapper component with a dynamic child component name:
<wrapper
title="Example"
view="show-1"
></wrapper>
This code is not working but if i change the parent view data "show-1" instead of empty, it works. why ?
When I change the view prop, child vue component should be changed too. How could I do this ?
I want to pass the view attribute to parent component dynamically.
You can use :is attribute. You can read more about it here:
https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components
You can use the same mount point and dynamically switch between
multiple components using the reserved element and
dynamically bind to its is attribute....
<template>
<div class="card border-light">
<div class="card-header">
<h5 class="title">{{ title }}</h5>
</div>
<div class="card-body">
<!-- make sure to use : -->
<component v-if="view" :is="view"></component >
</div>
<div class="card-footer"></div>
</div>
</template>
<script>
export default {
props : ['title'],
data() {
return {
view : ''
}
}
}
</script>
#Eduardo has the right answer. To add to it, import your components into the parent and switch between them via a data property:
...
<component :is="current"></component >
...
data: {
current: 'show1'
},
components: {
show1: Show1Component,
show2: Show2Component,
show3: Show3Component
}
The key is to bind the component using the name of the dynamic component.
https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components

Unable to access vue data in basic modal

I am trying to loop and reference vue data values within a modal and am getting an error that the field needs to be reactive, despite the values being provided in the component initialization. Any idea why this is?
Fiddle:
https://jsfiddle.net/mwLbw11k/2618/
JS
// register modal component
Vue.component('modal', {
template: '#modal-template'
})
// start app
new Vue({
el: '#app',
data: {
myData: [{'first': 'Matt', 'last': 'Smith'}, {'first': 'Tom', 'last': 'Brady'}],
showModal: false
}
})
HTML
<script type="text/x-template" id="modal-template">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
default header
</slot>
</div>
<div class="modal-body">
<slot name="body">
<ul>
<li v-for="user in myData"> {{ user.first }} {{ user.last }}</li>
</ul>
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>
<!-- app -->
<div id="app">
<button id="show-modal" #click="showModal = true">Show Modal</button>
<!-- use the modal component, pass in the prop -->
<modal v-if="showModal" #close="showModal = false">
</modal>
</div>
Vue Warning
[Vue warn]: Property or method "myData" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Yous should add myData to modal component props
Vue.component('modal', {
template: '#modal-template',
props: ['myData']
})
and then pass it from parent like this:
<modal v-if="showModal" :my-data="myData" #close="showModal = false">
</modal>
corrected demo from Bsalex
<modal v-if="showModal" :my-data="myData" #close="showModal = false">

Categories