How to get parent of clicked (this) element in Vue.js?
In jQuery this looks like:
$(this).parents(':eq(2)').next('.press__news__nav--view').show();
Thanks!
It's not a good practice in Vue when you're trying to manipulate DOM directly. If you want to show/hide an element, you should use v-if or v-show directives.
Anyway, you can access event object like this:
new Vue({
el: '#app',
methods: {
logme: function(event) { // a regular event object is passed by $event in template
console.log(event.target.parentElement) // parent element
}
}
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<div class="hello">
<button #click="logme($event)">Click me</button>
</div>
</div>
Related
Here is a strange issue i am facing.
<script src="https://unpkg.com/vue#2.6.11/dist/vue.min.js"></script>
<div id="app">
<transition-group name="fadeLeft" tag="ul">
<section key="0">
<testt></testt>
<template v-pre id="myId">
<div>My neighbors: <a v-for="(val,index) in myArray">{{val}}</a></div>
</template>
</section>
</transition-group>
</div>
<script>
Vue.component('testt', {
template: '#myId',
props: {
myArray: {
type: Array,
default: function() {
return ['James', 'Mike'];
}
}
}
})
new Vue({
el: '#app'
})
</script>
transition-group renders the component twice (and the second rendering is done without parsed "{{variable}}").
If you just remove transition-group parent at all, it works as expected and there is no duplicated content. So, definitely the problem seems somewhere there. How to fix that (so, retain transition-group and solve the problem)
Please don't post answers "use component outside of app" or similar offtopic, i described the problem I need to find answer. Also, the aprior is that the template needs to be within transition-group decendants.
The problem:
In the section tack you have the testt tag which was rendered with the parsed HTML and also the template which was rendered as another literal tag (no rendering). And since transition-group elements must be keyed, the template had to be moved out.
The solution:
<script src="https://unpkg.com/vue"></script>
<div id="app">
<transition-group name="fadeLeft" tag="ul">
<section key="0">
<testt></testt>
</section>
</transition-group>
<template v-pre id="myId">
<div>My neighbors: <a v-for="(val,index) in myArray">{{val}} </a></div>
</template>
</div>
<script>
Vue.component('testt', {
template: '#myId',
props: {
myArray : { type:Array, default :function(){ return ['James','Mike'];} }
}
})
new Vue({
el: '#app'
})
</script>
I'm trying to build a parent-child tree in Vue, and I want to pass the parent's DOM/element ID down to the child so that they can append to it. Here is a simple example of what I am trying to achieve as the DOM structure in the browser:
<div id="my-id">
<p>parent-comp header</p>
<div id="my-id-child">
<p id="my-id-child-content">child-comp content</p>
</div>
<p>parent-comp footer</p>
</div>
The only way I have been able to do this so far is to duplicate the id into another property propid and pass them both down the tree. This seems messy. See my sample code:
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<parent-comp id="my-id" propid="my-id"></parent-comp>
<script type="application/javascript">
Vue.component('parent-comp', {
props: {
propid: String
},
template: ` <div>
<p>parent-comp header</p><child-comp :id="propid + '-child'" :propid="propid + '-child'"></child-comp><p>parent-comp footer</p>
</div>`,
});
Vue.component('child-comp', {
props: {
propid: String
},
template: `<div>
<p :id="propid + '-content'">child-comp content</p>
</div>`,
});
new Vue({
el: '#my-id'
});
</script>
</body>
</html>
I'm guessing there must be a better way to achieve this? It seems like it should be a simple task? Thanks.
There are indeed better ways to refer to specific elements within the current component's template: use refs in the template, which would allow your component script to access them via this.$refs:
<template>
<div>
<button ref="myBtn">Click</button>
</div>
</template>
<script>
export default {
methods: {
doFoo() {
console.log(this.$refs.myBtn)
}
}
}
</script>
The scope isolation is maintained. For example, when there are multiple instances of component A on a page, and one of them gets a reference to its button (via this.$refs.myBtn) to disable it, only that instance's button is disabled. All other A instances are unaffected.
So I have my outer default.vue layout in nuxt architecture. I'my trying to add #keyup.esc="test" to outer element of default.vue:
<template>
<div #keyup.esc="test">
<navigation></navigation>
<nuxt/>
<transition name="fade">
<overlay-modals v-if="showModalLogin || showModalRegister"></overlay-modals>
</transition>
<transition name="zoom">
<div class="modal__outer" v-if="showModalRegister || showModalLogin">
<modal-login v-if="showModalLogin"></modal-login>
<modal-register v-if="showModalRegister"></modal-register>
</div>
</transition>
</div>
</template>
methods: {
test() {
alert('come on...');
},
test method is never fired which makes me confused.
The keyup event will only be detected by the div when the div has focus, so you have to set tabindex to make it focusable, and you have to give it focus.
new Vue({
el: '#app',
methods: {
test() {
console.log("Come on");
}
},
mounted() {
this.$el.focus();
}
});
<script src="https://unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app" #keyup.esc="test" tabindex="0">
Here is my div
</div>
if u look into documentation u will see that #keyup used in inputs. In your case - u are using this to div, and there is no focus on it so keyup will not possible. However u need to add some stuff to make it working. Please read this
I'm trying to create a component, that can show/hide on click, similar to an accordion.
I have the following error and I don't know why:
[Vue warn]: Property or method "is_open" is not defined on the
instance but referenced during render. Make sure to declare reactive
data properties in the data option. (found in root instance)
<div id="app">
<div is="m-panel" v-show="is_open"></div>
<div is="m-panel" v-show="is_open"></div>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="comp_a.js" ></script>
<!--<script src="app.js" ></script>-->
</html>
Vue.component('m-panel', {
data: function() {
return {
is_open: true
}
},
template: '<p>Lorem Ipsum</p>'
})
new Vue({
el:'#app',
})
Your code seems a little confused, your is_open is in your component but you are trying to access it in the parent. You just need to make sure this logic is contained inside your component. The easiest way is to simply place an event on the relevant element in your component template:
<template>
<div>
<!-- Toggle when button is clicked-->
<button #click="is_open=!is_open">
Open Me!
</button>
<span v-show="is_open">
I'm Open!
</span>
</div>
</template>
Here's the JSFiddle: https://jsfiddle.net/ytw22k3w/
Because u used is_open property in '#app instance' but u didnt declare in it,u decladed in 'm-panel component' which has no relation with it.Try something like this can avoid it.
new Vue({
el:'#app',
data:{
is_open:''
}
})
I have a dynamic component that is resolved and bound on runtime using the documented dynamic component syntax;
<div class="field">
<component v-if="component" :is="component" #valueUpdated="onUpdate($event)"></component>
</div>
Decided using a prop assigned to on mounting.
For whatever reason, when the child component, rendered dynamically, emits an event this.$emit('eventName', /*someData*/) the parent does not seem to be able to hear it. Is the approach used in standard components applicable to those rendered dynamically? Props seem to work, so maybe I am not doing something correctly?
yeah you can use props with dynamic components it's just you need to use lowercase hyphenated (kebab-case) names for the html attribute, i.e.
<component v-if="component" :is="component" #value-updated="onUpdate"></component>
Vue.component('foo', {
template: `
<div>
<button #click="$emit('value-updated', { bar: 'baz' })">pass data</button
</div>
`
});
new Vue({
el: '#app',
data: {
currentComponent: 'foo',
output: {},
},
methods: {
onUpdate (payload) {
this.output = payload
}
}
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<component v-if="currentComponent" :is="currentComponent" #value-updated="onUpdate"></component>
<pre>{{ output }}</pre>
</div>