2

I’m currently evaluating vuejs and I like it a lot except for the use of a domain specific language used for the directives in the html templates. Is it (at least theoretically) possible use vuejs without the dns and specify the information in the directives programmatically in javascript?

Example:

Is there a way to specify a template like <a v-on:click="doSomething">...</a> without the directive and the directive separately in JavaScript?

doberkofler
  • 9,511
  • 18
  • 74
  • 126
  • 1
    Sure, you can do it with DOM template technique. But it has its caveats and usually is discouraged for more-o-less advanced projects. Check [this article for details](https://vuejsdevelopers.com/2017/09/17/vue-js-avoid-dom-templates/). – raina77ow Feb 12 '18 at 13:38
  • Why would you ever want to do that. You are basically resorting back to plain JavaScript events and functional programming to create lists, etc. – Stephan-v Feb 12 '18 at 13:40
  • Alternatively you can use JSX with Vue. If you dislike templates altogether you can write render functions yourself. – Bert Feb 12 '18 at 13:41
  • You may have a very good reason for asking such a question but if you don't have much experience using vue directives (or directives with another js framework) you owe it to yourself to do a toy project and get some experience with directives before deciding against them. They have enormous benefits and serve in a sense to extend the html language in ways that are highly readable and quite powerful. – RonC Feb 12 '18 at 13:56
  • I do understand the advantages of the directives embedded in the templates and am also planning to evaluate vuejs in a comprehensive example project. The reason for my question is rather about the general possibilities of the framework and (at least to me) the possibility to use use a programmatic JavaScript API as an alternative to the declarative directives seems useful if I for example might want to change a directive without having to change the template itself. – doberkofler Feb 12 '18 at 14:11

3 Answers3

2

Since Vue 2.0, there is support for using JSX in vue components.

If you want to avoid any DSL entirely, you can directly use the API that babel-plugin-transform-vue-jsx (Vue's JSX transformation plugin) targets.

Example from the linked post:

new Vue({
  el: '#app',
  data: {
    msg: 'Click to see the message'
  },
  methods: {
    hello () {
      alert('This is the message')
    }
  },
  render (createElement) {
    return createElement(
      'span',
      {
        class: { 'my-class': true },
        style: { cursor: 'pointer' },
        on: {
          click: this.hello
        }
      },
      [ this.msg ]
    );
  },
});
tony19
  • 125,647
  • 18
  • 229
  • 307
lorefnon
  • 12,875
  • 6
  • 61
  • 93
  • In my eyes JSX is actually just a different type of DSL but I understand that it offers a lot more procedural control over the template based approach in vuejs. – doberkofler Feb 14 '18 at 13:46
  • Yes. But basically you don't actually have to use JSX. You can just use the API it uses without the syntax sugar, which is standard javascript. – lorefnon Feb 14 '18 at 14:52
  • I understand and will have a deeper look at it. Would you nevertheless agree that using a render function is most likely the way to go, if an imperative definition is desired or needed? – doberkofler Feb 14 '18 at 15:29
  • I think UI should almost always be declaratively defined, and still components (and render functions) are better as they don't separate out DOM/inner-component hierarchy and behavior which are usually closely coupled. – lorefnon Feb 14 '18 at 16:17
  • I don't use Vue a lot though. – lorefnon Feb 14 '18 at 16:17
  • I would generally agree with you, but in my experience when things get really complicated an imperative approach is sometimes easier to understand than the declarative. I quite often have this discussion on the backend when arguing on how to best express a query in sql and sometimes it gets so complicated that we resort to multiple sql statements and some procedural code. – doberkofler Feb 14 '18 at 16:29
  • Ok, I see where you are coming from. – lorefnon Feb 14 '18 at 16:39
1

The short answer to your question is "no", there is no (good) way to use a template and apply directives to it programmatically. You would end up writing your own replacement for the directive system.

You don't explain what you don't like about directives, but as they're central to the notion of templates in Vue, I'm not sure it makes sense to say you like Vue apart from them.

The role of the template is to describe the appearance and behavior of the app, in terms of the viewmodel, which is an API. The viewmodel code provides the implementation of the API. The desire to change behavior without changing the template seems arbitrary and pointless, or at least misunderstands the purpose of a template. Making the template less expressive means that it is less understandable: anything could be bound to anything, and you wouldn't know without looking into the implementation code.

Roy J
  • 42,522
  • 10
  • 78
  • 102
  • I do understand your point and see the advantages of a declarative approach. My question was intended at better understanding if a procedural approach is possible and what the options are. My example to dynamically change the template is not the best one but generally speaking there is always limitation to what can be expressed in a declarative way and that’s what I wanted to say. – doberkofler Feb 14 '18 at 13:50
  • See [Render functions](https://vuejs.org/v2/guide/render-function.html) for situations "where you really need the full programmatic power of JavaScript". – Roy J Feb 14 '18 at 13:57
  • I was just updating my question and came to the same conclusion. Thank you! – doberkofler Feb 14 '18 at 14:04
0

By further digging into the vuejs documentation I seem to have found what I have been looking.

With vuejs 2 the framework introduced render functions that allow to switch from a declarative (template/directives) to an imperative (JavaScript) definition of the component.

If I got it right and there are no major drawbacks in using a render function in vuejs, this it what I was searching for.

doberkofler
  • 9,511
  • 18
  • 74
  • 126