[{"data":1,"prerenderedAt":1979},["ShallowReactive",2],{"page-\u002Fvue\u002Femit讲解":3},{"id":4,"title":5,"body":6,"description":12,"extension":1970,"meta":1971,"navigation":203,"path":1975,"seo":1976,"stem":1977,"__hash__":1978},"content\u002FVue\u002Femit讲解.md","Emit讲解",{"type":7,"value":8,"toc":1966},"minimark",[9,13,17,20,651,654,718,738,797,800,803,806,902,905,1049,1052,1090,1158,1161,1191,1247,1253,1315,1318,1597,1962],[10,11,12],"p",{},"emit用于触发事件，当它在子组件里被调用的时候，就可以通知父组件，这样父组件监听到了事件就可以更新自己的状态",[14,15,16],"h2",{"id":16},"代码切入",[10,18,19],{},"举例来说，我这里有个dialog组件，这个dialog组件被包含在了一个父组件里，并且使用了emit来通知父组件，父组件使用了v-model来传递modelValue。",[21,22,27],"pre",{"className":23,"code":24,"language":25,"meta":26,"style":26},"language-ts shiki shiki-themes github-light github-dark","\u003Ctemplate>\n  \u003CTeleport to=\"body\">\n    \u003Cdiv v-if=\"isOpen\" class=\"overlay\" @click=\"closeDialog\">\n      \u003Cdiv class=\"dialog\" @click.stop>\n        \u003CVueUiSparkStackbar :dataset=\"store.chartDataset\" :config=\"sparkConfig\" \u002F>\n        \u003CUpdateHeatmap \u002F>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002FTeleport>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup lang=\"ts\">\nimport { VueUiSparkStackbar } from 'vue-data-ui'\nimport 'vue-data-ui\u002Fstyle.css'\n\nconst store = useContentStore()\nconst { t } = useI18n()\n\nconst props = defineProps\u003C{\n  modelValue: boolean\n}>()\n\nconst emit = defineEmits\u003C{\n  'update:modelValue': [value: boolean]\n}>()\n\nconst isOpen = computed({\n  get: () => props.modelValue,\n  set: (val) => emit('update:modelValue', val)\n})\n\n\u002F\u002F 父组件\n\u003CClientOnly>\u003CDialog v-model=\"showDialog\" \u002F>\u003C\u002FClientOnly>\n\u003Cbutton\n  type=\"button\"\n  class=\"btn chart-btn\"\n  aria-haspopup=\"dialog\"\n  :aria-label=\"t('home.chartButtonAria')\"\n  @click=\"showDialog = true\"\n>\n  \u003Cspan class=\"chart-btn__icon\" :style=\"chartIconStyle\" aria-hidden=\"true\" \u002F>\n  \u003Cspan class=\"chart-btn__label\">{{ t('home.chartButton') }}\u003C\u002Fspan>\n\u003C\u002Fbutton>\n","ts","",[28,29,30,46,65,98,117,145,156,167,177,188,198,205,220,235,243,248,267,288,293,309,322,328,333,348,371,376,381,397,412,440,446,451,458,493,501,512,523,539,555,566,571,607,641],"code",{"__ignoreMap":26},[31,32,35,39,43],"span",{"class":33,"line":34},"line",1,[31,36,38],{"class":37},"sVt8B","\u003C",[31,40,42],{"class":41},"sScJk","template",[31,44,45],{"class":37},">\n",[31,47,49,53,56,59,63],{"class":33,"line":48},2,[31,50,52],{"class":51},"szBVR","  \u003C",[31,54,55],{"class":37},"Teleport to",[31,57,58],{"class":51},"=",[31,60,62],{"class":61},"sZZnC","\"body\"",[31,64,45],{"class":51},[31,66,68,71,74,77,80,83,85,88,91,93,96],{"class":33,"line":67},3,[31,69,70],{"class":51},"    \u003C",[31,72,73],{"class":37},"div v",[31,75,76],{"class":51},"-if=",[31,78,79],{"class":61},"\"isOpen\"",[31,81,82],{"class":37}," class",[31,84,58],{"class":51},[31,86,87],{"class":61},"\"overlay\"",[31,89,90],{"class":37}," @click",[31,92,58],{"class":51},[31,94,95],{"class":61},"\"closeDialog\"",[31,97,45],{"class":51},[31,99,101,104,107,109,112,115],{"class":33,"line":100},4,[31,102,103],{"class":51},"      \u003C",[31,105,106],{"class":37},"div class",[31,108,58],{"class":51},[31,110,111],{"class":61},"\"dialog\"",[31,113,114],{"class":37}," @click.stop",[31,116,45],{"class":51},[31,118,120,123,126,129,131,134,137,139,142],{"class":33,"line":119},5,[31,121,122],{"class":51},"        \u003C",[31,124,125],{"class":41},"VueUiSparkStackbar",[31,127,128],{"class":37}," :dataset",[31,130,58],{"class":51},[31,132,133],{"class":61},"\"store.chartDataset\"",[31,135,136],{"class":37}," :config",[31,138,58],{"class":51},[31,140,141],{"class":61},"\"sparkConfig\"",[31,143,144],{"class":51}," \u002F>\n",[31,146,148,150,153],{"class":33,"line":147},6,[31,149,122],{"class":51},[31,151,152],{"class":37},"UpdateHeatmap ",[31,154,155],{"class":51},"\u002F>\n",[31,157,159,162,165],{"class":33,"line":158},7,[31,160,161],{"class":51},"      \u003C\u002F",[31,163,164],{"class":37},"div",[31,166,45],{"class":51},[31,168,170,173,175],{"class":33,"line":169},8,[31,171,172],{"class":51},"    \u003C\u002F",[31,174,164],{"class":37},[31,176,45],{"class":51},[31,178,180,183,186],{"class":33,"line":179},9,[31,181,182],{"class":51},"  \u003C\u002F",[31,184,185],{"class":37},"Teleport",[31,187,45],{"class":51},[31,189,191,194,196],{"class":33,"line":190},10,[31,192,193],{"class":51},"\u003C\u002F",[31,195,42],{"class":37},[31,197,45],{"class":51},[31,199,201],{"class":33,"line":200},11,[31,202,204],{"emptyLinePlaceholder":203},true,"\n",[31,206,208,210,213,215,218],{"class":33,"line":207},12,[31,209,38],{"class":51},[31,211,212],{"class":37},"script setup lang",[31,214,58],{"class":51},[31,216,217],{"class":61},"\"ts\"",[31,219,45],{"class":51},[31,221,223,226,229,232],{"class":33,"line":222},13,[31,224,225],{"class":51},"import",[31,227,228],{"class":37}," { VueUiSparkStackbar } ",[31,230,231],{"class":51},"from",[31,233,234],{"class":61}," 'vue-data-ui'\n",[31,236,238,240],{"class":33,"line":237},14,[31,239,225],{"class":51},[31,241,242],{"class":61}," 'vue-data-ui\u002Fstyle.css'\n",[31,244,246],{"class":33,"line":245},15,[31,247,204],{"emptyLinePlaceholder":203},[31,249,251,254,258,261,264],{"class":33,"line":250},16,[31,252,253],{"class":51},"const",[31,255,257],{"class":256},"sj4cs"," store",[31,259,260],{"class":51}," =",[31,262,263],{"class":41}," useContentStore",[31,265,266],{"class":37},"()\n",[31,268,270,272,275,278,281,283,286],{"class":33,"line":269},17,[31,271,253],{"class":51},[31,273,274],{"class":37}," { ",[31,276,277],{"class":256},"t",[31,279,280],{"class":37}," } ",[31,282,58],{"class":51},[31,284,285],{"class":41}," useI18n",[31,287,266],{"class":37},[31,289,291],{"class":33,"line":290},18,[31,292,204],{"emptyLinePlaceholder":203},[31,294,296,298,301,303,306],{"class":33,"line":295},19,[31,297,253],{"class":51},[31,299,300],{"class":256}," props",[31,302,260],{"class":51},[31,304,305],{"class":41}," defineProps",[31,307,308],{"class":37},"\u003C{\n",[31,310,312,316,319],{"class":33,"line":311},20,[31,313,315],{"class":314},"s4XuR","  modelValue",[31,317,318],{"class":51},":",[31,320,321],{"class":256}," boolean\n",[31,323,325],{"class":33,"line":324},21,[31,326,327],{"class":37},"}>()\n",[31,329,331],{"class":33,"line":330},22,[31,332,204],{"emptyLinePlaceholder":203},[31,334,336,338,341,343,346],{"class":33,"line":335},23,[31,337,253],{"class":51},[31,339,340],{"class":256}," emit",[31,342,260],{"class":51},[31,344,345],{"class":41}," defineEmits",[31,347,308],{"class":37},[31,349,351,354,356,359,362,365,368],{"class":33,"line":350},24,[31,352,353],{"class":61},"  'update:modelValue'",[31,355,318],{"class":51},[31,357,358],{"class":37}," [",[31,360,361],{"class":41},"value",[31,363,364],{"class":37},": ",[31,366,367],{"class":256},"boolean",[31,369,370],{"class":37},"]\n",[31,372,374],{"class":33,"line":373},25,[31,375,327],{"class":37},[31,377,379],{"class":33,"line":378},26,[31,380,204],{"emptyLinePlaceholder":203},[31,382,384,386,389,391,394],{"class":33,"line":383},27,[31,385,253],{"class":51},[31,387,388],{"class":256}," isOpen",[31,390,260],{"class":51},[31,392,393],{"class":41}," computed",[31,395,396],{"class":37},"({\n",[31,398,400,403,406,409],{"class":33,"line":399},28,[31,401,402],{"class":41},"  get",[31,404,405],{"class":37},": () ",[31,407,408],{"class":51},"=>",[31,410,411],{"class":37}," props.modelValue,\n",[31,413,415,418,421,424,427,429,431,434,437],{"class":33,"line":414},29,[31,416,417],{"class":41},"  set",[31,419,420],{"class":37},": (",[31,422,423],{"class":314},"val",[31,425,426],{"class":37},") ",[31,428,408],{"class":51},[31,430,340],{"class":41},[31,432,433],{"class":37},"(",[31,435,436],{"class":61},"'update:modelValue'",[31,438,439],{"class":37},", val)\n",[31,441,443],{"class":33,"line":442},30,[31,444,445],{"class":37},"})\n",[31,447,449],{"class":33,"line":448},31,[31,450,204],{"emptyLinePlaceholder":203},[31,452,454],{"class":33,"line":453},32,[31,455,457],{"class":456},"sJ8bj","\u002F\u002F 父组件\n",[31,459,461,463,466,469,472,475,478,481,483,486,489,491],{"class":33,"line":460},33,[31,462,38],{"class":37},[31,464,465],{"class":41},"ClientOnly",[31,467,468],{"class":37},">\u003C",[31,470,471],{"class":41},"Dialog",[31,473,474],{"class":41}," v",[31,476,477],{"class":37},"-",[31,479,480],{"class":41},"model",[31,482,58],{"class":37},[31,484,485],{"class":61},"\"showDialog\"",[31,487,488],{"class":37}," \u002F>\u003C\u002F",[31,490,465],{"class":41},[31,492,45],{"class":37},[31,494,496,498],{"class":33,"line":495},34,[31,497,38],{"class":51},[31,499,500],{"class":37},"button\n",[31,502,504,507,509],{"class":33,"line":503},35,[31,505,506],{"class":37},"  type",[31,508,58],{"class":51},[31,510,511],{"class":61},"\"button\"\n",[31,513,515,518,520],{"class":33,"line":514},36,[31,516,517],{"class":37},"  class",[31,519,58],{"class":51},[31,521,522],{"class":61},"\"btn chart-btn\"\n",[31,524,526,529,531,534,536],{"class":33,"line":525},37,[31,527,528],{"class":37},"  aria",[31,530,477],{"class":51},[31,532,533],{"class":37},"haspopup",[31,535,58],{"class":51},[31,537,538],{"class":61},"\"dialog\"\n",[31,540,542,545,547,550,552],{"class":33,"line":541},38,[31,543,544],{"class":37},"  :aria",[31,546,477],{"class":51},[31,548,549],{"class":37},"label",[31,551,58],{"class":51},[31,553,554],{"class":61},"\"t('home.chartButtonAria')\"\n",[31,556,558,561,563],{"class":33,"line":557},39,[31,559,560],{"class":37},"  @click",[31,562,58],{"class":51},[31,564,565],{"class":61},"\"showDialog = true\"\n",[31,567,569],{"class":33,"line":568},40,[31,570,45],{"class":51},[31,572,574,576,579,581,584,587,589,592,595,597,600,602,605],{"class":33,"line":573},41,[31,575,52],{"class":51},[31,577,578],{"class":37},"span class",[31,580,58],{"class":51},[31,582,583],{"class":61},"\"chart-btn__icon\"",[31,585,586],{"class":37}," :style",[31,588,58],{"class":51},[31,590,591],{"class":61},"\"chartIconStyle\"",[31,593,594],{"class":37}," aria",[31,596,477],{"class":51},[31,598,599],{"class":37},"hidden",[31,601,58],{"class":51},[31,603,604],{"class":61},"\"true\"",[31,606,144],{"class":51},[31,608,610,612,614,616,619,622,625,627,629,632,635,637,639],{"class":33,"line":609},42,[31,611,52],{"class":51},[31,613,578],{"class":37},[31,615,58],{"class":51},[31,617,618],{"class":61},"\"chart-btn__label\"",[31,620,621],{"class":51},">",[31,623,624],{"class":37},"{{ ",[31,626,277],{"class":41},[31,628,433],{"class":37},[31,630,631],{"class":61},"'home.chartButton'",[31,633,634],{"class":37},") }}",[31,636,193],{"class":51},[31,638,31],{"class":37},[31,640,45],{"class":51},[31,642,644,646,649],{"class":33,"line":643},43,[31,645,193],{"class":51},[31,647,648],{"class":37},"button",[31,650,45],{"class":51},[10,652,653],{},"我们知道，v-model是一个语法糖，展开为一个prop和一个事件监听。父组件这里showDialog通过v-model传入进去，v-model展开大致如下：",[21,655,659],{"className":656,"code":657,"language":658,"meta":26,"style":26},"language-vue shiki shiki-themes github-light github-dark","\u003CChild\n  :modelValue=\"show\"\n  @update:modelValue=\"show = $event\"\n\u002F>\n","vue",[28,660,661,669,688,714],{"__ignoreMap":26},[31,662,663,665],{"class":33,"line":34},[31,664,38],{"class":37},[31,666,668],{"class":667},"s9eBZ","Child\n",[31,670,671,674,677,679,682,685],{"class":33,"line":48},[31,672,673],{"class":37},"  :",[31,675,676],{"class":41},"modelValue",[31,678,58],{"class":37},[31,680,681],{"class":61},"\"",[31,683,684],{"class":37},"show",[31,686,687],{"class":61},"\"\n",[31,689,690,693,696,698,700,702,704,707,709,712],{"class":33,"line":67},[31,691,692],{"class":37},"  @",[31,694,695],{"class":41},"update",[31,697,318],{"class":37},[31,699,676],{"class":41},[31,701,58],{"class":37},[31,703,681],{"class":61},[31,705,706],{"class":37},"show ",[31,708,58],{"class":51},[31,710,711],{"class":37}," $event",[31,713,687],{"class":61},[31,715,716],{"class":33,"line":100},[31,717,155],{"class":37},[10,719,720,721,725,726,729,730,733,734,737],{},"子组件",[722,723,724],"strong",{},"只能读"," ",[28,727,728],{},"props.modelValue","，不能直接赋值。直接写 ",[28,731,732],{},"props.modelValue = true"," 会报错。子组件不能直接改 props，只能",[722,735,736],{},"通知父组件","“我想改成 true”",[21,739,741],{"className":23,"code":740,"language":25,"meta":26,"style":26},"const emit = defineEmits\u003C{\n  'update:modelValue': [value: boolean]\n}>()\n\nemit('update:modelValue', true)\n",[28,742,743,755,771,775,779],{"__ignoreMap":26},[31,744,745,747,749,751,753],{"class":33,"line":34},[31,746,253],{"class":51},[31,748,340],{"class":256},[31,750,260],{"class":51},[31,752,345],{"class":41},[31,754,308],{"class":37},[31,756,757,759,761,763,765,767,769],{"class":33,"line":48},[31,758,353],{"class":61},[31,760,318],{"class":51},[31,762,358],{"class":37},[31,764,361],{"class":41},[31,766,364],{"class":37},[31,768,367],{"class":256},[31,770,370],{"class":37},[31,772,773],{"class":33,"line":67},[31,774,327],{"class":37},[31,776,777],{"class":33,"line":100},[31,778,204],{"emptyLinePlaceholder":203},[31,780,781,784,786,788,791,794],{"class":33,"line":119},[31,782,783],{"class":41},"emit",[31,785,433],{"class":37},[31,787,436],{"class":61},[31,789,790],{"class":37},", ",[31,792,793],{"class":256},"true",[31,795,796],{"class":37},")\n",[10,798,799],{},"我们可以使用一个computed来定义一个isOpen，这样v-if获取isOpen的时候就会触发延迟计算，触发get和set方法，这样就可以决定是访问props.modelValue还是触发set的emit方法了。我们点击了遮罩overlay之后就会调用closeDialog方法，然后closeDialog就会给isOpen.value赋值，vue当然知道isOpen是一个computed ref ，所以赋值的时候会调用set，这时候就是触发emit事件，通知父组件，父组件的@update:modelValue就会被触发，showDialog会变成false，然后重要的来了！之后父组件会重新传递值进去，get会被调用，computed又会调用props.modelValue，dialog组件关闭。",[14,801,802],{"id":802},"编译器产物",[10,804,805],{},"有没有想过v-model在编译后产物里长什么样子。",[21,807,809],{"className":656,"code":808,"language":658,"meta":26,"style":26},"\u003Cscript setup>\nimport { ref } from 'vue'\nconst showDialog = ref(false)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CDialog v-model=\"showDialog\" \u002F>\n\u003C\u002Ftemplate>\n",[28,810,811,823,835,854,862,866,874,894],{"__ignoreMap":26},[31,812,813,815,818,821],{"class":33,"line":34},[31,814,38],{"class":37},[31,816,817],{"class":667},"script",[31,819,820],{"class":41}," setup",[31,822,45],{"class":37},[31,824,825,827,830,832],{"class":33,"line":48},[31,826,225],{"class":51},[31,828,829],{"class":37}," { ref } ",[31,831,231],{"class":51},[31,833,834],{"class":61}," 'vue'\n",[31,836,837,839,842,844,847,849,852],{"class":33,"line":67},[31,838,253],{"class":51},[31,840,841],{"class":256}," showDialog",[31,843,260],{"class":51},[31,845,846],{"class":41}," ref",[31,848,433],{"class":37},[31,850,851],{"class":256},"false",[31,853,796],{"class":37},[31,855,856,858,860],{"class":33,"line":100},[31,857,193],{"class":37},[31,859,817],{"class":667},[31,861,45],{"class":37},[31,863,864],{"class":33,"line":119},[31,865,204],{"emptyLinePlaceholder":203},[31,867,868,870,872],{"class":33,"line":147},[31,869,38],{"class":37},[31,871,42],{"class":667},[31,873,45],{"class":37},[31,875,876,878,880,883,885,887,890,892],{"class":33,"line":158},[31,877,52],{"class":37},[31,879,471],{"class":667},[31,881,882],{"class":41}," v-model",[31,884,58],{"class":37},[31,886,681],{"class":61},[31,888,889],{"class":37},"showDialog",[31,891,681],{"class":61},[31,893,144],{"class":37},[31,895,896,898,900],{"class":33,"line":169},[31,897,193],{"class":37},[31,899,42],{"class":667},[31,901,45],{"class":37},[10,903,904],{},"编译为render方法之后大致如下：",[21,906,910],{"className":907,"code":908,"language":909,"meta":26,"style":26},"language-js shiki shiki-themes github-light github-dark","import { ref, createVNode, toDisplayString } from 'vue'\nimport Dialog from '.\u002FDialog.vue'\n\nexport default {\n  setup() {\n    const showDialog = ref(false)\n\n    return () => {\n      return createVNode(Dialog, {\n        modelValue: showDialog.value,\n        'onUpdate:modelValue': ($event) => (showDialog.value = $event)\n      })\n    }\n  }\n}\n","js",[28,911,912,923,935,939,950,958,975,979,991,1002,1007,1029,1034,1039,1044],{"__ignoreMap":26},[31,913,914,916,919,921],{"class":33,"line":34},[31,915,225],{"class":51},[31,917,918],{"class":37}," { ref, createVNode, toDisplayString } ",[31,920,231],{"class":51},[31,922,834],{"class":61},[31,924,925,927,930,932],{"class":33,"line":48},[31,926,225],{"class":51},[31,928,929],{"class":37}," Dialog ",[31,931,231],{"class":51},[31,933,934],{"class":61}," '.\u002FDialog.vue'\n",[31,936,937],{"class":33,"line":67},[31,938,204],{"emptyLinePlaceholder":203},[31,940,941,944,947],{"class":33,"line":100},[31,942,943],{"class":51},"export",[31,945,946],{"class":51}," default",[31,948,949],{"class":37}," {\n",[31,951,952,955],{"class":33,"line":119},[31,953,954],{"class":41},"  setup",[31,956,957],{"class":37},"() {\n",[31,959,960,963,965,967,969,971,973],{"class":33,"line":147},[31,961,962],{"class":51},"    const",[31,964,841],{"class":256},[31,966,260],{"class":51},[31,968,846],{"class":41},[31,970,433],{"class":37},[31,972,851],{"class":256},[31,974,796],{"class":37},[31,976,977],{"class":33,"line":158},[31,978,204],{"emptyLinePlaceholder":203},[31,980,981,984,987,989],{"class":33,"line":169},[31,982,983],{"class":51},"    return",[31,985,986],{"class":37}," () ",[31,988,408],{"class":51},[31,990,949],{"class":37},[31,992,993,996,999],{"class":33,"line":179},[31,994,995],{"class":51},"      return",[31,997,998],{"class":41}," createVNode",[31,1000,1001],{"class":37},"(Dialog, {\n",[31,1003,1004],{"class":33,"line":190},[31,1005,1006],{"class":37},"        modelValue: showDialog.value,\n",[31,1008,1009,1012,1014,1017,1019,1021,1024,1026],{"class":33,"line":200},[31,1010,1011],{"class":61},"        'onUpdate:modelValue'",[31,1013,420],{"class":37},[31,1015,1016],{"class":314},"$event",[31,1018,426],{"class":37},[31,1020,408],{"class":51},[31,1022,1023],{"class":37}," (showDialog.value ",[31,1025,58],{"class":51},[31,1027,1028],{"class":37}," $event)\n",[31,1030,1031],{"class":33,"line":207},[31,1032,1033],{"class":37},"      })\n",[31,1035,1036],{"class":33,"line":222},[31,1037,1038],{"class":37},"    }\n",[31,1040,1041],{"class":33,"line":237},[31,1042,1043],{"class":37},"  }\n",[31,1045,1046],{"class":33,"line":245},[31,1047,1048],{"class":37},"}\n",[10,1050,1051],{},"如果是多个v-model的情况就是：",[21,1053,1055],{"className":656,"code":1054,"language":658,"meta":26,"style":26},"\u003CUserForm v-model=\"user\" v-model:email=\"email\" \n",[28,1056,1057],{"__ignoreMap":26},[31,1058,1059,1061,1064,1066,1068,1070,1073,1075,1077,1079,1082,1084,1086,1088],{"class":33,"line":34},[31,1060,38],{"class":37},[31,1062,1063],{"class":667},"UserForm",[31,1065,882],{"class":41},[31,1067,58],{"class":37},[31,1069,681],{"class":61},[31,1071,1072],{"class":37},"user",[31,1074,681],{"class":61},[31,1076,882],{"class":41},[31,1078,318],{"class":37},[31,1080,1081],{"class":41},"email",[31,1083,58],{"class":37},[31,1085,681],{"class":61},[31,1087,1081],{"class":37},[31,1089,687],{"class":61},[21,1091,1093],{"className":907,"code":1092,"language":909,"meta":26,"style":26},"h(UserForm, {\n  modelValue: user.value,\n  'onUpdate:modelValue': ($event) => (user.value = $event),\n  email: email.value,\n  'onUpdate:email': ($event) => (email.value = $event)\n})\n",[28,1094,1095,1103,1108,1129,1134,1154],{"__ignoreMap":26},[31,1096,1097,1100],{"class":33,"line":34},[31,1098,1099],{"class":41},"h",[31,1101,1102],{"class":37},"(UserForm, {\n",[31,1104,1105],{"class":33,"line":48},[31,1106,1107],{"class":37},"  modelValue: user.value,\n",[31,1109,1110,1113,1115,1117,1119,1121,1124,1126],{"class":33,"line":67},[31,1111,1112],{"class":61},"  'onUpdate:modelValue'",[31,1114,420],{"class":37},[31,1116,1016],{"class":314},[31,1118,426],{"class":37},[31,1120,408],{"class":51},[31,1122,1123],{"class":37}," (user.value ",[31,1125,58],{"class":51},[31,1127,1128],{"class":37}," $event),\n",[31,1130,1131],{"class":33,"line":100},[31,1132,1133],{"class":37},"  email: email.value,\n",[31,1135,1136,1139,1141,1143,1145,1147,1150,1152],{"class":33,"line":119},[31,1137,1138],{"class":61},"  'onUpdate:email'",[31,1140,420],{"class":37},[31,1142,1016],{"class":314},[31,1144,426],{"class":37},[31,1146,408],{"class":51},[31,1148,1149],{"class":37}," (email.value ",[31,1151,58],{"class":51},[31,1153,1028],{"class":37},[31,1155,1156],{"class":33,"line":147},[31,1157,445],{"class":37},[10,1159,1160],{},"带修饰符版本：",[21,1162,1164],{"className":656,"code":1163,"language":658,"meta":26,"style":26},"\u003CDialog v-model.trim=\"name\" \u002F>\n",[28,1165,1166],{"__ignoreMap":26},[31,1167,1168,1170,1172,1174,1177,1180,1182,1184,1187,1189],{"class":33,"line":34},[31,1169,38],{"class":37},[31,1171,471],{"class":667},[31,1173,882],{"class":41},[31,1175,1176],{"class":37},".",[31,1178,1179],{"class":41},"trim",[31,1181,58],{"class":37},[31,1183,681],{"class":61},[31,1185,1186],{"class":37},"name",[31,1188,681],{"class":61},[31,1190,144],{"class":37},[21,1192,1194],{"className":907,"code":1193,"language":909,"meta":26,"style":26},"h(Dialog, {\n  modelValue: name.value,\n  'onUpdate:modelValue': ($event) => {\n    name.value = $event.trim()   \u002F\u002F .trim 修饰符\n  }\n})\n",[28,1195,1196,1202,1207,1221,1239,1243],{"__ignoreMap":26},[31,1197,1198,1200],{"class":33,"line":34},[31,1199,1099],{"class":41},[31,1201,1001],{"class":37},[31,1203,1204],{"class":33,"line":48},[31,1205,1206],{"class":37},"  modelValue: name.value,\n",[31,1208,1209,1211,1213,1215,1217,1219],{"class":33,"line":67},[31,1210,1112],{"class":61},[31,1212,420],{"class":37},[31,1214,1016],{"class":314},[31,1216,426],{"class":37},[31,1218,408],{"class":51},[31,1220,949],{"class":37},[31,1222,1223,1226,1228,1231,1233,1236],{"class":33,"line":100},[31,1224,1225],{"class":37},"    name.value ",[31,1227,58],{"class":51},[31,1229,1230],{"class":37}," $event.",[31,1232,1179],{"class":41},[31,1234,1235],{"class":37},"()   ",[31,1237,1238],{"class":456},"\u002F\u002F .trim 修饰符\n",[31,1240,1241],{"class":33,"line":119},[31,1242,1043],{"class":37},[31,1244,1245],{"class":33,"line":147},[31,1246,445],{"class":37},[10,1248,1249,1252],{},[722,1250,1251],{},"修饰符的处理","：",[1254,1255,1256,1269],"table",{},[1257,1258,1259],"thead",{},[1260,1261,1262,1266],"tr",{},[1263,1264,1265],"th",{},"修饰符",[1263,1267,1268],{},"编译结果",[1270,1271,1272,1285,1297],"tbody",{},[1260,1273,1274,1280],{},[1275,1276,1277],"td",{},[28,1278,1279],{},".trim",[1275,1281,1282],{},[28,1283,1284],{},"$event.trim()",[1260,1286,1287,1292],{},[1275,1288,1289],{},[28,1290,1291],{},".number",[1275,1293,1294],{},[28,1295,1296],{},"Number($event)",[1260,1298,1299,1304],{},[1275,1300,1301],{},[28,1302,1303],{},".lazy",[1275,1305,1306,1307,1310,1311,1314],{},"用 ",[28,1308,1309],{},"onChange"," 代替 ",[28,1312,1313],{},"onInput","（原生元素）",[10,1316,1317],{},"我们刚才的组件可能会展开为：",[21,1319,1321],{"className":656,"code":1320,"language":658,"meta":26,"style":26},"\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{ modelValue: boolean }>()\nconst emit = defineEmits\u003C{ 'update:modelValue': [value: boolean] }>()\n\nconst isOpen = computed({\n  get: () => props.modelValue,\n  set: (val) => emit('update:modelValue', val),\n})\n\nconst closeDialog = () => {\n  isOpen.value = false\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CTeleport to=\"body\">\n    \u003Cdiv v-if=\"isOpen\" class=\"overlay\" @click=\"closeDialog\">\n      \u003Cdiv class=\"dialog\" @click.stop>\n        \u003Cslot \u002F>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002FTeleport>\n\u003C\u002Ftemplate>\n",[28,1322,1323,1340,1363,1390,1394,1406,1416,1437,1441,1445,1460,1470,1474,1482,1486,1494,1509,1536,1552,1565,1573,1581,1589],{"__ignoreMap":26},[31,1324,1325,1327,1329,1331,1334,1336,1338],{"class":33,"line":34},[31,1326,38],{"class":37},[31,1328,817],{"class":667},[31,1330,820],{"class":41},[31,1332,1333],{"class":41}," lang",[31,1335,58],{"class":37},[31,1337,217],{"class":61},[31,1339,45],{"class":37},[31,1341,1342,1344,1346,1348,1350,1353,1355,1357,1360],{"class":33,"line":48},[31,1343,253],{"class":51},[31,1345,300],{"class":256},[31,1347,260],{"class":51},[31,1349,305],{"class":41},[31,1351,1352],{"class":37},"\u003C{ ",[31,1354,676],{"class":314},[31,1356,318],{"class":51},[31,1358,1359],{"class":256}," boolean",[31,1361,1362],{"class":37}," }>()\n",[31,1364,1365,1367,1369,1371,1373,1375,1377,1379,1381,1383,1385,1387],{"class":33,"line":67},[31,1366,253],{"class":51},[31,1368,340],{"class":256},[31,1370,260],{"class":51},[31,1372,345],{"class":41},[31,1374,1352],{"class":37},[31,1376,436],{"class":61},[31,1378,318],{"class":51},[31,1380,358],{"class":37},[31,1382,361],{"class":41},[31,1384,364],{"class":37},[31,1386,367],{"class":256},[31,1388,1389],{"class":37},"] }>()\n",[31,1391,1392],{"class":33,"line":100},[31,1393,204],{"emptyLinePlaceholder":203},[31,1395,1396,1398,1400,1402,1404],{"class":33,"line":119},[31,1397,253],{"class":51},[31,1399,388],{"class":256},[31,1401,260],{"class":51},[31,1403,393],{"class":41},[31,1405,396],{"class":37},[31,1407,1408,1410,1412,1414],{"class":33,"line":147},[31,1409,402],{"class":41},[31,1411,405],{"class":37},[31,1413,408],{"class":51},[31,1415,411],{"class":37},[31,1417,1418,1420,1422,1424,1426,1428,1430,1432,1434],{"class":33,"line":158},[31,1419,417],{"class":41},[31,1421,420],{"class":37},[31,1423,423],{"class":314},[31,1425,426],{"class":37},[31,1427,408],{"class":51},[31,1429,340],{"class":41},[31,1431,433],{"class":37},[31,1433,436],{"class":61},[31,1435,1436],{"class":37},", val),\n",[31,1438,1439],{"class":33,"line":169},[31,1440,445],{"class":37},[31,1442,1443],{"class":33,"line":179},[31,1444,204],{"emptyLinePlaceholder":203},[31,1446,1447,1449,1452,1454,1456,1458],{"class":33,"line":190},[31,1448,253],{"class":51},[31,1450,1451],{"class":41}," closeDialog",[31,1453,260],{"class":51},[31,1455,986],{"class":37},[31,1457,408],{"class":51},[31,1459,949],{"class":37},[31,1461,1462,1465,1467],{"class":33,"line":200},[31,1463,1464],{"class":37},"  isOpen.value ",[31,1466,58],{"class":51},[31,1468,1469],{"class":256}," false\n",[31,1471,1472],{"class":33,"line":207},[31,1473,1048],{"class":37},[31,1475,1476,1478,1480],{"class":33,"line":222},[31,1477,193],{"class":37},[31,1479,817],{"class":667},[31,1481,45],{"class":37},[31,1483,1484],{"class":33,"line":237},[31,1485,204],{"emptyLinePlaceholder":203},[31,1487,1488,1490,1492],{"class":33,"line":245},[31,1489,38],{"class":37},[31,1491,42],{"class":667},[31,1493,45],{"class":37},[31,1495,1496,1498,1500,1503,1505,1507],{"class":33,"line":250},[31,1497,52],{"class":37},[31,1499,185],{"class":667},[31,1501,1502],{"class":41}," to",[31,1504,58],{"class":37},[31,1506,62],{"class":61},[31,1508,45],{"class":37},[31,1510,1511,1513,1515,1518,1520,1522,1524,1526,1528,1530,1532,1534],{"class":33,"line":269},[31,1512,70],{"class":37},[31,1514,164],{"class":667},[31,1516,1517],{"class":41}," v-if",[31,1519,58],{"class":37},[31,1521,79],{"class":61},[31,1523,82],{"class":41},[31,1525,58],{"class":37},[31,1527,87],{"class":61},[31,1529,90],{"class":41},[31,1531,58],{"class":37},[31,1533,95],{"class":61},[31,1535,45],{"class":37},[31,1537,1538,1540,1542,1544,1546,1548,1550],{"class":33,"line":290},[31,1539,103],{"class":37},[31,1541,164],{"class":667},[31,1543,82],{"class":41},[31,1545,58],{"class":37},[31,1547,111],{"class":61},[31,1549,114],{"class":41},[31,1551,45],{"class":37},[31,1553,1554,1556,1559,1563],{"class":33,"line":295},[31,1555,122],{"class":37},[31,1557,1558],{"class":667},"slot",[31,1560,1562],{"class":1561},"s7hpK"," \u002F",[31,1564,45],{"class":37},[31,1566,1567,1569,1571],{"class":33,"line":311},[31,1568,161],{"class":37},[31,1570,164],{"class":667},[31,1572,45],{"class":37},[31,1574,1575,1577,1579],{"class":33,"line":324},[31,1576,172],{"class":37},[31,1578,164],{"class":667},[31,1580,45],{"class":37},[31,1582,1583,1585,1587],{"class":33,"line":330},[31,1584,182],{"class":37},[31,1586,185],{"class":667},[31,1588,45],{"class":37},[31,1590,1591,1593,1595],{"class":33,"line":335},[31,1592,193],{"class":37},[31,1594,42],{"class":667},[31,1596,45],{"class":37},[21,1598,1600],{"className":907,"code":1599,"language":909,"meta":26,"style":26},"import { defineComponent, computed, createVNode, Teleport, withCtx } from 'vue'\n\nconst Dialog = defineComponent({\n  name: 'Dialog',\n  props: {\n    modelValue: { type: Boolean, required: true }\n  },\n  emits: ['update:modelValue'],\n  setup(props, { emit, slots }) {\n    const isOpen = computed({\n      get: () => props.modelValue,\n      set: (val) => emit('update:modelValue', val)\n    })\n\n    const closeDialog = () => {\n      isOpen.value = false\n    }\n\n    return () => {\n      return isOpen.value\n        ? createVNode(Teleport, { to: 'body' }, {\n            default: withCtx(() => [\n              createVNode('div', {\n                class: 'overlay',\n                onClick: closeDialog\n              }, [\n                createVNode('div', {\n                  class: 'dialog',\n                  onClick: (e) => e.stopPropagation()\n                }, slots.default?.())\n              ])\n            ])\n          })\n        : null\n    }\n  }\n})\n\nexport default Dialog\n",[28,1601,1602,1613,1617,1631,1642,1647,1657,1662,1672,1694,1706,1717,1738,1743,1747,1761,1770,1774,1778,1788,1795,1811,1827,1840,1850,1855,1860,1871,1881,1903,1914,1919,1924,1929,1937,1941,1945,1949,1953],{"__ignoreMap":26},[31,1603,1604,1606,1609,1611],{"class":33,"line":34},[31,1605,225],{"class":51},[31,1607,1608],{"class":37}," { defineComponent, computed, createVNode, Teleport, withCtx } ",[31,1610,231],{"class":51},[31,1612,834],{"class":61},[31,1614,1615],{"class":33,"line":48},[31,1616,204],{"emptyLinePlaceholder":203},[31,1618,1619,1621,1624,1626,1629],{"class":33,"line":67},[31,1620,253],{"class":51},[31,1622,1623],{"class":256}," Dialog",[31,1625,260],{"class":51},[31,1627,1628],{"class":41}," defineComponent",[31,1630,396],{"class":37},[31,1632,1633,1636,1639],{"class":33,"line":100},[31,1634,1635],{"class":37},"  name: ",[31,1637,1638],{"class":61},"'Dialog'",[31,1640,1641],{"class":37},",\n",[31,1643,1644],{"class":33,"line":119},[31,1645,1646],{"class":37},"  props: {\n",[31,1648,1649,1652,1654],{"class":33,"line":147},[31,1650,1651],{"class":37},"    modelValue: { type: Boolean, required: ",[31,1653,793],{"class":256},[31,1655,1656],{"class":37}," }\n",[31,1658,1659],{"class":33,"line":158},[31,1660,1661],{"class":37},"  },\n",[31,1663,1664,1667,1669],{"class":33,"line":169},[31,1665,1666],{"class":37},"  emits: [",[31,1668,436],{"class":61},[31,1670,1671],{"class":37},"],\n",[31,1673,1674,1676,1678,1681,1684,1686,1688,1691],{"class":33,"line":179},[31,1675,954],{"class":41},[31,1677,433],{"class":37},[31,1679,1680],{"class":314},"props",[31,1682,1683],{"class":37},", { ",[31,1685,783],{"class":314},[31,1687,790],{"class":37},[31,1689,1690],{"class":314},"slots",[31,1692,1693],{"class":37}," }) {\n",[31,1695,1696,1698,1700,1702,1704],{"class":33,"line":190},[31,1697,962],{"class":51},[31,1699,388],{"class":256},[31,1701,260],{"class":51},[31,1703,393],{"class":41},[31,1705,396],{"class":37},[31,1707,1708,1711,1713,1715],{"class":33,"line":200},[31,1709,1710],{"class":41},"      get",[31,1712,405],{"class":37},[31,1714,408],{"class":51},[31,1716,411],{"class":37},[31,1718,1719,1722,1724,1726,1728,1730,1732,1734,1736],{"class":33,"line":207},[31,1720,1721],{"class":41},"      set",[31,1723,420],{"class":37},[31,1725,423],{"class":314},[31,1727,426],{"class":37},[31,1729,408],{"class":51},[31,1731,340],{"class":41},[31,1733,433],{"class":37},[31,1735,436],{"class":61},[31,1737,439],{"class":37},[31,1739,1740],{"class":33,"line":222},[31,1741,1742],{"class":37},"    })\n",[31,1744,1745],{"class":33,"line":237},[31,1746,204],{"emptyLinePlaceholder":203},[31,1748,1749,1751,1753,1755,1757,1759],{"class":33,"line":245},[31,1750,962],{"class":51},[31,1752,1451],{"class":41},[31,1754,260],{"class":51},[31,1756,986],{"class":37},[31,1758,408],{"class":51},[31,1760,949],{"class":37},[31,1762,1763,1766,1768],{"class":33,"line":250},[31,1764,1765],{"class":37},"      isOpen.value ",[31,1767,58],{"class":51},[31,1769,1469],{"class":256},[31,1771,1772],{"class":33,"line":269},[31,1773,1038],{"class":37},[31,1775,1776],{"class":33,"line":290},[31,1777,204],{"emptyLinePlaceholder":203},[31,1779,1780,1782,1784,1786],{"class":33,"line":295},[31,1781,983],{"class":51},[31,1783,986],{"class":37},[31,1785,408],{"class":51},[31,1787,949],{"class":37},[31,1789,1790,1792],{"class":33,"line":311},[31,1791,995],{"class":51},[31,1793,1794],{"class":37}," isOpen.value\n",[31,1796,1797,1800,1802,1805,1808],{"class":33,"line":324},[31,1798,1799],{"class":51},"        ?",[31,1801,998],{"class":41},[31,1803,1804],{"class":37},"(Teleport, { to: ",[31,1806,1807],{"class":61},"'body'",[31,1809,1810],{"class":37}," }, {\n",[31,1812,1813,1816,1819,1822,1824],{"class":33,"line":330},[31,1814,1815],{"class":37},"            default: ",[31,1817,1818],{"class":41},"withCtx",[31,1820,1821],{"class":37},"(() ",[31,1823,408],{"class":51},[31,1825,1826],{"class":37}," [\n",[31,1828,1829,1832,1834,1837],{"class":33,"line":335},[31,1830,1831],{"class":41},"              createVNode",[31,1833,433],{"class":37},[31,1835,1836],{"class":61},"'div'",[31,1838,1839],{"class":37},", {\n",[31,1841,1842,1845,1848],{"class":33,"line":350},[31,1843,1844],{"class":37},"                class: ",[31,1846,1847],{"class":61},"'overlay'",[31,1849,1641],{"class":37},[31,1851,1852],{"class":33,"line":373},[31,1853,1854],{"class":37},"                onClick: closeDialog\n",[31,1856,1857],{"class":33,"line":378},[31,1858,1859],{"class":37},"              }, [\n",[31,1861,1862,1865,1867,1869],{"class":33,"line":383},[31,1863,1864],{"class":41},"                createVNode",[31,1866,433],{"class":37},[31,1868,1836],{"class":61},[31,1870,1839],{"class":37},[31,1872,1873,1876,1879],{"class":33,"line":399},[31,1874,1875],{"class":37},"                  class: ",[31,1877,1878],{"class":61},"'dialog'",[31,1880,1641],{"class":37},[31,1882,1883,1886,1888,1891,1893,1895,1898,1901],{"class":33,"line":414},[31,1884,1885],{"class":41},"                  onClick",[31,1887,420],{"class":37},[31,1889,1890],{"class":314},"e",[31,1892,426],{"class":37},[31,1894,408],{"class":51},[31,1896,1897],{"class":37}," e.",[31,1899,1900],{"class":41},"stopPropagation",[31,1902,266],{"class":37},[31,1904,1905,1908,1911],{"class":33,"line":442},[31,1906,1907],{"class":37},"                }, slots.",[31,1909,1910],{"class":41},"default",[31,1912,1913],{"class":37},"?.())\n",[31,1915,1916],{"class":33,"line":448},[31,1917,1918],{"class":37},"              ])\n",[31,1920,1921],{"class":33,"line":453},[31,1922,1923],{"class":37},"            ])\n",[31,1925,1926],{"class":33,"line":460},[31,1927,1928],{"class":37},"          })\n",[31,1930,1931,1934],{"class":33,"line":495},[31,1932,1933],{"class":51},"        :",[31,1935,1936],{"class":256}," null\n",[31,1938,1939],{"class":33,"line":503},[31,1940,1038],{"class":37},[31,1942,1943],{"class":33,"line":514},[31,1944,1043],{"class":37},[31,1946,1947],{"class":33,"line":525},[31,1948,445],{"class":37},[31,1950,1951],{"class":33,"line":541},[31,1952,204],{"emptyLinePlaceholder":203},[31,1954,1955,1957,1959],{"class":33,"line":557},[31,1956,943],{"class":51},[31,1958,946],{"class":51},[31,1960,1961],{"class":37}," Dialog\n",[1963,1964,1965],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":26,"searchDepth":48,"depth":48,"links":1967},[1968,1969],{"id":16,"depth":48,"text":16},{"id":802,"depth":48,"text":802},"md",{"date":1972,"tags":1973,"excalidraw-plugin":1974},"2026-10-15",[658,783],"parsed","\u002Fvue\u002Femit讲解",{"description":12},"Vue\u002Femit讲解","JzlA-BmO2ZWlNEiuKAp5plLUh-I8pWuMCCUmCiwmcDA",1791957915982]