VueJs Scroll bar desappering after switching to mobile view - vue.js

I started an internship, and they gave me an existing app to improve in VueJs. However I still a beginner in web dev.
Here's my problem: there is a form that is divided into many rows, each one contains a lot of inputs, so I added a scroll bar as the user can fill them all, but once I switch to mobile mode,
it appears in the first row, but when I go to others it disappears. After re-switching to the PC mode, and going to another row, it reappears.
<template>
<v-tab-item>
<v-container
id="scroll-target"
style="max-height: 400px"
class="overflow-y-auto"
>
<v-card flat>
<v-card v-if="##############">
<v-card-text>
<inputs v-bind="$props" />
</v-card-text>
</v-card>
<v-row v-for="########":key="#####">
<v-col>
<inputSectionCard :######" />
</v-col>
</v-row>
<v-row v-if="#####">
<v-col>
<localisationCard />
</v-col>
</v-row>
<v-row v-if="####">
<v-col>
<attachments />
</v-col>
</v-row>
</v-card>
<scrollbar />
</v-container>
</v-tab-item>
</template>
component scrollBar:
<template>
<v-row
v-scroll:#scroll-target="onScroll"
align="center"
justify="center"
style="height: 100%"
>
</v-row>
</template>
<script>
export default {
data: () => ({
offsetTop: 0
}),
methods: {
onScroll(e) {
this.offsetTop = e.target.scrollTop
}
}
}
</script>

Related

Vue Vuetify center horizontally and vertically

I'm trying to center my auth component (v-card) horizontally and vertically. I tried all kinds of solutions like justify=center and align=center on the rows, fill-height on the v-container, class="fill-height" on the v-container but its not working. What am I doing wrong here ?
Code :
<script setup lang="ts">
import { useUserStore } from "../../stores/user";
const store = useUserStore();
</script>
<template>
<v-card width="800" >
<v-card-title>
Authentication
</v-card-title>
<v-card-subtitle>
login with username and password
</v-card-subtitle>
<v-card-text>
<v-row>
<v-col cols="12" md="6">
<v-text-field v-model="store.username" label="Username"></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field v-model="store.password" label="Password"></v-text-field>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
<script setup lang="ts">
import Auth from "../components/auth/Auth.component.vue"
</script>
<template>
<v-container>
<v-row style="border:1px solid red;" fill-height>
<v-col class="d-flex justify-center items-center">
<Auth/>
</v-col>
</v-row>
</v-container>
</template>
<template>
<v-app>
<v-main>
<router-view></router-view>
</v-main>
</v-app>
</template>
<script setup lang="ts">
</script>
Update
Check this codesanbox I made: https://codesandbox.io/s/stack71483246-center-login-p1u6zv?file=/src/views/Home.vue
Looks like by just adding the class fill-height to the root container you can center it vertically.
<template>
<v-container fluid class="fill-height">
<v-row style="border:1px solid red;">
<v-col class="d-flex justify-center">
<Auth/>
</v-col>
</v-row>
</v-container>
</template>
The following snippet will center the card vertically in the parent in Vuetify 3:
<v-row align="center" class="fill-height">
<v-col>
<v-card class="ma-3">
...
</v-card>
</v-col>
<v-row>

Vue-leaflet and vuetify

