• Proxy对象英语创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找,赋值、枚举、函数调用等)

    语法

    1. const proxy = new Proxy(target, handler);

    参数

    target

  • 要使用Proxy包装的目标对象,可以是任何类型的对象,包括原生数组,函数,甚至是另一个代理。

    handler

  • 一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)。

    基本使用

    1. const obj = {name: "Tony", age: 20}
    2. const proxy = new Proxy(obj, {
    3. get(obj, property) {
    4. // property: 对象的key
    5. // obj: 代理的对象
    6. return obj[property]
    7. },
    8. set(obj, property, value) {
    9. obj[property] = value;
    10. return true
    11. }
    12. })
    13. console.log(proxy.name)
    14. proxy.name = 'Tom'
    15. console.log(obj)

    基本方法

    handler.get()

    描述:

  • get方法用于拦截对象的读取属性操作。

    语法:

    1. new Proxy(obj, {
    2. get(obj, key, receiver) {
    3. return obj[key]
    4. }
    5. })

    参数:

  • target:目标对象。

  • key:被获取的属性名。
  • receiver:Proxy或者继承Proxy的对象。

    返回值:

  • 可以返回任何值。

    handler.set()

    描述:

  • set方法是设置属性值操作的捕获器。用于拦截设置属性值的操作

    语法:

    1. new Proxy(obj, {
    2. set(obj, key, value, receiver) {
    3. obj[key] = value;
    4. return true;
    5. }
    6. })

    参数:

  • target:目标对象。

  • key:属性名。
  • value: 新属性值。
  • receiver:最初被调用的对象。

    返回值:

  • set()方法应当返回一个布尔值。

    • 返回true表示属性设置成功。
    • 在严格模式下,如果set()方法返回false,那么会抛出一个TypeError异常。

      handler.apply()

      描述:

  • apply() 方法用于拦截函数的调用。

    语法:

    1. function sum(a, b) {
    2. return a + b
    3. }
    4. const proxy = new Proxy(sum, {
    5. apply(target, thisArg, paramsList) {
    6. return target(paramsList[0] + paramsList[1] * 10);
    7. }
    8. })
    9. sum(1, 2) // 3
    10. proxy(1, 2) // 21

    参数:

  • target:目标函数

  • thisArg:被调用时的上下文对象。
  • paramsList:被调用时的参数数组。

    返回值:

  • apply() 方法可以返回任何值。

    VueJs input 双向绑定实例

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. </head>
    9. <body>
    10. <input type="text" v-model="title">
    11. <input type="text" v-model="title">
    12. <div v-bind="title"></div>
    13. <script>
    14. function View() {
    15. let proxy = new Proxy({},{
    16. get() {},
    17. set(obj, key, value) {
    18. document.querySelectorAll(`[v-model="${key}"]`).forEach(item => item.value = value)
    19. document.querySelectorAll(`[v-bind="${key}"]`).forEach(item => item.innerHTML = value)
    20. return true;
    21. }
    22. })
    23. this.init = function() {
    24. let inputs = document.querySelectorAll("[v-model]");
    25. inputs.forEach(item => {
    26. item.addEventListener('keyup', function() {
    27. proxy[this.getAttribute('v-model')] = this.value;
    28. })
    29. })
    30. }
    31. }
    32. new View().init()
    33. </script>
    34. </body>
    35. </html>

    表单验证实例

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. <style>
    9. .error {
    10. border: 5px solid red;
    11. }
    12. </style>
    13. </head>
    14. <body>
    15. <input type="text" validate rule='max:5,min:2'>
    16. <input type="text" validate rule='max:5,isNumber:true'>
    17. <script>
    18. class Validate {
    19. max(value, len) {
    20. return value.length <= len;
    21. };
    22. min(value, len) {
    23. return value.length >= len;
    24. };
    25. isNumber(value) {
    26. return value instanceof Number
    27. }
    28. }
    29. function proxyFactory(value) {
    30. return new Proxy(value, {
    31. get(obj, key) {
    32. return obj[key]
    33. },
    34. set(obj, key, el) {
    35. const rule = el.getAttribute("rule");
    36. const validate = new Validate();
    37. let state = rule.split(',').every(rule => {
    38. const info = rule.split(":");
    39. return validate[info[0]](el.value, info[1]);
    40. });
    41. console.log(state);
    42. el.classList[state ? "remove" : "add"]('error');
    43. return true
    44. }
    45. })
    46. }
    47. const proxy = proxyFactory(document.querySelectorAll('[validate]'));
    48. proxy.forEach(item => {
    49. item.addEventListener('keyup', function() {
    50. proxy.set = this;
    51. })
    52. })
    53. </script>
    54. </body>
    55. </html>