Passing props from page layout through parent slot into child component - vue.js

I have a Card component that I'd like to inherit a title value from the <Card /> tag's title property defined within the parent layout after passing through a <Cards></Cards> component's slot.
Card:
<template>
<div class="card">
{{ title }}
</div>
</template>
<script lang="ts">
import Component from 'nuxt-class-component'
import Vue from 'vue'
import { Prop } from 'vue-property-decorator'
#Component
export default class extends Vue {
#Prop() title: string
}
</script>
Cards:
<template>
<div class="cards">
<slot></slot>
</div>
</template>
Page:
<template>
<Cards>
<Card :title="ABC" />
</Cards>
</template>
I'm not quite sure how to reference the title property. How is this written in Vue?

You should be able to do this by defining a title property in the Card component:
Card:
<template>
<div class="card">
{{ title }}
</div>
</template>
<script>
export default {
props: ['title']
}
</script>

Related

VueJS: How can I pass params into a component?

I am new to vueJS.
What I want to do is passing parameters to a component, depending on the selection of the routes. Here is my App.vue:
<template>
<div id="main">
<header>
<h1 style="color:red">{{msg}}</h1>
</header>
<div>
<aside class="sidebar">
<router-link v-for="el in this.$router.options.routes" :to="el">
{{el.name}}
</router-link>
</aside>
<SubMenu></SubMenu>
<div class="content">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import SubMenu from './components/SubMenu.vue'
export default {
components: {
'SubMenu': SubMenu
},
data() {
return {
msg: 'Welcome to Your Vue.js App' }
}
}
</script>
<style>
#import 'style.css';
#import 'grid.css';
</style>
and the SubMenu component I would like to make dynamic:
<template>
<div>
something dynamic
</div>
</template>
How can I pass some parameters to use in the component?
thank you
Your App.vue can be like this:
<template>
<div id="main">
<header>
<h1 style="color:red">{{msg}}</h1>
</header>
<div>
<aside class="sidebar">
<router-link v-for="el in this.$router.options.routes" :to="el">
{{el.name}}
</router-link>
</aside>
<SubMenu :menuTitle="subMenuTitle"></SubMenu>
<div class="content">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import SubMenu from './components/SubMenu.vue';
export default {
components: {
SubMenu
},
data() {
return {
subMenuTitle: "This is the sub menu",
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<style>
#import 'style.css';
#import 'grid.css';
</style>
The SubMenu.vue component could be like this:
<template>
<div>
<h2>{{ menuTitle }}</h2>
something dynamic
</div>
</template>
<script>
export default {
name: "SubMenu",
props: {
menuTitle: String,
}
}
</script>
In the SubMenu component that was used in App.vue, notice the colon that appears before the menuTitle attribute. When you do that before an attribute, the value of that attribute would be evaluated by Vue and passed to the component. You can pass literal Javascript expressions or items in your App.vue component.
In the SubMenu component, you can use the props in whatever way you can. If the prop's value is an array, you can use the v-for directive with it to create a list of items in the SubMenu.
Welcome to SO,
In Vue.js passing parameters to components is called "Props"
You can pass props to your SubMenu like below
<SubMenu :id="12345" someText="Some Text About Something" :dataArray="[1,2,3,4,5]" />
then inside your SubMenu component you can define Prop Types as below
props: ['dataArray']
or
props: {
dataArray: {
type: Array,
default: []
}
}
After that you can use the data you passed to your liking
You can also read up on this Vue Documentation regarding the Props, which has much more detailed explanations about various Props related stuff and sample code
Ok many thanks to both.
But what if I would like to pass something that depends on the voices in router-link? I mean, router-link prints a menu with 4 voices...what if I would like a behavior like this:
click on voice1 in router-link ---> pass this object ['input1', 'input2'] to SubMenu
click on voice2 in router-link ---> pass this other object ['input3', 'input4', 'input5'] to SubMenu
and so on.
thanks again :)

Vue layout with named slots

Is it possible?
I have something like this:
<template>
<my-layout>
<template #header>
Some header html goes here
</template>
Body html here
</my-layout>
</template>
<script>
import MyLayout from './MyLayout.vue'
export default {
layout: MyLayout,
components: {
//MyLayout
}
}
</script>
And template like that
<template>
<div>
<slot name="header"/>
</div>
<slot/>
</template>
The default slot works, but "header" slot doesn't display itself (unless using MyLayout as standard component).
I believe there is a problem with the closing tags on the template you have given and it should be like the following:
<template>
<div>
<slot name="header"> </slot>
</div>
</template>
After that, layout property only excepts strings or functions that return strings, so parent should be like the following:
<template>
<my-layout>
<template #header>
Some header html goes here
</template>
Body html here
</my-layout>
</template>
<script>
import MyLayout from "./MyLayout.vue";
export default {
layout: "MyLayout",
components: {
//MyLayout
}
};
</script>
I hope this solves your problem and have a nice day :)

VueJS extends component with slots

I have a BaseModal Component like this :
<template>
<div class="base-modal" :class="{open: isOpen}">
<div class="modal">
<h2 class="modal-title">
<slot name="title"></slot>
</h2>
<div class="modal-content">
<slot name="content"></slot>
</div>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
#Component({})
export default class BaseModal extends Vue {
public isOpen: boolean = false;
// Some methods
}
</script>
I want to create an other modal component that will extend this one and pass it the content for the named slots. Here is where I am :
<template>
// How to give slots content here
</template>
<script lang="ts">
import BaseModal from "#app/components/BaseModal.vue";
import { Vue, Prop, Component } from "vue-property-decorator";
#Component({
extends: BaseModal,
})
export default class OtherDropdown extends Vue {
}
</script>
The extends is working but I can't figure out how to pass content to the named slot of the extended component. Not to have to write again all the BaseModal template.
Thanks
I'm using VueJS 2.6.8
You would want to use components named slots like this:
<template>
<BaseModal>
<template v-slot:title>
Some Title
</template>
<template v-slot:content>
Some content goes here
</template>
</BaseModal>
</template>
You can read more about named slots here: https://v2.vuejs.org/v2/guide/components-slots.html#Named-Slots
Hope this helps!

