Skip to content
Advertisement

v-model in html.erb template renders function () { [native code] }

I am in the process of adding Vue.js to my Rails 6 app. The project is using turbolinks so “vue-turbolinks” is installed via yarn and my Vue config looks like this:

import TurbolinksAdapter from 'vue-turbolinks';
import Vue from 'vue/dist/vue.esm';
Vue.use(TurbolinksAdapter);

document.addEventListener('turbolinks:load', () => {
  const app = new Vue({
    el: '[data-behavior="vue"]',

    data() {
      return {
        message: 'This string will update with input from text field',
      };
    },

    methods: {
      updateMessage(event) {
        this.message = event.target.value;
      },
    }
  });
});

and my rails template(.html.erb) contains a text field with a Vuejs “v-model” attribute

  <div data-behavior="vue">
    {{ message }}
      <%= f.text_field :title, "v-model": "updateMessage" %>
  </div>

Vue seems to be working as expected, except “v-model” is outputting literal function instead of calling the function(updateMessage). As a result the text field renders with value of

"function () { [native code] }"

However changing “v-model” to “v-on:input” does what i expect it to do: update the message on input.

Can anyone shed light on whats happening here or point me in the right direction for troubleshooting this. Thanks for your time in advance.

Answer

You create a template binding with v-model:

You can use the v-model directive to create two-way data bindings

You attach an event listener with v-on:

Attaches an event listener to the element. The event type is denoted by the argument. The expression can be a method name, an inline statement, or omitted if there are modifiers present.

So this is expected behavior since you are apparently trying to attach an event listener to the input event.

When you used v-model (wrongly), it evaluated the expression to put it in the input’s value, as if it had been a primitive binding. Since your expression was a function instead, you got the result that you did.

Your confusion may have come from the fact that v-model is special syntax that is both a binding and a listener, but those are predefined. Meaning that when you use it, you don’t specify your own listener with it, but rather the model that you want it to change when it receives an input event from the child.

Advertisement