Display Vuetify cards in a single row instead of a column? - javascript

I am using Vuetify 1.5 and Vuetify grid system to set up my layout. Now i have a component HelloWorld which i am importing into my Parent Component. I have set up the layout in my HelloWorld and i am trying to display my cards in a single row instead having all of them show up in a column. I am not sure what i am doing wrong here.
I have setup the <v-layout align-center justify-center row fill-height class="mt-5"> which should render it in one row.
Check out this working CodeSandbox.
I am not adding my Vuex store below since the problem is in the layout and not the data itself. The store is minimal and is in the link above.
This is my HellWorld Component:-
<template>
<v-layout align-center justify-center row fill-height class="mt-5">
<v-flex xs4>
<v-card class="mx-4">
<v-img :src="src"></v-img>
<v-card-title primary-title>
<div>{{title}}</div>
</v-card-title>
</v-card>
</v-flex>
</v-layout>
</template>
<script>
export default {
name: "HelloWorld",
props: {
title: String,
src: String,
id: Number
},
data() {
return {};
}
};
</script>
And this is my Parent component:-
<template>
<v-container>
<v-layout align-center justify-center row fill-height class="mt-5">
<h2>Parent Component</h2>
</v-layout>
<draggable v-model="draggableCards">
<template v-for="(tech,i) in getCardArray">
<HelloWorld :src="tech.src" :title="tech.title" :key="i"/>
</template>
</draggable>
</v-container>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
import HelloWorld from "./HelloWorld";
import draggable from "vuedraggable";
export default {
components: {
draggable,
HelloWorld
},
computed: {
...mapGetters({
getCardArray: "getCardArray"
}),
draggableCards: {
get() {
return this.$store.state.cardArray;
},
set(val) {
this.$store.commit("setCardArray", val);
}
}
},
methods: {
...mapMutations({
setCardArray: "setCardArray"
})
}
};
</script>
Basically i am trying to show the cards in a row instead of a column. Any help will be appreciated. Thank you :).

You are looping through <v-layout> this means you are creating a new line (layout) for each card. You need to take the layout out of the loop put in the parent and they will be more than one on one row.
Something like:
<draggable v-model="draggableCards">
<v-layout>
<template v-for="(tech,i) in getCardArray">
<HelloWorld :src="tech.src" :title="tech.title" :key="i"/>
</template>
</v-layout>
</draggable>
And remove from HelloWorld

Related

How to set parent component data from child component in vuejs

