vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
207.86k stars 33.69k forks source link

Optional chaining in templates does not seem to work #11088

Closed DRoet closed 2 years ago

DRoet commented 4 years ago

Version

15.8.3

Reproduction link

https://template-explorer.vuejs.org/#%3Cdiv%20id%3D%22app%22%20v-if%3D%22obj%3F.a%22%3E%7B%7B%20msg%20%7D%7D%3C%2Fdiv%3E

Steps to reproduce

Use a v-if that uses optional chaining w/ @vue/cli version 4.2.0:

v-if="test?.length > 0"

What is expected?

no error is thrown

What is actually happening?

following error is thrown:

  Errors compiling template:

  invalid expression: Unexpected token '.' in

    test?.length > 0

  Raw expression: v-if="test?.length > 0"
robert-niestroj commented 2 years ago

I tested it today with Quasar Framework 1.19.4, based on Vue 2.7.1 and can confirm it works.

DRoet commented 2 years ago

I'm gunna go ahead and close this issue for now since there is a solid solution, upgrading to v2.7 should be pretty easy for most users.

maxkopych commented 2 years ago

@DRoet updating vue to 2.7.10 didn't fix problem for me. My packages:

    "vue": "2.7.10",
    "vue-loader": "15.10.0",
    "vue-style-loader": "^4.1.3",
    "vue-template-compiler": "^2.7.10",

Did you configure something in webpack?

Songoo7 commented 2 years ago

Sadly plugin above did not help at all for chaining. To update from 2.4 to 2.7 and webpack from 3 to 4 with babel to 7 seems like one month job alone on my project T.T .

I wish there would be some easy solution :( , like on vue 1 project it worked just like that with no changes needed :D .

For now using function above, tnx at least for that!

MartinX3 commented 2 years ago

Sadly plugin above did not help at all for chaining. To update from 2.4 to 2.7 and webpack from 3 to 4 with babel to 7 seems like one month job alone on my project T.T .

I wish there would be some easy solution :( , like on vue 1 project it worked just like that with no changes needed :D .

For now using function above, tnx at least for that!

Just migrate to each minor version instead of doing a big jump.

Songoo7 commented 2 years ago

Plugin did not work because it needs vue-loader 15, but jump from 14 to 15 has so many bcbreaks that after day I was lucky to even be able roll back to working solution :D .

For webpack 3 to 4 is much much worse, I have all minors at max, but when doing big jumps there are just too many bc-breaks, its old project and it show like hundreds of errors :) . At times like this, just miss vue 1, where chain work just like that :-) .

TheJaredWilcurt commented 2 years ago

Vue-CLI 4 + Vue 2.7

I am not able to get {{ foo?.bar?.baz }} or v-if="foo?.bar?.baz" to work.

Here is a simplified version of my deps:

"dependencies": {
  "vue": "2.7.11",
  "vue-router": "3.6.5",
  "vuex": "3.6.2"
},
"devDependencies": {
  "@babel/core": "^7.19.3",
  "@babel/eslint-parser": "^7.19.1",
  "@babel/runtime": "^7.19.4",
  "@vue/cli-plugin-babel": "^4.5.19",
  "@vue/cli-plugin-eslint": "^5.0.0-rc.2",
  "@vue/cli-plugin-router": "^4.5.19",
  "@vue/cli-plugin-vuex": "^4.5.19",
  "@vue/cli-service": "^4.5.19",
  "@vue/test-utils": "^1.3.0",
  "core-js": "^3.25.5",
  "eslint": "^8.25.0"
}

I removed vue-template-compiler because the docs said it is no longer needed with Vue 2.7.

What do I need to change to allow Optional Chaining in the template?

Tagging @DRoet because they closed this in hopes of an answer or re-opening. As this seems like a very common situation (Vue-CLI).

maxkopych commented 2 years ago

Vue-CLI 4 + Vue 2.7

I am not able to get {{ foo?.bar?.baz }} or v-if="foo?.bar?.baz" to work.

Here is a simplified version of my deps:

"dependencies": {
  "vue": "2.7.11",
  "vue-router": "3.6.5",
  "vuex": "3.6.2"
},
"devDependencies": {
  "@babel/core": "^7.19.3",
  "@babel/eslint-parser": "^7.19.1",
  "@babel/runtime": "^7.19.4",
  "@vue/cli-plugin-babel": "^4.5.19",
  "@vue/cli-plugin-eslint": "^5.0.0-rc.2",
  "@vue/cli-plugin-router": "^4.5.19",
  "@vue/cli-plugin-vuex": "^4.5.19",
  "@vue/cli-service": "^4.5.19",
  "@vue/test-utils": "^1.3.0",
  "core-js": "^3.25.5",
  "eslint": "^8.25.0"
}

I removed vue-template-compiler because the docs said it is no longer needed with Vue 2.7.

