link2740 link2741 link2742 link2743 link2744 link2745 link2746 link2747 link2748 link2749 link2750 link2751 link2752 link2753 link2754 link2755 link2756 link2757 link2758 link2759 link2760 link2761 link2762 link2763 link2764 link2765 link2766 link2767 link2768 link2769 link2770 link2771 link2772 link2773 link2774 link2775 link2776 link2777 link2778 link2779 link2780 link2781 link2782 link2783 link2784 link2785 link2786 link2787 link2788 link2789 link2790 link2791 link2792 link2793 link2794 link2795 link2796 link2797 link2798 link2799 link2800 link2801 link2802 link2803 link2804 link2805 link2806 link2807 link2808 link2809 link2810 link2811 link2812 link2813 link2814 link2815 link2816 link2817 link2818 link2819 link2820 link2821 link2822 link2823 link2824 link2825 link2826 link2827 link2828 link2829 link2830 link2831 link2832 link2833 link2834 link2835 link2836 link2837 link2838 link2839 link2840 link2841 link2842 link2843 link2844 link2845 link2846 link2847 link2848 link2849 link2850 link2851 link2852 link2853 link2854 link2855 link2856 link2857 link2858 link2859 link2860 link2861 link2862 link2863 link2864 link2865 link2866 link2867 link2868 link2869 link2870 link2871 link2872 link2873 link2874 link2875 link2876

[Vue.js] Vue CLI 3 build outputs files with tilde ~

In my application I’ve created different components that share common UI components like AppButton, AppSelect etc. I’m using webpack’s code splitting feature to lazy load components and get a separate chunk. Using vue.js CLI 3 build command I get ready to deploy files in dist folder.

Does anyone know what tilde “~” means? For example, in dist folder I can find name like settings-diet~start-personalization.6e2ac313.js that contains tilde.

Solution :

As of Webpack 4.2.0 the delimiter for the split chunk filenames can be configured through splitChunks.automaticNameDelimiter

Solution 2:

I’m using webpack’s code splitting feature to lazy load components and get a separate chunk.

This is why: you are lazy-loading modules.

In this case it looks like one of two things is going on:

you have an entry settings-diet that somewhere in its tree requires a file start-personalization. Rather than the source code of this required file being included in the bundle settings-diet it is being extracted (“split”) out of the main bundle to a separate file. This separate file can then be loaded only when it needs to be, i.e. lazily.
this file contains modules common to both the settings-diet and start-personalization entries.

The ~ character indicates that everything on its right has been extracted from whatever is on its left. The character used is configurable via the splitChunks.automaticNameDelimiter configuration property.

This is the work of the SplitChunksPlugin:

By default it only affects on-demand chunks, because changing initial chunks would affect the script tags the HTML file should include to run the project.

[Vue.js] How can I add condition on vue component that is loaded from the view blade laravel?

My view blade laravel like this :

@extends(‘layouts.app’)
@section(‘content’)

<transaction></transaction>

@endsection
@section(‘modal’)
<transaction-modal/>
@endsection

The view blade laravel load two vue.js component. That are transaction component and transaction modal component. So if the view blade executed, it will run the components

My transaction component like this :

<template>

<a href=”#” data-toggle=”modal” data-target=”#modal-transaction” @click=”show(item.id)”>View</a>

</template>
<script>

export default {

methods: {
show(id) {
….
}
}
}
</script>

My transaction modal like this :

<template>
<div id=”modal-transaction” class=”modal fade” tabindex=”-1” role=”dialog”>

</div>
</template>
<script>
export default {

}
</script>

From the script, the transaction modal component will run if the view blade called. the transaction modal run if user click view. If user not click view, the transaction modal component not executed

How can I do it?

Solution :

You are mixing of instantiation of vue.js components and Bootstrap’s modals event triggered.

What you can do is using Bootstrap modal events. Example code below:

<template>
<div id=”modal-transaction” class=”modal fade” tabindex=”-1” role=”dialog”>

