how to pass a function as parameter in a vue directive - vue.js

in react and jsx I would use curly braces to pass nested functions and their params, as parameters. but since there is this quote syntax in vue js, I am confused.
what I'm trying to do is something like this:
<span #click="myFirstFunction( ()=> console.log('param') )" />
myFirstFunction(code){
code();
}
actually, this is the simplified version
what I'm trying to do is to save that code in an state and run it in other situations
but this doesn't seem to work.

Actually, your syntax is correct. But in your simple example, you are trying to access a property or a data which is not defined. You may think console is a global object it should be accessed from anywhere, but no. You can only access component properties (data, methods, etc.) from the template in VUE. So you should do something like below to access the console or any other global object:
data() {
return {
console: Object,
};
},
created() {
this.console = console;
},
SandBox

You should do either
<span #click="() => console.log('param')" />
or
<span #click="myFirstFunction" />
myFirstFunction should be defined as a method.
methods: {
myFirstFunction() {
// your function
}
}

Related

How do you get variables from the setup script in vue3

How would I access variables declared within the setup script within the none setup script? I attempt to update the message in the example below when something happens within the script tags. However, msg just returns undefined, I've looked through the Vue documentation on setup scrips, but there doesn't seem to be any mention of accessing the variable in none setup scripts.
<script setup>
var msg = 'Hello!';
</script>
<script>
export default {
data() {
return {
};
},
mounted(){
// my current attempt to get msg and update it. However, I just get undefined.
this.msg = 'Something happened inside script tags';
//or msg = 'Something happened inside script tags';
},
</script>
<template>
<p>{{ msg }}</p>
</template>
Seems like you are mixing up two syntaxes here - the newer, Composition API (Vue3, setup script) and Options API (Vue2 style, one with data and mounted functions). While it's still ok to use the Options API syntax, you should only use one of the two. I suggest reading up on the different syntaxes:
Composition API
Options API
The tag is syntactic sugar for THIS type of syntax. Everything returned by the setup() function will be made available to the template. If you're using the tag, by default everything is made available.
For the Options API syntax, everything returned by the data function is made available to the template. Delete the entire first tag and try adding the "msg" property to the object returned by the data function and see if it works.
data() {
return {
msg: ''
};
}

How can I update the msg variable in the following code?

I have written the following code in a single Vue component. I am very new to Vue. I want to know how can I update the msg variable in the following and pass the updated value to the template in this Vue component:
<template>
<div class="dropzone">
<form id="dropzone" method='POST' enctype="multipart/form-data" v-on:drop="upload" #dragover.prevent>
<my-vue-component v-model="msg" ref="markdownEditor" />
</form>
</div>
</template>
<script>
export default {
data: () => {
return {
msg: 'zyx'
}
},
methods: {
upload: (e) => {
self.msg = '123'
}
}
}
</script>
I am really stuck and none of the links that google redirects me to are out of my reach. Because all of them either talk about new Vue({}) or dont provide much on export default.
Am I doing something wrong here?
I have also tried this.msg, but then I get the error saying msg of undefined...
Change this:
upload: (e) => {
self.msg = '123'
}
to this:
upload (e) {
this.msg = '123'
}
Note that upload (e) { is short-hand for upload: function (e) {.
The key changes are:
Use this instead of self.
Don't use an arrow function because that binds this to the surrounding scope and in this case that's the global scope. What you want is for this to be bound to your component instance (which is actually a Vue instance) so you need to use a normal function. Vue tries to ensure the binding is correct but it can't do that with an arrow function because it is already bound.
The config options that appear in a component like this are almost all the same as the config options that you would pass to new Vue, so if you see examples that are using the other one it will rarely make any difference. Usually it is pretty obvious when a config setting doesn't make sense for one or the other.

How can i use the method like "paper.on('cell:pointerdblclick', function (cellView){})" in a vue file?

I want to use jointjs to achieve a demand, like this:
paper.on('cell:pointerdblclick', function(cellView) {}). In vue, what should i do?
ReferenceError: cellView is not defined
<script>
export default {
mounted(){},
methods: {
registerDoubleClickEvent()
{this.paper.on('cell:pointerdblclick',
this.connectTwoObject(cellView))},
connectTwoObject(cellView){alert('1234');},
}}
</script>
Thanks in advance!
As i understood from the question, you want to pass the first argument of callback to your method. Seems like your syntax is wrong. You are just calling your method with an undefined variable. To access this variable try the code bellow (arrow function is used to save the context). Also, I believe you have connectTwoObject method defined in your methods.
export default {
mounted() {},
methods: {
registerDoubleClickEvent() {
this.paper.on('cell:pointerdblclick', cellView =>
this.connectTwoObject(cellView),
)
},
},
}

VeeValidate check for errors in entire scope

I am trying to render out a warning if there is an error within a specific scope. This is due to the form being across multiple tabs and hopefully making it easier for people to see what needs fixing.
The issue is, I have tried multiple methods but they are not working. This is the current method:
const TabInternals = Vue.component('TabInternals', {
props: {
title: String,
scope: String
},
render() {
return (
<div>
<i v-show={this.errors.any(`${this.scope}.*`)} class="fas fa-exclamation-circle"></i>{` ${this.title}`}
</div>
);
}
});
Can anyone see what I am doing wrong?
Thanks in advance
By default, each component gets its own instance of a vee validator (and therefore errors too). If you want to access errors from a different scope, you will need to use inject to pass the parent validator instance to the child components so that they share a validator instance:
export default {
inject:[ '$validator'],
// ...
};
ref - https://github.com/baianat/vee-validate/issues/1774

vue-i18n : how to use inside vue instance filter

I want to use a filter to perform translations.
Problem is that 'this' doesn't point to my vue instance inside my filter function.
This is what I currently have.
inside my template I have this:
<p>{{ parking.status | translate }} </p>
inside my component I have this:
new Vue({ ...
filters: {
translate: function(value, vue) {
return this.$i18n.t('MLAA-47');
}
The error I get is that this == undefined.
How do i point it to my vue instance inside my filter function ?
As points #vitaly-mosin in the comment in that answer explains that you couldn't use this inside the filter functions.
filters are primarily designed for text transformation purposes. For
more complex data transforms in other directives, you should use
Computed properties instead.
I had the same issue and I resolved moving the translation with $i18n to a computed method, like:
Inside your template, instead of this:
<p>{{ parking.status | translate }} </p>
Change it to:
<p>{{ translateStatus(parking.status) }} </p>
And in the methods:
methods: {
translateStatus (status) {
return this.$t(status)
}
},
I guess that you have a dynamic status (not returning always: 'MLAA-47') and you should assert that you have translations for all of them. It worked for me!
Hope it helps to you too
We can import file exporting i18n instance like this
import i18n from '#/i18n.js'
And use it like this
i18n.t('your.message')
I am not sure if this is a good idea, but so far it is doing what I want.
Define the filters like
// the instance.vue will be set on App.vue
export const instance = {
vue: null
};
// little helper
const t = (key) => instance.vue?.$t?.(key);
export default {
filter: (v) => v + t('somekey')
}
Then in App.vue (or whatever it is you use), do
import {instance} from '#/filters'
export default {
mounted() {
instance.vue = this; // set the instance here