Create my own component vuejs, with two diferents parts - javascript

I have a component with an input that when clicking opens a modal.
When I use this component, and insert it inside a div with relative position, the modal that opens, it does not display well. I would need the html of the modal to be outside the div position relative.
It is important that my component contains both the input and the modal, since this component itself will be used several times within another component.
<div class="position-relative">
<MyOwnComponet />
</div>
<div class="position-relative">
<MyOwnComponet />
</div>
My component would be something like this, more or less:
<template>
<input #click="showModal = true" />
<div class="modal" v-if="showModal">
...
</div>
</template>

I am not sure what's your point for this kind of requirement but anyway there is a workaround you can do with props.
You can have props in "MyOwnComponet" like this. And use that prop value to render accordingly.
Your main component
<div class="position-relative">
<MyOwnComponet :isInput="true" />
</div>
<div class="position-relative">
<MyOwnComponet :isInput="false" />
</div>
Your (MyOwnComponent)
<template>
<div v-if="isInput">div-1</div>
<div v-else>div-2</div>
</template>
<script>
export default {
props: {
isInput : Boolean,
},
data() {
}
};
</script>
You can replace div-1 with your input and div-2 with modal.

Related

vue button related event not fired

In:
https://codesandbox.io/s/upbeat-hodgkin-qjt61?file=/src/components/EditCategory.vue
the modal is shown as expected upon long click over a category:
but clicking OK does not fire the close event:
<template>
<div>
<p v-longclick="() => longClicked()" #click="longClicked()">
{{ taskItemLocal["name"] }}
</p>
<div v-if="this.showModal" #close="closeModal()">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header"> Edit Category </slot>
</div>
<div class="modal-body">
<slot name="name"> Edit Name </slot>
</div>
<div class="modal-body">
<slot name="delete"> Delete Category </slot>
</div>
<div class="modal-footer">
<slot name="footer">
<!-- default footer -->
<!-- EVENT NOT FIRING -->
<button class="modal-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</div>
</div>
</template>
closeModal() is not called; changing showModal "directly" also fails.
You have dispatch event to parent but in parent component you have not done any thing with "close" event. Here, in GenericItem.vue I have made event listener with #close="closeBox($event)" . Here, it will trigger method of closeBox
GenericItem.vue
Changes on Template
<edit-category
v-if="editCategoryStatus"
:taskItem="taskItemLocal"
#close="closeBox($event)"
/>
Add one closeBox method
closeBox() {
this.editCategoryStatus = !this.editCategoryStatus;
},
Add editCategoryStatus on data
data() {
return {
editCategoryStatus: true,
taskItemLocal: {
type: Object,
default: {},
},
};
If you want to listen to an event within the component that emitted that event, you use the instance $on method:
mounted() {
this.$on("close", () => {
this.closeModal();
});
}
The template event handler #close="closeModal()" is used to listen to events from parent. It has no effect within the child component.
The working codesandbox: https://codesandbox.io/s/loving-kirch-vrhwn?file=/src/components/EditCategory.vue .
You could just make your button like this. You made this more complicated than it should be
<button class="modal-default-button" #click="showModal = false">
Also, there is this example from the official docs
here.

VUE- How do I put the values inside of components imported?

I remember I have seen once how to put the values in the html text area after importing components in VUE.
I'm not sure there is a way to do that or I just remember things in a wrong way.
my code is as below.
<template>
<div class="container">
<div class="row">
<Heading></Heading>
</div>
<hr>
<div class="row">
<div class="col-xs-12 col-sm-6">
<ul class="list-group">
<comp v-for='(value,index) in listing' :key='index'>{{value}}</comp>
</ul>
</div>
<serverstat></serverstat>
</div>
<hr>
<div class="row">
<footing></footing>
</div>
</div>
</template>
<script>
import Heading from './assets/Heading.vue';
import comp from './assets/comp.vue';
import serverstat from './assets/serverstatus.vue';
import footing from'./assets/footing.vue';
export default {
data() {
return {
listing: ['max','toms','judy','michael','dumdum']
}
},
components: {
Heading,comp,serverstat,footing
},
};
</script>
<style>
</style>
-comp-
<template>
<li class="list-group-item">
</li>
</template>
<script>
export default {
}
</script>
<style>
</style>
After I render this,
it doesn't show {{value}}. It only shows blank .
How do I insert the {{value}} within the html element?
Thank you in advance.
Since you are entering a value inside of a component, you can render it by using a slot in your component like this:
<template>
<li class="list-group-item">
<slot />
</li>
</template>
<comp v-for='(value,index) in listing' :key='index'>
<slot>{{ value }} </slot>
</comp>
Then in comp component use slot as
<slot/>
Not including the approach for props as you don't want to use that. Use the link above to learn more about slots.
When you use v-for it calls all the value from an array and :key='index' defines each object row from an array. If your object listing consists of firstname, lastname as your object then the value you want to print will be {{value.firstname}}. You are missing object name in value.
Can you try this once :
<comp v-for='(value,index) in listing' :key='index'>{{value.index}}</comp>

Svelte: transferring props between parent and child

I've wrote simple Modal component with two slots named button and content:
<script>
let opened = false;
function open() {
opened = true;
}
</script>
<slot name="button" opened={opened} open={open}/>
{#if opened}
<slot name="content"/>
{/if}
Also, opened and open-method are passed to parent component via <slot name="button"
In App.svelte:
<script>
import Modal from './Modal.svelte';
</script>
<Modal let:opened let:open>
<button slot="button" on:click={open} class:opened>Open</button>
<div slot="content">Content</div>
</Modal>
So, there are two questions:
1) It looks a little bit weird that props can be passed to parent just through any random slot.
Is it a good practice to do it like this?:
<slot opened={opened} open={open}/>
<slot name="button"/>
{#if opened}
<slot name="content"/>
{/if}
2) <div slot="content">Content</div> passed with its <div>. Could I pass only Content without <div> or can Content be unwrapped somehow?
Thx
1) Yes it's totally fine.
Alternative is to use data-binding or events to send info to a parent.
2) You can have a default slot, and it wouldn't need a wrapping element. Example:
<!-- Modal.svelte -->
<!-- named slot -->
<slot name="button"/>
<!-- unnamed/default slot -->
<slot/>
<!-- usage -->
<Modal>
<button slot="button"/>
I'm unwrapped in the default slot!
<slot/>

