{"id":94343,"date":"2026-08-14T10:40:58","date_gmt":"2026-08-14T02:40:58","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/94343.html"},"modified":"2026-08-14T10:40:58","modified_gmt":"2026-08-14T02:40:58","slug":"vue-3-%e7%9f%a5%e8%af%86%e7%82%b9%e6%80%bb%e7%bb%93","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/94343.html","title":{"rendered":"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3"},"content":{"rendered":"<h2>Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3<\/h2>\n<p>\u6700\u540e\u66f4\u65b0&#xff1a;2026-07-29<\/p>\n<hr \/>\n<h3>\u76ee\u5f55<\/h3>\n<li>Vue 3 \u6838\u5fc3\u53d8\u5316\u6982\u89c8<\/li>\n<li>\u7ec4\u5408\u5f0f API&#xff08;Composition API&#xff09;<\/li>\n<li>\u54cd\u5e94\u5f0f\u7cfb\u7edf<\/li>\n<li>\u751f\u547d\u5468\u671f\u94a9\u5b50<\/li>\n<li>\u8ba1\u7b97\u5c5e\u6027\u4e0e\u4fa6\u542c\u5668<\/li>\n<li>\u7ec4\u4ef6\u7cfb\u7edf<\/li>\n<li>\u6a21\u677f\u8bed\u6cd5\u4e0e\u6307\u4ee4<\/li>\n<li>\u5185\u7f6e\u7ec4\u4ef6<\/li>\n<li>\u8def\u7531&#xff08;Vue Router 4&#xff09;<\/li>\n<li>\u72b6\u6001\u7ba1\u7406&#xff08;Pinia&#xff09;<\/li>\n<li>TypeScript \u96c6\u6210<\/li>\n<li>\u6027\u80fd\u4f18\u5316<\/li>\n<li>\u7f16\u8bd1\u4f18\u5316<\/li>\n<li>Teleport \/ Suspense \/ \u5f02\u6b65\u7ec4\u4ef6<\/li>\n<li>\u81ea\u5b9a\u4e49\u6307\u4ee4<\/li>\n<li>\u63d2\u4ef6\u7cfb\u7edf<\/li>\n<li>\u6e32\u67d3\u51fd\u6570\u4e0e JSX<\/li>\n<li>\u670d\u52a1\u7aef\u6e32\u67d3&#xff08;SSR&#xff09;<\/li>\n<li>\u6d4b\u8bd5<\/li>\n<li>\u5e38\u89c1\u8bbe\u8ba1\u6a21\u5f0f\u4e0e\u6700\u4f73\u5b9e\u8df5<\/li>\n<hr \/>\n<h3>1. Vue 3 \u6838\u5fc3\u53d8\u5316\u6982\u89c8<\/h3>\n<h4>1.1 \u4e0e Vue 2 \u7684\u4e3b\u8981\u533a\u522b<\/h4>\n<table>\n<tr>\u7279\u6027Vue 2Vue 3<\/tr>\n<tbody>\n<tr>\n<td>API \u98ce\u683c<\/td>\n<td>Options API<\/td>\n<td>Options API &#043; Composition API<\/td>\n<\/tr>\n<tr>\n<td>\u54cd\u5e94\u5f0f\u539f\u7406<\/td>\n<td>Object.defineProperty<\/td>\n<td>Proxy<\/td>\n<\/tr>\n<tr>\n<td>\u591a\u6839\u8282\u70b9<\/td>\n<td>\u4e0d\u652f\u6301&#xff08;\u9700\u552f\u4e00\u6839\u8282\u70b9&#xff09;<\/td>\n<td>\u652f\u6301 Fragment<\/td>\n<\/tr>\n<tr>\n<td>\u5168\u5c40 API<\/td>\n<td>Vue.xxx \u6302\u8f7d<\/td>\n<td>createApp() \u5e94\u7528\u5b9e\u4f8b<\/td>\n<\/tr>\n<tr>\n<td>\u72b6\u6001\u7ba1\u7406<\/td>\n<td>Vuex<\/td>\n<td>Pinia&#xff08;\u5b98\u65b9\u63a8\u8350&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u8def\u7531<\/td>\n<td>Vue Router 3<\/td>\n<td>Vue Router 4<\/td>\n<\/tr>\n<tr>\n<td>TypeScript<\/td>\n<td>\u652f\u6301\u8f83\u5f31<\/td>\n<td>\u539f\u751f TS \u7f16\u5199&#xff0c;\u4e00\u7b49\u652f\u6301<\/td>\n<\/tr>\n<tr>\n<td>\u5305\u4f53\u79ef<\/td>\n<td>~23KB<\/td>\n<td>~10KB&#xff08;tree-shaking&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u6e32\u67d3\u6027\u80fd<\/td>\n<td>\u57fa\u7ebf<\/td>\n<td>\u7ea6 1.3~2 \u500d\u63d0\u5347<\/td>\n<\/tr>\n<tr>\n<td>v-model<\/td>\n<td>\u4ec5\u4e00\u4e2a<\/td>\n<td>\u591a\u4e2a v-model<\/td>\n<\/tr>\n<tr>\n<td>\u8fc7\u6e21\u7c7b\u540d<\/td>\n<td>v-enter<\/td>\n<td>v-enter-from<\/td>\n<\/tr>\n<tr>\n<td>\u8fc7\u6ee4\u5668<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u5df2\u79fb\u9664<\/td>\n<\/tr>\n<tr>\n<td>$on\/$off\/$once<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u5df2\u79fb\u9664&#xff08;\u7528 mitt \u7b49\u66ff\u4ee3&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u51fd\u6570\u5f0f\u7ec4\u4ef6<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u4ec5\u4fdd\u7559\u51fd\u6570\u5f0f\u5199\u6cd5&#xff0c;\u6027\u80fd\u4f18\u52bf\u6d88\u5931<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>1.2 \u521b\u5efa\u5e94\u7528<\/h4>\n<p><span class=\"token comment\">\/\/ Vue 3<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> createApp <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> App <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;.\/App.vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> app <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createApp<\/span><span class=\"token punctuation\">(<\/span>App<span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span>router<span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span>pinia<span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">mount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;#app&#039;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>1.3 \u5168\u5c40 API \u53d8\u66f4<\/h4>\n<p><span class=\"token comment\">\/\/ Vue 2: Vue.component \/ Vue.directive \/ Vue.mixin<\/span><br \/>\n<span class=\"token comment\">\/\/ Vue 3: \u6302\u5728 app \u5b9e\u4f8b\u4e0a<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">component<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;MyComp&#039;<\/span><span class=\"token punctuation\">,<\/span> MyComp<span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">directive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;focus&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">mounted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> el<span class=\"token punctuation\">.<\/span><span class=\"token function\">focus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">mixin<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token comment\">\/* &#8230; *\/<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>globalProperties<span class=\"token punctuation\">.<\/span>$http <span class=\"token operator\">&#061;<\/span> axios<br \/>\napp<span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span><span class=\"token function-variable function\">errorHandler<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">err<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token comment\">\/* &#8230; *\/<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>2. \u7ec4\u5408\u5f0f API&#xff08;Composition API&#xff09;<\/h3>\n<h4>2.1 setup() \u51fd\u6570<\/h4>\n<p>&lt;script setup&gt;<br \/>\n\/\/ &lt;script setup&gt; \u662f\u8bed\u6cd5\u7cd6&#xff0c;\u65e0\u9700 return&#xff0c;\u9876\u5c42\u53d8\u91cf\/\u51fd\u6570\u81ea\u52a8\u66b4\u9732\u7ed9\u6a21\u677f<br \/>\nimport { ref, computed, onMounted } from &#039;vue&#039;<\/p>\n<p>const count &#061; ref(0)<br \/>\nconst double &#061; computed(() &#061;&gt; count.value * 2)<\/p>\n<p>function increment() {<br \/>\n  count.value&#043;&#043;<br \/>\n}<\/p>\n<p>onMounted(() &#061;&gt; {<br \/>\n  console.log(&#039;mounted&#039;)<br \/>\n})<br \/>\n&lt;\/script&gt;<\/p>\n<p>\u666e\u901a setup() \u5199\u6cd5&#xff1a;<\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function\">setup<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">props<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> emit<span class=\"token punctuation\">,<\/span> expose<span class=\"token punctuation\">,<\/span> slots<span class=\"token punctuation\">,<\/span> attrs <span class=\"token punctuation\">}<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u5fc5\u987b return \u66b4\u9732\u7ed9\u6a21\u677f<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> count <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.2 \u7ec4\u5408\u5f0f\u51fd\u6570&#xff08;Composables&#xff09;<\/h4>\n<p>\u5c06\u53ef\u590d\u7528\u903b\u8f91\u62bd\u53d6\u4e3a\u51fd\u6570&#xff0c;\u4ee5 use \u5f00\u5934\u547d\u540d&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ useCounter.js<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">useCounter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">initial <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span>initial<span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">increment<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> count<span class=\"token punctuation\">.<\/span>value<span class=\"token operator\">&#043;&#043;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">decrement<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> count<span class=\"token punctuation\">.<\/span>value<span class=\"token operator\">&#8212;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">reset<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> initial<span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> count<span class=\"token punctuation\">,<\/span> increment<span class=\"token punctuation\">,<\/span> decrement<span class=\"token punctuation\">,<\/span> reset <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>&lt;script setup&gt;<br \/>\nimport { useCounter } from &#039;.\/useCounter&#039;<br \/>\nconst { count, increment } &#061; useCounter(10)<br \/>\n&lt;\/script&gt;<\/p>\n<p>\u5e38\u7528\u7ec4\u5408\u5f0f\u51fd\u6570\u793a\u4f8b&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ useMouse.js &#8211; \u8ffd\u8e2a\u9f20\u6807\u4f4d\u7f6e<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref<span class=\"token punctuation\">,<\/span> onMounted<span class=\"token punctuation\">,<\/span> onUnmounted <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">useMouse<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> x <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> y <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token keyword\">function<\/span> <span class=\"token function\">update<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">e<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    x<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> e<span class=\"token punctuation\">.<\/span>pageX<br \/>\n    y<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> e<span class=\"token punctuation\">.<\/span>pageY<br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token function\">onMounted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> window<span class=\"token punctuation\">.<\/span><span class=\"token function\">addEventListener<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;mousemove&#039;<\/span><span class=\"token punctuation\">,<\/span> update<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token function\">onUnmounted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> window<span class=\"token punctuation\">.<\/span><span class=\"token function\">removeEventListener<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;mousemove&#039;<\/span><span class=\"token punctuation\">,<\/span> update<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> x<span class=\"token punctuation\">,<\/span> y <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ useFetch.js &#8211; \u6570\u636e\u8bf7\u6c42<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref<span class=\"token punctuation\">,<\/span> watchEffect<span class=\"token punctuation\">,<\/span> toValue <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">useFetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">url<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> data <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> error <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> isPending <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token function\">watchEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    isPending<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><br \/>\n    data<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">null<\/span><br \/>\n    error<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">null<\/span><br \/>\n    <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token keyword\">const<\/span> res <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">toValue<\/span><span class=\"token punctuation\">(<\/span>url<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n      <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>res<span class=\"token punctuation\">.<\/span>ok<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Error<\/span><span class=\"token punctuation\">(<\/span>res<span class=\"token punctuation\">.<\/span>statusText<span class=\"token punctuation\">)<\/span><br \/>\n      data<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      error<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> e<br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">finally<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      isPending<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> data<span class=\"token punctuation\">,<\/span> error<span class=\"token punctuation\">,<\/span> isPending <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.3 provide \/ inject&#xff08;\u4f9d\u8d56\u6ce8\u5165&#xff09;<\/h4>\n<p><span class=\"token comment\">\/\/ \u7236\u7ec4\u4ef6<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> provide<span class=\"token punctuation\">,<\/span> ref<span class=\"token punctuation\">,<\/span> readonly <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token function\">provide<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;count&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">readonly<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>          <span class=\"token comment\">\/\/ \u53ea\u8bfb\u6ce8\u5165<\/span><br \/>\n<span class=\"token function\">provide<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;increment&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> count<span class=\"token punctuation\">.<\/span>value<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u6ce8\u5165\u65b9\u6cd5<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u4e5f\u53ef\u7528 Symbol \/ InjectionKey \u505a\u7c7b\u578b\u5b89\u5168<\/span><br \/>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">const<\/span> CountKey <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">Symbol<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;count&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token function\">provide<\/span><span class=\"token punctuation\">(<\/span>CountKey<span class=\"token punctuation\">,<\/span> count<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5b50\u7ec4\u4ef6&#xff08;\u4efb\u610f\u6df1\u5ea6&#xff09;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> inject <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">inject<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;count&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token comment\">\/\/ \u7b2c\u4e8c\u4e2a\u53c2\u6570\u4e3a\u9ed8\u8ba4\u503c<\/span><\/p>\n<hr \/>\n<h3>3. \u54cd\u5e94\u5f0f\u7cfb\u7edf<\/h3>\n<h4>3.1 \u6838\u5fc3 API<\/h4>\n<h5>ref()<\/h5>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span>          <span class=\"token comment\">\/\/ \u57fa\u672c\u7c7b\u578b<\/span><br \/>\ncount<span class=\"token punctuation\">.<\/span>value<span class=\"token operator\">&#043;&#043;<\/span>                 <span class=\"token comment\">\/\/ \u901a\u8fc7 .value \u8bbf\u95ee\/\u4fee\u6539<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> obj <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">a<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>    <span class=\"token comment\">\/\/ \u5bf9\u8c61\u4e5f\u53ef\u4ee5&#xff0c;\u5185\u90e8\u7528 reactive \u5305\u88c5<\/span><br \/>\nobj<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">.<\/span>a <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u6a21\u677f\u4e2d\u81ea\u52a8\u89e3\u5305&#xff0c;\u65e0\u9700 .value<\/span><br \/>\n<span class=\"token comment\">\/\/ &lt;p&gt;{{ count }}&lt;\/p&gt;<\/span><\/p>\n<h5>reactive()<\/h5>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> reactive <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> state <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">reactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">count<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">nested<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">deep<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>state<span class=\"token punctuation\">.<\/span>count<span class=\"token operator\">&#043;&#043;<\/span>        <span class=\"token comment\">\/\/ \u76f4\u63a5\u4fee\u6539&#xff0c;\u65e0\u9700 .value<\/span><br \/>\nstate<span class=\"token punctuation\">.<\/span>nested<span class=\"token punctuation\">.<\/span>deep    <span class=\"token comment\">\/\/ \u6df1\u5c42\u4e5f\u662f\u54cd\u5e94\u5f0f\u7684<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u26a0\ufe0f \u4e0d\u80fd\u89e3\u6784&#xff0c;\u5426\u5219\u4e22\u5931\u54cd\u5e94\u6027<\/span><br \/>\n<span class=\"token comment\">\/\/ const { count } &#061; state  \/\/ \u274c count \u4e0d\u518d\u662f\u54cd\u5e94\u5f0f<\/span><\/p>\n<h5>ref vs reactive \u9009\u62e9<\/h5>\n<table>\n<tr>\u573a\u666f\u63a8\u8350<\/tr>\n<tbody>\n<tr>\n<td>\u57fa\u672c\u7c7b\u578b&#xff08;number\/string\/boolean&#xff09;<\/td>\n<td>ref<\/td>\n<\/tr>\n<tr>\n<td>\u9700\u8981\u6574\u4f53\u66ff\u6362\u7684\u5bf9\u8c61<\/td>\n<td>ref<\/td>\n<\/tr>\n<tr>\n<td>\u8868\u5355\u7b49\u56fa\u5b9a\u7ed3\u6784\u7684\u5bf9\u8c61<\/td>\n<td>reactive<\/td>\n<\/tr>\n<tr>\n<td>\u901a\u7528 \/ \u4e0d\u786e\u5b9a<\/td>\n<td>ref&#xff08;\u66f4\u5b89\u5168&#xff09;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>3.2 \u89e3\u6784\u4fdd\u6301\u54cd\u5e94\u6027<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> reactive<span class=\"token punctuation\">,<\/span> toRefs<span class=\"token punctuation\">,<\/span> toRef <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> state <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">reactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;Vue&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">version<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">3<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ toRefs&#xff1a;\u6574\u4f53\u89e3\u6784<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">{<\/span> name<span class=\"token punctuation\">,<\/span> version <span class=\"token punctuation\">}<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">toRefs<\/span><span class=\"token punctuation\">(<\/span>state<span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u6bcf\u4e2a\u90fd\u662f ref<\/span><\/p>\n<p><span class=\"token comment\">\/\/ toRef&#xff1a;\u5355\u4e2a\u5c5e\u6027<\/span><br \/>\n<span class=\"token keyword\">const<\/span> nameRef <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">toRef<\/span><span class=\"token punctuation\">(<\/span>state<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;name&#039;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>3.3 \u53ea\u8bfb\u4e0e\u6d45\u5c42<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> readonly<span class=\"token punctuation\">,<\/span> shallowRef<span class=\"token punctuation\">,<\/span> shallowReactive<span class=\"token punctuation\">,<\/span> shallowReadonly<span class=\"token punctuation\">,<\/span> triggerRef <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> original <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">reactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">count<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">const<\/span> copy <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">readonly<\/span><span class=\"token punctuation\">(<\/span>original<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token comment\">\/\/ copy.count&#043;&#043;  \/\/ \u274c \u8b66\u544a&#xff0c;\u4e0d\u53ef\u4fee\u6539<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> shallow <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">shallowRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">nested<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">count<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0<\/span> <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token comment\">\/\/ shallow.value.nested.count&#043;&#043;  \/\/ \u274c \u4e0d\u89e6\u53d1\u66f4\u65b0<\/span><br \/>\nshallow<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">nested<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">count<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1<\/span> <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">}<\/span>  <span class=\"token comment\">\/\/ \u2705 \u66ff\u6362\u6574\u4e2a .value \u624d\u89e6\u53d1<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u624b\u52a8\u89e6\u53d1 shallowRef \u66f4\u65b0<\/span><br \/>\n<span class=\"token function\">triggerRef<\/span><span class=\"token punctuation\">(<\/span>shallow<span class=\"token punctuation\">)<\/span><\/p>\n<h4>3.4 \u54cd\u5e94\u5f0f\u539f\u7406&#xff08;Proxy&#xff09;<\/h4>\n<p>reactive(obj)<br \/>\n  \u2192 new Proxy(obj, {<br \/>\n      get(target, key, receiver) {<br \/>\n        track(target, key)       \/\/ \u6536\u96c6\u4f9d\u8d56<br \/>\n        const res &#061; Reflect.get(target, key, receiver)<br \/>\n        return isObject(res) ? reactive(res) : res  \/\/ \u60f0\u6027\u6df1\u5c42\u4ee3\u7406<br \/>\n      },<br \/>\n      set(target, key, value, receiver) {<br \/>\n        const oldVal &#061; target[key]<br \/>\n        const res &#061; Reflect.set(target, key, value, receiver)<br \/>\n        if (oldVal !&#061;&#061; value) trigger(target, key)  \/\/ \u89e6\u53d1\u66f4\u65b0<br \/>\n        return res<br \/>\n      },<br \/>\n      deleteProperty(target, key) { &#8230; }<br \/>\n    })<\/p>\n<p>\u4f18\u52bf&#xff1a;<\/p>\n<ul>\n<li>\u53ef\u68c0\u6d4b\u5c5e\u6027\u65b0\u589e\/\u5220\u9664<\/li>\n<li>\u53ef\u68c0\u6d4b\u6570\u7ec4\u7d22\u5f15\/length \u53d8\u5316<\/li>\n<li>\u60f0\u6027\u6df1\u5c42\u4ee3\u7406&#xff08;\u8bbf\u95ee\u65f6\u624d\u4ee3\u7406\u5b50\u5bf9\u8c61&#xff09;&#xff0c;\u6027\u80fd\u66f4\u597d<\/li>\n<\/ul>\n<h4>3.5 \u54cd\u5e94\u5f0f\u5de5\u5177\u51fd\u6570<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> isRef<span class=\"token punctuation\">,<\/span> isReactive<span class=\"token punctuation\">,<\/span> isReadonly<span class=\"token punctuation\">,<\/span> isProxy<span class=\"token punctuation\">,<\/span> toRaw<span class=\"token punctuation\">,<\/span> markRaw<span class=\"token punctuation\">,<\/span> customRef <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token function\">isRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>           <span class=\"token comment\">\/\/ true<\/span><br \/>\n<span class=\"token function\">isReactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">reactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token comment\">\/\/ true<\/span><br \/>\n<span class=\"token function\">isProxy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">reactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>    <span class=\"token comment\">\/\/ true<\/span><\/p>\n<p><span class=\"token comment\">\/\/ toRaw&#xff1a;\u83b7\u53d6\u539f\u59cb\u5bf9\u8c61&#xff08;\u8df3\u8fc7\u4ee3\u7406&#xff09;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> raw <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">toRaw<\/span><span class=\"token punctuation\">(<\/span>state<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ markRaw&#xff1a;\u6807\u8bb0\u5bf9\u8c61\u6c38\u4e0d\u8f6c\u4e3a\u54cd\u5e94\u5f0f&#xff08;\u9002\u5408\u7b2c\u4e09\u65b9\u5e93\u5b9e\u4f8b&#xff09;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> chart <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">markRaw<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ECharts<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ customRef&#xff1a;\u81ea\u5b9a\u4e49 ref&#xff08;\u5982\u9632\u6296&#xff09;<\/span><br \/>\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">useDebouncedRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">value<span class=\"token punctuation\">,<\/span> delay <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">200<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">let<\/span> timeout<br \/>\n  <span class=\"token keyword\">return<\/span> <span class=\"token function\">customRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">track<span class=\"token punctuation\">,<\/span> trigger<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token function\">track<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n      <span class=\"token keyword\">return<\/span> value<br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">set<\/span><span class=\"token punctuation\">(<\/span>newValue<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token function\">clearTimeout<\/span><span class=\"token punctuation\">(<\/span>timeout<span class=\"token punctuation\">)<\/span><br \/>\n      timeout <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">setTimeout<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        value <span class=\"token operator\">&#061;<\/span> newValue<br \/>\n        <span class=\"token function\">trigger<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> delay<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>4. \u751f\u547d\u5468\u671f\u94a9\u5b50<\/h3>\n<h4>4.1 \u9009\u9879\u5f0f vs \u7ec4\u5408\u5f0f\u5bf9\u7167<\/h4>\n<table>\n<tr>Options APIComposition API\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>beforeCreate<\/td>\n<td>setup() \u672c\u8eab<\/td>\n<td>setup \u5728\u6b64\u9636\u6bb5\u6267\u884c<\/td>\n<\/tr>\n<tr>\n<td>created<\/td>\n<td>setup() \u672c\u8eab<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>beforeMount<\/td>\n<td>onBeforeMount<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>mounted<\/td>\n<td>onMounted<\/td>\n<td>DOM \u5df2\u6302\u8f7d<\/td>\n<\/tr>\n<tr>\n<td>beforeUpdate<\/td>\n<td>onBeforeUpdate<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>updated<\/td>\n<td>onUpdated<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>beforeUnmount<\/td>\n<td>onBeforeUnmount<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>unmounted<\/td>\n<td>onUnmounted<\/td>\n<td>\u6e05\u7406\u526f\u4f5c\u7528<\/td>\n<\/tr>\n<tr>\n<td>errorCaptured<\/td>\n<td>onErrorCaptured<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>renderTracked<\/td>\n<td>onRenderTracked<\/td>\n<td>\u8c03\u8bd5&#xff1a;\u4f9d\u8d56\u8ffd\u8e2a<\/td>\n<\/tr>\n<tr>\n<td>renderTriggered<\/td>\n<td>onRenderTriggered<\/td>\n<td>\u8c03\u8bd5&#xff1a;\u89e6\u53d1\u66f4\u65b0<\/td>\n<\/tr>\n<tr>\n<td>activated<\/td>\n<td>onActivated<\/td>\n<td>KeepAlive \u6fc0\u6d3b<\/td>\n<\/tr>\n<tr>\n<td>deactivated<\/td>\n<td>onDeactivated<\/td>\n<td>KeepAlive \u505c\u7528<\/td>\n<\/tr>\n<tr>\n<td>serverPrefetch<\/td>\n<td>onServerPrefetch<\/td>\n<td>SSR \u4e13\u7528<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>4.2 \u4f7f\u7528\u793a\u4f8b<\/h4>\n<p>&lt;script setup&gt;<br \/>\nimport { onMounted, onUnmounted, onUpdated } from &#039;vue&#039;<\/p>\n<p>onMounted(() &#061;&gt; {<br \/>\n  console.log(&#039;DOM ready&#039;)<br \/>\n  window.addEventListener(&#039;resize&#039;, handler)<br \/>\n})<\/p>\n<p>onUnmounted(() &#061;&gt; {<br \/>\n  window.removeEventListener(&#039;resize&#039;, handler)<br \/>\n})<\/p>\n<p>\/\/ \u53ef\u591a\u6b21\u8c03\u7528&#xff0c;\u6309\u6ce8\u518c\u987a\u5e8f\u6267\u884c<br \/>\nonMounted(() &#061;&gt; { \/* \u7b2c\u4e8c\u4e2a\u56de\u8c03 *\/ })<br \/>\n&lt;\/script&gt;<\/p>\n<h4>4.3 \u751f\u547d\u5468\u671f\u56fe\u793a<\/h4>\n<p>setup()<br \/>\n  \u2502<br \/>\n  \u251c\u2500 onBeforeMount<br \/>\n  \u2502     \u2502<br \/>\n  \u2502   \u6302\u8f7d DOM<br \/>\n  \u2502     \u2502<br \/>\n  \u251c\u2500 onMounted  \u25c4\u2500\u2500 \u53ef\u8bbf\u95ee DOM \/ \u53d1\u8d77\u8bf7\u6c42<br \/>\n  \u2502     \u2502<br \/>\n  \u2502   \u6570\u636e\u53d8\u5316 \u2192 \u91cd\u65b0\u6e32\u67d3<br \/>\n  \u2502     \u2502<br \/>\n  \u251c\u2500 onBeforeUpdate<br \/>\n  \u251c\u2500 onUpdated<br \/>\n  \u2502     \u2502<br \/>\n  \u2502   \u5378\u8f7d\u7ec4\u4ef6<br \/>\n  \u2502     \u2502<br \/>\n  \u251c\u2500 onBeforeUnmount \u25c4\u2500\u2500 \u6e05\u7406\u5b9a\u65f6\u5668\/\u4e8b\u4ef6<br \/>\n  \u2514\u2500 onUnmounted<\/p>\n<hr \/>\n<h3>5. \u8ba1\u7b97\u5c5e\u6027\u4e0e\u4fa6\u542c\u5668<\/h3>\n<h4>5.1 computed<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref<span class=\"token punctuation\">,<\/span> computed <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> firstName <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;John&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">const<\/span> lastName <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Doe&#039;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u53ea\u8bfb\u8ba1\u7b97\u5c5e\u6027<\/span><br \/>\n<span class=\"token keyword\">const<\/span> fullName <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">computed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>firstName<span class=\"token punctuation\">.<\/span>value<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>lastName<span class=\"token punctuation\">.<\/span>value<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u53ef\u5199\u8ba1\u7b97\u5c5e\u6027<\/span><br \/>\n<span class=\"token keyword\">const<\/span> fullNameWritable <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">computed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function-variable function\">get<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>firstName<span class=\"token punctuation\">.<\/span>value<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>lastName<span class=\"token punctuation\">.<\/span>value<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function-variable function\">set<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">val<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">[<\/span>first<span class=\"token punctuation\">,<\/span> last<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> val<span class=\"token punctuation\">.<\/span><span class=\"token function\">split<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039; &#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    firstName<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> first<br \/>\n    lastName<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> last<br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>\u7279\u70b9&#xff1a; \u57fa\u4e8e\u4f9d\u8d56\u7f13\u5b58&#xff0c;\u4f9d\u8d56\u4e0d\u53d8\u5219\u4e0d\u91cd\u65b0\u8ba1\u7b97\u3002<\/p>\n<h4>5.2 watch<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref<span class=\"token punctuation\">,<\/span> watch<span class=\"token punctuation\">,<\/span> reactive <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">const<\/span> state <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">reactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">age<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 1. \u4fa6\u542c ref<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">newVal<span class=\"token punctuation\">,<\/span> oldVal<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>oldVal<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> \u2192 <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>newVal<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 2. \u4fa6\u542c reactive \u5bf9\u8c61\u7684\u67d0\u4e2a\u5c5e\u6027&#xff08;\u5fc5\u987b\u7528 getter&#xff09;<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span><br \/>\n  <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> state<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">newName<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>newName<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 3. \u4fa6\u542c\u591a\u4e2a\u6e90<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span>count<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> state<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\"><span class=\"token punctuation\">[<\/span>newCount<span class=\"token punctuation\">,<\/span> newName<span class=\"token punctuation\">]<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token comment\">\/\/ &#8230;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 4. \u6df1\u5ea6\u4fa6\u542c<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>state<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">newState<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token comment\">\/\/ \u4efb\u4f55\u5d4c\u5957\u5c5e\u6027\u53d8\u5316\u90fd\u89e6\u53d1<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">deep<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 5. \u7acb\u5373\u6267\u884c<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">val<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token comment\">\/\/ \u7acb\u5373\u6267\u884c\u4e00\u6b21<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">immediate<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 6. \u56de\u8c03\u5237\u65b0\u65f6\u673a<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">,<\/span> cb<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">flush<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;post&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>   <span class=\"token comment\">\/\/ DOM \u66f4\u65b0\u540e\u6267\u884c<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">,<\/span> cb<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">flush<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;sync&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>   <span class=\"token comment\">\/\/ \u540c\u6b65\u6267\u884c&#xff08;\u8c28\u614e\u4f7f\u7528&#xff09;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 7. \u4e00\u6b21\u6027\u4fa6\u542c&#xff08;Vue 3.4&#043;&#xff09;<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">,<\/span> cb<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">once<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 8. \u505c\u6b62\u4fa6\u542c<\/span><br \/>\n<span class=\"token keyword\">const<\/span> stop <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">,<\/span> cb<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token function\">stop<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u624b\u52a8\u505c\u6b62<\/span><\/p>\n<h4>5.3 watchEffect<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> watchEffect <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u81ea\u52a8\u8ffd\u8e2a\u56de\u8c03\u4e2d\u4f7f\u7528\u7684\u6240\u6709\u54cd\u5e94\u5f0f\u4f9d\u8d56<\/span><br \/>\n<span class=\"token keyword\">const<\/span> stop <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">watchEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">onCleanup<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u81ea\u52a8\u4f9d\u8d56 count<\/span><\/p>\n<p>  <span class=\"token comment\">\/\/ \u6e05\u7406\u51fd\u6570&#xff1a;\u4e0b\u6b21\u6267\u884c\u524d\u6216\u7ec4\u4ef6\u5378\u8f7d\u65f6\u8c03\u7528<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> timer <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">setInterval<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">1000<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token function\">onCleanup<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token function\">clearInterval<\/span><span class=\"token punctuation\">(<\/span>timer<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u505c\u6b62<\/span><br \/>\n<span class=\"token function\">stop<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>5.4 watch vs watchEffect<\/h4>\n<table>\n<tr>\u7279\u6027watchwatchEffect<\/tr>\n<tbody>\n<tr>\n<td>\u6307\u5b9a\u4fa6\u542c\u6e90<\/td>\n<td>\u2705 \u663e\u5f0f\u6307\u5b9a<\/td>\n<td>\u274c \u81ea\u52a8\u8ffd\u8e2a<\/td>\n<\/tr>\n<tr>\n<td>\u8bbf\u95ee\u65e7\u503c<\/td>\n<td>\u2705 (new, old)<\/td>\n<td>\u274c<\/td>\n<\/tr>\n<tr>\n<td>\u60f0\u6027\u6267\u884c<\/td>\n<td>\u2705 \u9ed8\u8ba4\u60f0\u6027<\/td>\n<td>\u274c \u7acb\u5373\u6267\u884c<\/td>\n<\/tr>\n<tr>\n<td>\u6df1\u5ea6\u9009\u9879<\/td>\n<td>\u2705 { deep: true }<\/td>\n<td>\u81ea\u52a8\u6df1\u5ea6\u8ffd\u8e2a<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>6. \u7ec4\u4ef6\u7cfb\u7edf<\/h3>\n<h4>6.1 \u7ec4\u4ef6\u5b9a\u4e49<\/h4>\n<p>&lt;!&#8211; \u5355\u6587\u4ef6\u7ec4\u4ef6 SFC &#8211;&gt;<br \/>\n&lt;script setup lang&#061;&#034;ts&#034;&gt;<br \/>\n\/\/ \u7ec4\u4ef6\u903b\u8f91<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;!&#8211; \u6a21\u677f &#8211;&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p>&lt;style scoped&gt;<br \/>\n\/* \u5c40\u90e8\u6837\u5f0f *\/<br \/>\n&lt;\/style&gt;<\/p>\n<h4>6.2 Props<\/h4>\n<p>&lt;script setup lang&#061;&#034;ts&#034;&gt;<br \/>\n\/\/ \u65b9\u5f0f\u4e00&#xff1a;defineProps \u5b8f&#xff08;\u7f16\u8bd1\u65f6&#xff0c;\u65e0\u9700 import&#xff09;<br \/>\nconst props &#061; defineProps&lt;{<br \/>\n  title: string<br \/>\n  count?: number<br \/>\n}&gt;()<\/p>\n<p>\/\/ \u5e26\u9ed8\u8ba4\u503c<br \/>\nconst props &#061; withDefaults(defineProps&lt;{<br \/>\n  title: string<br \/>\n  count?: number<br \/>\n}&gt;(), {<br \/>\n  count: 0<br \/>\n})<\/p>\n<p>\/\/ \u8fd0\u884c\u65f6\u58f0\u660e<br \/>\nconst props &#061; defineProps({<br \/>\n  title: { type: String, required: true },<br \/>\n  count: { type: Number, default: 0 },<br \/>\n  list: { type: Array as PropType&lt;string[]&gt;, default: () &#061;&gt; [] }<br \/>\n})<br \/>\n&lt;\/script&gt;<\/p>\n<p>Props \u6ce8\u610f\u4e8b\u9879&#xff1a;<\/p>\n<ul>\n<li>Props \u662f\u53ea\u8bfb\u7684&#xff0c;\u4e0d\u8981\u76f4\u63a5\u4fee\u6539<\/li>\n<li>\u5bf9\u8c61\/\u6570\u7ec4\u7c7b\u578b\u7684 default \u5fc5\u987b\u7528\u5de5\u5382\u51fd\u6570<\/li>\n<li>\u672a\u58f0\u660e\u7684 attribute \u4f1a\u843d\u5165 $attrs<\/li>\n<\/ul>\n<h4>6.3 Emits<\/h4>\n<p>&lt;script setup lang&#061;&#034;ts&#034;&gt;<br \/>\nconst emit &#061; defineEmits&lt;{<br \/>\n  change: [value: string]<br \/>\n  update: [id: number, data: object]<br \/>\n}&gt;()<\/p>\n<p>\/\/ \u8fd0\u884c\u65f6\u58f0\u660e<br \/>\nconst emit &#061; defineEmits([&#039;change&#039;, &#039;update&#039;])<\/p>\n<p>\/\/ \u89e6\u53d1<br \/>\nemit(&#039;change&#039;, &#039;hello&#039;)<br \/>\nemit(&#039;update&#039;, 1, { name: &#039;test&#039; })<br \/>\n&lt;\/script&gt;<\/p>\n<h4>6.4 v-model&#xff08;\u7ec4\u4ef6\u53cc\u5411\u7ed1\u5b9a&#xff09;<\/h4>\n<p>&lt;!&#8211; \u7236\u7ec4\u4ef6&#xff1a;\u591a\u4e2a v-model &#8211;&gt;<br \/>\n&lt;UserForm<br \/>\n  v-model:firstName&#061;&#034;first&#034;<br \/>\n  v-model:lastName&#061;&#034;last&#034;<br \/>\n\/&gt;<\/p>\n<p>&lt;!&#8211; UserForm.vue &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\nconst firstName &#061; defineModel(&#039;firstName&#039;)  \/\/ Vue 3.4&#043; \u8bed\u6cd5\u7cd6<br \/>\nconst lastName &#061; defineModel(&#039;lastName&#039;)<\/p>\n<p>\/\/ \u7b49\u4ef7\u4e8e&#xff1a;<br \/>\n\/\/ const props &#061; defineProps([&#039;firstName&#039;, &#039;lastName&#039;])<br \/>\n\/\/ const emit &#061; defineEmits([&#039;update:firstName&#039;, &#039;update:lastName&#039;])<br \/>\n&lt;\/script&gt;<\/p>\n<p>\u4fee\u9970\u7b26&#xff1a;<\/p>\n<p>&lt;UserForm v-model:firstName.trim&#061;&#034;first&#034; \/&gt;<\/p>\n<p>&lt;!&#8211; \u5b50\u7ec4\u4ef6\u4e2d &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\nconst [model, modifiers] &#061; defineModel(&#039;firstName&#039;)<br \/>\nif (modifiers.trim) { \/* &#8230; *\/ }<br \/>\n&lt;\/script&gt;<\/p>\n<h4>6.5 Slots \u63d2\u69fd<\/h4>\n<p>&lt;!&#8211; \u7236\u7ec4\u4ef6 &#8211;&gt;<br \/>\n&lt;Card&gt;<br \/>\n  &lt;template #header&gt;\u6807\u9898&lt;\/template&gt;<br \/>\n  &lt;template #default&#061;&#034;{ item }&#034;&gt;<br \/>\n    {{ item.name }}<br \/>\n  &lt;\/template&gt;<br \/>\n  &lt;template #footer&gt;\u5e95\u90e8&lt;\/template&gt;<br \/>\n&lt;\/Card&gt;<\/p>\n<p>&lt;!&#8211; Card.vue &#8211;&gt;<br \/>\n&lt;template&gt;<br \/>\n  &lt;div class&#061;&#034;card&#034;&gt;<br \/>\n    &lt;header&gt;&lt;slot name&#061;&#034;header&#034; \/&gt;&lt;\/header&gt;<br \/>\n    &lt;main&gt;&lt;slot :item&#061;&#034;currentItem&#034; \/&gt;&lt;\/main&gt;<br \/>\n    &lt;footer&gt;&lt;slot name&#061;&#034;footer&#034;&gt;\u9ed8\u8ba4\u5e95\u90e8&lt;\/slot&gt;&lt;\/footer&gt;<br \/>\n  &lt;\/div&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p><span class=\"token comment\">\/\/ \u5728 setup \u4e2d\u8bbf\u95ee\u63d2\u69fd<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useSlots <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> slots <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">useSlots<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token comment\">\/\/ slots.default?.()<\/span><br \/>\n<span class=\"token comment\">\/\/ slots.header?.()<\/span><\/p>\n<h4>6.6 expose \/ \u7ec4\u4ef6\u5b9e\u4f8b<\/h4>\n<p>&lt;!&#8211; \u5b50\u7ec4\u4ef6 &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\nimport { ref } from &#039;vue&#039;<br \/>\nconst count &#061; ref(0)<br \/>\nconst reset &#061; () &#061;&gt; (count.value &#061; 0)<\/p>\n<p>\/\/ \u53ea\u66b4\u9732 reset&#xff0c;\u4e0d\u66b4\u9732 count<br \/>\ndefineExpose({ reset })<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;!&#8211; \u7236\u7ec4\u4ef6 &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\nimport { ref, onMounted } from &#039;vue&#039;<br \/>\nimport Child from &#039;.\/Child.vue&#039;<\/p>\n<p>const childRef &#061; ref(null)<br \/>\nonMounted(() &#061;&gt; {<br \/>\n  childRef.value.reset()  \/\/ \u2705<br \/>\n  \/\/ childRef.value.count  \/\/ \u274c \u672a\u66b4\u9732<br \/>\n})<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;Child ref&#061;&#034;childRef&#034; \/&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<h4>6.7 attrs \u900f\u4f20<\/h4>\n<p>&lt;!&#8211; \u81ea\u52a8\u7ee7\u627f&#xff1a;\u672a\u58f0\u660e\u7684 props\/emits \u81ea\u52a8\u7ed1\u5b9a\u5230\u6839\u5143\u7d20 &#8211;&gt;<br \/>\n&lt;!&#8211; \u7981\u7528\u7ee7\u627f &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\ndefineOptions({ inheritAttrs: false })<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;input v-bind&#061;&#034;$attrs&#034; \/&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<h4>6.8 \u52a8\u6001\u7ec4\u4ef6<\/h4>\n<p>&lt;script setup&gt;<br \/>\nimport { shallowRef } from &#039;vue&#039;<br \/>\nimport TabA from &#039;.\/TabA.vue&#039;<br \/>\nimport TabB from &#039;.\/TabB.vue&#039;<\/p>\n<p>const current &#061; shallowRef(TabA)<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;component :is&#061;&#034;current&#034; \/&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<hr \/>\n<h3>7. \u6a21\u677f\u8bed\u6cd5\u4e0e\u6307\u4ee4<\/h3>\n<h4>7.1 \u63d2\u503c\u4e0e\u7ed1\u5b9a<\/h4>\n<p><span class=\"token comment\">&lt;!&#8211; \u6587\u672c\u63d2\u503c &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>p<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>{{ message }}<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>p<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; \u539f\u59cb HTML &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">v-html<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>rawHtml<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; \u5c5e\u6027\u7ed1\u5b9a &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>img<\/span> <span class=\"token attr-name\">:src<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>imageUrl<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">:alt<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>title<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">:class<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>{ active: isActive, &#039;text-danger&#039;: hasError }<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">:class<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>[activeClass, errorClass]<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">:style<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>{ color: activeColor, fontSize: fontSize &#043; &#039;px&#039; }<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; \u52a8\u6001\u53c2\u6570 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>a<\/span> <span class=\"token attr-name\">:[attrName]<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>url<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>Link<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>a<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>button<\/span> <span class=\"token attr-name\">&#064;[eventName]<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>handler<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>Click<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>button<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<h4>7.2 \u6761\u4ef6\u6e32\u67d3<\/h4>\n<p><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">v-if<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>type &#061;&#061;&#061; &#039;A&#039;<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>A<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">v-else-if<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>type &#061;&#061;&#061; &#039;B&#039;<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>B<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">v-else<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>C<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; v-show&#xff1a;\u5207\u6362 display&#xff0c;\u9891\u7e41\u5207\u6362\u65f6\u6027\u80fd\u66f4\u597d &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">v-show<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>isVisible<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>Toggle me<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; template \u4e0a\u4f7f\u7528 v-if&#xff08;\u4e0d\u6e32\u67d3\u989d\u5916\u5143\u7d20&#xff09; &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>template<\/span> <span class=\"token attr-name\">v-if<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>showGroup<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>h1<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>Title<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>h1<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>p<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>Content<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>p<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>template<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<h4>7.3 \u5217\u8868\u6e32\u67d3<\/h4>\n<p><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>li<\/span> <span class=\"token attr-name\">v-for<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>(item, index) in items<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">:key<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>item.id<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n  {{ index }} &#8211; {{ item.name }}<br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>li<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; \u5bf9\u8c61\u904d\u5386 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">v-for<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>(value, key, index) in obj<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">:key<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>key<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n  {{ key }}: {{ value }}<br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>div<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; \u8303\u56f4 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>span<\/span> <span class=\"token attr-name\">v-for<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>n in 10<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">:key<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>n<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>{{ n }}<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>span<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>\u26a0\ufe0f key \u7684\u91cd\u8981\u6027&#xff1a; \u5fc5\u987b\u7528\u552f\u4e00\u6807\u8bc6&#xff08;\u5982 id&#xff09;&#xff0c;\u4e0d\u8981\u7528 index\u3002<\/p>\n<h4>7.4 \u4e8b\u4ef6\u5904\u7406<\/h4>\n<p><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>button<\/span> <span class=\"token attr-name\">&#064;click<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>handler<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>Click<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>button<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>button<\/span> <span class=\"token attr-name\">&#064;click<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>handler($event, &#039;arg&#039;)<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>With args<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>button<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; \u4fee\u9970\u7b26 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>form<\/span> <span class=\"token attr-name\">&#064;submit.prevent<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>onSubmit<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>       <span class=\"token comment\">&lt;!&#8211; \u963b\u6b62\u9ed8\u8ba4 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>a<\/span> <span class=\"token attr-name\">&#064;click.stop<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>doThis<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>               <span class=\"token comment\">&lt;!&#8211; \u963b\u6b62\u5192\u6ce1 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">&#064;click.self<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>onlySelf<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>           <span class=\"token comment\">&lt;!&#8211; \u4ec5\u81ea\u8eab\u89e6\u53d1 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">&#064;keyup.enter<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>submit<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>          <span class=\"token comment\">&lt;!&#8211; \u6309\u952e\u4fee\u9970\u7b26 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>button<\/span> <span class=\"token attr-name\">&#064;click.once<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>doOnce<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>          <span class=\"token comment\">&lt;!&#8211; \u4ec5\u89e6\u53d1\u4e00\u6b21 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>div<\/span> <span class=\"token attr-name\">&#064;scroll.passive<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>onScroll<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>       <span class=\"token comment\">&lt;!&#8211; passive \u76d1\u542c &#8211;&gt;<\/span><\/p>\n<h4>7.5 \u8868\u5355\u7ed1\u5b9a<\/h4>\n<p><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">v-model<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>text<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>textarea<\/span> <span class=\"token attr-name\">v-model<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>desc<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>textarea<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">type<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>checkbox<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">v-model<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>checked<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">type<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>checkbox<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">v-model<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>picked<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">value<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>a<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">type<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>radio<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">v-model<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>picked<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">value<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>b<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>select<\/span> <span class=\"token attr-name\">v-model<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>selected<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>option<\/span> <span class=\"token attr-name\">value<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>1<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>One<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>option<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>select<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">&lt;!&#8211; \u4fee\u9970\u7b26 &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">v-model.trim<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>msg<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span>       <span class=\"token comment\">&lt;!&#8211; \u81ea\u52a8 trim &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">v-model.number<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>age<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span>     <span class=\"token comment\">&lt;!&#8211; \u8f6c number &#8211;&gt;<\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input<\/span> <span class=\"token attr-name\">v-model.lazy<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>msg<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token punctuation\">\/&gt;<\/span><\/span>       <span class=\"token comment\">&lt;!&#8211; change \u800c\u975e input \u4e8b\u4ef6 &#8211;&gt;<\/span><\/p>\n<hr \/>\n<h3>8. \u5185\u7f6e\u7ec4\u4ef6<\/h3>\n<h4>8.1 Transition<\/h4>\n<p>&lt;template&gt;<br \/>\n  &lt;Transition name&#061;&#034;fade&#034; mode&#061;&#034;out-in&#034;&gt;<br \/>\n    &lt;p v-if&#061;&#034;show&#034;&gt;Hello&lt;\/p&gt;<br \/>\n  &lt;\/Transition&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p>&lt;style&gt;<br \/>\n.fade-enter-active,<br \/>\n.fade-leave-active {<br \/>\n  transition: opacity 0.3s ease;<br \/>\n}<br \/>\n.fade-enter-from,<br \/>\n.fade-leave-to {<br \/>\n  opacity: 0;<br \/>\n}<br \/>\n&lt;\/style&gt;<\/p>\n<p>\u8fc7\u6e21\u7c7b\u540d&#xff08;Vue 3&#xff09;&#xff1a;<\/p>\n<ul>\n<li>v-enter-from \u2192 v-enter-active \u2192 v-enter-to<\/li>\n<li>v-leave-from \u2192 v-leave-active \u2192 v-leave-to<\/li>\n<\/ul>\n<h4>8.2 TransitionGroup<\/h4>\n<p>&lt;TransitionGroup name&#061;&#034;list&#034; tag&#061;&#034;ul&#034;&gt;<br \/>\n  &lt;li v-for&#061;&#034;item in items&#034; :key&#061;&#034;item.id&#034;&gt;{{ item.text }}&lt;\/li&gt;<br \/>\n&lt;\/TransitionGroup&gt;<\/p>\n<p>&lt;style&gt;<br \/>\n.list-enter-active, .list-leave-active {<br \/>\n  transition: all 0.5s ease;<br \/>\n}<br \/>\n.list-enter-from, .list-leave-to {<br \/>\n  opacity: 0;<br \/>\n  transform: translateX(30px);<br \/>\n}<br \/>\n.list-move {<br \/>\n  transition: transform 0.5s ease;<br \/>\n}<br \/>\n&lt;\/style&gt;<\/p>\n<h4>8.3 KeepAlive<\/h4>\n<p>&lt;KeepAlive :include&#061;&#034;[&#039;TabA&#039;, &#039;TabB&#039;]&#034; :max&#061;&#034;10&#034;&gt;<br \/>\n  &lt;component :is&#061;&#034;currentTab&#034; \/&gt;<br \/>\n&lt;\/KeepAlive&gt;<\/p>\n<p>&lt;!&#8211; \u914d\u5408\u751f\u547d\u5468\u671f &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\nimport { onActivated, onDeactivated } from &#039;vue&#039;<\/p>\n<p>onActivated(() &#061;&gt; { \/* \u4ece\u7f13\u5b58\u6062\u590d *\/ })<br \/>\nonDeactivated(() &#061;&gt; { \/* \u8fdb\u5165\u7f13\u5b58 *\/ })<br \/>\n&lt;\/script&gt;<\/p>\n<hr \/>\n<h3>9. \u8def\u7531&#xff08;Vue Router 4&#xff09;<\/h3>\n<h4>9.1 \u57fa\u672c\u914d\u7f6e<\/h4>\n<p><span class=\"token comment\">\/\/ router\/index.js<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> createRouter<span class=\"token punctuation\">,<\/span> createWebHistory <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue-router&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> routes <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n  <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token literal-property property\">path<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\/&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;Home&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function-variable function\">component<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;..\/views\/Home.vue&#039;<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u61d2\u52a0\u8f7d<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token literal-property property\">path<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\/user\/:id&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;User&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function-variable function\">component<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;..\/views\/User.vue&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token literal-property property\">props<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u5c06 params \u4f5c\u4e3a props \u4f20\u5165<\/span><br \/>\n    <span class=\"token literal-property property\">children<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n      <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">path<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;profile&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function-variable function\">component<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;..\/views\/Profile.vue&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token literal-property property\">path<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\/:pathMatch(.*)*&#039;<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ 404 \u515c\u5e95<\/span><br \/>\n    <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;NotFound&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function-variable function\">component<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;..\/views\/404.vue&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> router <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createRouter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">history<\/span><span class=\"token operator\">:<\/span> <span class=\"token function\">createWebHistory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">import<\/span><span class=\"token punctuation\">.<\/span>meta<span class=\"token punctuation\">.<\/span>env<span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASE_URL<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  routes<span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function\">scrollBehavior<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">to<span class=\"token punctuation\">,<\/span> from<span class=\"token punctuation\">,<\/span> savedPosition<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> savedPosition <span class=\"token operator\">||<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">top<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> router<\/p>\n<h4>9.2 \u7ec4\u5408\u5f0f API \u4e2d\u4f7f\u7528<\/h4>\n<p>&lt;script setup&gt;<br \/>\nimport { useRouter, useRoute } from &#039;vue-router&#039;<\/p>\n<p>const router &#061; useRouter()<br \/>\nconst route &#061; useRoute()<\/p>\n<p>\/\/ \u7f16\u7a0b\u5f0f\u5bfc\u822a<br \/>\nrouter.push(&#039;\/user\/1&#039;)<br \/>\nrouter.push({ name: &#039;User&#039;, params: { id: 1 } })<br \/>\nrouter.replace(&#039;\/login&#039;)<br \/>\nrouter.back()<br \/>\nrouter.go(-2)<\/p>\n<p>\/\/ \u5f53\u524d\u8def\u7531\u4fe1\u606f<br \/>\nconsole.log(route.params.id)<br \/>\nconsole.log(route.query.search)<br \/>\nconsole.log(route.hash)<br \/>\n&lt;\/script&gt;<\/p>\n<h4>9.3 \u5bfc\u822a\u5b88\u536b<\/h4>\n<p><span class=\"token comment\">\/\/ \u5168\u5c40\u524d\u7f6e\u5b88\u536b<\/span><br \/>\nrouter<span class=\"token punctuation\">.<\/span><span class=\"token function\">beforeEach<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">to<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">from<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> auth <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">useAuthStore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>to<span class=\"token punctuation\">.<\/span>meta<span class=\"token punctuation\">.<\/span>requiresAuth <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token operator\">!<\/span>auth<span class=\"token punctuation\">.<\/span>isLoggedIn<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;Login&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">query<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">redirect<\/span><span class=\"token operator\">:<\/span> to<span class=\"token punctuation\">.<\/span>fullPath <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5168\u5c40\u540e\u7f6e\u94a9\u5b50<\/span><br \/>\nrouter<span class=\"token punctuation\">.<\/span><span class=\"token function\">afterEach<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">to<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">from<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  document<span class=\"token punctuation\">.<\/span>title <span class=\"token operator\">&#061;<\/span> to<span class=\"token punctuation\">.<\/span>meta<span class=\"token punctuation\">.<\/span>title <span class=\"token operator\">||<\/span> <span class=\"token string\">&#039;App&#039;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u8def\u7531\u72ec\u4eab\u5b88\u536b<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">path<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\/admin&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">component<\/span><span class=\"token operator\">:<\/span> Admin<span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function-variable function\">beforeEnter<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">to<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">from<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span><span class=\"token function\">isAdmin<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">false<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>&lt;!&#8211; \u7ec4\u4ef6\u5185\u5b88\u536b &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\nimport { onBeforeRouteLeave, onBeforeRouteUpdate } from &#039;vue-router&#039;<\/p>\n<p>onBeforeRouteLeave((to, from) &#061;&gt; {<br \/>\n  if (hasUnsavedChanges.value) {<br \/>\n    return window.confirm(&#039;\u786e\u5b9a\u79bb\u5f00&#xff1f;\u672a\u4fdd\u5b58\u7684\u66f4\u6539\u5c06\u4e22\u5931\u3002&#039;)<br \/>\n  }<br \/>\n})<\/p>\n<p>onBeforeRouteUpdate((to, from) &#061;&gt; {<br \/>\n  \/\/ \u540c\u7ec4\u4ef6\u590d\u7528&#xff0c;\u53c2\u6570\u53d8\u5316\u65f6&#xff08;\u5982 \/user\/1 \u2192 \/user\/2&#xff09;<br \/>\n  fetchData(to.params.id)<br \/>\n})<br \/>\n&lt;\/script&gt;<\/p>\n<h4>9.4 \u8def\u7531\u5143\u4fe1\u606f<\/h4>\n<p><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">path<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\/dashboard&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">component<\/span><span class=\"token operator\">:<\/span> Dashboard<span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">meta<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token literal-property property\">requiresAuth<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token literal-property property\">title<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\u63a7\u5236\u53f0&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token literal-property property\">roles<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;admin&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;editor&#039;<\/span><span class=\"token punctuation\">]<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>10. \u72b6\u6001\u7ba1\u7406&#xff08;Pinia&#xff09;<\/h3>\n<h4>10.1 \u57fa\u672c\u4f7f\u7528<\/h4>\n<p><span class=\"token comment\">\/\/ stores\/counter.js<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> defineStore <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;pinia&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref<span class=\"token punctuation\">,<\/span> computed <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7ec4\u5408\u5f0f\u5199\u6cd5&#xff08;\u63a8\u8350&#xff09;<\/span><br \/>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">const<\/span> useCounterStore <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineStore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;counter&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token comment\">\/\/ state<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> name <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Vue&#039;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token comment\">\/\/ getters<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> doubleCount <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">computed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> count<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">*<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token comment\">\/\/ actions<\/span><br \/>\n  <span class=\"token keyword\">function<\/span> <span class=\"token function\">increment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    count<span class=\"token punctuation\">.<\/span>value<span class=\"token operator\">&#043;&#043;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">fetchCount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> res <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> api<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    count<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> res<span class=\"token punctuation\">.<\/span>data<br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> count<span class=\"token punctuation\">,<\/span> name<span class=\"token punctuation\">,<\/span> doubleCount<span class=\"token punctuation\">,<\/span> increment<span class=\"token punctuation\">,<\/span> fetchCount <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u9009\u9879\u5f0f\u5199\u6cd5<\/span><br \/>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">const<\/span> useCounterStore <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineStore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;counter&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function-variable function\">state<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">count<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;Vue&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">getters<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function-variable function\">doubleCount<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">state<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> state<span class=\"token punctuation\">.<\/span>count <span class=\"token operator\">*<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">doublePlusOne<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>doubleCount <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">actions<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">increment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>count<span class=\"token operator\">&#043;&#043;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token function\">fetchCount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>count <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> api<span class=\"token punctuation\">.<\/span><span class=\"token function\">getCount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>10.2 \u5728\u7ec4\u4ef6\u4e2d\u4f7f\u7528<\/h4>\n<p>&lt;script setup&gt;<br \/>\nimport { useCounterStore } from &#039;&#064;\/stores\/counter&#039;<br \/>\nimport { storeToRefs } from &#039;pinia&#039;<\/p>\n<p>const store &#061; useCounterStore()<\/p>\n<p>\/\/ \u26a0\ufe0f \u89e3\u6784\u4f1a\u4e22\u5931\u54cd\u5e94\u6027&#xff0c;\u7528 storeToRefs<br \/>\nconst { count, doubleCount } &#061; storeToRefs(store)<br \/>\n\/\/ actions \u53ef\u4ee5\u76f4\u63a5\u89e3\u6784<br \/>\nconst { increment } &#061; store<\/p>\n<p>\/\/ \u4fee\u6539 state<br \/>\nstore.count&#043;&#043;<br \/>\nstore.$patch({ count: 10, name: &#039;Pinia&#039; })<br \/>\nstore.$patch((state) &#061;&gt; {<br \/>\n  state.count&#043;&#043;<br \/>\n  state.name &#061; &#039;batch&#039;<br \/>\n})<br \/>\nstore.$reset()  \/\/ \u91cd\u7f6e&#xff08;\u4ec5\u9009\u9879\u5f0f\u5199\u6cd5\u652f\u6301&#xff09;<br \/>\n&lt;\/script&gt;<\/p>\n<h4>10.3 Store \u7ec4\u5408<\/h4>\n<p><span class=\"token comment\">\/\/ stores\/user.js<\/span><br \/>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">const<\/span> useUserStore <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineStore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;user&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> token <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> isLoggedIn <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">computed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token operator\">!<\/span><span class=\"token operator\">!<\/span>token<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> token<span class=\"token punctuation\">,<\/span> isLoggedIn <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ stores\/cart.js<\/span><br \/>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">const<\/span> useCartStore <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineStore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;cart&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> user <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">useUserStore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u7ec4\u5408\u5176\u4ed6 store<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> items <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token keyword\">const<\/span> canCheckout <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">computed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> user<span class=\"token punctuation\">.<\/span>isLoggedIn <span class=\"token operator\">&amp;&amp;<\/span> items<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">.<\/span>length <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> items<span class=\"token punctuation\">,<\/span> canCheckout <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>10.4 \u63d2\u4ef6\u4e0e\u6301\u4e45\u5316<\/h4>\n<p><span class=\"token comment\">\/\/ pinia \u63d2\u4ef6<\/span><br \/>\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">piniaLogger<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\"><span class=\"token punctuation\">{<\/span> store <span class=\"token punctuation\">}<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  store<span class=\"token punctuation\">.<\/span><span class=\"token function\">$subscribe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">mutation<span class=\"token punctuation\">,<\/span> state<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">[<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>store<span class=\"token punctuation\">.<\/span>$id<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">] <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>mutation<span class=\"token punctuation\">.<\/span>type<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">,<\/span> state<span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> pinia <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createPinia<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\npinia<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span>piniaLogger<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u6301\u4e45\u5316&#xff08;pinia-plugin-persistedstate&#xff09;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> piniaPluginPersistedstate <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;pinia-plugin-persistedstate&#039;<\/span><br \/>\npinia<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span>piniaPluginPersistedstate<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ store \u4e2d\u542f\u7528<\/span><br \/>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">const<\/span> useUserStore <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineStore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;user&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token comment\">\/\/ &#8230;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">persist<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span>  <span class=\"token comment\">\/\/ \u6216 { key: &#039;user&#039;, storage: localStorage }<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<hr \/>\n<h3>11. TypeScript \u96c6\u6210<\/h3>\n<h4>11.1 \u9879\u76ee\u914d\u7f6e<\/h4>\n<p><span class=\"token function\">npm<\/span> create vue&#064;latest  <span class=\"token comment\"># \u9009\u62e9 TypeScript<\/span><\/p>\n<p><span class=\"token comment\">\/\/ tsconfig.json \u5173\u952e\u914d\u7f6e<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;compilerOptions&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#034;target&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;ESNext&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;module&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;ESNext&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;moduleResolution&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;bundler&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;strict&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;jsx&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;preserve&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;paths&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;&#064;\/*&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;.\/src\/*&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>11.2 \u7ec4\u4ef6\u4e2d\u7684 TS<\/h4>\n<p>&lt;script setup lang&#061;&#034;ts&#034;&gt;<br \/>\nimport { ref, computed } from &#039;vue&#039;<br \/>\nimport type { Ref } from &#039;vue&#039;<\/p>\n<p>\/\/ \u81ea\u52a8\u63a8\u65ad<br \/>\nconst count &#061; ref(0)  \/\/ Ref&lt;number&gt;<\/p>\n<p>\/\/ \u663e\u5f0f\u6cdb\u578b<br \/>\nconst list &#061; ref&lt;string[]&gt;([])<br \/>\nconst user &#061; ref&lt;{ name: string; age: number } | null&gt;(null)<\/p>\n<p>\/\/ Props \u7c7b\u578b<br \/>\ninterface Props {<br \/>\n  title: string<br \/>\n  items?: string[]<br \/>\n}<br \/>\nconst props &#061; withDefaults(defineProps&lt;Props&gt;(), {<br \/>\n  items: () &#061;&gt; []<br \/>\n})<\/p>\n<p>\/\/ Emits \u7c7b\u578b<br \/>\nconst emit &#061; defineEmits&lt;{<br \/>\n  change: [value: string]<br \/>\n  delete: [id: number]<br \/>\n}&gt;()<\/p>\n<p>\/\/ Ref \u7c7b\u578b<br \/>\nconst inputRef &#061; ref&lt;HTMLInputElement | null&gt;(null)<\/p>\n<p>\/\/ \u7ec4\u4ef6 ref \u7c7b\u578b<br \/>\nimport Child from &#039;.\/Child.vue&#039;<br \/>\nconst childRef &#061; ref&lt;InstanceType&lt;typeof Child&gt; | null&gt;(null)<br \/>\n&lt;\/script&gt;<\/p>\n<h4>11.3 \u6ce8\u5165\u7c7b\u578b\u5b89\u5168<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token keyword\">type<\/span> <span class=\"token punctuation\">{<\/span> InjectionKey<span class=\"token punctuation\">,<\/span> Ref <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">const<\/span> CountKey<span class=\"token operator\">:<\/span> InjectionKey<span class=\"token operator\">&lt;<\/span>Ref<span class=\"token operator\">&lt;<\/span><span class=\"token builtin\">number<\/span><span class=\"token operator\">&gt;&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">Symbol<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;count&#039;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ provide<\/span><br \/>\n<span class=\"token function\">provide<\/span><span class=\"token punctuation\">(<\/span>CountKey<span class=\"token punctuation\">,<\/span> <span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ inject &#8211; \u81ea\u52a8\u63a8\u65ad\u4e3a Ref&lt;number&gt;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> count <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">inject<\/span><span class=\"token punctuation\">(<\/span>CountKey<span class=\"token punctuation\">)<\/span><span class=\"token operator\">!<\/span><\/p>\n<h4>11.4 \u6a21\u677f ref \u7c7b\u578b<\/h4>\n<p>&lt;script setup lang&#061;&#034;ts&#034;&gt;<br \/>\nimport { ref, onMounted } from &#039;vue&#039;<\/p>\n<p>\/\/ DOM \u5143\u7d20<br \/>\nconst el &#061; ref&lt;HTMLDivElement | null&gt;(null)<\/p>\n<p>\/\/ \u7ec4\u4ef6\u5b9e\u4f8b<br \/>\nimport MyComp from &#039;.\/MyComp.vue&#039;<br \/>\nconst comp &#061; ref&lt;InstanceType&lt;typeof MyComp&gt; | null&gt;(null)<\/p>\n<p>onMounted(() &#061;&gt; {<br \/>\n  el.value?.focus()<br \/>\n  comp.value?.reset()<br \/>\n})<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;div ref&#061;&#034;el&#034; tabindex&#061;&#034;0&#034;&gt;Focusable&lt;\/div&gt;<br \/>\n  &lt;MyComp ref&#061;&#034;comp&#034; \/&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<hr \/>\n<h3>12. \u6027\u80fd\u4f18\u5316<\/h3>\n<h4>12.1 \u7f16\u8bd1\u5c42\u4f18\u5316<\/h4>\n<ul>\n<li>Tree-shaking&#xff1a;\u672a\u4f7f\u7528\u7684 API \u4e0d\u4f1a\u6253\u5305<\/li>\n<li>\u9759\u6001\u63d0\u5347&#xff08;hoistStatic&#xff09;&#xff1a;\u9759\u6001\u8282\u70b9\u63d0\u5347\u5230\u6e32\u67d3\u51fd\u6570\u5916<\/li>\n<li>Patch Flags&#xff1a;\u7f16\u8bd1\u65f6\u6807\u8bb0\u52a8\u6001\u7ed1\u5b9a\u7c7b\u578b&#xff0c;\u8fd0\u884c\u65f6\u7cbe\u51c6 diff<\/li>\n<li>Block Tree&#xff1a;\u5c06\u6a21\u677f\u5206\u5757&#xff0c;\u53ea\u8ffd\u8e2a\u52a8\u6001\u8282\u70b9<\/li>\n<li>\u7f13\u5b58\u4e8b\u4ef6\u5904\u7406\u51fd\u6570&#xff1a;cacheHandlers<\/li>\n<\/ul>\n<h4>12.2 \u8fd0\u884c\u65f6\u4f18\u5316<\/h4>\n<p>&lt;script setup&gt;<br \/>\nimport { shallowRef, vModelText } from &#039;vue&#039;<\/p>\n<p>\/\/ 1. \u5927\u5217\u8868\u7528 shallowRef \/ shallowReactive<br \/>\nconst bigList &#061; shallowRef(hugeArray)<\/p>\n<p>\/\/ 2. v-once&#xff1a;\u53ea\u6e32\u67d3\u4e00\u6b21<br \/>\n\/\/ &lt;div v-once&gt;{{ staticContent }}&lt;\/div&gt;<\/p>\n<p>\/\/ 3. v-memo&#xff1a;\u6761\u4ef6\u8bb0\u5fc6\u5316<br \/>\n\/\/ &lt;div v-memo&#061;&#034;[item.id &#061;&#061;&#061; selected]&#034;&gt;&#8230;&lt;\/div&gt;<\/p>\n<p>\/\/ 4. \u865a\u62df\u5217\u8868&#xff08;\u5927\u91cf\u6570\u636e&#xff09;<br \/>\n\/\/ \u4f7f\u7528 vue-virtual-scroller \/ &#064;tanstack\/vue-virtual<br \/>\n&lt;\/script&gt;<\/p>\n<h4>12.3 \u7ec4\u4ef6\u7ea7\u4f18\u5316<\/h4>\n<p><span class=\"token comment\">\/\/ 1. \u5f02\u6b65\u7ec4\u4ef6 \/ \u4ee3\u7801\u5206\u5272<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> defineAsyncComponent <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> HeavyChart <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineAsyncComponent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span><br \/>\n  <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.\/HeavyChart.vue&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 2. KeepAlive \u7f13\u5b58<\/span><br \/>\n<span class=\"token comment\">\/\/ &lt;KeepAlive :max&#061;&#034;5&#034;&gt;<\/span><br \/>\n<span class=\"token comment\">\/\/   &lt;component :is&#061;&#034;currentView&#034; \/&gt;<\/span><br \/>\n<span class=\"token comment\">\/\/ &lt;\/KeepAlive&gt;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 3. \u907f\u514d\u4e0d\u5fc5\u8981\u7684\u54cd\u5e94\u5f0f<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> markRaw <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> chartInstance <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">markRaw<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ECharts<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u4e0d\u9700\u8981\u54cd\u5e94\u5f0f<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 4. \u51fd\u6570\u5f0f\u7ec4\u4ef6&#xff08;\u7eaf\u5c55\u793a&#xff09;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">FuncComp<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">props<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;div&#039;<\/span><span class=\"token punctuation\">,<\/span> props<span class=\"token punctuation\">.<\/span>msg<span class=\"token punctuation\">)<\/span><\/p>\n<h4>12.4 \u5217\u8868\u4f18\u5316<\/h4>\n<p>&lt;!&#8211; \u2705 \u6b63\u786e&#xff1a;\u552f\u4e00 key &#8211;&gt;<br \/>\n&lt;li v-for&#061;&#034;item in list&#034; :key&#061;&#034;item.id&#034;&gt;{{ item.name }}&lt;\/li&gt;<\/p>\n<p>&lt;!&#8211; \u274c \u9519\u8bef&#xff1a;\u7528 index &#8211;&gt;<br \/>\n&lt;li v-for&#061;&#034;(item, i) in list&#034; :key&#061;&#034;i&#034;&gt;{{ item.name }}&lt;\/li&gt;<\/p>\n<p>&lt;!&#8211; \u5927\u5217\u8868&#xff1a;\u5206\u9875 \/ \u865a\u62df\u6eda\u52a8 &#8211;&gt;<br \/>\n&lt;VirtualList :items&#061;&#034;items&#034; :item-height&#061;&#034;50&#034; v-slot&#061;&#034;{ item }&#034;&gt;<br \/>\n  &lt;div&gt;{{ item.name }}&lt;\/div&gt;<br \/>\n&lt;\/VirtualList&gt;<\/p>\n<h4>12.5 \u5176\u4ed6\u6280\u5de7<\/h4>\n<p><span class=\"token comment\">\/\/ \u9632\u6296\/\u8282\u6d41\u641c\u7d22<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useDebouncedRef <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;.\/useDebouncedRef&#039;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> search <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">useDebouncedRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">300<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>search<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">val<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token function\">fetchResults<\/span><span class=\"token punctuation\">(<\/span>val<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u56fe\u7247\u61d2\u52a0\u8f7d<\/span><br \/>\n<span class=\"token comment\">\/\/ &lt;img v-lazy&#061;&#034;imageUrl&#034; \/&gt;  &#xff08;\u81ea\u5b9a\u4e49\u6307\u4ee4\u6216 vue-lazyload&#xff09;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u8def\u7531\u61d2\u52a0\u8f7d<\/span><br \/>\n<span class=\"token function-variable function\">component<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.\/views\/About.vue&#039;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7b2c\u4e09\u65b9\u5e93\u6309\u9700\u5f15\u5165<\/span><br \/>\n<span class=\"token comment\">\/\/ import { debounce } from &#039;lodash-es&#039;  \/\/ \u2705<\/span><br \/>\n<span class=\"token comment\">\/\/ import _ from &#039;lodash&#039;                \/\/ \u274c<\/span><\/p>\n<hr \/>\n<h3>13. \u7f16\u8bd1\u4f18\u5316<\/h3>\n<h4>13.1 Patch Flags \u8be6\u89e3<\/h4>\n<p><span class=\"token comment\">\/\/ \u7f16\u8bd1\u524d<\/span><br \/>\n<span class=\"token comment\">\/\/ &lt;div&gt;&lt;span&gt;static&lt;\/span&gt;&lt;span&gt;{{ dynamic }}&lt;\/span&gt;&lt;\/div&gt;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7f16\u8bd1\u540e&#xff08;\u7b80\u5316&#xff09;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> createElementVNode <span class=\"token keyword\">as<\/span> _createElementVNode<span class=\"token punctuation\">,<\/span> toDisplayString <span class=\"token keyword\">as<\/span> _toDisplayString<span class=\"token punctuation\">,<\/span> openBlock <span class=\"token keyword\">as<\/span> _openBlock<span class=\"token punctuation\">,<\/span> createElementBlock <span class=\"token keyword\">as<\/span> _createElementBlock <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#034;vue&#034;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> _hoisted_1 <span class=\"token operator\">&#061;<\/span> <span class=\"token comment\">\/*#__PURE__*\/<\/span><span class=\"token function\">_createElementVNode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;span&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;static&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span> <span class=\"token comment\">\/* HOISTED *\/<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">render<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">_ctx<span class=\"token punctuation\">,<\/span> _cache<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">_openBlock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">_createElementBlock<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;div&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n    _hoisted_1<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token function\">_createElementVNode<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;span&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">_toDisplayString<\/span><span class=\"token punctuation\">(<\/span>_ctx<span class=\"token punctuation\">.<\/span>dynamic<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">1<\/span> <span class=\"token comment\">\/* TEXT *\/<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5e38\u89c1 PatchFlag&#xff1a;<\/p>\n<table>\n<tr>Flag\u503c\u542b\u4e49<\/tr>\n<tbody>\n<tr>\n<td>TEXT<\/td>\n<td>1<\/td>\n<td>\u52a8\u6001\u6587\u672c<\/td>\n<\/tr>\n<tr>\n<td>CLASS<\/td>\n<td>2<\/td>\n<td>\u52a8\u6001 class<\/td>\n<\/tr>\n<tr>\n<td>STYLE<\/td>\n<td>4<\/td>\n<td>\u52a8\u6001 style<\/td>\n<\/tr>\n<tr>\n<td>PROPS<\/td>\n<td>8<\/td>\n<td>\u52a8\u6001\u975e class\/style props<\/td>\n<\/tr>\n<tr>\n<td>FULL_PROPS<\/td>\n<td>16<\/td>\n<td>\u52a8\u6001 key \u4e0d\u786e\u5b9a\u7684 props<\/td>\n<\/tr>\n<tr>\n<td>NEED_HYDRATION<\/td>\n<td>32<\/td>\n<td>SSR \u9700\u8981\u6c34\u5408<\/td>\n<\/tr>\n<tr>\n<td>STABLE_FRAGMENT<\/td>\n<td>64<\/td>\n<td>\u5b50\u8282\u70b9\u987a\u5e8f\u4e0d\u53d8<\/td>\n<\/tr>\n<tr>\n<td>KEYED_FRAGMENT<\/td>\n<td>128<\/td>\n<td>\u6709 key \u7684 fragment<\/td>\n<\/tr>\n<tr>\n<td>UNKEYED_FRAGMENT<\/td>\n<td>256<\/td>\n<td>\u65e0 key \u7684 fragment<\/td>\n<\/tr>\n<tr>\n<td>HOISTED<\/td>\n<td>-1<\/td>\n<td>\u9759\u6001\u63d0\u5347<\/td>\n<\/tr>\n<tr>\n<td>BAIL<\/td>\n<td>-2<\/td>\n<td>\u9000\u51fa\u4f18\u5316\u6a21\u5f0f<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>13.2 Block Tree<\/h4>\n<p>&lt;template&gt;<br \/>\n  &lt;div&gt;                    &lt;!&#8211; Block root &#8211;&gt;<br \/>\n    &lt;p&gt;static&lt;\/p&gt;          &lt;!&#8211; \u4e0d\u8ffd\u8e2a &#8211;&gt;<br \/>\n    &lt;p&gt;{{ a }}&lt;\/p&gt;         &lt;!&#8211; \u8ffd\u8e2a &#8211;&gt;<br \/>\n    &lt;p v-if&#061;&#034;ok&#034;&gt;{{ b }}&lt;\/p&gt; &lt;!&#8211; \u6761\u4ef6\u5757 &#8211;&gt;<br \/>\n    &lt;p&gt;{{ c }}&lt;\/p&gt;         &lt;!&#8211; \u8ffd\u8e2a &#8211;&gt;<br \/>\n  &lt;\/div&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p>\u8fd0\u884c\u65f6 diff \u53ea\u6bd4\u8f83 Block \u6536\u96c6\u7684\u52a8\u6001\u8282\u70b9\u6570\u7ec4&#xff0c;\u8df3\u8fc7\u6240\u6709\u9759\u6001\u5185\u5bb9\u3002<\/p>\n<hr \/>\n<h3>14. Teleport \/ Suspense \/ \u5f02\u6b65\u7ec4\u4ef6<\/h3>\n<h4>14.1 Teleport<\/h4>\n<p>\u5c06\u5185\u5bb9\u6e32\u67d3\u5230 DOM \u6811\u7684\u5176\u4ed6\u4f4d\u7f6e&#xff1a;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;button &#064;click&#061;&#034;showModal &#061; true&#034;&gt;\u6253\u5f00\u5f39\u7a97&lt;\/button&gt;<\/p>\n<p>  &lt;Teleport to&#061;&#034;body&#034;&gt;<br \/>\n    &lt;div v-if&#061;&#034;showModal&#034; class&#061;&#034;modal-overlay&#034;&gt;<br \/>\n      &lt;div class&#061;&#034;modal&#034;&gt;<br \/>\n        &lt;p&gt;\u5f39\u7a97\u5185\u5bb9&lt;\/p&gt;<br \/>\n        &lt;button &#064;click&#061;&#034;showModal &#061; false&#034;&gt;\u5173\u95ed&lt;\/button&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n    &lt;\/div&gt;<br \/>\n  &lt;\/Teleport&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p>&lt;!&#8211; \u7981\u7528 teleport &#8211;&gt;<br \/>\n&lt;Teleport to&#061;&#034;body&#034; :disabled&#061;&#034;isMobile&#034;&gt;<br \/>\n  &lt;div class&#061;&#034;tooltip&#034;&gt;&#8230;&lt;\/div&gt;<br \/>\n&lt;\/Teleport&gt;<\/p>\n<h4>14.2 Suspense&#xff08;\u5b9e\u9a8c\u6027&#xff09;<\/h4>\n<p>&lt;template&gt;<br \/>\n  &lt;Suspense&gt;<br \/>\n    &lt;!&#8211; \u9ed8\u8ba4\u63d2\u69fd&#xff1a;\u5f02\u6b65\u5185\u5bb9 &#8211;&gt;<br \/>\n    &lt;template #default&gt;<br \/>\n      &lt;AsyncDashboard \/&gt;  &lt;!&#8211; setup() \u4e2d\u6709 await \u7684\u7ec4\u4ef6 &#8211;&gt;<br \/>\n    &lt;\/template&gt;<\/p>\n<p>    &lt;!&#8211; \u52a0\u8f7d\u72b6\u6001 &#8211;&gt;<br \/>\n    &lt;template #fallback&gt;<br \/>\n      &lt;LoadingSpinner \/&gt;<br \/>\n    &lt;\/template&gt;<br \/>\n  &lt;\/Suspense&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p>&lt;!&#8211; AsyncDashboard.vue &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\n\/\/ \u9876\u5c42 await \u2192 \u7ec4\u4ef6\u53d8\u4e3a\u5f02\u6b65\u4f9d\u8d56<br \/>\nconst data &#061; await fetchDashboardData()<br \/>\n&lt;\/script&gt;<\/p>\n<p>Suspense \u4e8b\u4ef6&#xff1a;<\/p>\n<p>&lt;Suspense<br \/>\n  &#064;resolve&#061;&#034;onResolve&#034;<br \/>\n  &#064;pending&#061;&#034;onPending&#034;<br \/>\n  &#064;fallback&#061;&#034;onFallback&#034;<br \/>\n&gt;<\/p>\n<h4>14.3 \u5f02\u6b65\u7ec4\u4ef6<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> defineAsyncComponent <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7b80\u5355\u7528\u6cd5<\/span><br \/>\n<span class=\"token keyword\">const<\/span> AsyncComp <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineAsyncComponent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.\/Comp.vue&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5b8c\u6574\u914d\u7f6e<\/span><br \/>\n<span class=\"token keyword\">const<\/span> AsyncCompWithOptions <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">defineAsyncComponent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function-variable function\">loader<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token keyword\">import<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.\/Comp.vue&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">loadingComponent<\/span><span class=\"token operator\">:<\/span> LoadingSpinner<span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">errorComponent<\/span><span class=\"token operator\">:<\/span> ErrorDisplay<span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">delay<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">200<\/span><span class=\"token punctuation\">,<\/span>           <span class=\"token comment\">\/\/ \u663e\u793a loading \u524d\u7684\u5ef6\u8fdf<\/span><br \/>\n  <span class=\"token literal-property property\">timeout<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">10000<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u8d85\u65f6<\/span><br \/>\n  <span class=\"token literal-property property\">suspensible<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span>   <span class=\"token comment\">\/\/ \u662f\u5426\u88ab Suspense \u63a5\u7ba1<\/span><br \/>\n  <span class=\"token function\">onError<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">error<span class=\"token punctuation\">,<\/span> retry<span class=\"token punctuation\">,<\/span> fail<span class=\"token punctuation\">,<\/span> attempts<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>attempts <span class=\"token operator\">&lt;&#061;<\/span> <span class=\"token number\">3<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token function\">retry<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">else<\/span> <span class=\"token function\">fail<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<hr \/>\n<h3>15. \u81ea\u5b9a\u4e49\u6307\u4ee4<\/h3>\n<h4>15.1 \u5b9a\u4e49<\/h4>\n<p><span class=\"token comment\">\/\/ Vue 3 \u94a9\u5b50\u540d\u79f0\u4e0e\u751f\u547d\u5468\u671f\u5bf9\u9f50<\/span><br \/>\n<span class=\"token keyword\">const<\/span> myDirective <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function\">created<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<span class=\"token punctuation\">,<\/span> vnode<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u5143\u7d20\u521b\u5efa\u540e<\/span><br \/>\n  <span class=\"token function\">beforeMount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<span class=\"token punctuation\">,<\/span> vnode<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u6302\u8f7d\u524d<\/span><br \/>\n  <span class=\"token function\">mounted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<span class=\"token punctuation\">,<\/span> vnode<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u6302\u8f7d\u540e<\/span><br \/>\n  <span class=\"token function\">beforeUpdate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<span class=\"token punctuation\">,<\/span> vnode<span class=\"token punctuation\">,<\/span> prevVnode<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function\">updated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<span class=\"token punctuation\">,<\/span> vnode<span class=\"token punctuation\">,<\/span> prevVnode<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function\">beforeUnmount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<span class=\"token punctuation\">,<\/span> vnode<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function\">unmounted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<span class=\"token punctuation\">,<\/span> vnode<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>15.2 \u4f7f\u7528<\/h4>\n<p>&lt;script setup&gt;<br \/>\n\/\/ \u5c40\u90e8\u6ce8\u518c&#xff08;script setup \u4e2d\u4ee5 v \u5f00\u5934\u7684\u53d8\u91cf\u81ea\u52a8\u6ce8\u518c&#xff09;<br \/>\nconst vFocus &#061; {<br \/>\n  mounted: (el) &#061;&gt; el.focus()<br \/>\n}<\/p>\n<p>const vHighlight &#061; {<br \/>\n  mounted(el, binding) {<br \/>\n    el.style.backgroundColor &#061; binding.value || &#039;yellow&#039;<br \/>\n  },<br \/>\n  updated(el, binding) {<br \/>\n    el.style.backgroundColor &#061; binding.value || &#039;yellow&#039;<br \/>\n  }<br \/>\n}<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;input v-focus \/&gt;<br \/>\n  &lt;p v-highlight&#061;&#034;&#039;lightblue&#039;&#034;&gt;\u9ad8\u4eae\u6587\u672c&lt;\/p&gt;<br \/>\n  &lt;p v-highlight&gt;\u9ed8\u8ba4\u9ec4\u8272&lt;\/p&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p><span class=\"token comment\">\/\/ \u5168\u5c40\u6ce8\u518c<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">directive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;focus&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function\">mounted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> el<span class=\"token punctuation\">.<\/span><span class=\"token function\">focus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7b80\u5199&#xff08;mounted &#043; updated \u76f8\u540c\u903b\u8f91&#xff09;<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">directive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;color&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">el<span class=\"token punctuation\">,<\/span> binding<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  el<span class=\"token punctuation\">.<\/span>style<span class=\"token punctuation\">.<\/span>color <span class=\"token operator\">&#061;<\/span> binding<span class=\"token punctuation\">.<\/span>value<br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>15.3 binding \u5bf9\u8c61<\/h4>\n<p><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">value<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\u7ed1\u5b9a\u503c&#039;<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ v-xxx:value<\/span><br \/>\n  <span class=\"token literal-property property\">oldValue<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\u65e7\u503c&#039;<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u4ec5 updated<\/span><br \/>\n  <span class=\"token literal-property property\">arg<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\u53c2\u6570&#039;<\/span><span class=\"token punctuation\">,<\/span>            <span class=\"token comment\">\/\/ v-xxx:arg<\/span><br \/>\n  <span class=\"token literal-property property\">modifiers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">mod<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ v-xxx.mod<\/span><br \/>\n  <span class=\"token literal-property property\">instance<\/span><span class=\"token operator\">:<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u7ec4\u4ef6\u5b9e\u4f8b<\/span><br \/>\n  <span class=\"token literal-property property\">dir<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token comment\">\/* \u6307\u4ee4\u5b9a\u4e49 *\/<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>16. \u63d2\u4ef6\u7cfb\u7edf<\/h3>\n<h4>16.1 \u7f16\u5199\u63d2\u4ef6<\/h4>\n<p><span class=\"token comment\">\/\/ myPlugin.js<\/span><br \/>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function\">install<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">app<span class=\"token punctuation\">,<\/span> options<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u5168\u5c40\u7ec4\u4ef6<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span><span class=\"token function\">component<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;MyIcon&#039;<\/span><span class=\"token punctuation\">,<\/span> MyIcon<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u5168\u5c40\u6307\u4ee4<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span><span class=\"token function\">directive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;tooltip&#039;<\/span><span class=\"token punctuation\">,<\/span> tooltipDirective<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u5168\u5c40\u5c5e\u6027<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>globalProperties<span class=\"token punctuation\">.<\/span><span class=\"token function-variable function\">$format<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">val<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token comment\">\/* &#8230; *\/<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ provide \u6ce8\u5165<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span><span class=\"token function\">provide<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;pluginOptions&#039;<\/span><span class=\"token punctuation\">,<\/span> options<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u5168\u5c40 mixin&#xff08;\u8c28\u614e\u4f7f\u7528&#xff09;<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span><span class=\"token function\">mixin<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token function\">created<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token comment\">\/* &#8230; *\/<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>16.2 \u4f7f\u7528\u63d2\u4ef6<\/h4>\n<p><span class=\"token keyword\">import<\/span> myPlugin <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;.\/myPlugin&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> app <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createApp<\/span><span class=\"token punctuation\">(<\/span>App<span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span>myPlugin<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">theme<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;dark&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">mount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;#app&#039;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<hr \/>\n<h3>17. \u6e32\u67d3\u51fd\u6570\u4e0e JSX<\/h3>\n<h4>17.1 h() \u51fd\u6570<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> h<span class=\"token punctuation\">,<\/span> ref <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u57fa\u672c\u7528\u6cd5<\/span><br \/>\n<span class=\"token keyword\">const<\/span> vnode <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;div&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">class<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;container&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n  <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;h1&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;Title&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;p&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">style<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;color: red&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;Content&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7ec4\u4ef6<\/span><br \/>\n<span class=\"token keyword\">import<\/span> MyComp <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;.\/MyComp.vue&#039;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> compVnode <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span>MyComp<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">title<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;Hello&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function-variable function\">onChange<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">val<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>val<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function-variable function\">default<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token string\">&#039;Slot content&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token function-variable function\">header<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;h2&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;Header&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u6761\u4ef6\u6e32\u67d3<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">render<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> show<span class=\"token punctuation\">.<\/span>value<br \/>\n    <span class=\"token operator\">?<\/span> <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;div&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;Visible&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token operator\">:<\/span> <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;span&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;Hidden&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5217\u8868\u6e32\u67d3<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">render<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;ul&#039;<\/span><span class=\"token punctuation\">,<\/span> items<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">item<\/span> <span class=\"token operator\">&#061;&gt;<\/span><br \/>\n    <span class=\"token function\">h<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;li&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">key<\/span><span class=\"token operator\">:<\/span> item<span class=\"token punctuation\">.<\/span>id <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> item<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>17.2 JSX&#xff08;\u9700 &#064;vitejs\/plugin-vue-jsx&#xff09;<\/h4>\n<p>import { defineComponent, ref } from &#039;vue&#039;<\/p>\n<p>export default defineComponent({<br \/>\n  setup() {<br \/>\n    const count &#061; ref(0)<\/p>\n<p>    return () &#061;&gt; (<br \/>\n      &lt;div class&#061;&#034;container&#034;&gt;<br \/>\n        &lt;h1&gt;Count: {count.value}&lt;\/h1&gt;<br \/>\n        &lt;button onClick&#061;{() &#061;&gt; count.value&#043;&#043;}&gt;&#043;1&lt;\/button&gt;<br \/>\n        {count.value &gt; 5 &amp;&amp; &lt;p&gt;Big number!&lt;\/p&gt;}<br \/>\n        &lt;ul&gt;<br \/>\n          {items.value.map(item &#061;&gt; (<br \/>\n            &lt;li key&#061;{item.id}&gt;{item.name}&lt;\/li&gt;<br \/>\n          ))}<br \/>\n        &lt;\/ul&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n    )<br \/>\n  }<br \/>\n})<\/p>\n<h4>17.3 \u6e32\u67d3\u51fd\u6570 vs \u6a21\u677f<\/h4>\n<table>\n<tr>\u573a\u666f\u63a8\u8350<\/tr>\n<tbody>\n<tr>\n<td>\u5e38\u89c4 UI<\/td>\n<td>\u6a21\u677f&#xff08;\u53ef\u8bfb\u6027 &#043; \u7f16\u8bd1\u4f18\u5316&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u9ad8\u5ea6\u52a8\u6001\/\u9012\u5f52\u7ec4\u4ef6<\/td>\n<td>\u6e32\u67d3\u51fd\u6570<\/td>\n<\/tr>\n<tr>\n<td>\u7ec4\u4ef6\u5e93\/\u62bd\u8c61\u7ec4\u4ef6<\/td>\n<td>\u6e32\u67d3\u51fd\u6570 \/ JSX<\/td>\n<\/tr>\n<tr>\n<td>\u9700\u8981\u5b8c\u6574 JS \u8868\u8fbe\u529b<\/td>\n<td>JSX<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>18. \u670d\u52a1\u7aef\u6e32\u67d3&#xff08;SSR&#xff09;<\/h3>\n<h4>18.1 \u57fa\u672c\u6d41\u7a0b<\/h4>\n<p>\u5ba2\u6237\u7aef\u8bf7\u6c42<br \/>\n    \u2502<br \/>\n    \u25bc<br \/>\n\u670d\u52a1\u5668\u6267\u884c Vue \u7ec4\u4ef6 \u2192 \u751f\u6210 HTML \u5b57\u7b26\u4e32<br \/>\n    \u2502<br \/>\n    \u25bc<br \/>\n\u8fd4\u56de\u5b8c\u6574 HTML&#xff08;\u9996\u5c4f\u53ef\u89c1&#xff09;<br \/>\n    \u2502<br \/>\n    \u25bc<br \/>\n\u5ba2\u6237\u7aef\u52a0\u8f7d JS \u2192 \u6c34\u5408&#xff08;Hydration&#xff09;\u2192 \u4ea4\u4e92\u53ef\u7528<\/p>\n<h4>18.2 \u6838\u5fc3 API<\/h4>\n<p><span class=\"token comment\">\/\/ \u670d\u52a1\u5668\u7aef<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> renderToString <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue\/server-renderer&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> createSSRApp <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> app <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createSSRApp<\/span><span class=\"token punctuation\">(<\/span>App<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">const<\/span> html <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">renderToString<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5ba2\u6237\u7aef<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> createSSRApp <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">createSSRApp<\/span><span class=\"token punctuation\">(<\/span>App<span class=\"token punctuation\">)<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">mount<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;#app&#039;<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u6c34\u5408\u800c\u975e\u91cd\u65b0\u6e32\u67d3<\/span><\/p>\n<h4>18.3 \u6570\u636e\u9884\u53d6<\/h4>\n<p>&lt;script setup&gt;<br \/>\nimport { useAsyncData } from &#039;#app&#039;  \/\/ Nuxt 3<\/p>\n<p>const { data, pending, error } &#061; await useAsyncData(&#039;posts&#039;, () &#061;&gt;<br \/>\n  $fetch(&#039;\/api\/posts&#039;)<br \/>\n)<br \/>\n&lt;\/script&gt;<\/p>\n<h4>18.4 \u6d41\u5f0f\u6e32\u67d3&#xff08;Vue 3.5&#043;&#xff09;<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> renderToStream <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue\/server-renderer&#039;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> stream <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">renderToStream<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><br \/>\nstream<span class=\"token punctuation\">.<\/span><span class=\"token function\">pipe<\/span><span class=\"token punctuation\">(<\/span>res<span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ Node.js response<\/span><\/p>\n<h4>18.5 Nuxt 3 \u6846\u67b6<\/h4>\n<p>npx nuxi&#064;latest init my-app<\/p>\n<p>nuxt.config.ts        # \u914d\u7f6e<br \/>\npages\/                # \u6587\u4ef6\u7cfb\u7edf\u8def\u7531<br \/>\ncomponents\/           # \u81ea\u52a8\u5bfc\u5165\u7ec4\u4ef6<br \/>\ncomposables\/          # \u81ea\u52a8\u5bfc\u5165\u7ec4\u5408\u5f0f\u51fd\u6570<br \/>\nserver\/api\/           # API \u8def\u7531<br \/>\nmiddleware\/           # \u8def\u7531\u4e2d\u95f4\u4ef6<br \/>\nplugins\/              # \u63d2\u4ef6<\/p>\n<hr \/>\n<h3>19. \u6d4b\u8bd5<\/h3>\n<h4>19.1 \u5355\u5143\u6d4b\u8bd5&#xff08;Vitest&#xff09;<\/h4>\n<p><span class=\"token comment\">\/\/ vitest.config.ts<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> defineConfig <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vitest\/config&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> vue <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;&#064;vitejs\/plugin-vue&#039;<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token function\">defineConfig<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token literal-property property\">plugins<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token function\">vue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token literal-property property\">test<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token literal-property property\">environment<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;jsdom&#039;<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u6216 happy-dom<\/span><br \/>\n    <span class=\"token literal-property property\">globals<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ Counter.test.ts<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> describe<span class=\"token punctuation\">,<\/span> it<span class=\"token punctuation\">,<\/span> expect <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vitest&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> ref<span class=\"token punctuation\">,<\/span> computed<span class=\"token punctuation\">,<\/span> nextTick <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vue&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useCounter <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;.\/useCounter&#039;<\/span><\/p>\n<p><span class=\"token function\">describe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;useCounter&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function\">it<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;increments&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">{<\/span> count<span class=\"token punctuation\">,<\/span> increment <span class=\"token punctuation\">}<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">useCounter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">increment<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>count<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toBe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token function\">it<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;computes double&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">{<\/span> count<span class=\"token punctuation\">,<\/span> double <span class=\"token punctuation\">}<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">useCounter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">5<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>double<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toBe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    count<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">10<\/span><br \/>\n    <span class=\"token keyword\">await<\/span> <span class=\"token function\">nextTick<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>double<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toBe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">20<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>19.2 \u7ec4\u4ef6\u6d4b\u8bd5&#xff08;Vue Test Utils&#xff09;<\/h4>\n<p><span class=\"token comment\">\/\/ npm i -D &#064;vue\/test-utils<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> mount <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;&#064;vue\/test-utils&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> describe<span class=\"token punctuation\">,<\/span> it<span class=\"token punctuation\">,<\/span> expect <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vitest&#039;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> Counter <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;.\/Counter.vue&#039;<\/span><\/p>\n<p><span class=\"token function\">describe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Counter&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token function\">it<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;renders count&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> wrapper <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mount<\/span><span class=\"token punctuation\">(<\/span>Counter<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token literal-property property\">props<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">initial<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">5<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>wrapper<span class=\"token punctuation\">.<\/span><span class=\"token function\">text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toContain<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;5&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token function\">it<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;increments on click&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> wrapper <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mount<\/span><span class=\"token punctuation\">(<\/span>Counter<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">await<\/span> wrapper<span class=\"token punctuation\">.<\/span><span class=\"token function\">find<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;button&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trigger<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;click&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>wrapper<span class=\"token punctuation\">.<\/span><span class=\"token function\">find<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.count&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toBe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;1&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token function\">it<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;emits change event&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> wrapper <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mount<\/span><span class=\"token punctuation\">(<\/span>Counter<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">await<\/span> wrapper<span class=\"token punctuation\">.<\/span><span class=\"token function\">find<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;button&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trigger<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;click&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>wrapper<span class=\"token punctuation\">.<\/span><span class=\"token function\">emitted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;change&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toHaveLength<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>wrapper<span class=\"token punctuation\">.<\/span><span class=\"token function\">emitted<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;change&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toEqual<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>  <span class=\"token function\">it<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;renders slot&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> wrapper <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mount<\/span><span class=\"token punctuation\">(<\/span>Counter<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token literal-property property\">slots<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">default<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&lt;span class&#061;&#034;custom&#034;&gt;Slot&lt;\/span&gt;&#039;<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>wrapper<span class=\"token punctuation\">.<\/span><span class=\"token function\">find<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.custom&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">exists<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toBe<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>19.3 E2E \u6d4b\u8bd5&#xff08;Playwright \/ Cypress&#xff09;<\/h4>\n<p><span class=\"token comment\">\/\/ playwright<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> test<span class=\"token punctuation\">,<\/span> expect <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;&#064;playwright\/test&#039;<\/span><\/p>\n<p><span class=\"token function\">test<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;counter interaction&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\"><span class=\"token punctuation\">{<\/span> page <span class=\"token punctuation\">}<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">await<\/span> page<span class=\"token punctuation\">.<\/span><span class=\"token function\">goto<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\/&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">await<\/span> page<span class=\"token punctuation\">.<\/span><span class=\"token function\">click<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;button.increment&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n  <span class=\"token keyword\">await<\/span> <span class=\"token function\">expect<\/span><span class=\"token punctuation\">(<\/span>page<span class=\"token punctuation\">.<\/span><span class=\"token function\">locator<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.count&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toHaveText<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;1&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<hr \/>\n<h3>20. \u5e38\u89c1\u8bbe\u8ba1\u6a21\u5f0f\u4e0e\u6700\u4f73\u5b9e\u8df5<\/h3>\n<h4>20.1 \u7ec4\u4ef6\u8bbe\u8ba1\u539f\u5219<\/h4>\n<p>\u2705 \u5355\u4e00\u804c\u8d23&#xff1a;\u4e00\u4e2a\u7ec4\u4ef6\u53ea\u505a\u4e00\u4ef6\u4e8b<br \/>\n\u2705 Props \u5411\u4e0b&#xff0c;Events \u5411\u4e0a&#xff08;\u5355\u5411\u6570\u636e\u6d41&#xff09;<br \/>\n\u2705 \u7ec4\u5408\u4f18\u4e8e\u7ee7\u627f<br \/>\n\u2705 \u5408\u7406\u62c6\u5206&#xff1a;\u5c55\u793a\u7ec4\u4ef6 vs \u5bb9\u5668\u7ec4\u4ef6<br \/>\n\u2705 \u547d\u540d&#xff1a;\u591a\u5355\u8bcd PascalCase&#xff08;MyComponent&#xff09;<br \/>\n\u2705 \u907f\u514d v-if \u548c v-for \u540c\u65f6\u4f7f\u7528<br \/>\n\u2705 \u5927\u5217\u8868\u5fc5\u987b\u7528 key&#xff0c;\u4e14\u4e0d\u7528 index<\/p>\n<h4>20.2 \u5e38\u89c1\u6a21\u5f0f<\/h4>\n<h5>\u53d7\u63a7\u7ec4\u4ef6\u6a21\u5f0f<\/h5>\n<p>&lt;!&#8211; \u7236\u7ec4\u4ef6\u5b8c\u5168\u63a7\u5236 &#8211;&gt;<br \/>\n&lt;Input :value&#061;&#034;text&#034; &#064;update:value&#061;&#034;text &#061; $event&#034; \/&gt;<br \/>\n&lt;!&#8211; \u6216 &#8211;&gt;<br \/>\n&lt;Input v-model&#061;&#034;text&#034; \/&gt;<\/p>\n<h5>\u6e32\u67d3\u4ee3\u7406 \/ \u65e0\u6e32\u67d3\u7ec4\u4ef6<\/h5>\n<p>&lt;!&#8211; RenderlessList.vue &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\ndefineProps({ items: Array })<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;slot :items&#061;&#034;items&#034; :isEmpty&#061;&#034;!items.length&#034; \/&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<p>&lt;!&#8211; \u4f7f\u7528 &#8211;&gt;<br \/>\n&lt;RenderlessList :items&#061;&#034;todos&#034; v-slot&#061;&#034;{ items, isEmpty }&#034;&gt;<br \/>\n  &lt;p v-if&#061;&#034;isEmpty&#034;&gt;\u6682\u65e0\u6570\u636e&lt;\/p&gt;<br \/>\n  &lt;ul v-else&gt;<br \/>\n    &lt;li v-for&#061;&#034;item in items&#034; :key&#061;&#034;item.id&#034;&gt;{{ item.text }}&lt;\/li&gt;<br \/>\n  &lt;\/ul&gt;<br \/>\n&lt;\/RenderlessList&gt;<\/p>\n<h5>\u9012\u5f52\u7ec4\u4ef6<\/h5>\n<p>&lt;!&#8211; TreeNode.vue &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\ndefineProps({ node: Object })<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;li&gt;<br \/>\n    {{ node.label }}<br \/>\n    &lt;ul v-if&#061;&#034;node.children&#034;&gt;<br \/>\n      &lt;TreeNode<br \/>\n        v-for&#061;&#034;child in node.children&#034;<br \/>\n        :key&#061;&#034;child.id&#034;<br \/>\n        :node&#061;&#034;child&#034;<br \/>\n      \/&gt;<br \/>\n    &lt;\/ul&gt;<br \/>\n  &lt;\/li&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<h4>20.3 \u9519\u8bef\u5904\u7406<\/h4>\n<p>&lt;!&#8211; ErrorBoundary \u7ec4\u4ef6 &#8211;&gt;<br \/>\n&lt;script setup&gt;<br \/>\nimport { ref, onErrorCaptured } from &#039;vue&#039;<\/p>\n<p>const error &#061; ref(null)<\/p>\n<p>onErrorCaptured((err, instance, info) &#061;&gt; {<br \/>\n  error.value &#061; err<br \/>\n  return false  \/\/ \u963b\u6b62\u7ee7\u7eed\u5411\u4e0a\u4f20\u64ad<br \/>\n})<br \/>\n&lt;\/script&gt;<\/p>\n<p>&lt;template&gt;<br \/>\n  &lt;div v-if&#061;&#034;error&#034; class&#061;&#034;error&#034;&gt;<br \/>\n    &lt;p&gt;\u51fa\u9519\u4e86&#xff1a;{{ error.message }}&lt;\/p&gt;<br \/>\n    &lt;button &#064;click&#061;&#034;error &#061; null&#034;&gt;\u91cd\u8bd5&lt;\/button&gt;<br \/>\n  &lt;\/div&gt;<br \/>\n  &lt;slot v-else \/&gt;<br \/>\n&lt;\/template&gt;<\/p>\n<h4>20.4 \u9879\u76ee\u7ed3\u6784\u63a8\u8350<\/h4>\n<p>src\/<br \/>\n\u251c\u2500\u2500 api\/              # API \u8bf7\u6c42\u5c01\u88c5<br \/>\n\u2502   \u251c\u2500\u2500 index.ts      # axios \u5b9e\u4f8b<br \/>\n\u2502   \u251c\u2500\u2500 user.ts<br \/>\n\u2502   \u2514\u2500\u2500 post.ts<br \/>\n\u251c\u2500\u2500 assets\/           # \u9759\u6001\u8d44\u6e90<br \/>\n\u251c\u2500\u2500 components\/       # \u901a\u7528\u7ec4\u4ef6<br \/>\n\u2502   \u251c\u2500\u2500 ui\/           # \u57fa\u7840 UI \u7ec4\u4ef6<br \/>\n\u2502   \u2514\u2500\u2500 business\/     # \u4e1a\u52a1\u7ec4\u4ef6<br \/>\n\u251c\u2500\u2500 composables\/      # \u7ec4\u5408\u5f0f\u51fd\u6570<br \/>\n\u2502   \u251c\u2500\u2500 useAuth.ts<br \/>\n\u2502   \u251c\u2500\u2500 useFetch.ts<br \/>\n\u2502   \u2514\u2500\u2500 usePagination.ts<br \/>\n\u251c\u2500\u2500 directives\/       # \u81ea\u5b9a\u4e49\u6307\u4ee4<br \/>\n\u251c\u2500\u2500 layouts\/          # \u5e03\u5c40\u7ec4\u4ef6<br \/>\n\u251c\u2500\u2500 pages\/ (views\/)   # \u9875\u9762\u7ec4\u4ef6<br \/>\n\u251c\u2500\u2500 router\/           # \u8def\u7531\u914d\u7f6e<br \/>\n\u2502   \u2514\u2500\u2500 index.ts<br \/>\n\u251c\u2500\u2500 stores\/           # Pinia stores<br \/>\n\u2502   \u251c\u2500\u2500 user.ts<br \/>\n\u2502   \u2514\u2500\u2500 app.ts<br \/>\n\u251c\u2500\u2500 styles\/           # \u5168\u5c40\u6837\u5f0f<br \/>\n\u251c\u2500\u2500 types\/            # TS \u7c7b\u578b\u5b9a\u4e49<br \/>\n\u251c\u2500\u2500 utils\/            # \u5de5\u5177\u51fd\u6570<br \/>\n\u251c\u2500\u2500 App.vue<br \/>\n\u2514\u2500\u2500 main.ts<\/p>\n<h4>20.5 \u5e38\u7528\u5de5\u5177\u5e93\u751f\u6001<\/h4>\n<table>\n<tr>\u7c7b\u522b\u63a8\u8350<\/tr>\n<tbody>\n<tr>\n<td>\u6784\u5efa\u5de5\u5177<\/td>\n<td>Vite&#xff08;\u5b98\u65b9&#xff09;\/ Nuxt<\/td>\n<\/tr>\n<tr>\n<td>\u8def\u7531<\/td>\n<td>Vue Router 4<\/td>\n<\/tr>\n<tr>\n<td>\u72b6\u6001\u7ba1\u7406<\/td>\n<td>Pinia<\/td>\n<\/tr>\n<tr>\n<td>HTTP<\/td>\n<td>axios \/ ky \/ ofetch<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u51fd\u6570<\/td>\n<td>VueUse&#xff08;\u5f3a\u70c8\u63a8\u8350&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>UI \u7ec4\u4ef6\u5e93<\/td>\n<td>Element Plus \/ Ant Design Vue \/ Naive UI \/ Vuetify 3 \/ PrimeVue<\/td>\n<\/tr>\n<tr>\n<td>CSS<\/td>\n<td>Tailwind CSS \/ UnoCSS<\/td>\n<\/tr>\n<tr>\n<td>\u56fe\u6807<\/td>\n<td>&#064;iconify\/vue \/ lucide-vue-next<\/td>\n<\/tr>\n<tr>\n<td>\u8868\u5355\u9a8c\u8bc1<\/td>\n<td>vee-validate &#043; zod \/ valibot<\/td>\n<\/tr>\n<tr>\n<td>\u56fe\u8868<\/td>\n<td>ECharts \/ Chart.js<\/td>\n<\/tr>\n<tr>\n<td>\u52a8\u753b<\/td>\n<td>GSAP \/ &#064;vueuse\/motion<\/td>\n<\/tr>\n<tr>\n<td>\u56fd\u9645\u5316<\/td>\n<td>vue-i18n<\/td>\n<\/tr>\n<tr>\n<td>\u6d4b\u8bd5<\/td>\n<td>Vitest &#043; Vue Test Utils &#043; Playwright<\/td>\n<\/tr>\n<tr>\n<td>\u4ee3\u7801\u89c4\u8303<\/td>\n<td>ESLint &#043; Prettier &#043; husky<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>20.6 VueUse \u5e38\u7528\u51fd\u6570<\/h4>\n<p><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  useStorage<span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u54cd\u5e94\u5f0f localStorage<\/span><br \/>\n  useDark<span class=\"token punctuation\">,<\/span>           <span class=\"token comment\">\/\/ \u6697\u9ed1\u6a21\u5f0f<\/span><br \/>\n  useToggle<span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u5207\u6362\u5e03\u5c14\u503c<\/span><br \/>\n  useMouse<span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u9f20\u6807\u4f4d\u7f6e<\/span><br \/>\n  useWindowSize<span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u7a97\u53e3\u5c3a\u5bf8<\/span><br \/>\n  useIntersectionObserver<span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u4ea4\u53c9\u89c2\u5bdf<\/span><br \/>\n  useEventListener<span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u81ea\u52a8\u6e05\u7406\u4e8b\u4ef6\u76d1\u542c<\/span><br \/>\n  useDebounceFn<span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u9632\u6296\u51fd\u6570<\/span><br \/>\n  useThrottleFn<span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u8282\u6d41\u51fd\u6570<\/span><br \/>\n  useClipboard<span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u526a\u8d34\u677f<\/span><br \/>\n  useMediaQuery<span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u5a92\u4f53\u67e5\u8be2<\/span><br \/>\n  useFetch<span class=\"token punctuation\">,<\/span>          <span class=\"token comment\">\/\/ \u6570\u636e\u8bf7\u6c42<\/span><br \/>\n  useVModel<span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u7ec4\u4ef6 v-model \u8f85\u52a9<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;&#064;vueuse\/core&#039;<\/span><\/p>\n<hr \/>\n<h3>\u9644\u5f55&#xff1a;Vue 3.4 \/ 3.5&#043; \u65b0\u7279\u6027\u901f\u89c8<\/h3>\n<h4>Vue 3.4<\/h4>\n<ul>\n<li>defineModel() \u7a33\u5b9a\u7248<\/li>\n<li>watch \u652f\u6301 { once: true }<\/li>\n<li>\u6539\u8fdb\u7684\u54cd\u5e94\u5f0f\u7cfb\u7edf&#xff08;\u66f4\u7cbe\u786e\u7684\u4f9d\u8d56\u8ffd\u8e2a&#xff09;<\/li>\n<li>\u89e3\u6790\u5668\u6027\u80fd\u63d0\u5347 2 \u500d<\/li>\n<\/ul>\n<h4>Vue 3.5<\/h4>\n<ul>\n<li>\u54cd\u5e94\u5f0f\u7cfb\u7edf\u91cd\u5199&#xff1a;\u5185\u5b58\u5360\u7528\u964d\u4f4e 56%&#xff0c;\u4f7f\u7528\u53cc\u5411\u94fe\u8868\u66ff\u4ee3 Set<\/li>\n<li>useTemplateRef() \u66ff\u4ee3 ref &#043; \u6a21\u677f ref \u5b57\u7b26\u4e32<\/li>\n<li>useId() \u751f\u6210 SSR \u5b89\u5168\u7684\u552f\u4e00 ID<\/li>\n<li>onWatcherCleanup() \u6e05\u7406\u51fd\u6570<\/li>\n<li>Lazy hydration&#xff08;\u5f02\u6b65\u7ec4\u4ef6\u6309\u9700\u6c34\u5408&#xff09;<\/li>\n<li>app.onUnmount() \u6e05\u7406\u5e94\u7528\u7ea7\u526f\u4f5c\u7528<\/li>\n<\/ul>\n<h4>Vue 3.6&#043;&#xff08;Vapor Mode&#xff0c;\u5f00\u53d1\u4e2d&#xff09;<\/h4>\n<ul>\n<li>Vapor Mode&#xff1a;\u65e0\u865a\u62df DOM \u7684\u7f16\u8bd1\u6a21\u5f0f<\/li>\n<li>\u76f4\u63a5\u7f16\u8bd1\u4e3a\u547d\u4ee4\u5f0f DOM \u64cd\u4f5c<\/li>\n<li>\u6027\u80fd\u63a5\u8fd1\u539f\u751f JS&#xff0c;\u5185\u5b58\u5360\u7528\u5927\u5e45\u964d\u4f4e<\/li>\n<li>\u53ef\u4e0e\u73b0\u6709\u865a\u62df DOM \u7ec4\u4ef6\u6df7\u7528<\/li>\n<\/ul>\n<hr \/>\n<h3>\u5feb\u901f\u53c2\u8003\u5361\u7247<\/h3>\n<p><span class=\"token comment\">\/\/ \u54cd\u5e94\u5f0f<\/span><br \/>\n<span class=\"token function\">ref<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span>                    <span class=\"token comment\">\/\/ \u57fa\u672c\u7c7b\u578b<\/span><br \/>\n<span class=\"token function\">reactive<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>              <span class=\"token comment\">\/\/ \u5bf9\u8c61<\/span><br \/>\n<span class=\"token function\">computed<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>        <span class=\"token comment\">\/\/ \u8ba1\u7b97\u5c5e\u6027<\/span><br \/>\n<span class=\"token function\">watch<\/span><span class=\"token punctuation\">(<\/span>source<span class=\"token punctuation\">,<\/span> cb<span class=\"token punctuation\">,<\/span> opts<span class=\"token punctuation\">)<\/span>   <span class=\"token comment\">\/\/ \u4fa6\u542c\u5668<\/span><br \/>\n<span class=\"token function\">watchEffect<\/span><span class=\"token punctuation\">(<\/span>fn<span class=\"token punctuation\">)<\/span>           <span class=\"token comment\">\/\/ \u81ea\u52a8\u8ffd\u8e2a<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u751f\u547d\u5468\u671f<\/span><br \/>\nonMounted <span class=\"token operator\">\/<\/span> onUnmounted <span class=\"token operator\">\/<\/span> onUpdated <span class=\"token operator\">\/<\/span> onActivated<\/p>\n<p><span class=\"token comment\">\/\/ \u7ec4\u4ef6\u901a\u4fe1<\/span><br \/>\ndefineProps <span class=\"token operator\">\/<\/span> defineEmits <span class=\"token operator\">\/<\/span> defineModel <span class=\"token operator\">\/<\/span> defineExpose<br \/>\nprovide <span class=\"token operator\">\/<\/span> inject<br \/>\nuseSlots <span class=\"token operator\">\/<\/span> useAttrs<\/p>\n<p><span class=\"token comment\">\/\/ \u5de5\u5177<\/span><br \/>\ntoRef <span class=\"token operator\">\/<\/span> toRefs <span class=\"token operator\">\/<\/span> toRaw <span class=\"token operator\">\/<\/span> markRaw<br \/>\nreadonly <span class=\"token operator\">\/<\/span> shallowRef <span class=\"token operator\">\/<\/span> shallowReactive<br \/>\nnextTick <span class=\"token operator\">\/<\/span> defineAsyncComponent<\/p>\n<p><span class=\"token comment\">\/\/ \u8def\u7531<\/span><br \/>\nuseRouter <span class=\"token operator\">\/<\/span> useRoute<br \/>\nrouter<span class=\"token punctuation\">.<\/span>push <span class=\"token operator\">\/<\/span> replace <span class=\"token operator\">\/<\/span> back <span class=\"token operator\">\/<\/span> go<\/p>\n<p><span class=\"token comment\">\/\/ Pinia<\/span><br \/>\ndefineStore <span class=\"token operator\">\/<\/span> storeToRefs <span class=\"token operator\">\/<\/span> $patch <span class=\"token operator\">\/<\/span> $reset<\/p>\n<hr \/>\n<p>&#x1f4da; \u53c2\u8003\u8d44\u6e90&#xff1a;<\/p>\n<ul>\n<li>Vue 3 \u5b98\u65b9\u6587\u6863<\/li>\n<li>Vue Router \u6587\u6863<\/li>\n<li>Pinia \u6587\u6863<\/li>\n<li>VueUse \u6587\u6863<\/li>\n<li>Vue 3 RFC<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 \u6700\u540e\u66f4\u65b0&#xff1a;2026-07-29 \u76ee\u5f55<br \/>\nVue 3 \u6838\u5fc3\u53d8\u5316\u6982\u89c8\u7ec4\u5408\u5f0f API&#xff08;Composition API&#xff09;\u54cd\u5e94\u5f0f\u7cfb\u7edf\u751f\u547d\u5468\u671f\u94a9\u5b50\u8ba1\u7b97\u5c5e\u6027\u4e0e\u4fa6\u542c\u5668\u7ec4\u4ef6\u7cfb\u7edf\u6a21\u677f\u8bed\u6cd5\u4e0e\u6307\u4ee4\u5185\u7f6e\u7ec4\u4ef6\u8def\u7531&#xff08;Vue Router 4&#xff09;\u72b6\u6001\u7ba1\u7406&#xff08;Pinia&#xff09;TypeScript \u96c6\u6210\u6027\u80fd\u4f18\u5316\u7f16\u8bd1\u4f18\u5316Teleport \/ Suspense \/ \u5f02\u6b65\u7ec4\u4ef6\u81ea\u5b9a\u4e49\u6307\u4ee4\u63d2\u4ef6\u7cfb\u7edf\u6e32\u67d3\u51fd\u6570\u4e0e <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[187,625,87],"topic":[],"class_list":["post-94343","post","type-post","status-publish","format-standard","hentry","category-server","tag-javascript","tag-vue-js","tag-87"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/94343.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 \u6700\u540e\u66f4\u65b0&#xff1a;2026-07-29 \u76ee\u5f55 Vue 3 \u6838\u5fc3\u53d8\u5316\u6982\u89c8\u7ec4\u5408\u5f0f API&#xff08;Composition API&#xff09;\u54cd\u5e94\u5f0f\u7cfb\u7edf\u751f\u547d\u5468\u671f\u94a9\u5b50\u8ba1\u7b97\u5c5e\u6027\u4e0e\u4fa6\u542c\u5668\u7ec4\u4ef6\u7cfb\u7edf\u6a21\u677f\u8bed\u6cd5\u4e0e\u6307\u4ee4\u5185\u7f6e\u7ec4\u4ef6\u8def\u7531&#xff08;Vue Router 4&#xff09;\u72b6\u6001\u7ba1\u7406&#xff08;Pinia&#xff09;TypeScript \u96c6\u6210\u6027\u80fd\u4f18\u5316\u7f16\u8bd1\u4f18\u5316Teleport \/ Suspense \/ \u5f02\u6b65\u7ec4\u4ef6\u81ea\u5b9a\u4e49\u6307\u4ee4\u63d2\u4ef6\u7cfb\u7edf\u6e32\u67d3\u51fd\u6570\u4e0e\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/94343.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-14T02:40:58+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/94343.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/94343.html\",\"name\":\"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-08-14T02:40:58+00:00\",\"dateModified\":\"2026-08-14T02:40:58+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/94343.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/94343.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/94343.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/94343.html","og_locale":"zh_CN","og_type":"article","og_title":"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 \u6700\u540e\u66f4\u65b0&#xff1a;2026-07-29 \u76ee\u5f55 Vue 3 \u6838\u5fc3\u53d8\u5316\u6982\u89c8\u7ec4\u5408\u5f0f API&#xff08;Composition API&#xff09;\u54cd\u5e94\u5f0f\u7cfb\u7edf\u751f\u547d\u5468\u671f\u94a9\u5b50\u8ba1\u7b97\u5c5e\u6027\u4e0e\u4fa6\u542c\u5668\u7ec4\u4ef6\u7cfb\u7edf\u6a21\u677f\u8bed\u6cd5\u4e0e\u6307\u4ee4\u5185\u7f6e\u7ec4\u4ef6\u8def\u7531&#xff08;Vue Router 4&#xff09;\u72b6\u6001\u7ba1\u7406&#xff08;Pinia&#xff09;TypeScript \u96c6\u6210\u6027\u80fd\u4f18\u5316\u7f16\u8bd1\u4f18\u5316Teleport \/ Suspense \/ \u5f02\u6b65\u7ec4\u4ef6\u81ea\u5b9a\u4e49\u6307\u4ee4\u63d2\u4ef6\u7cfb\u7edf\u6e32\u67d3\u51fd\u6570\u4e0e","og_url":"https:\/\/www.wsisp.com\/helps\/94343.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-08-14T02:40:58+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"22 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/94343.html","url":"https:\/\/www.wsisp.com\/helps\/94343.html","name":"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-08-14T02:40:58+00:00","dateModified":"2026-08-14T02:40:58+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/94343.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/94343.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/94343.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"Vue 3 \u77e5\u8bc6\u70b9\u603b\u7ed3"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/94343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=94343"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/94343\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=94343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=94343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=94343"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=94343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}