博客 / 詳情

返回

vue3 模板編譯 —— 把 v-model 默認改為 v-model:value

📰 前言

Vue3 中,v-model 指令默認綁定到組件的 modelValue 屬性上。

但如果我們想要的是默認綁定到 value 屬性呢?
我們可以使用 AST(抽象語法樹) 轉換來實現這一點。

🌈 在線演示


📄 vite.config.ts

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

export default defineConfig({
  plugins: [
    vue({
      template: { compilerOptions: { nodeTransforms: [transformModel] } }
    })
  ]
})

📄 transformModel.ts

import { NodeTransform, findDir, createSimpleExpression } from '@vue/compiler-core'

const ELEMENT = 1

export const transformModel: NodeTransform = node => {
  if (node.type != ELEMENT) return

  const VModel = findDir(node, 'model')

  // v-model 沒有傳入綁定的屬性,則將屬性綁定到 value
  // e.g. v-model => v-model:value
  // e.g. v-model:xxx => v-model:xxx
  if (VModel && VModel.arg == null) {
    VModel.arg = createSimpleExpression('value', true, undefined, 3)
  }
}

🔺 以上就是完整代碼了


🎃 讓我們來試試效果

<!-- TestModel.vue -->
<template>
  <input :value="value" @input="$emit('update:value', $event.target.value)" />
</template>

<script setup lang="ts">
defineProps<{ value: string }>()
</script>
<!-- App.vue -->
<template>
  <TestModel v-model="value" />
  <div>👉{{ value }}</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const value = ref('')
</script>

🚀 運行成功 😆

🚀 在線 StackBlitz 編輯


👍 點個贊吧 ✨ 👈

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.