Vue Scroll to anchor between components - vue.js

I'm trying to build my portfolio using Vue and Vue Router. What I'm trying to do is have a link in my navbar and when you click it, it will scroll down to that section. I have all my sections in separate components so I can't figure out how to make the scroll behaver function for everything. I have one Home.vue, and that component is the main component and all other components are included inside Home.vue.
Home.vue
<template>
<div class="home">
<HeaderSection />
<AboutSection />
<SkillsSection />
<TimelineSection />
<PortfolioSection />
<TestimonialsSection />
<ContactSection />
</div>
</template>
<script>
// # is an alias to /src
import HeaderSection from "#/components/HeaderSection.vue";
import AboutSection from "#/components/AboutSection.vue";
import SkillsSection from "#/components/SkillsSection.vue";
import TimelineSection from "#/components/TimelineSection.vue";
import PortfolioSection from "#/components/PortfolioSection.vue";
import TestimonialsSection from "#/components/TestimonialsSection.vue";
import ContactSection from "#/components/ContactSection.vue";
export default {
name: "Home",
components: {
HeaderSection,
AboutSection,
SkillsSection,
TimelineSection,
PortfolioSection,
TestimonialsSection,
ContactSection,
},
};

I just found a solution to this. in my Navbar i have an anchor tag <v-btn depressed plain text color="white"> Portfolio </v-btn> that points to the specific id in that component I want to move to <div id="portfolio"></div>. You can also make is scroll smoothly with document.querySelector(element).scrollIntoView({ behavior: "smooth" });

Related

Insert 2 components in nuxt.js page

i'm new of this framework :(
the problem is here because i've tried to put the component in another page and work it.
It sign error the component
this is my index.vue page
If you're using nuxt2.0, you should wrap them in a container but this is not needed in nuxt3.0.
<template>
<main>
<navbar />
<slideshow />
</main>
</template>
If this is nuxt2.0, then you should also import the component and register it but you haven't done it here. The path you've given to the component is not correct also.
<script>
import Slideshow from '~/components/slideshow.vue';
export default {
components: { Slideshow }
}
</script>
You need to wrap the into a div or any other tag (to not have multiple tags at the root of the template) like that
<template>
<div>
<navbar></navbar>
<slideshow></slideshow>
</div>
</template>
And you can also skip the import part because Nuxt is already doing that for you as explained here: https://nuxtjs.org/tutorials/improve-your-developer-experience-with-nuxt-components/

Vue - Component that accepts a nested component

I would like to have a component that can have another component placed into it. I'm struggling to find how this can be achieved.
If I pass a component in it doesn't get displayed. I'm assuming I need to specify it in the component however I can't find how in the documentation.
E.g.
<component-that-allows-nesting>
<nested-component/>
</component-that-allows-nesting>
What needs to be added to my component to allow it to accept a nested component?
Vuejs support nested component like Base Component and you can use it. if you want send data from parent component to child component you can use props.
for example
//parent-component
<form>
<base-input />
<base-button>
add form
</base-button>
</form>
//child-component
//BaseInput.vue
<input type="text" placeholder="userName" />
//BaseButton.vue
<button #click="submitForm" >
<slot></slot>
</button>
Here is an example for vue3 carousel.
You should import nested component
You should add this component in components
Use it as nested component
<template>
<carousel :items-to-show="1.5">
<slide v-for="slide in 10" :key="slide">
{{ slide }}
</slide>
</carousel>
</template>
<script>
import { Carousel, Slide } from 'vue3-carousel';
export default {
name: 'App',
components: {
Carousel,
Slide,
},
};
</script>

How to efficiently render different nav bar using Vue router?

