Subscribe on changes!

v-model value uses square bracket syntax with double quotes in <template lang="pug"> doesn't work since 3.2.13 version

avatar
Dec 21st 2021

Version

3.2.26

Reproduction link

github.com

Steps to reproduce

  • npm i
  • npm run serve
  • Visit http://localhost:8080/
  • Edit item2 in src/components/Case1.vue, then save the changes.
  • Uncomment input(v-model='row["item2"]') in src/components/Case1.vue, then save the changes.
  • Refresh http://localhost:8080/

Use vue@3.2.13 (has error)

  • Delete the node_modules folder.
  • Switch to 5147/use-vue-3.2.13-version branch.
  • Reinstall the dependencies and build.

Use vue@3.2.12 (ok)

  • Delete the node_modules folder.
  • Switch to 5147/use-vue-3.2.12-version branch.
  • Reinstall the dependencies and build.

What is expected?

Compiled Successfully.

What is actually happening?

VueCompilerError: v-model value must be a valid JavaScript member expression.
at /Users/lsnsh/study/other/vue-issue-examples/src/components/Case1.vue:1:189
1  |  <div><h3>[Pug template]: </h3><div :title="row['item1']">{{ row['item1'] }}</div><input v-model="row['item1']"><div :title="row[&quot;item2&quot;]">{{ row["item2"] }}</div><input v-model="row[&quot;item2&quot;]"></div>
   |                                                                                                                                                                                              ^^^^^^^^^^^^

//- The Error code in src/components/Case1.vue
input(v-model='row["item2"]')

Because i have some Chinese object property names.

At first I thought that the value of v-model does not support Chinese, but it is not

My project works fine on vue@3.2.11.

avatar
Dec 21st 2021

This is actually because of how pug transforms the expression you give to it:

div
  div(:title='row["item2"]') {{ row["item2"] }}
  input(v-model='row["item2"]')

becomes

<div>
    <div :title="row[&quot;item2&quot;]">{{ row["item2"] }}</div><input v-model="row[&quot;item2&quot;]" />
</div>

It works well when using HTML

avatar
Dec 22nd 2021

@posva Thanks for your reply, I forgot to describe the four examples written in my code:

  1. Double quotes outside, Single quotes inside 1.1. :title="row['item1']" 1.2. v-model="row['item1']"
  2. Single quotes outside, double quotes inside 2.1. :title='row["item2"]' 2.2. v-model='row["item2"]'

Among them, 2.2 does not work in <template lang="pug">:

div
  //- 2.1, ok
  div(:title='row["item2"]') {{ row["item2"] }}
  //- 2.2, error
  input(v-model='row["item2"]')

All four are working fine in <template lang="html">.

avatar
Dec 22nd 2021

I found that my steps to reproduce cannot be reproduced normally because of the cache.

The first build will report an error, and the second build will not report an error.

I updated the steps to reproduce:

  • Edit item2 in src/components/Case1.vue, then save the changes.
  • Uncomment input(v-model='row["item2"]') in src/components/Case1.vue, then save the changes.
avatar
Dec 22nd 2021

@posva Because of the problem of troubleshooting and time, I did not have time to point out:

My project works fine on vue@3.2.11.

I updated the issue title:

- When using square brackets to access objects, the value of v-model cannot be "Single quotes outside, double quotes inside"
+ v-model value is a special syntax in <template lang="pug">  doesn't work since 3.2.13 version

And added steps to reproduce, see "Steps to reproduce"

avatar
Dec 22nd 2021

What you have is a pug syntax issue. It works fine when written in HTML as shown on the SFC. I'm not a pug expert, but you can just write v-model="row['item']", or v-model='row.item'`.

avatar
Dec 22nd 2021

谢谢你的建议,我们知道:

<template lang="pug"> 中,使用方括号语法设置 HTML 标签或 Vue 组件属性值,常见的两种语法:

  1. 双引号在外,单引号在内 3.1. v-model="row['item-3']"
  2. 单引号在外,双引号在内 4.1. v-model='row["item-3"]'
// ...
<script>
export default {
  data() {
    return {
      row: { "item-3": "item-3 value", },
    };
  },
};
</script>

但是:

  1. 因为在我的多个项目中,单文件组件一直使用 <template lang="pug">,搭配「单引号在外,双引号在内」的自动格式化规则 5.1. 在 vue@2.x 中,我使用 vetur + prettier 的组合能自动格式化 <template lang="pug"> 中的代码 5.2.在 vue@3.x 中,由于 volar 不能和 prettier 搭配,没法自动格式化 <template lang="pug"> 中的代码,因此两种写法不可避免的会混用
  2. 这种写法,我认为是常见的,我应该更正 issue 标题
  3. 这种写法,在 vue@3.2.13 之前工作正常,我的项目使用的是 vue@3.2.11 7.1. 5147/use-vue-3.2.13-version 7.2. 5147/use-vue-3.2.12-version
  4. 我会停留在 vue@3.2.11,直到我认识到它是错误的或是“错误的”,或者它在 vue@next 工作正常。

Thank you for your suggestion, we know:

In <template lang="pug">, use square bracket syntax to set HTML tag or Vue component attribute value, two common syntaxes:

  1. Double quotation marks are outside, single quotation marks are inside 3.1. v-model="row['item-3']"
  2. Single quotation marks are outside, double quotation marks are inside 4.1. v-model='row["item-3"]'
// ...
<script>
export default {
  data() {
    return {
      row: { "item-3": "item-3 value", },
    };
  },
};
</script>

but:

  1. Because in many of my projects, single file components have always used <template lang="pug">, with the automatic formatting rules of "single quotes outside, double quotes inside" 5.1. In vue@2.x, I use the combination of vetur + prettier to automatically format the code in <template lang="pug"> 5.2. In vue@3.x, because volar cannot be used with prettier, the code in <template lang="pug"> cannot be automatically formatted, so the two writing methods will inevitably be Mix
  2. I think this way of writing is common. I should correct the title of issue
  3. This writing method worked fine before vue@3.2.13, and my project used vue@3.2.11 7.1. 5147/use-vue-3.2.13-version 7.2. 5147/use-vue-3.2.12-version
  4. I will stay at vue@3.2.11 until I realize that it is wrong or "wrong", or it works fine in vue@next.