What do I need to change to allow Optional Chaining in the template?

Tagging @DRoet because they closed this in hopes of an answer or re-opening. As this seems like a very common situation (Vue-CLI).

I had similar problem. Fix for that was configure babel-loader in webpack for js files. Example for my rails app:

module.exports = {
    test: /\.(js)?(\.erb)?$/,
    exclude: /node_modules/,
    use: ['babel-loader']
};
TheJaredWilcurt commented 2 years ago

@maxkopych You showed code, but did not mention what file to put it in. To be clear, I am not using Webpack. I am using Vue-CLI (which in turn handles Webpack for me). So any Webpack tweaks need to be handled via the vue.config.js file, likely piggy-backing off of chainWebpack.

I'm asking if I need to change something there, and if so, what do I change?

maxkopych commented 2 years ago

@maxkopych You showed code, but did not mention what file to put it in. To be clear, I am not using Webpack. I am using Vue-CLI (which in turn handles Webpack for me). So any Webpack tweaks need to be handled via the vue.config.js file, likely piggy-backing off of chainWebpack.

I'm asking if I need to change something there, and if so, what do I change?

I didn't work with vue-cli for awhile. But again if you gonna read this article you will see line: 2.7 also supports using ESNext syntax in template expressions. When using a build system, the compiled template render function will go through the same loaders / plugins configured for normal JavaScript. This means if you have configured Babel for .js files, it will also apply to the expressions in your SFC templates.

All you need is search how to add new rules to loaders in vue-cli. first that I found: https://stackoverflow.com/questions/59960121/how-can-i-add-new-rules-to-loaders-while-using-vue-cli-3-x

DRoet commented 2 years ago

@TheJaredWilcurt are you using vue-loader: ^v15.10.0? might want to check your lockfile to check if it is pulling in the right version

TheJaredWilcurt commented 2 years ago

Here is my package-lock.json, slimmed down to just the parts relating to vue-loader:

{
  "packages": {
    "node_modules/@vue/cli-service": {
      "version": "4.5.19",
      "dependencies": {
        "vue-loader": "^15.9.2"
      },
      "optionalDependencies": {
        "vue-loader-v16": "npm:vue-loader@^16.1.0"
      }
    },
    "node_modules/@vue/cli-service/node_modules/vue-loader-v16": {
      "name": "vue-loader",
      "version": "16.8.3"
    },
    "node_modules/vue-loader": {
      "version": "15.9.8"
    }
  },
  "dependencies": {
    "@vue/cli-service": {
      "version": "4.5.19",
      "requires": {
        "vue-loader": "^15.9.2",
        "vue-loader-v16": "npm:vue-loader@^16.1.0"
      },
      "dependencies": {
        "vue-loader-v16": {
          "version": "npm:vue-loader@16.8.3"
        }
      }
    },
    "vue-loader": {
      "version": "15.9.8"
    }
  }
}
amc1999 commented 1 year ago

I had same problem and manage to solve it by adding babel plugins:

// babel.config.js
module.exports = {
  plugins: [
    '@babel/plugin-proposal-nullish-coalescing-operator',
    '@babel/plugin-proposal-optional-chaining'
  ],
  presets: [
    .....did not change anything in presets....

Just for the info, versions from package-lock (as it is today) are:

"quasar": {
      "version": "1.22.2",
"vue": {
      "version": "2.7.14",
 "vue-loader": {
      "version": "15.10.1",

As you can see we are still on Quasar 1 and Vue 2, planning move to Vue 3, but not now.

richard-d-vindico commented 1 year ago

Can I just check, this wasn't working in the template before (only in script logic), but now it works in the template just fine.

Did something change (i'm using v2.6.11)?

cwilby commented 1 year ago

@richard-d-vindico Vue 2.7 added support for using ESNext syntax in template expressions. (https://blog.vuejs.org/posts/vue-2-7-naruto.html)

Run npm ls | grep vue@ to see what your specific version of Vue is.

richard-d-vindico commented 1 year ago

I'm on v2.6.11 and it's works just fine in the template.

On Thu, 19 Jan 2023, 00:48 Cameron Wilby, @.***> wrote:

@richard-d-vindico https://github.com/richard-d-vindico Vue 2.7 added support for using ESNext syntax in template expressions. ( https://blog.vuejs.org/posts/vue-2-7-naruto.html)

Run npm ls | grep vue@ to see what your specific version of Vue is.

— Reply to this email directly, view it on GitHub https://github.com/vuejs/vue/issues/11088#issuecomment-1396297854, or unsubscribe https://github.com/notifications/unsubscribe-auth/AT2ULAKDZ7QF2O44CZP7X5TWTCFMZANCNFSM4KRMZCZQ . You are receiving this because you were mentioned.Message ID: @.***>