Below is the parent component and child component. I am trying to access tabs_value data in the parent component from the child component but it is returning as undefined.
this.$parent.tabs_value returns as undefined when I try to access it inside the run method in the child component.
Please help me find where I am going wrong? Below is the code
Parent Component
<template>
<div>
<v-layout row wrap>
<v-flex xs12 sm12 lg12>
<div>
<v-card>
<v-tabs v-model="tabs_value"
color="black"
centered
show-arrows
>
<v-toolbar-title>Custom</v-toolbar-title>
<v-spacer></v-spacer>
<v-tab href="#build">Build</v-tab>
<v-tab href="#run">Run</v-tab>
</v-tabs>
<v-tabs-items v-model="tabs_value">
<v-tab-item value="#build" id="build">
<Build ref="build_reports" />
</v-tab-item>
<v-tab-item value="#run" id="run">
<Run :reports="reports" ref="run_reports" />
</v-tab-item>
</v-tabs-items>
</v-card>
</div>
</v-flex>
</v-layout>
</div>
</template>
<script>
import Build from 'views/build.vue'
import Run from 'views/run.vue'
import URLs from 'views/routes'
export default {
components: {
Build,
Run
},
data: function() {
return {
tabs_value: 'build',
isLoaded: true,
reports: []
}
},
created() {
this.fetch();
},
methods: {
fetch() {
this.$axios.get(URLs.REPORTS_URL)
.then(response => {
this.reports = response.data
});
}
}
};
</script>
Child Component run.vue
<template>
<div>
<v-layout row wrap>
<v-flex xs12 sm12 lg12>
<div>
<v-card>
<div>
<v-data-table
:headers="headers"
:items="reports"
hide-default-footer
:mobile-breakpoint="0">
<template slot="item" slot-scope="props">
<tr>
<td>{{props.item.name}}</td>
<td>
<div>
<v-tooltip attach left>
<template v-slot:activator="{ on, attrs }">
<a v-bind="attrs" v-on="on"
class="" href='javascript:void(0);'
#click="run(props.item)"><i small slot="activator" dark color="primary" class="fas fa-play"></i></a>
</template>
<span>Run</span>
</v-tooltip>
</div>
</td>
</tr>
</template>
<template slot="no-data" >
<v-alert id='no-data' :value="true" color="error" icon="warning">
No Reports Yet
</v-alert>
</template>
</v-data-table>
</div>
</v-card>
</div>
</v-flex>
</v-layout>
</div>
</template>
<script>
import URLs from 'views/routes'
export default {
props: ['reports'],
data: function() {
return {
headers: [
{ text: 'Name', value: 'name', sortable: false },
{ text: 'Actions', sortable: false }
],
}
},
methods: {
run(report) {
debugger
// this.$parent.tabs_value returns as undefined
}
}
}
</script>
you can use component events i.e $emit.
Below is example which will tell you how to use $emit. (https://vuejs.org/guide/components/events.html#emitting-and-listening-to-events)
Parent Component
<template>
<ChildComponent #updateTabsValue="updateTabsValue"/>
</template>
<script>
export default {
data(){
return {
tabsValue: 'tabs',
};
},
methods:{
updateTabsValue(val){
this.tabsValue = val;
}
},
}
</script>
Child Component
<template>
<button #click="$emit('updateTabsValue','newVal')"/>
</template>

How to modify a child component's colour attribute from the parent in vue js

I have a child Card component:
<template>
<v-card
class="mx-auto"
max-width="500"
color=color
outlined
dark
>
<v-list-item three-line>
<v-list-item-content>
<div class="overline mb-4">
OVERLINE
{{color}}
</div>
<v-list-item-title class="headline mb-1">
Headline 5
</v-list-item-title>
<v-list-item-subtitle>Greyhound divisely hello coldly fonwderfully</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-avatar
tile
size="80"
color="grey"
></v-list-item-avatar>
</v-list-item>
<v-card-actions>
<v-btn
outlined
rounded
text
>
Button
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
name: 'Card',
props: {
color: String
}
}
</script>
And from the parent component I want to pass in the color to the child. A part of the parent component's code is shown below.
<template>
<Card v-bind:color="color"/>
</template>
<script>
export default {
data() {
return {
color: "#FFC400"
}
},
}
</script>
As you can see I tried to use a prop to pass the color from the parent to the child, however even though I'm able to pass the data to the child, {{color}} prints out #FFC400 I'm not sure how to assign the color value to the v-card's color attribute. How can I achieve this? Thank you.
The only thing missing is to also bind the prop to the color attribute of the <v-card>, otherwise it's only receiving the string "color", rather than the variable of that name.
You can use v-bind:color="color" or the shorthand :color="color"
<v-card
class="mx-auto"
max-width="500"
:color="color"
outlined
dark
>

Create static left navbar component with Vue