So I'm creating a relatively large website using Vue and Vue-router and different pages require different navigation bars (each custom components rendered on top of the page)(and some pages don't have a navbar at all) and currently I'm using a similar format to this:
<template>
<div>
<div v-if="firstNavbar">
<FirstNav />
<div>
<div v-if="secondNavbar">
<SecondNav />
</div>
<router-view />
</div>
</template>
But re-rendering the entire page for every routing event just because the navbar changed seems a bit inefficient, and I was wondering what I could do to remedy this.
Any help would be appreciated, thanks.
I would suggest the use of <keep-alive> element to cache the navbars. Try this
APP.vue
<template>
<keep-alive>
<component :is="getConditionallyRenderedNavbar"></component>
</keep-alive>
<router-view />
</template>
<script>
import firstNavbar from './firstNavbar.vue';
import secondNavbar from './secondNavbar.vue;
export default{
components:{
firstNavbar,
secondNavbar
},
computed: {
getConditionallyRenderedNavbar() {
return firstNav //or second nav or no nav
}
}
}
</script>
To find out more, check here

Vue - include Vue file into other Vue file

I'm new to Vue.
I have created some elements (I'm using Element Components) and the code gets too long.
I would like to know if there is any way to create a several Vue files and include them all to one?
For exmaple, I have Navbar.vue, Header.vue , Footer.vue and Body.vue.
I want to include them all into one file.
Is it possible?
Sure. You import and use them like in my example. Don't forget to register them in the components as you can see.
This could be your app.vue file
<template>
<div id="app" class="container">
<the-header />
<!-- this could be <TheHeader /> depending on your setup -->
<the-navigation />
<!-- this could be <TheNavigation /> depending on your setup -->
</div>
</template>
<script>
import TheHeader from '#/components/the-header.vue'
import TheNavigation from '#/components/the-navigation.vue'
export default {
name: 'app',
components: {
TheHeader,
TheNavigation
}
</script>
<style lang="scss">
</style>

Vue.js dynamic layout renderless component layout with multiple slots

I am trying to build a dynamic layout for my application. I have two different layouts, one being DefaultLayout.vue:
<template>
<div>
<main>
<slot/>
</main>
</div>
</template>
and a second one being LayoutWithFooter.vue, with two slots:
<template>
<div>
<main>
<slot/>
</main>
<footer>
<slot name="footer"/>
</footer>
</div>
</template>
My renderless component to handle the dynamic layout looks like this:
<script>
import Vue from 'vue';
import DefaultLayout from './DefaultLayout';
import LayoutWithFooter from './LayoutWithFooter';
export default {
props: {
name: {
type: String,
required: true
}
},
created(){
this.registerComponent("DefaultLayout", DefaultLayout);
this.registerComponent("LayoutWithFooter", LayoutWithFooter);
this.$parent.$emit('update:layout', this.name);
},
methods: {
registerComponent(name, component) {
if(!Vue.options.components[name]) {
Vue.component(name, component);
}
}
},
render() {
return this.$slots.default[0];
},
}
</script>
All of this works fine for the DefaultLayout.vue but when I want to use the LayoutWithFooter.vue, it cannot handle the two slots inside it. Here's an example usage:
<template>
<layout name="LayoutWithFooter">
<div>
<div>some content</div>
<div slot="footer">content for the footer slot</div>
</div>
</layout>
</template>
Problem now is, that the "content for the footer slot" does not get rendered inside of the footer slot of the LayoutWithFooter.vue.
First of all I want you to pay an attention to defining slots level in your example. You provided this code:
<template>
<layout name="LayoutWithFooter">
<div>
<div>some content</div>
<div slot="footer">content for the footer slot</div>
</div>
</layout>
</template>
But actually your div slot="footer" does not refer to footer slot of LayoutWithFooter.vue component. It because of anyway the very first child refers to default slot. And as a result it looks like:
"You want to set content for default slot and inside this default slot you tried to set content for footer slot" - but it's two different scopes.
The right options would look like on the next example:
<template>
<layout name="LayoutWithFooter">
<!-- default slot content -->
<div>
<div>some content</div>
</div>
<!-- footer slot content -->
<div slot="footer">content for the footer slot</div>
</layout>
</template>
I prepared some example based on code and structure you've provided. There you are able to switch layouts and check out how it works and use different components slot in one layout.
Check it here:
https://codesandbox.io/s/sad-fog-zr39m
P.S. Maybe some point are not totally clear, please reply on my answer and I will try to explain more and/or provide you with more links and sources.