Vue component stops working when wrapped into another component

I got stucked with Vue.js. I am trying to basically wrap a component(that is already inside one component) into one more. I have a dropdown with a select and I call a function on change. Everything works fine until I wrap the component in one more on top. The top level one is in blade as it's used with Laravel. Snippets:
Component with dropdown:
<template>
<div id="watchlist-item">
<select #change="changed()" class="form-control"
id="currencies" name="currencyList">
<option value="USD" selected="selected">USD</option>
<option value="EUR">EUR</option>
</select>
</div>
</template>
<script>
export default {
name: "watchlist-item.vue",
methods: {
changed() {
alert("CHANGED");
},
},
}
</script>
Wrapper:
<template>
<div id="watchlistItem">
<watchlist-item></watchlist-item>
</div>
</template>
<script>
export default {
name: "watchlist"
}
</script>
Top component:
<template>
<div id="watchlist">
<watchlist></watchlist>
</div>
</template>
<script>
export default {
name: "main-component"
}
</script>
Blade template:
#extends('layouts.layout')
<div>
{{-- <div id="maincomponent">--}}
{{-- <main-component></main-component>--}}
{{-- </div>--}}
<div id="watchlistItem">
<watchlist-item></watchlist-item>
</div>
</div>
This works fine and i get alert on change. However, when i uncomment the commented part and vice-versa (so basically wrap it one more time) vue stops aletring me. I find this behaviour pretty weird but I am just starting with Vue so maybe its just a small detail I'm missing. I don't really even know what to search for though, so any help would be greatly appreciated. Thank you.
Just make sure that you are importing child components inside it's parent correctly:
main-component > watchlist > watchlist-item
| |
has has
Well it doesnt work because you need to register it via components, but first you need to import it.
<template>
<div id="watchlistItem">
<watchlist></watchlist>
</div>
</template>
<script>
import watchlist from "path/to/watchlist";
export default {
name: "watchlist",
components: {
watchlist: watchlist
}
}

Change route with vue- <router-link>

I have a <router-link to = "/ endreco / test">, but I need to perform the same behavior on a vue-material tab, something like this: <md-tab md- icon = "books"> .. to change my route, same as the href = ""
What should I do?
I'm using vue.js, the vue-router to control routes and style with vue-material
You can add a #click.native handler to push to a route manually (the .native modifier is needed since the md-tab component does not have a click event):
<md-tab #click.native="$router.push('/endreco/test')">
Here's the documentation on Programmatic Navigation with Vue Router.
See my code I have implemented a method which traverses to router to see routes of mentioned name of component, you can easily get idea!
<template>
<div>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--3-col mdl-cell mdl-cell--1-col-tablet mdl-cell--hide-phone"></div>
<div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-phone">
<div class="image-card" v-for="picture in this.pictures" #click="displaydetails(picture.id) ">
<div class="image-card__picture">
<img :src="picture.url" />
</div>
<div class="image-card__comment mdl-card__actions">
<span>{{ picture.comment }}</span>
</div>
</div>
</div>
</div>
<router-link class="add-picture-button mdl-button mdl-js-button mdl-button--fab mdl-button--colored" to="/postview">
<i class="material-icons">add</i>
</router-link>
</div>
</template>
<script>
import data from '../data'
export default {
data() {
return{
'pictures' : data.pictures
}
},
methods :{
displaydetails (id){
this.$router.push({name:'detailview', params:{id:id}});
console.log("helo");
}
}
}
</script>
Hope get something resourceful out of it!

Categories

Resources