vue how to access v-model from child component

my child component is like this
<editor v-model="edit_thread.body"></editor>
and then I access the component from inside like this
<template>
<div>
<input :value="this.value">
</div>
</template>
<script>
export default {
data() {
return {
value: this.edit_thread.body
}
}
}
</script>
not working, I miss something?
To use v-model on custom components, the component needs to:
have a prop (not a data property) named value:
<template>
<div>
<input :value="value">
</div>
</template>
<script>
export default {
props: ['value']
}
</script>
and emit an input event with new values:
<template>
<div>
<input #input="$emit('input', $event.target.value)">
</div>
</template>
demo

Can't Embed Vue Component into an md-app using Vue Material

I have the following...
PageHeader.vue
<template>
<span> ${message} </span>
</template>
<script>
export default{
data: function(){
return {message: "asdsad" };
}
}
</script>
app.vue
<template>
<jg-header></jg-header>
</template>
<script>
import PageHeader from "./PageHeader.vue"
export default{
components: {
"jg-header": PageHeader
}
}
</script>
This works great so I want to convert it to using Vue Material so I change app.vue to this...
<template>
<md-app> <jg-header></jg-header> </md-app>
</template>
<script>
import PageHeader from "./PageHeader.vue"
export default{
components: {
"jg-header": PageHeader
}
}
</script>
It seems to create and render the Vue material component, however, the custom component doesn't show up anywhere. How do I get the Vue component to actually render inside the md-app
Update
Since there was some confusion, I create the Vue app I do call Vue.use (hence why it renders)
Vue.use(VueMaterial);
new Vue(App).$mount("#my-id");
<md-app> has specific content elements. Wrap your content in <md-app-content>.
Instead of:
<template>
<md-app> <jg-header></jg-header> </md-app>
</template>
Do:
<template>
<md-app>
<md-app-content>
<jg-header></jg-header>
<md-app-content>
</md-app>
</template>
Or, with a toolbar:
<template>
<md-app>
<md-app-toolbar> ... </md-app-toolbar>
<md-app-content>
<jg-header></jg-header>
<md-app-content>
</md-app>
</template>
Try wrapping the tags inside template with a div :
<template>
<div>
<md-app>
<jg-header></jg-header>
</md-app>
</div>
</template>