vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.64k stars 8.33k forks source link

Using whitespace "preserve" wont compile v-if/v-else using same slot name #6063

Open jesusgn90 opened 2 years ago

jesusgn90 commented 2 years ago

Vue version

3.2.37

Link to minimal reproduction

https://github.com/jesusgn90/issue-whitespace

Steps to reproduce

Run the project

yarn
yarn dev

See the console

What is expected?

No error is shown

What is actually happening?

Is showing an error that it should not, and is not compiling the template properly

image

this is valid code that should compile and it's not

  <HelloWorld>
    <template v-if="true" #buttons>
      <h1>Hello World</h1>
    </template>
    <template v-else="false" #buttons>
      <h1>Hello World</h1>
    </template>
  </HelloWorld>

System Info

I do not think this applies here but...

<details>
  System:
    OS: Linux 5.13 Pop!_OS 20.04 LTS
    CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    Memory: 676.01 MB / 31.27 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 16.13.0 - /usr/local/bin/node
    Yarn: 1.22.15 - ~/.yarn/bin/yarn
    npm: 8.1.0 - /usr/local/bin/npm
  Browsers:
    Brave Browser: 92.1.27.111
    Chrome: 101.0.4951.41
    Chromium: 83.0.4103.116
    Firefox: 96.0
    Firefox Nightly: 97.0a1
  npmPackages:
    vue: ^3.2.25 => 3.2.37 
</details>

Any additional comments?

I tested this with the vue-cli as well, so it's not related to vite vs vue-cli, the problem resides on @vue/compiler-core potentially, and I suspect this is the problem:

Since both template nodes are using the same slot name (#buttons), it thinks they are the same node so when it reaches the second node (the one using v-else-if) there is no previous node using the v-if because it just replaced the previous node.

snoozbuster commented 2 years ago

+1 on this. found a similar issue in my codebase. had to rewrite the affected code to not use v-else/-if.

liulinboyi commented 2 years ago

In the file vite.config.js remove the whitespace: 'preserve' it will be fine.

Doc

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue({
    template: {
      compilerOptions: {
        // whitespace: 'preserve'
      }
    }
  })]
})