I want to change Vue components with media Queries - vue.js

In my App.vue I've set my template like this
<app-header></app-header>
<router-view></router-view>
<app-footer ></app-footer>
app-header sets a header component to every other component of my project (so I don't have to repeat myself). app-footer does the same, but with a common footer for all of my components.
This works perfect with my Desktop web, but for Mobile I would like to change the header component to a new-header.vuecomponent, and I would like to get rid of the Footer when using a mobile device so it doesn't use screenspace.
How can I achieve this? I tried to use app-footer {display: none;} in a media query at App.Vue but its not working.

You do not want to use CSS to hide. The beauty of Vue is that in the case of mobile, the code will not even be generated at all.
Use a v-if directive, and add an isMobile property to your data, computed, store, etc. Or call a method to get it.
<app-footer v-if='!isMobile'></app-footer>
For the header, there are 2 ways. Using a component element with v-bind:is to swap in the correct one, or using v-if and v-else
<app-header v-if='!isMobile'></app-header>
<app-header-mobile v-else></app-header-mobile>
Here is the official link to the Vue dynamic component approach.
https://v2.vuejs.org/v2/guide/components-dynamic-async.html.
It would look like this:
<component v-bind:is="currentHeaderComponent"></component>
In this case, you would set currentHeaderComponent based on your conditions.
If you insist on CSS and media queries for the footer, set the component id or class, and that in your CSS
Component
<app-header id='app-header'></app-header>
<router-view></router-view>
<app-footer id='app-footer'></app-footer>
CSS
#app-footer {display: none;}

Related

Vue component communication between header component and components in the router-view

Im facing a problem for my VUE app, Im using the vue Router to navigate to my component
In my Header component I use router-link to navigate to a Home component
The problem is :
In my Header component I would like a checkBox (a boolean variable) that change the content of my Home component (rendered in the router-view) like a v-if that would check the boolean variable in the Header
Here is my App.vue template I was trying to solve the problem through emits but Im Kinda stuck for passing data inside a component (inside the router-view)
<template>
<div class="content">
<HeaderComponent #eventCheckBox="handleCheckBox" />
<router-view />
<FooterComponent />
</div>
Do you guys have already faced this issue, is there a way to do it the classic way or should I try plugins like Portal or Teleport ?
Portal and Teleport are the same, just a different name (teleport in Vue3, being the official name).
As of the rest of the question, this explains it very well: https://stackoverflow.com/a/49702934/8816585
Mainly, you need to see if you need to use a store like Pinia (recommended one) and Vuex. Most of the time, you could use a parent/child relationship. Here is another article explaining when you would need something like that: https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/#alternatives-to-storing-data-in-vuex
In Vue3, you could even not use a store and rely solely on the singleton pattern + composables (again, a lot of articles are available for that one).
TLDR: use your Vue devtools and inspect the state flowing.
If you need more, reach for more powerful tools.

Modal window in nuxt architecture

Before I was working with Vue2JS and I used to creating modal as just component within App.vue root component for example:
<template>
<div>
<app-navbar></app-navbar>
<router-view></router-view>
<app-footer></app-footer>
<my-modal v-if="someBoolean"></my-modal>
</div>
</template>
Now basing on some custom events or Vuex storage I was able to change someBoolean and trigger when I want modal to be visible.
Since in Nuxt we don't have such thing as root App.vue component I'm wondering how to achieve same as above but with Nuxt.
Of course I could use some package as bootstrap-vue but I don't really want to inject this big package just for that one purpose.
You can write code in layouts/default.vue file and this file works on your defaults, work the code at where you used as a layout of your pages(generally almost everywhere.)
Different approach is use portalvue to render components whereever you want. Nice article here but in Turkish.

How to disable replacing the app root div with the component HTML while using templates

So basically, when using components - the app root passed to the Vue instance gets replaced by whatever HTML is in the component. Is there a way to disable this and just nest the stuff Vue renders inside the app root instead?
for example - if index.html has a wrapper of
<div id="myVueApp"></div>
and I set el: "#myVueApp" on the Vue instance, the whole node will get removed and replaced by whatever I have in my template resulting in
<div id="myComponent">...</div>
Is there a way to make it into
<div id="myVueApp">
<div id="myComponent">...</div>
</div>
Should work. From what I understand, you want to have multiple parts of your Vue app to be splitted up in the rendered HTML output as well, more specifically into multiple divs.
I think this should work if you use multiple Vue instances.
Set up a structure in your HTML file and give them appropriate id's.
Then, create the Vue instances you want and assign each of them to their specific div using el.
However, I can't tell you if this is a good idea and follows the best practice..
Hope this helps!

Vue-js and different layouts

how would one layout the router-views, if you have, lets say 3 different layout to use for you app (e.g. layout for customers, layout for employer and admin-interface).
At the moment i implemented the customer "view" like:
<template>
<div id="app">
<HeaderBar/>
<Navigation></Navigation>
<router-view></router-view>
</div>
</template>
inside the App.vue file. I could use something like:
<div id="app">
<router-view name="header">
<HeaderBar/>
<Navigation></Navigation>
</router-view>
<router-view></router-view>
</div>
</template>
and load different headers for those "subroutes" but this seem's to be odd.
Also what, if i'd like to use an other index.html?
I'm using webpack for this app.
Or would you suggest to create different apps for this?
Many thanks
rene
You could try using dynamic components.
Basically you change which component is being rendered depending on your route.
So it would probably be something like this:
<component v-bind:is="headerComponent"></component>
and then your app can contain heeaderComponent property in data object that has a default value and gets changed when you click on a route that should use different header. Rinse and repeat for the footer.
As for the last question, I think you should only use one app. As it is possible to do and everything is still connected. I'm not sure but I don't know how would you, if need be, communicate between different instances of Vue.

Applying v-transition to vue.js(v 1.0.1) router-view

I'm building a single page application, using vue.js and vue-router.. right now the links work, but I want to add transition using v-transition.
but according to the documentation
What’s more important though, is that non-flow-control directives, non-prop attributes and transitions on the component element will be ignored, because there is no root element to bind them to - vue.js components
<router-view class="bounce" v-transition="bounce" transition-mode="out-in"></router-view>
so technically the v-transition in the router-view tag will be ignored because it is a Fragment instance..
so any idea where I can put the v-transition to apply transitions on route change?
Define at least one route node in your component:
<router-view class="bounce">
<div v-transition="bounce" transition-mode="out-in">
</div>
</router-view>
Vue need one element to insert in the DOM if you want to apply transition, or v-show.