I've been trying to execute a method when a image has fully loaded, but it simply throws an error that my function doesn't exists:
Uncaught ReferenceError: imageLoaded is not defined
at HTMLImageElement.onload (projetos:1)
Here's my code:
<template>
<div class="card">
<h2>{{projeto.nome}}</h2>
<div class="row">
<div class="col-sm-10 col-sm-offset-1" id="img-container">
<img :src="projeto.foto" :alt="projeto.nome" onload="imageLoaded()">
<div class="row" id="info">
<div class="col-xs-6">Conclusão: {{projeto.duracao}}</div>
<div class="col-xs-6">Projeto realizado em {{projeto.ano}}</div>
<br><br>
<p>{{projeto.descricao}}</p>
</div>
</div>
</div>
</div>
</template>
<script>
import { eventBus } from "../../main";
export default {
props: ["projeto"],
methods: {
imageLoaded() { // the function i want to execute
eventBus.loading(false);
}
}
};
</script>
I've tried using :load="" (wich i discovered that doesn't exists) and placing a function outside my export default scope. Since my images are in a v-for i think onload is the best way of achieving this.
So is there a better way? How can i do this? Is there a directive i can use? Am i doing something wrong?
Use the v-on directive or the shorthand # for listening for DOM events like you would do for example with #click="" - so #load="imageLoaded()" should work.
Related
New to vuejs. I am trying to write javascript directly in the vue file. Below is the code. I keep getting the following errors...
compiled with problems
70:18 error 'openpopup' is defined but never used no-unused-vars
73:18 error 'closepopup' is defined but never used no-unused-vars
Html with script:
<template>
<div class="customers-page">
<h2>Customers</h2>
<button type="add" class="add-button" onclick="openpopup()">Add</button>
<div class="popup" id="popup">
<h3>Input the following information</h3>
<button type="add-customer" class="submit-customer-button" onclick="closepopup()">Submit</button>
</div>
</div>
</template>
<script type="application/javascript" >
let popup = document.getElementById("popup");
function openpopup(){
popup.classList.add("open-popup")
}
function closepopup(){
popup.classList.remove("open-popup")
}
</script>
The very purpose to use Vue is to leverage its features for handling this type of logic reactively, Following is the snippet which can be used(vue 3 options api)
<template>
<div class="customers-page">
<h2>Customers</h2>
<button type="add" class="add-button" #click="openpopup">Add</button>
<!-- onclick="openpopup()" -->
<div class="popup" :class="popupToggle ? 'open-popup' : ''">
<h3>Input the following information</h3>
<button type="add-customer" class="submit-customer-button" #click="closepopup">Submit</button>
<!-- onclick="closepopup()" -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
popupToggle: false,
};
},
methods: {
openpopup() {
this.popupToggle = true;
},
closepopup() {
this.popupToggle = false;
},
},
};
</script>
Here the popup view is maintained by a state variable popupToggle, if you want to use something similar to id then you should go through refs here
When you use frameworks like Vue / React etc, using the native DOM is discourage (basically those .getElementById, .classlist.add or similar). One main reason is security, anyone can go to inspect and do DOM manipulations.
If you want to avoid the Options API boilerplate, you can use Composition API, which is similar to what you are doing.
Besides, if you are using conditional rendering, v-if is recommended instead of class binding, because the elements are not rendered if it is false.
<template>
<div class="customers-page">
<h2>Customers</h2>
<button type="add" class="add-button" #click="openPopup()">Add</button>
<div v-if="isShowPopup" class="popup">
<h3>Input the following information</h3>
<button type="add-customer" class="submit-customer-button" #click="closePopup()">Submit</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isShowPopup = ref(false)// acts similar to options api data block
// here I am using arrow functions
const openPopup = () => {
isShowPopup.value = true // in composition API, instead of using this., you use .value
}
const closePopup = () => {
isShowPopup.value = false
}
</script>
I have just started to learn VueJs and trying to bind a clickEvent and hide the message <article>. But it show the following warning-
[Vue warn]: Property or method "hideModel" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Although when i m trying in-line like.
<button type='button' v-on:click='isInvisible=false'>X</button>
It working fine. But with the function it not working.
index.html
<div id="root">
<message title="my-message" body="lorem ipsum sit ben"></message>
<message title="Other message" body="This is other message">
</message>
</div>
<link rel="stylesheet"href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css" />
<script src="https://unpkg.com/vue#2.6.10/dist/vue.js"></script>
<script src="main.js"></script>
main.js
Vue.component('message', {
props:['title', 'body'],
data(){
return {
isVisible:true
};
},
template:`<article class="message" v-show='isVisible'>
<div class="message-header">
<p>{{ title }}</p>
<button type='button' v-on:click='hideModel'>X</button>
</div>
<div class="message-body">
{{body}}
</div>
</article>`,
method:{
hideModel(){
this.isVisible=false;
}
}
})
new Vue({
el:"#root",
});
It happens because of mistyping. All methods should be placed into the methods. Don't forget about s in the end.
...
methods:{
hideModel(){
this.isVisible=false;
}
}
...
rename method to methods and you should be fine. You can add any arbitrary number of keys to the Vue component constructor object, but they will only be picked up by Vue if they correspond to the the known properties. Hence 'method' will be ignored, whereas 'methods' will work.
I've created a component, and in that component is an audio tag. I've been trying to pass the file path of the mp3 to the component from its parent, but the audio element doesn't seem to be able to load the file successfully for some reason. The element just ends up greyed out, and I don't get any kind of error. I know the properties are being passed successfully because I'm also passing in the title of the track, and that loads just fine in the component. However, if I hardcode the same path in for the source, then it works fine. Which isn't a big deal, but I have 11 tracks to do and it would be much easier with a v-for statement.
Here's my parent component:
<template>
<div container>
<div class=banner>
<img src="../assets/CryptoLogo2.svg"/>
</div>
<div class="albumcontainer">
<div class="covercontainer"><img src="../assets/TIADCover(Final).png"/></div>
<div class="arrow"></div>
<div class="tracklistcontainer">
<table class="tracklist">
<tr class="track" v-for="track in tracks" :key="track.file" style="padding: 20px;">
<td>
<player :name="track.name" :file="track.file" />
</td>
</tr>
</table>
</div>
</div>
<div class="bio">
<p>
</p>
</div>
<div class="footer">
<div class="footericons">
<img src="../assets/icons/Facebook.svg" />
<img src="../assets/icons/Instagram.svg" />
<img src="../assets/icons/Twitter.svg" />
</div>
</div>
</div>
</template>
<script>
import player from './player'
export default {
name: "Album1",
data() {
return {
tracks: [
{
name: '5G',
file: '../assets/tracks/5G.mp3'
}
]
}
},
components:{
player
}
};
</script>
And then the component with the audio tag:
<template>
<div>
<h3>{{ name }}</h3>
<audio controls controlsList="nodownload">
<source ref="player" v-bind:src="file" type="audio/mpeg">
</audio>
</div>
</template>
<script>
export default{
name: "player",
props: {
name: {
type: String,
default: null
},
file:{
type: String,
default: null
}
}
}
</script>
Here you can see that my data is being passed successfully.
And you see that the source attribute is being loaded correctly as well.
This is what I get, and you can see the h3 loads fine, so I know the data is being passed. But the element is greyed out.
To test it out, I tried just hard coding the file path:
<source src="../assets/tracks/5G.mp3">
And that works just fine:
But I don't want to do it like that because I have about 11 tracks to do, so I would like for it to load from the data being passed so that I can reuse the component. Any ideas?
try using something like this in your Vue v-for I use this when src is not loading on the img tag.
:src="getSrc(x.src)"
methods: {
getSrc(src) {
return require("../assets/" + src);
}
}
Your watch function on file prop is never triggered because your file name is static, it never triggers a change on the watcher, before mounting the component, at least in the code you provided it is that way.
From Vue.js API vm.$watch
Watch an expression or a computed function on the Vue instance for changes. The callback gets called with the new value and the old value.
I am trying to use the parallax within a react component. I have gotten this to work in the past. This is a MeteorJs project as well
I get a console error:
$(...).parallax is not a function
My component:
import React from 'react';
import $ from 'jquery';
export default class Index extends React.Component{
render(){
$(document).ready(function(){
$('.parallax').parallax();
});
return(
<div className="container">
<div className="parallax-container">
<div className="parallax"><img src="images/parallax1.jpg"/></div>
</div>
<div className="section white">
<div className="row container">
<h2 className="header">Parallax</h2>
<p className="grey-text text-darken-3 lighten-3">Parallax is an effect where the background
content or image in this case, is moved at a different speed than the foreground content while
scrolling.</p>
</div>
</div>
<div className="parallax-container">
<div className="parallax"><img src="images/parallax2.jpg"/></div>
</div>
</div>
)
}
}
My client main.js file:
import '../imports/startup/client/routes';
import '../node_modules/materialize-css/dist/js/materialize.min';
import '../node_modules/materialize-css/js/parallax';
The error message is telling you that .parallax() isn't a function in this line of code:
``
$('.parallax').parallax();
```
Which means that $('.parallax') is returning an object (usually a html element). It is not surprising that .parallax() is not a function, because it's just a html element.
Looking at the documentation, I think you are missing this initialisation code:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.parallax');
var instances = M.Parallax.init(elems, options); });
My view is like this :
<div class="row no-gutter">
<div class="col-md-9 col-xs-12">
<div class="wrap-tabs">
<ul class="nav nav-tabs nav-cat">
<li role="presentation" class="active">England</li>
<li role="presentation">Spain</li>
<li role="presentation">Italy</li>
</ul>
</div>
</div>
</div>
<br>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active">
<top-player-view country_id="1"></top-player-view>
</div>
</div>
My component top player view is like this :
<template>
...
</template>
<script>
export default{
props:['country_id'],
created() {
this.$store.dispatch('getTopPlayers', this.country_id)
}
methods: {
getPlayer: function(country_id) {
this.$store.dispatch('getTopPlayers', country_id)
}
}
}
</script>
I try call getPlayer method in top player view component. I call the method from view. You can see my code above
When I click the tab, I check on the console exist error :
[Vue warn]: Property or method "getPlayer" 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)
Uncaught TypeError: getPlayer is not a function
How can I solve it?
You need to actually call the method on the element.
One solution:
add ref="player" to your top-player-view and then call $refs.player.getPlayer(1) instead of just getPlayer(1)