this.$refs.name.select() function not found in vue - vue.js

I am using Vue refs in my application so that in click a button some text will be select and copy. So I am using like
//In template
<input type="text" ref="url" value="my url"/>
<button #click="copylink">Copy Link</button>
//in methods
copylink() {
this.$refs.url.select()
}
that is undefined.
But Using document.querySelector('input').select() I can select that.
My question is it possible all document methods using $refs. How do you do this?

If you do console.log(this.$refs.url) it will give you back an array type result. All you have to do is: this.$refs.url[0].select() and it will work.
Let me know.

Related

Vue : Custom parameter [duplicate]

I pass a parameter in v-on:input directives. If I don't pass it, I can access the event in the method. Is there any way I can still access the event when passing the parameter to the function? Note that I am using vue-router.
This is without passing the parameter. I can access the event object:
HTML
<input type="number" v-on:input="addToCart" min="0" placeholder="0">
Javascript
methods: {
addToCart: function (event) {
// I need to access the element by using event.target
console.log('In addToCart')
console.log(event.target)
}
}
This is when passing the parameter. I can't access the event object:
HTML
<input type="number" v-on:input="addToCart(ticket.id)" min="0" placeholder="0">
Javascript
methods: {
addToCart: function (id) {
// How can I access the element by using event
console.log('In addToCart')
console.log(id)
}
}
Here is a fiddle of the code, it should be good enough to replicate the problem that I am having:
https://jsfiddle.net/lookman/vdhwkrmq/
If you want to access event object as well as data passed, you have to pass event and ticket.id both as parameters, like following:
HTML
<input type="number" v-on:input="addToCart($event, ticket.id)" min="0" placeholder="0">
Javascript
methods: {
addToCart: function (event, id) {
// use event here as well as id
console.log('In addToCart')
console.log(id)
}
}
See working fiddle: https://jsfiddle.net/nee5nszL/
Edited: case with vue-router
In case you are using vue-router, you may have to use $event in your v-on:input method like following:
<input type="number" v-on:input="addToCart($event, num)" min="0" placeholder="0">
Here is working fiddle.
You can also do something like this...
<input #input="myHandler('foo', 'bar', ...arguments)">
Evan You himself recommended this technique in one post on Vue forum. In general some events may emit more than one argument. Also as documentation states internal variable $event is meant for passing original DOM event.
Depending on what arguments you need to pass, especially for custom event handlers, you can do something like this:
<div #customEvent='(arg1) => myCallback(arg1, arg2)'>Hello!</div>
I like this way of passing parameters because we can pass events and parameters both using an anonymous callback function.
<button v-on:click="(e)=>deleteHandler(e, args1)" > Click me </button>

Vue seems to be calling all custom directives more often than expected. Why, can this be avoided?

I'm only a few months into vue coming from an angularjs background.
I built my first custom directive and it's acting a little odd to me.
Vue.directive('silly',{
componentUpdated: function (el, binding, vnode) {
console.log("it was called");
}
});
and I place it on my form like this:
<form id="opt-cpmt-form" method="post" class="mri-grid mri-p-none">
<label for="one">name<input id="one" type="text" v-model="local.name" v-silly class="form-control"></label><br/>
<label for="two">phone<input v-isnumeric id="two" type="text" v-model="local.phone" class="form-control "></label><br/>
<label for="two">zip<input id="three" type="text" v-model="local.zip" class="form-control" ></label><br/>
</form>
It kinda works...the part that I didn't understand is that my v-silly directive is called when any of the other fields are updated too. It seems to be related to the model but I only want my directive called when the field changes.
Any ideas??
It's an expected behaviour as the component updates whenever a piece of its data object is updated. To not trigger the logic too many times, you can create an event listener when the directive is bound to its parent and then run the logic when a desired event happens.
Vue.directive('silly', {
bind(el) {
this.updateCallback = function(event) {
// Your logic
};
el.addEventListener('input', this.updateCallback);
},
unbind(el) {
el.removeEventListener('input', this.updateCallback);
}
});
In case you plan to listen to the changes of v-model directive, bear in mind that it uses different events based on what element it's bound to. You can read more about that topic in v-model documentation.
v-model internally uses different properties and emits different events for different input elements:
text and textarea elements use value property and input event;
checkbox and radiobutton inputs use checked property and change event;
select fields use value as a prop and change as an event.
Also, from my experience when it comes to the form validation; I've done it using the directives and regretted it afterwards. I found it best to create reusable functions and create the custom form validation for every form. See custom form validation for more.

