[Vue2] Vue 的 MVC 探索 [2]

135 阅读1分钟

方案 B

直接替换整个 data 结果 View.vue

<template>
  <div>
    <div>
      <div @click="watchedMethod">{{name}}</div>
      <div @click="watchedMethod">{{$data.unwatch}}</div>
      <div>{{$data.onlyGet}}</div>
      <div @click="$data.cMethod">cMethod</div>
    </div>
  </div>
</template>
<script>
import { Controller } from "./Controller";
export default {
  data(vc) {
    console.log(vc);
    return new Controller(vc);
  },
  mounted() {
    this.$data.mount();
  }
};
</script>

Controller.vue 如下:

export class Controller<T = any>
{
    name = `This is a Controller's name`; // 普通的属性
    private pivateValue = '_pValue'; // 私有的属性,由于只是 ts 的语法糖,同样会被 vue 复制到 VueComponent 转 getter 和 setter 属性
    _unwatch = '_unwatch'; // 私有属性,vue 不会把 _开头的属性复制到 VueComponent, 不会和 vue 的私有属性冲突 
    _ctx: T; // 上下文属性,VueComponent 实例,可以方便的调用 $开头的的方法。
    constructor(ctx: T)
    {
        this._ctx = ctx;
    }
    get unwatch() { return this._unwatch };
    set unwatch(val) { this._unwatch = val };

    watchedMethod = (e: any) =>
    {
        console.log(` A controller do something ${e}`)
    }

    mount = () => console.log('c mounted');

    get onlyGet() { return `only get` }

    cMethod(e: any)
    {
        console.log(`cMethid:${e}`)
    }
}

方案 B 结果分析:

优点:

  • controller 可以有私有属性,以 _ 开头即可;
  • controller 的方法不会被观察
  • controller 可以自由扩展(继承,实现接口等等)
  • controller 的一级属性在 vue 中可以直接使用 缺点:
  • controller 的方法在 vue 中不可直接用, 使用 $data.f() 可以解决

结语

方案 B 相对于 方案 A 优点更多,可以在不修改脚手架情况下使用,并且能充分发挥 vue 的作用,目前还比较满意,后续有更好的方案会再补充比较。