手撕v-model

Mr.Song2020年8月7日
小于 1 分钟

Object.defineProperty

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title></title>
 </head>
 <body>
  手写一个简单双向绑定<br />
  <input type="text" id="model"><br />
  <div id="modelText"></div>
 </body>
 <script type="text/javascript">
  var user = {
   name: '希染'
  };
  var defaultName = '希染'

  var input = document.querySelector("#model");
  var text = document.querySelector("#modelText");

  input.value = user.name;
  text.textContent = user.name;

  // 数据到视图 model => view
  Object.defineProperty(user, "name", {
   get: function() {
    console.log('获取user')
   },
   set: function(val) {
    console.log('修改user')
    input.value = val;
    text.textContent = val;
   }
  })

  // 视图到数据 view => model
  input.addEventListener('input', function(val) {
   user.name = input.value;
  })
 </script>
</html>

proxy

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
 </head>
 <body>
  <input type="text" v-model="content">
  <input type="text" v-model="content">
  <h4 v-bind="content">dd</h4>
  <input type="text" v-model="title">
  <input type="text" v-model="title">
  <h4 v-bind="title">数据改变</h4>
 </body>
 <script type="text/javascript">
  function View() {
   let proxy = new Proxy({}, {
    get(obj, key) {
     return obj[key]
    },
    set(obj, key, value) {
     console.log(obj,key,value)
     document.querySelectorAll(`[v-model="${key}"]`).forEach(item => {
      item.value = value
     })
     document.querySelectorAll(`[v-bind="${key}"]`).forEach(item => {
      item.innerHTML = value
     })
    },
   })

   document.querySelectorAll('[v-model]').forEach(item => {
    item.addEventListener('keyup', function() {
     proxy[this.getAttribute('v-model')] = this.value
    })
   })
  }
  new View()
 </script>
</html>
评论
Powered by Waline v2.6.2