I need a vertical navbar to the left of my app's layout, and with the content all across the right.
As it stands, I can't do that. My navbar pushes all the content down. How can I fix this?
This is what my App.vue's template looks like:
<template>
<div id="app">
<v-app>
<navbar/>
<v-main>
<v-container class="main-container">
<router-view/>
</v-container>
</v-main>
</v-app>
</div>
</template>
For the navbar component I am using vuetify, specifically the mini navbar
As per the example code, here is what it currently looks like:
<template>
<v-navigation-drawer
v-model="drawer"
:mini-variant.sync="mini"
permanent
>
<v-list-item class="px-2">
<v-list-item-avatar>
<v-img src="https://randomuser.me/api/portraits/men/85.jpg"></v-img>
</v-list-item-avatar>
<v-list-item-title>John Leider</v-list-item-title>
<v-btn
icon
#click.stop="mini = !mini"
>
<v-icon>mdi-chevron-left</v-icon>
</v-btn>
</v-list-item>
<v-divider></v-divider>
<v-list dense>
<v-list-item
v-for="item in items"
:key="item.title"
link
>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
#Component<Navbar>({})
export default class Navbar extends Vue {
private value: string = 'home';
private drawer: boolean = true;
private items: Array<Object> = [
{ title: 'Home', icon: 'mdi-home-city' },
{ title: 'My Account', icon: 'mdi-account' },
{ title: 'Users', icon: 'mdi-account-group-outline' }
]
private mini: boolean = true;
}
</script>
As mentioned on the top, this is still just pushing all the app's content down. This is what it currently looks like:
What can I do so that on the left I have my navbar but on the right
Edit: For the sake of clarification, I do want the navbar to be vertical, but I just don't want it to push down all the content. Basically I want my app to have a side navigation
Wrap the navbar and main in a <v-row>:
<template>
<div id="app">
<v-app>
<v-row>
<navbar/>
<v-main>
<v-container class="main-container">
<router-view/>
</v-container>
</v-main>
</v-row>
</v-app>
</div>
</template>
By default, v-app has an internal wrapper with flex-direction: column CSS, meaning that its child elements are placed vertically. By wrapping these 2 child elements in a v-row, you place them in a wrapping element with flex-direction: row.
I guess you are misunderstanding the concepts. You are wrapping a v-navigation-drawer inside a navbar component.
In Vuetify v-navigation-drawer is a component used to build Sidebars and that's why your component is on vertical.
You should try to use v-app-bar instead. Here's the documentation: https://vuetifyjs.com/en/components/app-bars/
Edit 1
You can configure an app sidebar or an app navbar using the app option inside the component like that:
<v-navigation-drawer
app
>
...
</v-navigation-drawer>
Just like in the official documentation. If you do it that way, the component will work properly and your content will not be pushed down.

unable to show signup page vue.js

I am unable to route to signup page when goto signup button is pressed, I have attached the code snippets below.
SignUp.vue
<template>
<v-app id="inspire">
<v-content>
<v-container
fluid
fill-height
>
<v-layout
align-center
justify-center
>
<v-flex
xs12
sm8
md4
>
<v-card class="elevation-12">
<v-toolbar
color="primary"
dark
flat
>
<v-toolbar-title>SIGNUP FORM</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field
label="Email"
name="email"
type="text"
></v-text-field>
<v-text-field
id="password"
label="Password"
name="password"
type="password"
></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary">SIGN UP</v-btn>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</v-container>
</v-content>
</v-app>
</template>
router.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
import SignUp from './views/SignUp.vue';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/home',
name: 'home',
component: Home,
},
{
path: '/signup',
name: 'signup',
component: SignUp,
},
],
});
App.vue
<template>
<v-app>
<v-content>
<v-btn :to="{ name:'signup'}">GOTO SIGNUP</v-btn>
</v-content>
</v-app>
</template>
<script>
export default {
name: 'App',
components: {
},
data: () => ({
//
}),
};
</script>
When I execute this code there is no error in console and everything compiles correctly I am able to see "GOTO SIGNUP" button but when I click it nothing happens no errors,nothing happens, can you please help me to reroute to signup page I am using feathersjs,vue.js and vuetify. Any help would be appreciated. Thanks in anticipation.
If App.vue is where you're defining your main Vue instance, you will need to add the router to it:
<script>
import 'router' from 'router.js'
export default {
name: 'App',
router,
components: {
},
data: () => ({
//
}),
};
</script>
Also, as #Alexander Staroselsky mentioned in the comment, you will need to add a <router-view> element so Vue knows where to render the route component.
<template>
<v-app>
<v-content>
<v-btn :to="{ name:'signup'}">GOTO SIGNUP</v-btn>
<router-view></router-view>
</v-content>
</v-app>
</template>

How to add an icon in front of every VuetifyJS combobox entry?

I'm using the combobox component of VuetifyJS and I need to add an icon in front of every entry in the drop down. How to do that?
Here is a CodePen example of the combobox: https://codepen.io/anon/pen/KBLXYO
HTML
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-layout wrap>
<v-flex xs12>
<v-combobox
v-model="select"
:items="items"
label="Select a favorite activity or create a new one"
></v-combobox>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
JS:
new Vue({
el: '#app',
data () {
return {
select: 'Programming',
items: [
'Programming',
'Design',
'Vue',
'Vuetify'
]
}
}
})
Use the item scoped slot.
<v-combobox
v-model="select"
:items="items"
label="Select a favorite activity or create a new one">
<template slot="item" slot-scope="data">
<v-icon>home</v-icon> {{data.item}}
</template>
</v-combobox>
Here is your pen updated.
FWIW, this is all covered in the documentation.

Categories

Resources