I have this.
<template>
<md-dialog :md-active.sync="show"
#md-closed="hideModal"
#md-clicked-outside="hideModal"
class="modal-tabs"
#keypress.enter.prevent="handleEnter"
>
<md-dialog-content ref="my-modal" v-on:scroll.native="handleScrolling" #click.native="handleScrolling">
<!--content-->
</md-dialog-content>
</md-dialog>
</template>
and handler function is
handleScrolling(): void {
console.log('scroll is on');
this.$root.$emit('scrollingModal', this.$refs['my-modal'].$el.scrollTop);
}
It easily called by clicking on content but cannot be called by scrolling content. Why? Regards.
In order for v-on:scroll to be triggered the element first needs to by overflowing with a scroll style declared.
Try doing this:
<div style="max-height: 300px; overflow: scroll;" v-on:scroll="handleScrolling()">
<md-dialog-content ref="my-modal" #click.native="handleScrolling">
<!--content-->
</md-dialog-content>
</div>
This should show you a proof of concept. As you scroll inside that div you should see the messages being logged.
This problem solved by wrapping content with md-tabs and md-tab tags. In my case, to achieve scroll event triggering i have changed code above to:
<template>
<md-dialog :md-active.sync="show"
#md-closed="hideModal"
#md-clicked-outside="hideModal"
class="modal-tabs"
#keypress.enter.prevent="handleEnter"
>
<md-dialog-content ref="edit-contact-modal" v-on:scroll.native="handleScrolling">
<md-tabs>
<md-tab><!--here md-tab in fact is first custom div of mine-->
<!--content-->
</md-tab>
</md-tabs>
</md-dialog-content>
</md-dialog>
</template>
Related
You can see the issue I'm having here:
https://codepen.io/ryanrapini/pen/LYeWZKR?editors=1010
Essentially, I have several dialogs which I have contained into their own custom "vue components" i.e. order-dialog.vue. In an ideal world, I could simply include this <order-dialog> component wherever I need it, and it would render the activator button and then handle all of the dialog state inside the component, so the parent doesn't need to worry.
Unfortunately, if I do this in a v-card-actions section I get spacing issues. Is this a bug with Vuetify or am I doing something wrong?
I thought that by moving the activator out of the <v-dialog> tag it might fix the issue, but it still doesn't unless I break my component up into a v-dialog component and a separate activator, which means I now need to manage the state of the dialog in the parent.
Thanks for any help.
I don't think you are doing something wrong, and I'm not sure that it's a Vuetify bug.
This comes from CSS rule in Vuetify library:
.v-application--is-ltr .v-card__actions>.v-btn.v-btn+.v-btn {
margin-left: 8px;
}
I think the authors assumed that this block should contain only buttons. But in your case (in 2nd and 3rd approach) an output HTML looks like this:
<div class="v-card__actions">
<button class="v-btn ...">
...
</button>
<div class="v-dialog__container"><!----></div>
<button type="button" class="v-btn ...">
...
</button>
<button type="button" class="v-btn ...">
...
</button>
</div>
So v-dialog__container breaks this rule.
You can fix you issue, by example, with an additional rule:
.v-application--is-ltr .v-card__actions>.v-btn:not(:first-child) {
margin-left: 8px !important;
}
Or you can also apply helper classes (ml-2) into specific buttons.
I'm trying to implement generic modal component with Vue 3.
And I want to close modal window on click outside the modal's content.
So I added 'close' event on modalWrapper and 'contentClick' to prevent closing (bubbling) when content is clicked:
contentClick(event:Event){
event.stopPropagation();
}
Modal:
<template>
<teleport to="body">
<div class="modal-window" v-on:click="close" v-show="isOpened">
<slot class="modal-window__content" v-on:click="contentClick($event)"></slot>
</div>
</teleport>
</template>
The problem is that contentClick(event:Event) is not fired for some reason. I can wrap slot into another div and put contentClick event on it, but not sure that it's a good solution
I tried to animate addition and deletion of element in v-for loop.
I searched some similar quesitons here and mainly the answers were about
class name change in vue3 from vue2.
I'm sure my case is not related to class name.
My code is as below.
Component name: VueOnly
<transition-group tag='div' class='VueOnly' name='fade'>
<div class='graphs' v-for="boro in lotteriesByBorough" :key="boro['value']">
<div>{{boro[0]}}</div>
<div class="bargraph" :style="{width: xScale(boro[1]) + 'px'}"></div>
</div>
</transition-group>
<div style='display:none'>{{console}}</div>
</template>
*css
.fade-enter-active{
animation:fade-in 1s
}
.fade-leave-active{
animation:fade-in 1s reverse
}
#keyframes fade-in {
from{
opacity:0 ;
width:0 ;
background-color:blue ;
}
to{
opacity:1;
width:100%;
}
}
I strongly believe I am following the syntax of
why is this not working?
It works only when 'leave' event is triggered.
Temporary class is added when 'leave' events are running while no class is added when 'enter' events are running.
So I think there is a problem in enter process in general.
Does it have anything to do with addition logic?
My addition logic is as below.
App.vue
<div class="filters">
<el-checkbox-group v-model="filters">
<el-checkbox label="1"></el-checkbox>
<el-checkbox label="2"></el-checkbox>
<el-checkbox label="3"></el-checkbox>
<el-checkbox label="4"></el-checkbox>
</el-checkbox-group>
</div>
<div class="section" :style="{width:`${width}px`,height:`${height}px`}">
<vue-only
:lotteries="filteredLotteries"
:lottery-stats="lotteryStats"
:width="width"
>
</vue-only>
</div>
The entire code can be seen in the following link.
https://github.com/jotnajoa/studioquestion/tree/main/d3vue
Set the appear property on <transition-group>:
<transition-group tag="div" class="VueOnly" name="fade" appear>
demo
I stumbled upon the same problem. It seems that the class animation_name-enter-active is not applied to new items (regardless of using appear or not). But the class animation_name-enter-to will be applied normally, so I moved my animation css to this class and it worked. Probably more a workaround than a real solution.
As part of becoming a better Vue programmer, I am trying to implement a popup similar to Popper with a clean and Vueish architecture. Here is a simple schematic that I came up with:
So basically there is a target component, which is the reference for the popup's position. The popup can be positioned above, below, right and left of the target, therefore I will need to have access to the target element in my popup. Also, the target can be an arbitrary component. It can be a simple button or span, but also something much more complex.
Then there is the popup itself, which will be put into a modal at the end of the body, It contains the actual content. The content again can be an arbitrary component.
I have a working implementation of the popup, but the basic structure seems to be far from perfect. I am using two slots, one for the target element and one for the content.
Here is what I have come up with so far for the template:
<template>
<div ref="targetContainer">
<slot name="target"></slot>
</div>
<teleport to="body">
<div v-show="show" class="modal" ref="modal">
<div ref="popover" class="popover" :style="{top: popoverTop + 'px', left: popoverLeft + 'px'}">
<slot name="content"></slot>
</div>
</div>
</teleport>
</template>
There are several issues with this that I am not really happy with.
Using the popup is not very simple
When using this popup in another component, two <template> tags are rquired. This is ungly and not very intuitive. A very simple use case looks like this:
<modal :show="showPopup" #close="showPopup=false">
<template v-slot:target>
<button #click="showPopup=true"></button>
</template>
<template v-slot:content>
<div>Hello World!</div>
</template>
</modal>
The target is wrapped in another <div>
This is done to get access to the target element, that I need for the layout. In mounted() I am referencing the target element like this:
let targetElement = this.$refs.targetContainer.children[0];
Is this really the best way to do this? I would like to get rid of the wrapping <div> element, which just asks for unintended side effects.
The best solution would be to get rid of one slot and somehow reference the target element in another way because I only need its layout information, it does not have to be rendered inside the popover component.
Can someone point me in the right direction?
Here is my solution, which was inspired by a comment on my question and which I think is worth sharing.
Instead of putting the target element into a slot, I am now passing its ref as a prop, which makes things much cleaner.
The popover component's template now looks like this.
<template>
<teleport to="body">
<div v-show="show" class="modal" ref="modal">
<div ref="popover" class="popover" :style="{top: popoverTop + 'px', left: popoverLeft + 'px'}">
<slot ref="content"></slot>
</div>
</div>
</teleport>
</template>
I has a targetRefprop, so the component can be simply used like this:
<div ref="myTargetElement" #click="isPopupVisible=true">
</div>
<modal :show="isPopupVisible" #close="isPopupVisible=false" targetRef="myTargetElement">
<!-- popup content goes here -->
</modal>
And after mounting I can access the target element like this:
let targetElement = this.$parent.$refs[this.targetRef];
I like this solution a lot. However, ideas, advice or words of caution are still highly welcome.
I know that there are similar questions with jquery, but this is related to vue.js
I'm using uiv which is a boostrap version for vue.js. Checking the docs I'm trying to trigger manually the popover using trigger="manual" with a hover event:
<popover title="Title" v-model="show">
Toggle Popover
<template slot="popover">
<p>Popover content</p>
</template>
</popover>
<script>
export default {
data () {
return {
show: false
}
}
}
</script>
Well, I understand why the popover is being closed due when I leave the button I set show to false.
So my question is: Where do I have to place that #mouseleave event in order to prevent closing the popover when it is being hovered?
Here I have a plunker link: https://plnkr.co/edit/gTsOJE4k8fQUMcMUpqS6?p=preview
I've solved my problem doing this:
<popover trigger="hover" title="Title">
<a href="#" #click.prevent>Toggle Popover</a>
<template slot="popover">
<p>Popover content</p>
</template>
</popover>
Basically, we can use trigger="hover" to prevent closing the popover when it is being hovered.
Take a look at this example: https://plnkr.co/edit/RSjhazfxqBhaNqcKijXe?p=preview