webfansplz / vuejs-challenges

Collection of Vue.js challenges
https://vuejs-challenges.netlify.app/
MIT License
2.71k stars 187 forks source link

26 - 实现简易版`v-model`指令 #2678

Open c11ee opened 6 months ago

c11ee commented 6 months ago
<script setup lang="ts">
import { effectScope, ref, watchEffect, type Directive } from 'vue'

/**
 * 实现以下自定义指令
 * 在表单输入元素和数据间创建双向绑定
 *
 */

const scope = effectScope()
const VOhModel: Directive<HTMLInputElement, string> = {
  mounted: (el, binging) => {
    scope.run(() => {
      watchEffect(() => {
        el.value = binging.value
        el.addEventListener('input', (e) => {
          value.value = (e.target as HTMLInputElement)!.value
        })
      })
    })
  }
}

const value = ref('Hello Vue.js')
</script>
<template>
  <input v-oh-model="value" type="text" />
  <!-- 不加 p 标签 单元测试未能通过。。。 -->
  <p>{{ value }}</p>
</template>