</div>
</template>
<script>
export default {
methods: {
onModalOpen() {
// Do something when modal opens
},
onModalClose() {
// Do something when modal closed
}
},
mounted() {
$(‘#modal-transaction’).on(‘shown.bs.modal’, this.onModalOpen.bind(this))
$(‘#modal-transaction’).on(‘hidden.bs.modal’, this.onModalClose.bind(this))
}
}
</script>

[Vue.js] Property or method is not defined on the instance but referenced during renderProblemWhat can I do about it?

var MainTable = Vue.extend({
template: “<ul>” +
“<li v-for=’(set,index) in settings’>” +
“{index}) “ +
“{set.title}” +
“<button @click=’changeSetting(index)’> Info </button>” +
“</li>” +
“</ul>”,
data: function() {
return data;
}
});

Vue.component(“main-table”, MainTable);

data.settingsSelected = {};
var app = new Vue({
el: “#settings”,
data: data,
methods: {
changeSetting: function(index) {
data.settingsSelected = data.settings[index];
}
}
});

With the above code, the error below occurs when the button is clicked.

[vue.js warn]: Property or method “changeSetting” is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in <MainTable>)

Solution :

Problem

[vue.js warn]: Property or method “changeSetting” is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in <MainTable>)

The error is occurring because the changeSetting method is being referenced in the MainTable component here:

“<button @click=’changeSetting(index)’> Info </button>” +

However the changeSetting method is not defined in the MainTable component. It is being defined in the root component here:

var app = new Vue({
el: “#settings”,
data: data,
methods: {
changeSetting: function(index) {
data.settingsSelected = data.settings[index];
}
}
});

What needs to be remembered is that properties and methods can only be referenced in the scope where they are defined.

Everything in the parent template is compiled in parent scope; everything in the child template is compiled in child scope.

You can read more about component compilation scope in Vue’s documentation.

What can I do about it?

So far there has been a lot of talk about defining things in the correct scope so the fix is just to move the changeSetting definition into the MainTable component?

It seems that simple but here’s what I recommend.

You’d probably want the MainTable component to be a dumb/presentational component. (Here is something to read if you don’t know what it is but a tl;dr is that the component is just responsible for rendering something no logic). The smart/container element is responsible for the logic in the example given in the question the root component would be the smart/container component. With this architecture you can use Vue’s parent-child communication methods for the components to interact. You pass down the data for MainTable via props and emit user actions from MainTable to its parent via events. It might look something like this:

Vue.component(‘main-table’, {
template: “<ul>” +
“<li v-for=’(set, index) in settings’>” +
“{index}) “ +
“{set.title}” +
“<button @click=’changeSetting(index)’> Info </button>” +
“</li>” +
“</ul>”,
props: [‘settings’],
methods: {
changeSetting(value) {
this.$emit(‘change’, value);
},
},
});

var app = new Vue({
el: ‘#settings’,
template: ‘<main-table :settings=”data.settings” @change=”changeSetting”></main-table>’,
data: data,
methods: {
changeSetting(value) {
// Handle changeSetting
},
},
}),

The above should be enough to give you a good idea of what to do and kickstart resolving the issue.

[Vue.js] Vue cli 3 project ,dynamic src in image path not working

when referencing an image url in a vue.js component like

<img alt=”vue.js logo” src=”~statics/reports/logo.png”>

this works

but while trying

<img alt=”vue.js logo” :src=”getURL()”>

data() {
return { imgPath: “~statics/reports/logo.png” };
},

methods: {

getURL() {
//

// console.log(path)
return (this.imgPath)
}
},

it fails

My folder structure is

In the first case the path is resolved to

http://localhost:8081/img/logo.82b9c7a5.png

and served automatically by the dev server

The path is not resolved in the second case
it remains http://localhost:8081/~statics/reports/logo.png

when using vue.js cli 3 generated default config for webpack .

I do not want to use relative paths for all images like ../images/ as it makes it more verbose.
there is tried require(pathVariable) that too does not work
Please help with resolving the img path when the url is dynamic ie asset name comes from server and i append a path in a method or computed and use :src dynamicbinding to serve it

