Skip to content

Rule proposal: simple-expressions-in-templates #253

Open
@michalsnik

Description

@michalsnik
Member

Style guide:
https://vuejs.org/v2/style-guide/#Simple-expressions-in-templates-strongly-recommended

Description:
This rule would enforce usage of simple expressions in templates. Instead of writing complex logic in templates it should be moved to computed properties and only referenced using them in templates.

What should we check?

  • expressions ({{}})
  • bindings (v-bind:foo="" and :foo="")

When should we throw a warning?
Simplest solution would be to define number of letters inside expressions, and to be honest I think it should work well for most cases.

Let's say we throw error when there are at least 20 signs in expressions:

<!-- Bad -->
{{todos.map(todo => todo.name)}}
<!-- Good -->
{{todosName}}

The bad example has 26 non-empty signs. It's clear that it would be too hard to fit any logic in 20 signs, so we could be quite certain this is a good and not overcomplicated solution.

On the other hand I can think of longer than 20 signs words, e.g.:
allNotCompletedTodosNames

So the other way would be to check for existence of one of the following types of nodes inside expressions:

  • CallExpression
  • FunctionExpression

Activity

chrisvfritz

chrisvfritz commented on Nov 27, 2017

@chrisvfritz
Contributor

I like the node type strategy better, as I definitely like long (especially computed) property names. 😄

mysticatea

mysticatea commented on Nov 28, 2017

@mysticatea
Member

How does this rule handle filters?
Though I think that it's function calls as well.

chrisvfritz

chrisvfritz commented on Nov 28, 2017

@chrisvfritz
Contributor

I think we can ignore filters (not mark them as a complex node type).

armano2

armano2 commented on Nov 19, 2018

@armano2
Contributor

@chrisvfritz i agree with you, but there has to be some additional conditions

  • if its not using properties from iterator
  • if it's not in scoped slot
<div v-for="todos of todosGroups">
   {{ todos.map(todo => todo.name )}}
</div>

example is simple but i have few use cases for that 😄


CallExpression is a little tricky due to translations, this example is going to considered complex

<p>{{ $t('message.hello', {'0': 'hello'}) }}</p>

https://kazupon.github.io/vue-i18n/guide/formatting.html#list-formatting


unless we up default limit to 2-3 and let users decide how many its allowed

{
   "vue/simple-expressions-in-templates": ["error", {
      "allowedCallExpression": "off" | number,
      "allowedFunctionExpression": "off" | number,
   }]
}

we can always go for list of excluded CallExpression / FunctionExpression

chrisvfritz

chrisvfritz commented on Nov 22, 2018

@chrisvfritz
Contributor

Maybe we should define complexity as logical branches or state changes? So loops, conditionals, and any other time a variable/argument can have different values could be considered complex.

@armano2 In your map example, I would say that's a good opportunity for a method other utility. 🙂 It's easy for that simple map to become more and more complex with time, possibly also adding a filter and other transforms eventually.

LesDomen

LesDomen commented on Jan 7, 2025

@LesDomen

We're very interrested in this rule being added and are open to implementing it.

Perhaps adding a ignoredFunctions: undefined | string[] property could be useful in i18n cases, with a single allowedExpressions: undefined | number setting, that can be overriden for each expression type separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @armano2@mysticatea@chrisvfritz@michalsnik@LesDomen

        Issue actions

          Rule proposal: `simple-expressions-in-templates` · Issue #253 · vuejs/eslint-plugin-vue