{"id":4869,"date":"2025-01-12T15:33:50","date_gmt":"2025-01-12T07:33:50","guid":{"rendered":"https:\/\/blog.odjbinail.cn\/?p=4869"},"modified":"2025-01-12T22:27:20","modified_gmt":"2025-01-12T14:27:20","slug":"%e5%9f%ba%e4%ba%8evue3vitets%e4%ba%8c%e6%ac%a1%e5%b0%81%e8%a3%85element-plus%e4%b8%9a%e5%8a%a1%e7%bb%84%e4%bb%b6","status":"publish","type":"post","link":"https:\/\/blog.odjbinail.cn\/?p=4869","title":{"rendered":"\u57fa\u4e8eVue3+Vite+TS\u4e8c\u6b21\u5c01\u88c5element-plus\u4e1a\u52a1\u7ec4\u4ef6"},"content":{"rendered":"<p>\u4ee3\u7801\u4ed3\u5e93\u5730\u5740: <a href=\"https:\/\/gitee.com\/lin-lin-DJ\/second-elementplus\">https:\/\/gitee.com\/lin-lin-DJ\/second-elementplus<\/a><\/p>\n<h2>\u642d\u5efa vite \u9879\u76ee\u5e76\u914d\u7f6e\u8def\u7531\u548c elementplus<\/h2>\n<ul>\n<li>npm init vite@latest second-elementplus -- --template vue-ts<\/li>\n<li>npm i -S vue-router@next element-plus<\/li>\n<\/ul>\n<h2>\u5168\u5c40\u6ce8\u518c\u56fe\u6807<\/h2>\n<ul>\n<li>npm install @element-plus\/icons<\/li>\n<li>\u5728\u6b64\u60f3\u8981\u628a vue3 \u56fe\u6807\u7684\u9a7c\u5cf0\u547d\u540d\u6cd5 \u6539\u9020\u6210 el-icon-xxx \u4f7f\u7528\u56fe\u6807\u7ec4\u4ef6, \u6240\u4ee5\u6211\u4eec\u5148\u7f16\u5199\u4e00\u4e2a\u5de5\u5177\u7c7b<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>\/\/\u628a\u9a7c\u5cf0\u8f6c\u6362\u6210\u6a2a\u6760\u94fe\u63a5\nexport const toLine=(value:string )=&gt;{\nreturn value.replace(\/(A-Z)g\/,&#039;-$1&#039;).toLocaleLowerCase()\n}<\/code><\/pre>\n<ul>\n<li>main.ts<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>import ElementPlus from &#039;element-plus&#039;\nimport &#039;element-plus\/dist\/index.css&#039;\nimport * as Icons from &#039;@element-plus\/icons&#039;\nimport {toLine} from &quot;.\/utils&quot;;\n\nconst app = createApp(App)\n\n\/\/\u5168\u5c40\u6ce8\u518c\u56fe\u6807 \u727a\u7272\u4e00\u70b9\u6027\u80fd\nfor (let i in Icons){\n    \/\/\u6ce8\u518c\u5168\u90e8\u7ec4\u4ef6\n    app.component(`el-icon-${toLine(i)}`, (Icons as any)[i])\n}\n\napp.use(ElementPlus)\napp.mount(&#039;#app&#039;)<\/code><\/pre>\n<ul>\n<li>\u5373\u53ef\u5728 vue \u7ec4\u4ef6\u91cc\u9762\u4f7f\u7528 el-icon-xxx \u4f7f\u7528\u56fe\u6807<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code> &lt;el-icon-edit\/&gt;<\/code><\/pre>\n<h2>\u4f38\u7f29\u83dc\u5355\u529f\u80fd<\/h2>\n<ul>\n<li>\u5229\u7528 elementplus \u4e2d el-menu \u7684 collapse \u5c5e\u6027\u548c v-if \u5224\u65ad\u6536\u7f29\/\u5c55\u5f00\u56fe\u6807, \u5b9e\u73b0\u4f38\u7f29\u83dc\u5355\u529f\u80fd<\/li>\n<\/ul>\n<h2>\u5de7\u7528\u4e24\u6b21 watch \u63a7\u5236\u5f39\u6846\u7684\u663e\u793a\u4e0e\u9690\u85cf<\/h2>\n<ul>\n<li>\u5b58\u5728\u95ee\u9898: \u70b9\u4e24\u6b21\u6309\u94ae\u624d\u51fa\u73b0\u5f39\u7a97?<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>&lt;template&gt;\n  &lt;el-button @click=&quot;handleClick&quot; type=&quot;primary&quot;&gt;\n    &lt;slot&gt;&lt;\/slot&gt;\n  &lt;\/el-button&gt;\n  &lt;el-dialog :modelValue=&quot;dialogVisible&quot; :title=&quot;title&quot;&gt;111&lt;\/el-dialog&gt;\n&lt;\/template&gt;\n\n&lt;script lang=&quot;ts&quot; setup&gt;\nimport {ref, watch} from &quot;vue&quot;;\n\nconst props = defineProps&lt;{\n  \/\/\u5f39\u51fa\u6846\u7684\u6807\u9898\n  title: string,\n  \/\/\u63a7\u5236\u5f39\u51fa\u6846\u7684\u663e\u793a\u4e0e\u9690\u85cf\n  visible: boolean,\n}&gt;()\nlet emits = defineEmits([&#039;update:visible&#039;])\n\/\/\u62f7\u8d1d\u4e00\u4efd\u7236\u7ec4\u4ef6\u4f20\u9012\u8fc7\u6765\u7684 visible \u503c\nlet dialogVisible = ref&lt;boolean&gt;(props.visible)\nconst handleClick = () =&gt; {\n  emits(&#039;update:visible&#039;, !props.visible)\n}\n\/\/ \u76d1\u542c\u7236\u7ec4\u4ef6\u4f20\u9012\u8fc7\u6765\u7684\u503c, \u53ea\u80fd\u76d1\u542c\u7b2c\u4e00\u6b21\u7684\u53d8\u5316\nwatch(() =&gt; props.visible, (newValue) =&gt; {\n  dialogVisible.value=newValue\n})\n\/\/\u76d1\u542c\u7ec4\u4ef6\u5185\u90e8\u7684 dialogVisible \u53d8\u5316\nwatch(() =&gt; dialogVisible.value, (newValue) =&gt; {\n  emits(&#039;update:visible&#039;, newValue)\n})\n&lt;\/script&gt;<\/code><\/pre>\n<ul>\n<li>\u7236\u7ec4\u4ef6\u8c03\u7528<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>&lt;template&gt;\n&lt;choose-icon title=&quot;\u9009\u62e9\u56fe\u6807&quot; v-model:visible=&quot;visible&quot;&gt;\u9009\u62e9\u56fe\u6807\n&lt;\/choose-icon&gt;\n&lt;\/template&gt;\n\n&lt;script lang=&quot;ts&quot; setup&gt;\nimport ChooseIcon from &#039;..\/..\/components\/chooseIcon\/src\/index.vue&#039;\nimport {ref} from &quot;vue&quot;;\nconst visible = ref&lt;boolean&gt;(false)\n&lt;\/script&gt;<\/code><\/pre>\n<h2>\u5de7\u7528 component \u52a8\u6001\u7ec4\u4ef6\u663e\u793a\u6240\u6709\u7684\u56fe\u6807<\/h2>\n<pre class=\"prettyprint linenums\" ><code>&lt;el-dialog :modelValue=&quot;dialogVisible&quot; :title=&quot;title&quot;&gt;\n    &lt;div class=&quot;container&quot;&gt;\n      &lt;div class=&quot;item&quot; v-for=&quot;(item,index) in Object.keys(ElIcons)&quot;  :key=&quot;index&quot;&gt;\n        &lt;div&gt;\n          &lt;component :is=&quot;`el-icon-${toLine(item)}`&quot;&gt;&lt;\/component&gt;\n        &lt;\/div&gt;\n        &lt;div&gt;{{item}}&lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/el-dialog&gt;<\/code><\/pre>\n<pre class=\"prettyprint linenums\" ><code>&lt;style scoped lang=&quot;less&quot;&gt;\n.container{\n  display: flex;\n  align-items: center;\n  flex-wrap: wrap;\n  .item{\n    width: 20%;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n    margin-bottom: 15px;\n    height: 70px;\n    svg{\n      width: 2em;\n      height: 2em;\n    }\n  }\n}\n&lt;\/style&gt;<\/code><\/pre>\n<p><img data-original=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/202412162238464.png\"  alt=\"\" \/><\/p>\n<noscript><img decoding=\"async\" src=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/202412162238464.png\" alt=\"\" \/><\/p><\/noscript>\n<h2>\u901a\u8fc7\u81ea\u5b9a\u4e49 hooks \u51fd\u6570\u5b9e\u73b0\u590d\u5236\u529f\u80fd<\/h2>\n<ul>\n<li>hooks\/useCopy\/index.ts<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>import {ElMessage} from &quot;element-plus&quot;;\n\nexport const useCopy=(text:string)=&gt;{\n    \/\/\u521b\u5efa\u8f93\u5165\u6846\n    let input=document.createElement(&#039;input&#039;)\n    \/\/\u7ed9\u8f93\u5165\u6846 value \u8d4b\u503c\n    input.value=text\n    \/\/\u8ffd\u52a0\u5230 body\n    document.body.appendChild(input)\n    \/\/\u9009\u62e9\u8f93\u5165\u6846\u7684\u64cd\u4f5c\n    input.select()\n    \/\/\u6267\u884c\u590d\u5236\u64cd\u4f5c\n    document.execCommand(&#039;Copy&#039;)\n    \/\/\u5220\u9664\u52a0\u5165\u7684\u8f93\u5165\u6846\n    document.body.removeChild(input)\n    \/\/\u63d0\u793a\u7528\u6237\n    ElMessage.success(&#039;\u590d\u5236\u6210\u529f&#039;)\n}<\/code><\/pre>\n<pre class=\"prettyprint linenums\" ><code>\/\/\u70b9\u51fb\u56fe\u6807\nconst clickItem = (item:string) =&gt; {\n  let text=`&lt;el-icon-${toLine(item)}\/&gt;`\n  useCopy(text)\n  dialogVisible.value=false\n}<\/code><\/pre>\n<h2>\u7701\u5e02\u533a\u9009\u62e9\u7ec4\u4ef6<\/h2>\n<ul>\n<li>\u4ece github \u4e2d\u83b7\u53d6\u7701\u5e02\u533a json \u6570\u636e<br \/>\n<a href=\"https:\/\/github.com\/modood\/Administrative-divisions-of-China\">https:\/\/github.com\/modood\/Administrative-divisions-of-China<\/a><\/li>\n<\/ul>\n<p><img data-original=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2024121623091392.png\"  alt=\"\" \/><\/p>\n<noscript><img decoding=\"async\" src=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2024121623091392.png\" alt=\"\" \/><\/p><\/noscript>\n<ul>\n<li>\u6f14\u793a\u6548\u679c<\/li>\n<\/ul>\n<p><img data-original=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2024121623324790.png\"  alt=\"\" \/><\/p>\n<noscript><img decoding=\"async\" src=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2024121623324790.png\" alt=\"\" \/><\/p><\/noscript>\n<ul>\n<li>\u7ec4\u4ef6\u4ee3\u7801<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>&lt;template&gt;\n  &lt;div&gt;\n    &lt;el-select placeholder=&quot;\u8bf7\u9009\u62e9\u7701\u4efd&quot; v-model=&quot;province&quot; clearable&gt;\n      &lt;el-option v-for=&quot;item in areas&quot; :key=&quot;item.code&quot; :value=&quot;item.code&quot; :label=&quot;item.name&quot;&gt;&lt;\/el-option&gt;\n    &lt;\/el-select&gt;\n    &lt;el-select :disabled=&quot;!province&quot; style=&quot;margin: 0 10px&quot; placeholder=&quot;\u8bf7\u9009\u62e9\u57ce\u5e02&quot; v-model=&quot;city&quot; clearable&gt;\n      &lt;el-option v-for=&quot;item in selectCity&quot; :key=&quot;item.code&quot; :value=&quot;item.code&quot; :label=&quot;item.name&quot;&gt;&lt;\/el-option&gt;\n    &lt;\/el-select&gt;\n    &lt;el-select :disabled=&quot;!province||!city&quot; placeholder=&quot;\u8bf7\u9009\u62e9\u533a\u53bf&quot; v-model=&quot;area&quot; clearable&gt;\n      &lt;el-option v-for=&quot;item in selectArea&quot; :key=&quot;item.code&quot; :value=&quot;item.code&quot; :label=&quot;item.name&quot;&gt;&lt;\/el-option&gt;\n    &lt;\/el-select&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script lang=&quot;ts&quot; setup&gt;\nimport {watch, ref} from &quot;vue&quot;;\nimport allAreas from &#039;..\/lib\/pca-code.json&#039;\n\nexport interface AreaItem{\n  name:string,\n  code:string,\n  children?:AreaItem[]\n}\n\nexport interface Data{\n  name:string,\n  code:string,\n}\n\nconst province = ref&lt;string&gt;(&#039;&#039;)\/\/\u7701\u4efd\nconst city = ref&lt;string&gt;(&#039;&#039;)\/\/\u57ce\u5e02\nconst area = ref&lt;string&gt;(&#039;&#039;)\/\/\u533a\u57df\nconst areas = ref(allAreas)\/\/\u6240\u6709\u7701\u5e02\u533a\u6570\u636e\n\/\/todo \u7528 computed \u4f1a\u62a5\u9519, \u9009\u62e9 \u7701\u5e02\u533a\u4e4b\u540e, \u518d\u9009\u62e9\u7701\u4efd\u4f1a\u62a5\u9519 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading &#039;children&#039;)\n\/\/\u57ce\u5e02\u4e0b\u62c9\u6846\u7684\u6240\u6709\u7684\u503c\nconst selectCity = ref&lt;AreaItem[]&gt;([])\n\/\/\u533a\u57df\u4e0b\u62c9\u6846\u7684\u6240\u6709\u7684\u503c\nconst selectArea = ref&lt;AreaItem[]&gt;([])\n\/\/ const selectCity = computed(() =&gt; {\n\/\/   if (!province.value) {\n\/\/     return []\n\/\/   } else {\n\/\/     return areas.value.find(item =&gt; item.code === province.value)!.children\n\/\/   }\n\/\/ })\n\n\/\/\u5206\u53d1\u4e8b\u4ef6\u7ed9\u7236\u7ec4\u4ef6\nconst emits = defineEmits([&#039;change&#039;])\n\n\/\/\u76d1\u542c\u9009\u62e9\u7701\u4efd\nwatch(() =&gt; province.value, (newValue) =&gt; {\n  if (newValue) {\n    \/\/\u52a0 ! \u662f\u6307\u4e00\u5b9a\u662f\u6709\u503c\u7684\n    selectCity.value = areas.value.find(item =&gt; item.code === newValue)!.children!\n  }\n  city.value=&#039;&#039;\n  area.value=&#039;&#039;\n})\n\/\/\u76d1\u542c\u9009\u62e9\u57ce\u5e02\nwatch(() =&gt; city.value, (newValue) =&gt; {\n  if (newValue) {\n    selectArea.value = selectCity.value.find(item =&gt; item.code === newValue)!.children!\n  }\n  area.value=&#039;&#039;\n})\n\/\/\u76d1\u542c\u9009\u62e9\u533a\u57df\nwatch(() =&gt; area.value, (newValue) =&gt; {\n if(newValue){\n   let provinceData:Data={\n     code:province.value,\n     name:province.value&amp;&amp;allAreas.find(item=&gt;item.code=== province.value)!.name\n   }\n   let cityData:Data={\n     code:city.value,\n     name: city.value&amp;&amp;selectCity.value.find(item=&gt;item.code=== city.value)!.name\n   }\n   let areaData:Data={\n     code:newValue,\n     name:newValue&amp;&amp;selectArea.value.find(item=&gt;item.code=== newValue)!.name\n   }\n   emits(&#039;change&#039;,{\n     province:provinceData,\n     city:cityData,\n     area:areaData\n   })\n }\n})\n&lt;\/script&gt;\n\n&lt;style scoped&gt;\n.el-select {\n  width: 200px;\n}\n&lt;\/style&gt;<\/code><\/pre>\n<ul>\n<li>\u7236\u7ec4\u4ef6\u8c03\u7528<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>&lt;template&gt;\n&lt;choose-area @change=&quot;changeArea&quot;\/&gt;\n&lt;\/template&gt;\n\n&lt;script setup lang=&quot;ts&quot;&gt;\nimport ChooseArea from &#039;..\/..\/components\/chooseArea\/src\/index.vue&#039;\nconst changeArea=(val)=&gt;{\n  console.log(val)\n}\n&lt;\/script&gt;<\/code><\/pre>\n<h2>\u5229\u7528 app.use \u7279\u6027\u5168\u5c40\u6ce8\u518c\u7ec4\u4ef6<\/h2>\n<ul>\n<li>\n<ol>\n<li>\u5728 components\/chooseArea \u7ec4\u4ef6\u91cc\u9762\u521b\u5efa index.ts<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>import {App} from &#039;vue&#039;\nimport chooseArea from &#039;.\/src\/index.vue&#039;\n\n\/\/\u8ba9\u8fd9\u4e2a\u7ec4\u4ef6\u53ef\u4ee5\u901a\u8fc7 use \u7684\u5f62\u5f0f\u4f7f\u7528\nexport default {\n  install(app: App) {\n    app.component(&#039;choose-area&#039;, chooseArea)\n  }\n}<\/code><\/pre>\n<ul>\n<li>2.\u5728 components \u91cc\u9762\u521b\u5efa index.ts<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>import {App} from &#039;vue&#039;\nimport chooseArea from &#039;.\/chooseArea&#039;\nimport chooseIcon from &#039;.\/chooseIcon&#039;\n\nconst components=[\n    chooseIcon,\n    chooseArea\n]\nexport default {\n    install(app: App) {\n        components.map(item=&gt;{\n            app.use(item)\n        })\n    }\n}<\/code><\/pre>\n<ul>\n<li>3.\u5728 main.ts \u4e2d\u5168\u5c40\u5f15\u5165\u7ec4\u4ef6<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>import App from &#039;.\/App.vue&#039;\nimport mUI from &#039;.\/components&#039;\/\/\u5168\u5c40\n\/\/import chooseArea from &#039;.\/components\/chooseArea&#039;\/\/\u6309\u9700\u5f15\u5165\n\nconst app = createApp(App)\napp.use(mUI)\n\/\/.use(chooseArea)<\/code><\/pre>\n<ul>\n<li>4.\u5728 views \u9875\u9762\u4e2d\u5c31\u4e0d\u7528\u5f15\u5165\u7ec4\u4ef6\u4e86<\/li>\n<\/ul>\n<h2>\u901a\u77e5\u83dc\u5355<\/h2>\n<ul>\n<li>\u60f3\u5b9e\u73b0\u7684\u6548\u679c<\/li>\n<\/ul>\n<p><img data-original=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2024122122042142.png\"  alt=\"\" \/><\/p>\n<noscript><img decoding=\"async\" src=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2024122122042142.png\" alt=\"\" \/><\/p><\/noscript>\n<ul>\n<li>\u901a\u77e5\u56fe\u6807\u5c01\u88c5<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>&lt;template&gt;\n  &lt;el-badge :value=&quot;value&quot; :max=&quot;max&quot; :is-dot=&quot;isDot&quot;&gt;\n    &lt;component :is=&quot;`el-icon-${toLine(icon)}`&quot;&gt;&lt;\/component&gt;\n  &lt;\/el-badge&gt;\n&lt;\/template&gt;\n\n&lt;script lang=&quot;ts&quot; setup&gt;\nimport {toLine} from &quot;..\/..\/..\/utils&quot;;\n\nconst props = defineProps({\n  \/\/\u663e\u793a\u7684\u56fe\u6807\n  icon: {\n    type: String,\n    default: &#039;Bell&#039;\n  },\n  \/\/\u901a\u77e5\u6570\u91cf\n  value: {\n    type: [String, Number],\n    default: &#039;&#039;\n  },\n  \/\/\u6700\u5927\u503c\n  max: {\n    type: Number\n  },\n  \/\/\u662f\u5426\u663e\u793a\u5c0f\u5706\u70b9\n  isDot: {\n    type: Boolean,\n    default: false\n  }\n})\n&lt;\/script&gt;<\/code><\/pre>\n<h2>\u4f7f\u7528 tsx \u5b9e\u73b0\u65e0\u9650\u5c42\u7ea7\u83dc\u5355<\/h2>\n<ul>\n<li>\n<p>npm i -D @vitejs\/plugin-vue-jsx<\/p>\n<\/li>\n<li>\n<p>vite.config.ts<\/p>\n<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>import { defineConfig } from &#039;vite&#039;\nimport vue from &#039;@vitejs\/plugin-vue&#039;\nimport vueJsx from &#039;@vitejs\/plugin-vue-jsx&#039;\nexport default defineConfig({\n  plugins: [vue(),vueJsx()],\n  server:{\n    port:8080\n  }\n})\n<\/code><\/pre>\n<ul>\n<li>menu.tsx<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>import {defineComponent, PropType, useAttrs} from &quot;vue&quot;;\nimport {MenuItem} from &quot;.\/types&quot;;\nimport * as Icons from &#039;@element-plus\/icons&#039;\nimport &#039;.\/styles\/index.css&#039;\nexport default defineComponent({\n    props: {\n        \/\/\u5bfc\u822a\u83dc\u5355\u7684\u6570\u636e\n        data: {\n            type: Array as PropType&lt;MenuItem[]&gt;,\n            required: true\n        },\n        \/\/\u9ed8\u8ba4\u9009\u4e2d\u7684\u83dc\u5355\n        defaultActive: {\n            type: String,\n            default: &#039;&#039;\n        },\n        \/\/\u662f\u5426\u662f\u8def\u7531\u6a21\u5f0f\n        router: {\n            type: Boolean,\n            default: false\n        }\n    },\n    setup(props, ctx) {\n        \/\/\u5c01\u88c5\u4e00\u4e2a\u6e32\u67d3\u65e0\u9650\u5c42\u7ea7\u83dc\u5355\u7684\u65b9\u6cd5\n        \/\/\u51fd\u6570\u4f1a\u8fd4\u56de\u4e00\u6bb5 jsx \u7684\u4ee3\u7801\n        let renderMenu = (data: MenuItem[]) =&gt; {\n            return data.map((item: MenuItem) =&gt; {\n                \/\/\u6bcf\u4e2a\u83dc\u5355\u7684\u56fe\u6807\n                item.i = (Icons as any)[item.icon!]\n                \/\/\u5904\u7406 sub-menu \u7684\u63d2\u69fd\n                let slots = {\n                    title: () =&gt; {\n                        return &lt;&gt;\n                            &lt;item.i\/&gt;\n                            &lt;span&gt;{item.name}&lt;\/span&gt;\n                        &lt;\/&gt;\n                    }\n                }\n                \/\/\u9012\u5f52\u6e32\u67d3 children\n                if (item.children &amp;&amp; item.children.length) {\n                    return (\n                        &lt;el-sub-menu index={item.index} v-slots={slots}&gt;\n                            {renderMenu(item.children)}\n                        &lt;\/el-sub-menu&gt;\n                    )\n                }\n                \/\/\u6b63\u5e38\u6e32\u67d3\u666e\u901a\u7684\u83dc\u5355\n                return (\n                    &lt;el-menu-item index={item.index}&gt;\n                        &lt;item.i\/&gt;\n                        &lt;span&gt;{item.name}&lt;\/span&gt;\n                    &lt;\/el-menu-item&gt;\n                )\n            })\n        }\n        let attrs= useAttrs()\n        return ()=&gt; {\n           return (\n                &lt;el-menu default-active={props.defaultActive} router={props.router} {...attrs}&gt;\n                    {renderMenu(props.data)}\n                &lt;\/el-menu&gt;\n            )\n        }\n    }\n})<\/code><\/pre>\n<h2>\u8fdb\u5ea6\u6761\u7ec4\u4ef6<\/h2>\n<ul>\n<li>\u5b8c\u6210\u8fdb\u5ea6\u6761\u52a8\u6001\u52a0\u8f7d\u6548\u679c<\/li>\n<li>progress\/src\/index.vue<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>&lt;template&gt;\n  &lt;div&gt;\n    &lt;el-progress v-bind=&quot;$attrs&quot; :percentage=&quot;p&quot;&gt;&lt;\/el-progress&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script lang=&quot;ts&quot; setup&gt;\n\nimport {onMounted, ref} from &quot;vue&quot;;\n\nconst props = defineProps({\n  \/\/\u8fdb\u5ea6\u6761\u8fdb\u5ea6\n  percentage: {\n    type: Number,\n    default: 60\n  },\n  \/\/\u8fdb\u5ea6\u6761\u662f\u5426\u6709\u52a8\u753b\u6548\u679c\n  isAnimation: {\n    type: Boolean,\n    default: false\n  },\n  \/\/\u52a8\u753b\u65f6\u957f(\u6beb\u79d2)\n  time: {\n    type: Number,\n    default: 3000\n  },\n})\nlet p = ref(0)\nonMounted(() =&gt; {\n  if (props.isAnimation) {\n\n    let t = Math.ceil(props.time \/ props.percentage)\n    let timer = setInterval(() =&gt; {\n      p.value += 1\n      if (p.value &gt; props.percentage) {\n        p.value = props.percentage\n        clearInterval(timer)\n      }\n    }, t)\n  } else {\n    p.value = props.percentage\n  }\n})\n&lt;\/script&gt;<\/code><\/pre>\n<h2>\u57ce\u5e02\u9009\u62e9<\/h2>\n<ul>\n<li>\u70b9\u51fb\u5b57\u6bcd\u8df3\u8f6c\u5230\u5bf9\u5e94\u4f4d\u7f6e<\/li>\n<li>\u7ed1\u5b9a id, \u4f7f\u7528 dom \u7684\u539f\u751f\u65b9\u6cd5<\/li>\n<li>\u6269\u5c55: \u5c0f\u7a0b\u5e8f\u91cc\u9762\u5bcc\u6587\u672c\u5982\u4f55\u8df3\u8f6c\u5230\u6307\u5b9a\u6587\u5b57\u7684\u533a\u57df<\/li>\n<\/ul>\n<pre class=\"prettyprint linenums\" ><code>let el= document.getElementById(item)\nif(el) el.scrollIntoView()<\/code><\/pre>\n<p><img data-original=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2025011212582217.png\"  alt=\"\" \/><\/p>\n<noscript><img decoding=\"async\" src=\"https:\/\/blog.odjbinail.cn\/wp-content\/uploads\/2024\/12\/2025011212582217.png\" alt=\"\" \/><\/p><\/noscript>\n<h2>\u8868\u5355\u7ec4\u4ef6<\/h2>\n<h3>\u529f\u80fd<\/h3>\n<p>1.\u53ef\u914d\u7f6e\u578b\u8868\u5355\uff0c\u901a\u8fc7 json \u5bf9\u8c61\u7684\u65b9\u5f0f\u81ea\u52a8\u751f\u6210\u8868\u5355<br \/>\n2.\u5177\u5907\u66f4\u5b8c\u5584\u7684\u529f\u80fd\uff0c\u8868\u5355\u9a8c\u8bc1\uff0c\u52a8\u6001\u5220\u51cf\u8868\u5355\uff0c\u96c6\u6210\u7b2c\u4e09\u65b9\u7684\u63d2\u4ef6\uff0c<br \/>\n3.\u7528\u6cd5\u7b80\u5355\uff0c\u6269\u5c55\u6027\u5f3a\uff0c\u53ef\u7ef4\u62a4\u6027\u5f3a<br \/>\n4.\u80fd\u591f\u7528\u5728\u66f4\u591a\u7684\u573a\u666f\uff0c\u6bd4\u5982\u5f39\u6846\u5d4c\u5957\u8868\u5355<\/p>\n<h3>\u51c6\u5907\u5de5\u4f5c<\/h3>\n<p>1.\u5206\u6790<code>element-plus<\/code>\u8868\u5355\u80fd\u591f\u5728\u54ea\u4e9b\u65b9\u9762\u505a\u4f18\u5316<br \/>\n2.\u5b8c\u5584\u6211\u4eec\u5c01\u88c5\u8868\u5355\u7684\u7c7b\u578b\uff0c\u652f\u6301 ts<br \/>\n3.\u5c01\u88c5\u7684\u8868\u5355\u8981\u5177\u5907<code>element-plus<\/code>\u539f\u8868\u5355\u7684\u6240\u6709\u529f\u80fd<br \/>\n4.\u96c6\u6210\u7b2c\u4e09\u65b9\u7684\u63d2\u4ef6: markdown \u7f16\u8f91\u5668, \u5bcc\u6587\u672c\u7f16\u8f91\u5668...<\/p>\n<h3>\u6ce8\u610f<\/h3>\n<ul>\n<li>npm i -S lodash @types\/lodash <\/li>\n<li>\u5728 Vue \u7ec4\u4ef6\u4e2d\u5904\u7406\u5f15\u7528\u7c7b\u578b\uff08\u5982\u5bf9\u8c61\u548c\u6570\u7ec4\uff09\u65f6\uff0c\u4f7f\u7528\u6df1\u62f7\u8d1d\u53ef\u4ee5\u907f\u514d\u610f\u5916\u7684\u526f\u4f5c\u7528\u3002\u6df1\u62f7\u8d1d\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u5bf9\u8c61\u6216\u6570\u7ec4\uff0c\u5e76\u4e14\u4e0d\u4f1a\u4e0e\u539f\u59cb\u6570\u636e\u5171\u4eab\u5f15\u7528\uff0c\u8fd9\u6837\u53ef\u4ee5\u786e\u4fdd\u6570\u636e\u7684\u72ec\u7acb\u6027\u3002<\/li>\n<\/ul>\n<h2>\u8868\u683c\u7ec4\u4ef6<\/h2>\n<h2>\u65e5\u5386\u7ec4\u4ef6 fullcalendar<\/h2>\n","protected":false},"excerpt":{"rendered":"<p>\u4ee3\u7801\u4ed3\u5e93\u5730\u5740: https:\/\/gitee.com\/lin-lin-DJ\/second-elementplus [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4869","post","type-post","status-publish","format-standard","hentry","category-1"],"_links":{"self":[{"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=\/wp\/v2\/posts\/4869","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4869"}],"version-history":[{"count":37,"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=\/wp\/v2\/posts\/4869\/revisions"}],"predecessor-version":[{"id":4922,"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=\/wp\/v2\/posts\/4869\/revisions\/4922"}],"wp:attachment":[{"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4869"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4869"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.odjbinail.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}