Solution :

The second way fails because “~” try to get this asset from node_modules. You can read more about handling assets here:
https://cli.vuejs.org/guide/html-and-static-assets.html#relative-path-imports.

To fix it just use require like below:

data() {
return {
imgPath: require(‘@/statics/logo.png’)
}
}

..or directly in template:

<img alt=”vue.js logo” :src=”require(‘@/statics/logo.png’)”>

[Vue.js] Pass method from parent component to child component in vuejs

Can someone help me with passing a method from a parent to a child component in vue.js? I’ve been trying to do it by passing the method in as a prop…

My parent component snippet:

methods: {

test: function () {
console.log(‘from test method’)
}

}

<template>
<child-component test=”test”><child-component>
</template>

Child component snippet

created: {
this.test() //returns test is not a function
},

props: [‘test’]

Can someone help?

Thanks in advance!

Solution :

You are trying to pass a function as literal as described here. You end up with test prop being String… You should use : to indicate dynamic binding as follows:

<child-component :test=”test”><child-component>”

Solution 2:

This is simple. No need for props.
From the child’s component just call this.$parent.test();

created: {
this.$parent.test() //calls function test() in parent
},

[Vue.js] CORS Post Request Fails

I built an API with the SLIM Micro-Framework. I setup some middleware that adds the CORS headers using the following code.

class Cors{

public function __invoke(Request $request, Response $response, $next){

$response = $next($request, $response);
return $response
->withHeader(‘Access-Control-Allow-Origin’, ‘http://mysite')
->withHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, Accept, Origin, Authorization’)
->withHeader(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’);
}

}

For my front-end, I used VueJS. I setup VueResource and created a function with the following code.

register (context, email, password) {
Vue.http({
url: ‘api/auth/register’,
method: ‘POST’,
data: {
email: email,
password: password
}
}).then(response => {
context.success = true
}, response => {
context.response = response.data
context.error = true
})
}

In chrome, the following error is logged to the console.

XMLHttpRequest cannot load http://mysite:9800/api/auth/register. Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://mysite' is therefore not allowed access.

Oddly enough, GET requests work perfectly.

Solution :

You half 1/2 the solution here.

What you are missing is an OPTIONS route where these headers need to be added as well.

$app->options(‘/{routes:.+}’, function ($request, $response, $args) {
return $response
->withHeader(‘Access-Control-Allow-Origin’, ‘http://mysite')
->withHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, Accept, Origin, Authorization’)
->withHeader(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’);
});

Solution 2:

Actually CORS is implemented at browser level. and Even with

return $response
->withHeader(‘Access-Control-Allow-Origin’, ‘http://mysite')
->withHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, Accept, Origin, Authorization’)
->withHeader(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’);

chrome and Mozilla will not set headers to allow cross origin. So, you need forcefully disable that..

Read more about disabling CORS

Disable same origin policy in Chrome

Solution 3:

This happens because preflight request is of OPTIONS type. You need to make an event listener on the request, which checks the type and sends a response with needed headers.

Unfortunately i don’t know Slim framework, but here’s the working example in Symfony.

First the headers example to be returned:

// Headers allowed to be returned.
const ALLOWED_HEADERS = [‘Authorization’, ‘Origin’, ‘Content-Type’, ‘Content-Length’, ‘Accept’];

And in the request listener, there’s a onKernelRequest method that watches all requests that are coming in:

