vue3 开发过程中遇到的问题

2,231 阅读2分钟

VUE_PROD_HYDRATION_MISMATCH_DETAILS is not explicitly defined

使用vite创建的项目,在开发过程中控制台报如下错误:

Since just upgrading vue.js to version 3.4.10 I now get the following warning in the console of my browser:

Feature flag VUE_PROD_HYDRATION_MISMATCH_DETAILS is not explicitly defined. You are running the esm-bundler build of Vue, which expects these compile-time feature flags to be globally injected via the bundler config in order to get better tree-shaking in the production bundle.

解决方案:升级@vitejs/plugin-vue版本号,刚开始版本是4.1.0,升级到4.6.2报错就消失了(问题的出现记不清是否升级了vue的版本号导致的,不过最终vue版本号为:3.4.10)

defineModel的问题

defineModel() is a compiler-hint helper that is only usable inside <script setup> of a single file component. Its arguments should be compiled away and passing it at runtime has no effect.

defineModel()是一个编译器提示帮助器,只能在脚本setup单个文件组件的。它的参数应该被编译掉,并且在运行时传递它没有影响。

// 父组件
<script lang="ts" setup>
import { ref } from 'vue'
import CustomInput from './CustomInput.vue'

const inputValue = ref('hello defineModel')
</script>

<template>
  <div>
    <CustomInput v-model="inputValue"></CustomInput>
    <p>Input value: {{ inputValue }}</p>
  </div>
</template>

// CustomInput.vue
<script setup lang="ts">
import { defineModel } from 'vue'

const inputVal = defineModel()
</script>

<template>
  <div class="custom-input">
    <input v-model="inputVal" type="text" />
  </div>
</template>

"vue": "^3.4.10

但是控制台依旧会报错,代码无法正常运行。

defineModel 宏默认是关闭的,使用它需要手动开启。vite.config.ts配置如下:

export default defineConfig({
  plugins: [
    vue({
      script: {
        // 开启 defineModel
        defineModel: true
      }
    })
  ]
})

父子组件使用相同的class,子组件根元素的样式会同时受父组件和子组件样式的影响

具体表现如下:

// App.vue
<template>
    <div class="container">
        <CompA></CompA>
    </div>
</template>

<style scoped lang='less'>
.container {
  width: 100%;
  height: 200px;
  background-color: pink;
}
</style>
// CompA.vue
<template>
    <div class="container">
        组件A
    </div>
</template>
<style scoped lang='less'>
.container {
  height: 50%;
  background-color: #123;
}
</style>

渲染样式为:

image.png 渲染DOM与编译后的css样式为:

Vite + Vue + TS 2024-01-18 17-41-42.png

覆盖原因:scoped css 子组件的根元素

使用 scoped 后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。