Vuejs keyup event trigger with keyCode and condition

I wanted to bind an event on condition and trigger it only when the user enters a particular key, For example,
I want to bind the event when the value of the label equal to tags
onTagAdd($event, index) : {} }" v-model="value">
onTagAdd: function (oEvent, index){
if(oEvent.key === ";"){
//some code
}
}
It's working as expected.
Further, I wanted to trigger the event only when ; (virtual key code = 186) pressed, so I have tried below code
onTagAdd($event, index) : {} }" v-model="value">
It is not working. I have referred vue.js documentation But, haven't got any workaround.
How to do this?
Note: I have eliminated this approach as it's giving me an error in IE for $event. still looking for the solution if any which solves the problem and support the browser compatibility.
Try this out and tell me if it worked.
<input type="text" v-on:keyup.186="{ (label == 'Tags') ? $event => onTagAdd($event, index) : {} }" v-model="value">
maybe the inline style doesn't support keycode in event type(not sure),try this out:
<input type="text" v-on:keyup.186="onTagAdd($event,2)" v-model="value">
methods: {
onTagAdd(event,index){
// put your logic codes here
console.info('==')
console.info(event)
console.info(index)
}
}
This page was helpful for me in Vue3: https://v3-migration.vuejs.org/breaking-changes/keycode-modifiers.html
3.x Syntax#
Since KeyboardEvent.keyCode has been deprecated, it no longer makes sense for Vue 3 to continue supporting this as well. As a result, it is now recommended to use the kebab-case name for any key you want to use as a modifier.
<!-- Vue 3 Key Modifier on v-on -->
<input v-on:keyup.page-down="nextPage">
<!-- Matches both q and Q -->
<input v-on:keypress.q="quit">
As a result, this means that config.keyCodes is now also deprecated and will no longer be supported.
TLDR: in Vue 3 keycodes appear to be deprecated in favour of using kebab case.
For example, #keyup.186 would be #keyup.;

Vue.js - Typeahead Directive

Vue.js Directive for Typeahead
I am trying to write a Vue Directive for typeahead.js functionality. I was able to instantiate typeahead on the input form control and also assign it options and dataset. Event handling too was not a problem.
The Issue :
Now, I also want to control the typeahead input element from the component. For example, I would like to control these methods $(el).typeahead('destroy') or $(el).typeahead('open'), etc. from the component.
How can i call these methods from the Component? Is it possible ?
Ok, I just figured it out 2 minutes after typing the question.
I add a ref to the input tag.
<!-- bindings is an object which has the "options" and "dataset" -->
<input ref="ttInput" v-typeahead="bindings" />
Then, I have added a method in the component which executes typeahead methods from the component:
...
methods: {
methodHook (action) {
const el = this.$refs.ttInput
$(el).typeahead(action)
}
}
...
So, now, in the html template, i can have a button/buttons:
<button type="button" #click="methodHook('open')" >Open</button>
<button type="button" #click="methodHook('close')">Close</button>
Works like a charm.
Thanks

When v-for array created by computed option changs, the DOM doesn't change accordingly

Recently, I've encountered a problem that caused by the computed option of vuejs.
Firstly, I use v-for to loop for an array (soloColImgs) which is created by the computed option.
my HTML
<div class="show-box" v-for="item in soloColImgs" track-by="$index">
<img v-bind:src="item.imgUrl"/>
<a v-bind:href="item.itemUrl" target="_blank"></a>
</div>
my JS
//...
computed: {
soloColImgs :function(){
//....
},
methods: {
change:function(){
this.soloColImgs.pop();
}
}
Secondly, I change the array (soloColImgs) by using pop() or splice() etc...When I look into the console, the array can change accordingly, however, the DOM does't change at all. It would be greatful if anyone can help me out of this.
The point of a computed property is that its determined solely by the function that defines it. You cannot change it directly, you must change it by acting on the dependencies. The dependencies are the properties that are used to calculate the returned value.