vue3.0的代理对象Proxy-用Proxy写一个双向绑定json-yml格式转换器

最近开始撸vue-next的源码了,慢慢开始理解作者为什么要用Proxy重写一遍了。我们现在在写vue代码的时候会遇到一个很神奇的问题,v-model绑定一个对象中的某一属性时,即便这个属性不存在也可以被绑定,但是若提前声明该属性为null则不能修改他的值,这就是Object.defineproperty的其中一个特征,当属性不存在时能创建一个属性为第一次传递的值,并且保留其数据格式,而且不能挟持到深度的对象属性中,而Proxy则完美的解决了这个问题,不但可以给所有未声明的变量一个默认值,还能对整个对象进行数据监听,而且速度更快,但唯一的劣势是不能在不支持ES6语法的浏览器下使用,所以想兼容目前还是只能使用2.X的vue版本。
具体不同看文章https://blog.csdn.net/qq_37195804/article/details/106094059

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    .main{
      display: flex;
    }
    div{
      width: 100%;
    }
    textarea{
      width:90%;
      height:500px;
    }
    #jsonWarn,#ymlWarn{
      color:red;
    }
  </style>
</head>
<body>
<div class="main">
  <div>
    <p>json</p>
    <textarea id="json" type="text" oninput="getJson(this)" row="20"></textarea>
    <p id="jsonWarn"></p>
  </div>
  <div>
    <p>yml</p>
    <textarea id="yml" type="text" oninput="getYml(this)" row="20"></textarea>
    <p id="ymlWarn"></p>
  </div>
</div>
</body>
<script>
var json = document.querySelector('#json');
var jsonWarn = document.querySelector('#jsonWarn');
var yml = document.querySelector('#yml');
var ymlWarn = document.querySelector('#ymlWarn');
let o = {};
let obj = new Proxy(o,{
  get(target,prop) {
    return prop in target ? target[prop] : {} //可以给不存在的变量被声明时给一个默认值
  },
  set(target,prop,value){ //双向绑定
    if(prop==='json'){
      //输入的json转换成yml
      yml.value = changeJson(value);
    }else if(prop==='yml'){
      //输入的yml转换成json
      json.value = changeYml(value);
    }
  }
})
function getJson(val){
  obj.json = val.value
}
function getYml(val){
  obj.yml = val.value
}
function changeJson(value){
  if(typeof value === 'string'){
    try{
      var obj = JSON.parse(value)
      if(typeof obj ==='object'){
        jsonWarn.innerHTML = ''
        return jsonToYml(obj).join('\n')
      }else{
        return ''
      }
    }catch(e){
      jsonWarn.innerHTML = 'json格式错误'
      return ''
    }
  }
}
function changeYml(value){ //jsonToYml格式过两天再撸
  return value
}
function jsonToYml(obj,isChild){
  var arr = []
  if(obj instanceof Array){
    obj.forEach(item=>{
      if(typeof item==='object'){
        arr.push((isChild?' ':'')+'-'+jsonToYml(item,true).join('\n'))
      }else{
        arr.push((isChild?' ':'')+'-'+item)
      }
    })
  }else {
    for(let i in obj){
      if(typeof obj[i]==='object'){
        arr.push(i+':\n'+jsonToYml(obj[i],true).join('\n'))
      }else{
        if(isChild){
          arr.push(' '+i+':'+obj[i])
        }else{
          arr.push(i+':'+obj[i])
        }
      }
    }
  }
  return arr
}
</script>
</html>

猜你喜欢

转载自blog.csdn.net/qq_37195804/article/details/106110225