<!--
 * vue3的数据响应性
  -->
<script setup lang="ts">
import { ref, unref, reactive, toRaw } from 'vue';
import { useMessage } from 'src/common/hooks';

const { info } = useMessage();

const text = ref('夕阳西下');
const refObj = ref({
  name: '张三',
  age: 18,
});
const state = reactive({
  name: '李四',
  age: 49,
  childs: {
    name: '李白',
    age: 111,
  },
});

function onView1() {
  console.log('查看1 =', text);
}

function onView2() {
  console.log('查看2 =', refObj);
}

function onChange() {
  text.value = '改变改变';
  info(unref(text));
}

function onViewState() {
  console.log('state', state);
}
function onToRawState() {
  console.log('toRaw(state) =', toRaw(state));
}

function onViewDefineProperty() {
  let o = {
    name: '张三',
    age: 18,
  };
  myreactive(o, 'name', 'zhang san');
  console.log('o >>>>', o.name);
  o.age = 20;
}

// 响应式函数
function myreactive(obj: any, key: any, value: any) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`访问了${key}属性`);
      return value;
    },
    set(val) {
      console.log(`将${key}由->${value}->设置成->${val}`);
      if (value !== val) {
        value = val;
      }
    },
  });
}

function onViewEffect() {
  let name = '孙师傅';
  let age = 18;
  let money = 200;
  let res1 = null;
  let res2 = null;
  let dep: any = new Set();

  const effect1 = () => {
    res1 = `${name}，今年${age}，有${money}元`;
  };
  const effect2 = () => {
    res2 = `刚满${age}岁没多少年的${name}，已经拥有了巨额存款${money}元`;
  };

  // 收集依赖
  (function track() {
    dep.add(effect1);
    dep.add(effect2);
  })();
  console.log('dep >>>>', dep);

  // 通知变了进行更新
  function trigger() {
    for (let item of dep) {
      item();
    }
  }

  trigger(); // 第一次执行，初始化
  console.log(res1);
  console.log(res2);

  money = 400;
  age = 40;
  trigger(); // 数据更新

  console.log(res1);
  console.log(res2);
}
</script>
<template>
  <div class="fit">
    <div class="title">数据响应性</div>
    <div>
      <a href="https://juejin.cn/post/7001999813344493581" target="_blank"
        >参考链接</a
      >
    </div>
    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <div>
            <q-btn label="查看1" color="primary" @click="onView1" />
            <q-btn label="查看2" color="primary" @click="onView2" />
            <q-btn label="改变数据" color="primary" @click="onChange" />
          </div>
          <div>
            <q-chip square>{{ text }}</q-chip>
          </div>
        </q-card-section>
      </q-card>
    </div>
    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <q-btn label="查看state" color="primary" @click="onViewState" />
          <q-btn label="toRaw(state)" color="primary" @click="onToRawState" />
        </q-card-section>
      </q-card>
    </div>
    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <div>
            <q-chip square>Object.defineProperty</q-chip>
          </div>
          <div>
            <q-btn label="查看" color="primary" @click="onViewDefineProperty" />
          </div>
        </q-card-section>
      </q-card>
    </div>

    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <div>
            <q-btn
              label="订阅与更新简单版"
              color="primary"
              @click="onViewEffect"
            />
          </div>
        </q-card-section>
      </q-card>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.title {
  font-size: 22px;
  color: #424242;
  margin-bottom: $padding-md;
}
</style>
