[{"data":1,"prerenderedAt":202},["ShallowReactive",2],{"content:\u002Fposts\u002Fvue3-snippets":3,"surround:\u002Fposts\u002Fvue3-snippets":190},{"id":4,"title":5,"body":6,"categories":164,"date":166,"description":167,"draft":168,"extension":169,"image":170,"meta":171,"navigation":173,"path":174,"permalink":170,"pinned":168,"published":170,"readingTime":175,"recommend":170,"references":170,"seo":180,"sitemap":181,"stem":182,"tags":183,"type":188,"updated":166,"__hash__":189},"content\u002Fposts\u002Fposts\u002Fvue3-snippets.md","Vue3 + Element Plus 常用代码片段",{"type":7,"value":8,"toc":156},"minimark",[9,19,24,32,38,48,53,61,65,72,76,82,87,93,98,104,109,115,119,125,131,135,142,150],[10,11,15],"alert",{"icon":12,"title":13,"type":14},"tabler:robot","AI 迁移提示","info",[16,17,18],"p",{},"本文由 AI 协助从旧站迁移，尚未完成逐篇人工审校；内容如有疏漏，将在复核后修订。",[20,21,23],"h2",{"id":22},"一el-table-添加序号","一、el-table 添加序号",[16,25,26,27,31],{},"在 ",[28,29,30],"code",{"code":30},"el-table"," 中添加从 1 开始的序号列，支持分页连续编号。",[16,33,34],{},[35,36,37],"strong",{},"template：",[39,40,46],"pre",{"className":41,"code":43,"language":44,"meta":45},[42],"language-html","\u003Cel-table-column label=\"序号\" align=\"center\" type=\"index\" :index=\"indexMethod\"\u002F>\n","html","",[28,47,43],{"__ignoreMap":45},[16,49,50],{},[35,51,52],{},"script：",[39,54,59],{"className":55,"code":57,"language":58,"meta":45},[56],"language-js","indexMethod(index) {\n  let pageNum = this.queryParams.pageNum - 1;\n  if ((pageNum !== -1 && pageNum !== 0)) {\n    return (index + 1) + (pageNum * this.queryParams.pageSize);\n  } else {\n    return (index + 1)\n  }\n},\n","js",[28,60,57],{"__ignoreMap":45},[20,62,64],{"id":63},"二el-upload-上传图片","二、el-upload 上传图片",[16,66,67,68,71],{},"使用 ",[28,69,70],{"code":70},"el-upload"," 组件实现图片上传、格式校验与回显。",[16,73,74],{},[35,75,37],{},[39,77,80],{"className":78,"code":79,"language":44,"meta":45},[42],"\u003Cel-form-item label=\"现场照片\" prop=\"urls\">\n  \u003Cel-upload\n    v-model:file-list=\"imgFileList1\"\n    :action=\"action\"\n    :headers=\"imgToken\"\n    :on-success=\"handleSuccess1\"\n    list-type=\"picture-card\"\n    :before-upload=\"beforeAvatarUpload\"\n    :on-preview=\"handlePictureCardPreview\"\n    :on-remove=\"handleRemove1\"\n  >\n    \u003Cel-icon>\n      \u003CPlus \u002F>\n    \u003C\u002Fel-icon>\n  \u003C\u002Fel-upload>\n\u003C\u002Fel-form-item>\n",[28,81,79],{"__ignoreMap":45},[16,83,84],{},[35,85,86],{},"data：",[39,88,91],{"className":89,"code":90,"language":58,"meta":45},[56],"imgFileList1: [],\nimgFileListForm: [],\npiclist1: [],\nimgToken: {\n  'Blade-Auth': 'Bearer ' + JSON.parse(localStorage.getItem('saber-token')).content\n},\nlimitImg: 10,\naction: `\u002Fapi\u002Fblade-resource\u002Foss\u002Fendpoint\u002Fput-file`,\ndisabled: false,\ndialogImageUrl: '',\ndialogVisible: false\n",[28,92,90],{"__ignoreMap":45},[16,94,95],{},[35,96,97],{},"methods：",[39,99,102],{"className":100,"code":101,"language":58,"meta":45},[56],"beforeAvatarUpload(file) {\n  const imgType = file.type === 'image\u002Fjpeg' || file.type === 'image\u002Fpng';\n  const imgSize = file.size \u002F 1024 \u002F 1024 \u003C 5;\n  if (!imgType) {\n    this.$utils.toast('图片只能是 JPG\u002FPNG 格式!', 'error');\n  }\n  if (!imgSize) {\n    this.$utils.toast('图片大小不能超过 5MB!', 'error');\n  }\n  return imgType && imgSize;\n},\n\nhandlePictureCardPreview(uploadFile) {\n  this.dialogImageUrl = uploadFile.url;\n  this.dialogVisible = true;\n},\n\nhandleRemove1(res) {\n  let index = this.imgFileListForm.findIndex(e => e === res.url);\n  this.imgFileListForm.splice(index, 1);\n},\n\nhandleSuccess1(res) {\n  if (res.code === 200) {\n    this.imgFileListForm.push(res.data.link);\n  }\n},\n",[28,103,101],{"__ignoreMap":45},[16,105,106],{},[35,107,108],{},"图片回显：",[39,110,113],{"className":111,"code":112,"language":58,"meta":45},[56],"if (this.form.images) {\n  this.form.images.forEach(value => {\n    this.imgFileList1.push({ url: value });\n  });\n}\n",[28,114,112],{"__ignoreMap":45},[20,116,118],{"id":117},"三动态添加输入框并校验","三、动态添加输入框并校验",[16,120,121,122,124],{},"利用 Vue3 响应式能力，在 ",[28,123,30],{"code":30}," 中动态添加输入框并实现实时校验。",[39,126,129],{"className":127,"code":128,"language":44,"meta":45},[42],"\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cel-form :model=\"info\" ref=\"forms\">\n      \u003Cel-table ref=\"tableRef\" :data=\"info.data\" border>\n        \u003Cel-table-column align=\"center\" property=\"name\" label=\"*姓名\">\n          \u003Ctemplate #default=\"row\">\n            \u003Cel-form-item :prop=\"'data.' + row.$index + '.name'\" :rules=\"formRules.name\">\n              \u003Cel-input placeholder=\"请输入姓名\" v-model=\"info.data[row.$index].name\" \u002F>\n            \u003C\u002Fel-form-item>\n          \u003C\u002Ftemplate>\n        \u003C\u002Fel-table-column>\n        \u003Cel-table-column align=\"center\" property=\"role\" label=\"角色\">\n          \u003Ctemplate #default=\"row\">\n            \u003Cel-form-item :prop=\"'data.' + row.$index + '.role'\" :rules=\"formRules.role\">\n              \u003Cel-input placeholder=\"请输入角色\" v-model=\"info.data[row.$index].role\" \u002F>\n            \u003C\u002Fel-form-item>\n          \u003C\u002Ftemplate>\n        \u003C\u002Fel-table-column>\n      \u003C\u002Fel-table>\n    \u003C\u002Fel-form>\n    \u003Cel-button type=\"primary\" @click=\"submitForm()\">Submit\u003C\u002Fel-button>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup lang=\"ts\">\nimport { ref, reactive } from 'vue'\nimport type { FormInstance } from 'element-plus'\n\nlet info: any = reactive({\n  data: [\n    { id: 0, name: '', role: '' },\n    { id: 1, name: '', role: '' }\n  ]\n})\n\nconst formRules = reactive({\n  name: [{ required: true, message: '请输入姓名', trigger: 'change' }],\n  role: [{ required: true, message: '请输入角色', trigger: 'change' }]\n})\n\nconst forms = ref\u003CFormInstance>()\nconst submitForm = async () => {\n  if (!forms) return\n  return await forms.value?.validate((valid: any) => {\n    if (valid) {\n      console.log('submit!')\n    } else {\n      console.log('error submit!')\n      return false\n    }\n  })\n}\n\u003C\u002Fscript>\n",[28,130,128],{"__ignoreMap":45},[20,132,134],{"id":133},"四flvjs-播放-flv-视频流","四、flv.js 播放 FLV 视频流",[16,136,137,138,141],{},"在 Vue3 中使用 ",[28,139,140],{"code":140},"flv.js"," 播放 HTTP-FLV 在线视频流。",[39,143,148],{"className":144,"code":146,"language":147,"meta":45},[145],"language-bash","npm install vue flv.js --save\n","bash",[28,149,146],{"__ignoreMap":45},[39,151,154],{"className":152,"code":153,"language":44,"meta":45},[42],"\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cvideo ref=\"videoPlayer\" controls width=\"640\" height=\"360\">\u003C\u002Fvideo>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport flvjs from 'flv.js';\n\nexport default {\n  data() {\n    return {\n      flvPlayer: null,\n      videoSource: 'http:\u002F\u002Fexample.com\u002Flive\u002Fstream.flv'\n    };\n  },\n  mounted() {\n    this.initFlvPlayer();\n  },\n  beforeDestroy() {\n    this.destroyFlvPlayer();\n  },\n  methods: {\n    initFlvPlayer() {\n      if (flvjs.isSupported()) {\n        const videoPlayer = this.$refs.videoPlayer;\n        const flvPlayer = flvjs.createPlayer({\n          type: 'flv',\n          url: this.videoSource\n        });\n        flvPlayer.attachMediaElement(videoPlayer);\n        flvPlayer.load();\n        flvPlayer.play();\n        this.flvPlayer = flvPlayer;\n      } else {\n        console.error('FLV.js is not supported in this browser.');\n      }\n    },\n    destroyFlvPlayer() {\n      if (this.flvPlayer) {\n        this.flvPlayer.destroy();\n      }\n    }\n  }\n};\n\u003C\u002Fscript>\n",[28,155,153],{"__ignoreMap":45},{"title":45,"searchDepth":157,"depth":157,"links":158},4,[159,161,162,163],{"id":22,"depth":160,"text":23},2,{"id":63,"depth":160,"text":64},{"id":117,"depth":160,"text":118},{"id":133,"depth":160,"text":134},[165],"开发","2025-01-25","收录 Vue3 与 Element Plus 开发中的常用代码片段，包括 el-table 序号、el-upload 图片上传、动态表单校验、flv.js 视频播放等。",false,"md",null,{"slots":172},{},true,"\u002Fposts\u002Fvue3-snippets",{"text":176,"minutes":177,"time":178,"words":179},"3 min read",2.98,178800,596,{"title":5,"description":167},{"loc":174},"posts\u002Fposts\u002Fvue3-snippets",[184,185,30,70,186,187],"Vue3","Element Plus","el-form","FLV","tech","-9WcKKTwwHnCGOtWX2rl2gflK5931Ko7ULrchK5ognI",[191,197],{"title":192,"path":193,"stem":194,"date":195,"type":196,"children":-1},"2023的某一天","\u002Fposts\u002Fgugugaga","posts\u002Fposts\u002Fgugugaga","2025-01-01","story",{"title":198,"path":199,"stem":200,"date":201,"type":188,"children":-1},"Chrome硬件加速功能开启与关闭","\u002Fposts\u002Fchrome-hardware-acceleration","posts\u002Fposts\u002Fchrome-hardware-acceleration","2025-03-31 10:07:47",1788712226284]