郑柏铃 6 dni temu
rodzic
commit
ebaf330d49

+ 5 - 1
11.vue3/vue-project1/src/App.vue

@@ -3,7 +3,8 @@
 <template>
   <div>
     <h1>首页</h1>
-    <Demo12></Demo12>
+    <Demo13 v-if="isShow"></Demo13>
+    <!-- <Demo12></Demo12> -->
     <!-- <Demo11></Demo11> -->
     <!-- <Demo10></Demo10> -->
     <!-- <Demo9></Demo9> -->
@@ -18,6 +19,7 @@
   </div>
 </template>
 <script setup name="App">
+import { ref } from 'vue';
 import Demo1 from './components/Demo1.vue';
 import Demo2 from './components/Demo2.vue';
 import Demo3 from './components/Demo3.vue';
@@ -30,6 +32,8 @@ import Demo9 from './components/Demo9.vue';
 import Demo10 from './components/Demo10.vue';
 import Demo11 from './components/Demo11.vue';
 import Demo12 from './components/Demo12.vue';
+import Demo13 from './components/Demo13.vue';
+let isShow = ref(true)
 </script>
 <style scoped>
 </style>

+ 50 - 0
11.vue3/vue-project1/src/components/Demo13.vue

@@ -0,0 +1,50 @@
+<template>
+  <div>
+    Demo13:生命周期
+    <p id="ww">{{ msg }}</p>
+    <br>
+    <br>
+    <button @click="changMain">修改</button>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from "vue" 
+let msg = ref('hi');
+function changMain() {
+    msg.value = 'hello'
+}
+console.log(msg.value);
+/**
+ * vue3生命周期
+ * 初始:
+ *  setup
+ * 运行:
+ *  挂载:onBeforeMount,onBeforeMount
+ *  更新:onBeforeUpdate,onUpdated
+ * 卸载:
+ *   onBeforeUnmount,onUnmounted
+ */
+onBeforeMount(()=>{
+    console.log("挂载前",msg.value,document.getElementById("ww"))
+});
+onMounted(()=>{
+    console.log("挂载后",msg.value,document.getElementById("ww"))
+})
+
+onBeforeUpdate(()=>{
+    console.log("更新前",msg.value,document.getElementById("ww")?.innerText)
+});
+onUpdated(()=>{
+    console.log("更新后",msg.value,document.getElementById("ww")?.innerText)
+})
+onBeforeUnmount(()=>{
+    console.log("卸载前")
+});
+onUnmounted(()=>{
+    console.log("卸载后")
+})
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 35 - 0
11.vue3/归档.md

@@ -3,3 +3,38 @@
 vue2 选项式 Opation API
 vue3 组合式 Component API
 2. 响应式不同
+vue2:
+    基于Object.defineProperty进行数据劫持,结合发布订阅模式实现;
+    数据劫持:
+        Object.defineProperty会遍历data中所有的property
+        为每一个属性添加了getter和setter
+        getter:读取属性时触发,依赖收集(记录那些地方用了什么属性,使用watch...)
+        setter:修改属性时触发,通知更新(告诉依赖哪些地方需要重新计算,或渲染模版...)
+    发布-订阅模式:
+        依赖管理器:Dep: 每一个响应式属性维护一个Dep
+        订阅者:Watcher:关联到视图或者逻辑,当Dep告诉Watch更新,执行具体更新
+    流程:
+       1.初始:观察者(Observer)会遍历所有的data,用Object.defineProperty劫持所有属性,并给每个属性添加依赖管理器(Dep)
+       2.渲染: render函数会访问响应式属性,触发getter,Dep收集当前所有依赖,渲染Watcher
+       3.修改:触发setter方法,Dep通知所有订阅的Watch,执行更新
+    缺陷:
+        1.数据劫持局限:无法监听数组下标,方法,长度等等实现响应式,对数组处理有难度增加;
+        2.无法监听新增/删除属性:Object.defineProperty只能对初始化的数据进行数据劫持,如果动态增加或者删除属性,无法触发响应式,需要使用(Vue.set/Vue.delete)
+
+vue3:
+    基于Proxy去代理对象,配合Reflect去实现强大的响应式,结合依赖追踪和更新机制,但底层还是劫持方式实现;
+    数据劫持:
+        Proxy包裹目标对象,拦截对象的所有操作
+        get拦截: 读取属性时触发,依赖收集
+        set拦截: 修改属性时触发,通知更新
+        其他拦截(deletPropery,...):支持监听属性的删除...;
+    依赖管理:
+        通过副作用(effect)收集依赖,track(追踪依赖)和tigger(触发更新)实现响应式更新;
+    流程:
+        1.通过ref(reactive)创建响应式数据,返回Proxy代理后的对象;
+        2.访问属性:Proxy中的get拦截器触发,tarck获取effect中当前的依赖;
+        3.修改属性:Proxy中的set拦截器触发,tigger通知所有关联的effect执行更新;
+    优势:
+        1.支持动态属性变化:Proxy直接代理整个对象,新增删除都可以被监听;
+        2.数组劫持更自然:不需要重新数组,Proxy代理后可以直接进行数据操作,响应式更加彻底;
+        3.性能优化:Proxy实现响应式,在初始化和更新时候都可以进行劫持数据,依赖被统一收集,减少代码的冗余;