I have a issue with vue-leaflet and vuetyfy. I have simple template which show different layout depends on mobile or not. If app detect mobile I want to make 2 row layout, first map, second for input form. But the map occupy all screen space and input form show above this map. My second layout for desktop screen work fine, I just set w-50 class to map and that all. I've tried to set h-50 to the map, but it doesn't work as expected. How to fix this issue?
My layout looks like this:
<template>
<v-container fluid v-if="mobile">
<v-row class="mb-5">
<v-col class="pl-0">
<Map marker="true" />
</v-col>
</v-row>
<v-row>
<v-col>
<AddPlaceDescription />
</v-col>
</v-row>
<Footer />
</v-container>
<v-container fluid v-else>
<v-row>
<v-col class="px-0">
<Map class_attr="w-50" marker="true" />
</v-col>
<v-col>
<AddPlaceDescription />
</v-col>
</v-row>
<Footer />
</v-container>
</template>
This is my Map component
<template>
<l-map
id="themap"
:class="class_attr"
:zoom="zoom"
:center="center"
#update:zoom="zoomUpdated"
#update:center="centerUpdated"
#update:bounds="boundsUpdated"
>
<l-tile-layer :url="url" ></l-tile-layer>
<v-marker-cluster>
<l-marker
v-if="marker"
ref="marker"
draggable
#dragend="onDragEnd"
:latLng="center"
></l-marker>
<l-marker
v-for="marker in markersData"
:key="marker['latLng'][0]"
:lat-lng="marker['latLng']"
>
<l-popup>{{marker['description']}}</l-popup>
</l-marker>
</v-marker-cluster>
</l-map>
</template>
AddPlaceDescription component
<template>
<v-row>
<v-col class="ml-3">
<v-alert
v-if="showMsg"
border="left"
:color="msgColor"
outlined
text
type="error"
>{{ msg }} {{countDown}} </v-alert
>
<form action="">
{{ this.$store.state.Map.markerLatLng }}
<v-textarea
outlined
name="place-description"
label="Description"
v-model="description"
:disabled='showMsg'
></v-textarea>
<v-btn #click="sendPoint" :disabled='showMsg'>Send</v-btn>
<v-btn #click="clearForm" :disabled='showMsg'>Clear</v-btn>
</form>
</v-col>
</v-row>
</template>
and result like this
So I've break it yahoooo)) I just interchange the position of components and it works as expected. Of course I want to description component below the map, but anyway it is better than nothing.

Vuetify grid system issues in Nuxt across layouts, pages and components (+ background color issue)

