<!-- * vue3的数据响应性 --> <script setup lang="ts"> import { ref, unref, reactive, toRaw } from 'vue'; import { useMessage } from 'src/common/hooks'; import { AUTHS } from '../config'; const { info } = useMessage(); const text = ref('夕阳西下'); const refObj = ref({ name: '张三', age: 18, }); const showTree = ref(false); const state = reactive({ name: '李四', age: 49, childs: { name: '李白', age: 111, }, nodes: [] as any, ticked: [] as any, }); 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); } function onHandleMap() { const myMap = new Map(); let data = [ { name: 'fruits', subclass: ['苹果'] }, { name: 'fruits', subclass: ['香蕉'] }, { name: 'vegetable', subclass: ['西蓝花'] }, { name: 'vegetable', subclass: ['芹菜'] }, { name: 'vegetable', subclass: ['菠菜'] }, { name: 'meat', subclass: ['猪肉'] }, ]; data.map((item: any) => { const key = item.name; let value = []; if (myMap.has(key)) { value = myMap.get(key); } value.push(item); myMap.set(key, value); }); let arr = []; for (const [key, value] of myMap) { arr.push({ name: key, children: value, }); } console.log('myMap >>>>', myMap); console.log(arr); } function onClickHandleAuth() { let res = onHandleAuth(AUTHS, 0); res.map((item: any) => { let children_res = onHandleAuth(item.children, 1); item.children = children_res; item.children.map((el: any) => { el.children = onHandleAuth(el.children, 2); }); }); console.log('结果 =', res); state.nodes = res; // showTree.value = !showTree.value; showTree.value = true; } function onHandleAuth(data: any, index: number) { const lang = 'zh-CN'; let myMap = new Map(); data.map((item: any) => { item[`title_${index}`] = item.i18n[lang].split('/')[index]; const nameList = item.name.split('/'); const maxLevel = nameList.length; const currentName = nameList[index]; const lastName = item[`name_${index - 1}`]; if (lastName) { item[`name_${index}`] = `${lastName}/${currentName}`; } else { item[`name_${index}`] = currentName; } const key = item[`name_${index}`]; let value = { id: item.id, title: item[`title_${index}`], name: key, children: [] as any, }; if (myMap.has(key)) { let child = myMap.get(key).children; if (index + 1 < maxLevel) { child.push(item); } value.children = child; } else if (index + 1 < maxLevel) { value.children.push(item); } myMap.set(key, value); }); let arr = []; for (const value of myMap.values()) { arr.push(value); } // console.log('data >>>>', data); // console.log('myMap >>>>', myMap); // console.log('arr >>>>', arr); return arr; } function onTicked() { console.log('查看勾选的节点 >>>>', state.ticked); } </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 class="q-mb-md"> <q-card> <q-card-section> <div> <q-btn label="扁平化数据结构转tree" color="primary" @click="onHandleMap" /> <q-btn label="权限扁平化数据结构转tree" color="primary" @click="onClickHandleAuth" /> <q-btn label="查看勾选的节点" color="primary" @click="onTicked" /> </div> <div> <q-tree v-if="showTree" :nodes="state.nodes" node-key="name" label-key="title" tick-strategy="leaf" default-expand-all v-model:ticked="state.ticked" /> </div> </q-card-section> </q-card> </div> </div> </template> <style lang="scss" scoped> .title { font-size: 22px; color: #424242; margin-bottom: $padding-md; } </style>