/**
* @param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
// Don’t do anything if it’s not the master request
if (!$event->isMasterRequest()) {
return;
}

// Catch all pre-request events
if ($event->getRequest()->isMethod(‘OPTIONS’)) {
$router = $this->container->get(‘router’);
$pathInfo = $event->getRequest()->getPathInfo();

$response = new Response();
$response->headers->set(‘Access-Control-Allow-Origin’, $event->getRequest()->headers->get(‘Origin’));
$response->headers->set(‘Access-Control-Allow-Methods’, $this->getAllowedMethods($router, $pathInfo));
$response->headers->set(‘Access-Control-Allow-Headers’, implode(‘, ‘, self::ALLOWED_HEADERS));
$response->headers->set(‘Access-Control-Expose-Headers’, implode(‘, ‘, self::ALLOWED_HEADERS));
$response->headers->set(‘Access-Control-Allow-Credentials’, ‘true’);
$response->headers->set(‘Access-Control-Max-Age’, 60 * 60 * 24);
$response->send();
}
}

Here i just reproduce the Origin (all domains are allowed to request the resource, you should probably change it to the domain).
Hope it will give some glues.

Solution 4:

CORS can be hard to config. The key is that you need to set the special headers in the server and the client, and I don’t see any vue.js headers set, besides as far as I know http is not a function. However here is some setup for a post request.

const data = {
email: email,
password: password
}
const options = {
headers: {
‘Access-Control-Expose-Headers’: // all of the headers,
‘Access-Control-Allow-Origin’: ‘*‘
}
}
Vue.http.post(‘api/auth/register’, JSON.stringify(data), options).then(response => {
// success
}, response => {
// error
})

Notice that you need to stringify the data and you need to expose the headers, usually including the Access-Control-Allow-Origin header.
What I did in one of my own apps was to define interceptors so I don’t worry to set headers for every request.

Vue.http.headers.common[‘Access-Control-Expose-Headers’] = ‘Origin, X-Requested-With, Content-Type, Accept, x-session-token, timeout, Content-Length, location, *‘
Vue.http.headers.common[‘Access-Control-Allow-Origin’] = ‘*‘

[Vue.js] Update parent model from child component Vue

there is a very small app that has a donation form. The form walks the user through the steps of filling in information. there is a main component, which is the form wrapper and the main vue.js instance which holds all of the form data (model). All of the child components are steps within the donation process. Each child component has input fields that are to be filled out and those field will update the parent model so that there is all of the form data in the parent model when I submit the form. Here is how the components are put together:

<donation-form></donation-form> // Main/Parent component

Inside the donation-form component:

<template>
<form action=”/“ id=”give”>
<div id=”inner-form-wrapper” :class=”sliderClass”>
<step1></step1>
<step2></step2>
<step3></step3>
</div>
<nav-buttons></nav-buttons>
</form>
</template>

Right now, when setting the data from the inputs in each child component and then there is a watch method that is watching for fields to update and then when pushing them to the $root by doing this…

watch: {
amount() {
this.$root.donation.amount = this.amount;
}
}

The problem is that one of my steps there is a lot of fields and I seem to be writing some repetitive code. Also, I’m sure this is not the best way to do this.

I tried passing the data as a prop to my child components but it seems that I cannot change the props in my child component.

What would be a better way to update the root instance, or even a parent instance besides add a watch to every value in my child components?

More examples
Here is my step2.vue.js file - step2 vue.js file
Here is my donation-form.vue.js file - donation-form vue.js file

Solution :

You can use custom events to send the data back.

To work with custom events, the data should be in the parent component, and pass down to children as props:

<step1 :someValue=”value” />

and now you want to receive updated data from child, so add an event to it:

<step1 :someValue=”value” @update=”onStep1Update” />

the child components will emit the event and pass data as arguments:

this.$emit(‘update’, newData)

the parent component:

methods: {
onStep1Update (newData) {
this.value = newData
}
}

Here is a simple example with custom events:
http://codepen.io/CodinCat/pen/QdKKBa?editors=1010

And if all the step1, step2 and step3 contain tons of fields and data, you can just encapsulate these data in child components (if the parent component doesn’t care about these row data).

So each child has its own data and bind with <input />

<input v-model=”data1” />
<input v-model=”data2” />

But the same, you will send the result data back via events.

const result = this.data1 * 10 + this.data2 * 5
this.$emit(‘update’, result)

(again, if the application becomes more and more complex, vuex will be the solution.

Solution 2:

Personally I prefer having a generic function for updating the parent, when working with forms, instead of writing a method for every child. To illustrate a bit condensed like this in the parent:

<template lang=”pug”>
child-component(:field=”form.name” fieldname=”name” @update=”sync”)
</template>
<script>
export default {
methods: {
sync: function(args) {
this.form[args.field] = args.value
}
}
}
</script>

And in the child component:

<template lang=”pug”>
input(@input=”refresh($event.target.value)”)
</template>
<script>
export default {
props: [‘field’, ‘fieldname’],
methods: {
refresh: function(value) {
this.$emit(‘update’, {‘value’: value, ‘field’: this.fieldname});
}
}
}
</script>

Solution 3:

For the case you can use v-model like following:

<form action=”/“ id=”give”>
<div id=”inner-form-wrapper” :class=”sliderClass”>
<step1 v-model=”step1Var”></step1>
<step2 v-model=”step2Var”></step2>
<step3 v-model=”step3Var”></step3>
</div>
<nav-buttons></nav-buttons>
</form>

v-model is essentially syntax sugar for updating data on user input events.

<input v-model=”something”>

is just syntactic sugar for:

<input v-bind:value=”something” v-on:input=”something = $event.target.value”>

You can pass a prop : value in the child components, and on change of input field call following which will change the step1Var variable.

this.$emit(‘input’, opt)

You can have a look at this answer where you can see implementation of such component where a variable is passed thouugh v-model.

[Vue.js] How to update data on a page without refreshing on the vue.js?

My view is like this :

<div class=”favorite” style=”margin-bottom:5px;”>
@if (Auth::user())
<add-favorite-store :id-store=”{ $store->id }”></add-favorite-store>
@else
<a href=”javascript:” class=”btn btn-block btn-success”>
<span class=”fa fa-heart”></span> Favorite
</a>
@endif
</div>

My component is like this :

<template>
<a href=”javascript:” class=”btn btn-block btn-success” @click=”addFavoriteStore($event)”>
<span class=”fa fa-heart”></span> <label id=”favoriteId”>{ store_id == ‘responseFound’ ? ‘Un-Favorite’ : ‘Favorite’ }</label>
</a>
</template>

<script>
export default{
props:[‘idStore’],
mounted(){
this.checkFavoriteStore()
},
methods:{
addFavoriteStore(event){

var label = $(‘#favoriteId’)
var text = label.text()

event.target.disabled = true
const payload= {id_store: this.idStore}

if(text == “Favorite”) {
this.$store.dispatch(‘addFavoriteStore’, payload)
}
else {
this.$store.dispatch(‘deleteFavoriteStore’, payload)
}

setTimeout(function () {
location.reload(true)
}, 1500)
},
checkFavoriteStore(){
const payload= {id_store: this.idStore}
var data = this.$store.dispatch(‘checkFavoriteStore’, payload)
data.then((res) => this.store_id = res)
}
},
data() {
return {
store_id: ‘’
}
}
}
</script>

On the my code above, I using

location.reload(true)

to update data on the page. But it’s reload the page.

when update the page, it’s not reload the page

How can I do it?

Solution :

Ok Here is a simple use case but less complicated as yours and using vuejs as it should be used. (http://codepen.io/simondavies/pen/MJOQEW)

OK let laravel/php code get the store ID as well as if its already been favorited. This way the script is not first checking the store to then decide what to do.

What this does is sends the store-id and the is-favorited through the component like:

<favorite :store-id=”{$store->id}” :is-favorited=”{$store->isFavorited}”></favorite>

Then the vue.js component will update the button to display if its already liked (red) or not (grey), and then also handle the click event and update accordingly as well.

As you are using Laravel to tell the component if it’s already favorited you can get rid of the checking function and one less http request. Then you only need to then update the store when the user clicks the favourite button.

And as seen in the demo it updates, no need to refresh.

I hope this help you re-write yours so you get waht you want.

PS there is left out the Logged IN check @if (Auth::user()) you have so you can put that back in etc

Vue.component(‘favorite’, {
template: ‘<button type=”button” @click.prevent=”updateFaviteOption” :class=”{ \‘is-favorited\‘: isFavorited }”><span class=”fa fa-heart”></span></button>’,
props: [
‘storeId’,
‘isFavorited’
],
data: function() {
return {}
},
methods: {
updateFaviteOption: function() {
this.isFavorited = !this.isFavorited;
///– DO YOU AJAX HERE i use axios
///– so you can updte the store the the this.isFavorited
}
}

});

new Vue({
el: ‘#app’,
});
.favorite-wrapper {
margin: 20px auto;
padding: 0;
text-align: center;
width: 500px;
height: 100px;
}
a:link,
a:active,
a:visited {
text-decoration: none;
text-transform: uppercase;
color: #444;
transition: color 800ms;
font-size: 18px;
}
a:hover,
a:hover:visited {
color: purple;
}
button {
margin: 10px auto;
padding: 8px 10px;
background: transparent;
width: auto;
color: white;
text-transform: uppercase;
transition: color 800ms;
border-radius: 4px;
border: none;
outline: none;
}
button:hover {
cursor: pointer;
color: #058A29;
}
.fa {
color: #d9d9d9;
font-size: 20px;
transition: color 400ms, transform 400ms;
opacity: 1;
}
.is-favorited .fa {
opacity: 1;
color: red;
transform: scale(1.4);
}
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<link href=”https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel=”stylesheet” />
<link href=”https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" rel=”stylesheet” />
<div id=”app”>

<div class=”favorite-wrapper”>
<favorite :store-id=”3” :is-favorited=”true”>
</favorite>
</div>

</div>

Solution 2:

Another solution explained in vue-router doc. Simply use the watch system applied to the $route native attribute. You’ll be able to detect new route even if they use the same component and fetch the data in consequence.

Solution 3:

What you need is vm-forceUpdate.

Force the vue.js instance to re-render. Note it does not affect all child components, only the instance itself and child components with inserted slot content.

I haven’t tried using this myself, just came across it while working on a project.

vue.js forceUpdate or you could just call the function in the setTimeout method.

setTimeout(function () {
this.checkFavoriteStore();
}, 1500)

You are using a lot of javascript here, you can use vue.js to do most of the work there.

Solution 4:

Theres a lot thats not mentioned here to help answer the question as good as we could, its needs the html in question, what need to update and to what etc.

I think it’s best you look at this https://laracasts.com/series/learn-vue-2-step-by-step for a good understanding of how Vuejs works and how to do simple things like, this.

the using in-depth store/vuex type coding and if the not understanding the basics then it can get hard to work out the answer for you.

Sorry to be a bit blah but.

[Vue.js] Select2 on change event is not working in Vuejs

I was working with select2 in vuejs , I found vuejs is not working with jquery select2 as vuejs is working with navite html.

when using this code

Vue.directive(‘select’, {
twoWay: true,
bind: function () {
$(this.el).select2()
.on(“select2:select”, function(e) {
this.set($(this.el).val());
}.bind(this));
},
update: function(nv, ov) {
$(this.el).trigger(“change”);
}
});
var app = new Vue({
el: ‘#app’,
data: {
supplier_id: “niklesh”
}
})
$(‘#supplier_id’).select2({});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.js"></script>
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css">
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css">
<div id=”app”>
{ supplier_id }

<select id=”supplier_id” class=’form-control’ v-model=’supplier_id’ v-select=’supplier_id’>
<option value=”atul”>Atul</option>
<option value=”niklesh”>Niklesh</option>
<option value=”sachin”>Sachin</option>
</select>

</div>

Please share the reply to handle this problem.

Solution :

To get this to work with a directive, we need to understand how v-model works. From the docs:

<input v-model=”something”>

is just syntactic sugar for:

<input v-bind:value=”something” v-on:input=”something = $event.target.value”>

In the case of a select element, v-model will listen for the change event (not input). So, if the directive dispatches a change event when the element changes, then v-model will work as expected.

Here is an updated version of the code:

Vue.directive(‘select’, {
twoWay: true,
bind: function (el, binding, vnode) {
$(el).select2().on(“select2:select”, (e) => {
// v-model looks for
// - an event named “change”
// - a value with property path “$event.target.value”
el.dispatchEvent(new Event(‘change’, { target: e.target }));
});
},
});
var app = new Vue({
el: ‘#app’,
data: {
supplier_id: “niklesh”
},
})
$(‘#supplier_id’).select2({});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.js"></script>
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css">
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css">
<div id=”app”>
{ supplier_id }

<select id=”supplier_id” class=’form-control’ v-model=’supplier_id’ v-select=’supplier_id’>
<option value=”atul”>Atul</option>
<option value=”niklesh”>Niklesh</option>
<option value=”sachin”>Sachin</option>
</select>

</div>

Solution 2:

By assigning select2 value to vuejs data when able to fix this problem. I didn’t use custom directive here.

var app = new Vue({
el: ‘#app’,
data: {
supplier_id: “niklesh”
},
filters: {
capitalize: function (value) {
if (!value) return ‘’
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
});

$(‘#supplier_id’).on(“change”,function(){
app.supplier_id = $(this).val();
console.log(‘Name : ‘+$(this).val());
});

$(‘#supplier_id’).select2({});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.js"></script>
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css">
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css">
<div id=”app”>
Name : { supplier_id | capitalize }
<select id=”supplier_id” class=’form-control’ v-model=’supplier_id’>
<option value=”atul”>Atul</option>
<option value=”niklesh”>Niklesh</option>
<option value=”sachin”>Sachin</option>
</select>

</div>

Please comment if this is not good way or any better solution you suggest.

Solution 3:

<select v-model=”selected”>
<option value=”1”>1</option>
<option value=”2”>2</option>
<option value=”3”>3</option>
</select>

const self = this;
$(“select”).change(function () {
const val = $(this).find(“option:selected”).val();
self.selected = val;
});

Solution 4:

Try add v-on:change=”onChange” in the select control

HTML template

<select id=”supplier_id” class=’form-control’
v-model=’supplier_id’ v-select=’supplier_id’ v-on:change=”onChange”>
<option value=”atul”>Atul</option>
<option value=”niklesh”>Niklesh</option>
<option value=”sachin”>Sachin</option>
</select>

“onChange” is the name of the method

JavaScript

methods: {
onChange(e) {
alert(“Change”);
}
}

[Vue.js] very simple vue.js component generate maximum call stack size exceeded

there is a very simple vue.js component which display list of data (2 objects with 2 fields).

component vue.js code :

<template>

<div>

<h1>Genre</h1>

<b-container>
<b-row>
<b-col v-for=”data in genre” v-bind:key=”data.id” v-bind:title=”data.name”>
<b-card title=”fefefe”
tag=”genre”
style=”max-width: 20rem;”
class=”mb-2”>
</b-card>
</b-col>
</b-row>
</b-container>

</div>

</template>

<script>

export default
{
name: ‘genre’,

data: function ()
{
return {
genre: [
{id:1, name:’toto’},
{id:2, name:’tata’},
]
}
},
}
</script>

<style scoped>

</style>

But when I displayed this component there is a error :

[vue.js warn]: Error in nextTick: “RangeError: Maximum call stack size
exceeded”

I don’t understand why my loop “for” throws that error dealing with my few data.
there is another component that retrieve data by SQL promise (on mounted()) and I don’t generate this error. Moreover there is more data for this component but no call stack error. This is very strange for me.

What nicety I forget ?

Solution :

The problem is the following:

You defined a component genre with name: “genre”
The tag=”genre” in the b-card tries to use the genre component as the card

The result is that you are loading the own component recursively, who goes through the same loop and loads the component again. Until you hit the maximum stack size.

The following sandbox shows that if you rename the component, vue.js will complain about a non-existent genre element that it tries to load. Otherwise you get the maximum call stack error.