I am trying to replicate this login page layout: Mentor Cruise Login Page
Basically a 1/3 vs 2/3 split and a vertically centered login component.
I'm using my default.vue layout to manage whether or not the navbar/appbar are shown at all. Also use middleware to redirect to the authentication.vue page if no user is present. The logic all works. But the layout has me struggling. The Vuetify documentation is spotty or assumes lots of CSS knowledge I don't have. I tried reading up on CSS flexbox but it does not seem to translate as I would expect or maybe Nuxt is getting in the way with the parent-child relationship handling between layouts, pages and components.
If someone could let me know how I can recreate this layout and where this should go, that would be great!
Here are the elements that should create this top-down:
default.vue layout file:
<template>
<v-app id="youtu.be/dQw4w9WgXcQ">
<template v-if="isLoggedIn">
<Navbar />
<Snackbar />
<Confirm />
</template>
<v-main>
<Nuxt />
</v-main>
<Footer />
</v-app>
</template>
authentication.vue page file
<template>
<v-container id="authentication">
<v-row no-gutters fluid align="center">
<v-col cols="4" class="info">
<v-img
:src="require('~/assets/XXX.png')"
contain
max-height="100"
max-width="100"
></v-img>
</v-col>
<v-col cols="8">
<client-only>
<Login />
</client-only>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
head() {
return {
title: this.title,
}
},
data: () => ({
title: 'Authentication',
}),
}
</script>
<style scoped>
.theme--dark.v-application {
background-color: var(--v-background-base, #121212) !important;
}
.theme--light.v-application {
background-color: var(--v-background-base, white) !important;
}
</style>
Login.vue component
<template>
<v-container>
<v-row justify="center" align="center">
<v-col cols="12" sm="8" md="6">
<v-card>
<v-card-title class="headline">
<span v-if="this.isLoggedIn">Welcome {{ this.displayName }}</span>
</v-card-title>
<v-card-text>
<div v-if="!this.isLoggedIn">
<div id="firebaseui-auth-container"></div>
</div>
<div v-else>
<p>You are logged in with {{ this.email }}.</p>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
const { mapGetters } = createNamespacedHelpers('user')
export default {
name: 'Login',
mounted() {
//firebaseUi stuff that works
},
computed: {
...mapGetters({
isLoggedIn: 'getIsLoggedIn',
displayName: 'getUserDisplayName',
email: 'getUserEmail',
}),
},
}
</script>
What I have:
What I have (Console):
What I want:
If someone can then tell me how the hell I set the col background color using the vuetify theme config from nuxt.config.js that would be amazing. I tried classes, I tried the color prop..nothing works.
// Edit1: Added console/CSS screenshot as per #kissu's request
// Edit2: Added codepen
Solved this in a hackey way by wrapping the elements contained in the 2 columns in a container again. I DO NOT think this is how you should do it. Probably upsetting the CSS gods. But it works.
<v-container id="authentication" fluid fill-height pa-0>
<v-row no-gutters style="height: 100%" id="authentication-row">
<v-col cols="4" class="primary darken-2">
<v-container fluid fill-height justify-center>
<v-img
:src="require('~/assets/logo.png')"
contain
max-height="100"
max-width="100"
></v-img>
</v-container>
</v-col>
<v-col cols="8">
<v-container fluid fill-height justify-center>
<client-only>
FirebaseUI component
</client-only>
</v-container>
</v-col>
</v-row>
</v-container>

make the button in the center of screen

There are two buttons and I want to place them in the middle, but it always appears in the right section as the picture.
How can I solve the problem?
Home.vue:
<template>
<v-container>
<v-row>
<v-col>
<v-btn
large
router
to="/viewRecipes"
class="red accent-4 btn-style text-sm-right text-xs-center"
>Explore Recipes</v-btn
>
</v-col>
<v-col>
<v-btn
large
router
to="/createrecipe"
class="red accent-4 btn-style text-sm-right text-xs-center"
>create Recipes</v-btn
>
</v-col>
</v-row>
</v-container>
</template>
<style scoped>
.btn-style {
color: aliceblue;
}
</style>
Your question is somehow unclear, but there are two options what do you want to achieve:
Center buttons inside columns
<v-container>
<v-row>
<v-col class="text-center">
<v-btn large
router
to="/viewRecipes"
class="red accent-4">
Explore Recipes
</v-btn>
</v-col>
<v-col class="text-center">
<v-btn large
router
to="/createrecipe"
class="red accent-4">
Create Recipes
</v-btn>
</v-col>
</v-row>
</v-container>
Center buttons on the page. In order to do so you need to modify your layout a bit and place your buttons inside one column
<v-container>
<v-row>
<v-col class="text-center">
<v-btn large
router
to="/viewRecipes"
class="red accent-4">
Explore Recipes
</v-btn>
<v-btn large
router
to="/createrecipe"
class="red accent-4">
Create Recipes
</v-btn>
</v-col>
</v-row>
</v-container>

How can I have a wrap horizontal alignment of cards in vuetify 2?

I have a tiny project that I am building using vuetify 2, but the issue I am coming across is in a col with width 7, all my cards are showing up vertically, instead of a horizontal overflow.
What I am hoping to achieve is that the cards are vertical to each other by counts of five, with overflow moving to the second line.
My row arrangement is row > col2 col7 col3 /row. I am not using a v-container because it seems to put a container in the middle and not take up the whole screen.
I have tried using the flex-wrap, flex-column, flex-row etc class based on the vuetify docs, but that doesnt seem to change anything. Most of the examples that I found regarding this is for vuetify 1, and the component structure is different.
Codesandbox
App.vue
<template>
<v-app>
<v-app-bar
color="dark"
dark dense
>
</v-app-bar>
<v-row no-gutters>
<v-col fluid cols="2"></v-col>
<v-col fluid cols="7">
<HelloWorld v-for="c in 10" :key="c" />
</v-col>
<v-col fluid cols="3"></v-col>
</v-row>
</v-app>
</template>
<script>
import HelloWorld from './components/HelloWorld';
export default {
name: 'App',
components: {
HelloWorld,
},
data: () => ({
//
}),
};
</script>
HelloWorld.vue
<template>
<v-card class="mx-auto" max-width="344" outlined>
<v-list-item three-line>
<v-list-item-content>
<div class="overline mb-4">OVERLINE</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 text>Button</v-btn>
<v-btn text>Button</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
name: "HelloWorld"
};
</script>
What I have at the moment is this: The arrows are showing how I would like the successive card to be next to the card and so forth.
If you want to ignore row wrap you can just add .flex-nowrap class:
<v-row class="flex-nowrap">
Update
I get it. You paste card inside of col. My bet.
You just can do this:
<template>
<v-app>
<v-app-bar
color="dark"
dark dense
>
</v-app-bar>
<v-row no-gutters>
<v-col cols="2"></v-col>
<v-col cols="7">
<v-row no-gutters>
<v-col v-for="c in 10" :key="c" cols="4">
<HelloWorld/>
</v-col>
</v-row>
</v-col>
<v-col cols="3"></v-col>
</v-row>
</v-app>
</template>