vue双向绑定
通过Object.defineProperty()来劫持各个属性的setter, getter,在数据发生变动时通知Vue实例,触发相应的getter和setter回调函数。
当把一个普通 Javascript 对象传给Vue 实例来作为它的 data 选项时, Vue 将遍历它的属性,用Object.defineProperty将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

<!DOCTYPE html>
<html>
<head>
  <title>双向绑定课堂演示</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@3.2.47/dist/vue.global.js"></script>
  <style>
    .demo-box { margin: 20px; padding: 15px; border: 2px solid #42b983; }
    .output { color: red; font-weight: bold; }
  </style>
</head>
<body>
  <div id="app">
    <!-- 演示1:基础文本绑定 -->
    <div class="demo-box">
      <h3>演示1:文本输入</h3>
      <input type="text" v-model="text">
      <p>输入内容:<span class="output">{{ text }}</span></p>
    </div>

    <!-- 演示2:复选框 -->
    <div class="demo-box">
      <h3>演示2:复选框</h3>
      <label>
        <input type="checkbox" v-model="checked">
        同意条款
      </label>
      <p>状态:<span class="output">{{ checked ? '已同意' : '未同意' }}</span></p>
    </div>

    <!-- 演示3:选择器 -->
    <div class="demo-box">
      <h3>演示3:颜色选择</h3>
      <select v-model="selectedColor">
        <option value="">请选择</option>
        <option>Red</option>
        <option>Green</option>
        <option>Blue</option>
      </select>
      <p>选择结果:<span class="output">{{ selectedColor }}</span></p>
    </div>

    <!-- 控制台操作提示 -->
    <div style="color: #666; margin-top: 30px;">
      <p>🌟操作:打开浏览器控制台(F12),尝试修改数据:</p>
      <p>app.text = 'Vue很棒!'</p>
      <p>app.checked = true</p>
      <p>app.selectedColor = 'Green'</p>
    </div>
  </div>

  <script>
    const app = Vue.createApp({
      data() {
        return {
          text: '初始文字',
          checked: false,
          selectedColor: ''
        }
      }
    }).mount('#app')
  </script>
</body>
</html>