关于vue.js:轻快图片管理系统-安装部署教程

<article class=“article fmt article-content”><p></p><h2>在线体验</h2><p><strong>如果你感觉我的项目不错,还望动动你的手指给点点star,让更多人看到优良的我的项目!!!</strong></p><p>为了便于大家在线体验,本零碎提供了演示地址,能够通过上面的演示地址和账号进行登录体验零碎性能。<br/><strong>演示地址</strong>: http://v2.picture.itchenliang.club/#/<br/><strong>演示账号:</strong></p><pre><code class=“yaml”>账号: guest@163.com明码: 000000</code></pre><p><strong>代码仓库地址:</strong> <br/>如果你感觉我的项目不错,还望动动你的手指给点点star,让更多人看到优良的我的项目!!!</p><ul><li>Github: https://github.com/ischenliang/quickly-picture-bed</li><li>Gitee: https://gitee.com/itchenliang/quickly-picture-bed</li></ul><h2>装置部署教程</h2><p>本零碎提供了多种装置部署的形式,能够依据须要抉择一种形式装置。</p><h3>形式一: docker-compose形式</h3><p>为了便于部署,这里提供了docker-compose一键部署前端和服务端的形式。</p><ol><li><p>初始化数据库: 思考到大多数人曾经装置了数据库,这里就没有将数据库的装置和配置集成到docker装置部署中<br/>零碎提供默认初始化数据库sql文件(<code>server/sql/init.sql</code>),而后在navicat或者其余工具中执行该sql文件,同时该sql文件中默认提供了一个管理员账号,不便用户首次应用时登录。</p><pre><code class=“yaml”>管理员账号: admin@163.com管理员明码: 000000</code></pre></li><li><p>数据库连贯配置: 批改<code>server/.env</code>文件中的数据库配置</p><pre><code class=“js”># mysql用户名,默认是rootDB_USERNAME=root# mysql明码DB_PASSWORD=xxxx# 数据库ip,不要应用localhost和127.0.0.1DB_HOST=xxx.xxx.xxx.xxx# 数据库端口,默认3306DB_PORT=3306# 数据库DB_DATABASE=picture-bed# 程序占用端口APP_PORT=4000# npm镜像源仓库,开端不要加斜杆/,常见的是npm官网镜像源,淘宝镜像源# unpkg: https://unpkg.com/@itchenliang/picture-rollup-mdnice-plugin@1.0.2/dist/index.umd.js# 淘宝: https://registry.npmmirror.com/@itchenliang/picture-rollup-oss-plugin/1.0.12/files/dist/index.jsNPM_REGISTRY=https://registry.npmmirror.com</code></pre></li><li><p>执行构建部署命令: 在命令行终端执行docker-compose的一键部署命令<br/>在操作该步骤前须要将我的项目拷贝到服务器上,而后关上命令行终端,进入到我的项目根目录下</p><pre><code class=“bash”>docker compose up -d</code></pre><p>部署实现后会呈现如下图所示后果:<br/></p></li><li>拜访零碎<br/>而后就能够通过<code>http://youip:port</code>间接拜访到零碎了。<br/>留神:</li><li>本地存储桶里的图片位于<code>server</code>部署目录下的<code>public</code>目录下,若须要重新部署时还请提前将其文件拷贝备份。</li><li>并且这里的后端接口是采纳的<code>nginx</code>的代理形式来配置,同时也应用了自定义网络的形式来实现间接通过容器名拜访到部署的<code>server</code>利用。</li></ol><h3>形式二: docker打包部署形式</h3><p>当然咱们也能够在本地构建docker镜像来部署。<br/>留神: 请务必确保严格依照下列的步骤执行,否则会呈现问题,其起因在于<code>client</code>和<code>server</code>利用都依赖了<code>pic-net</code>自定义网络,并且<code>client</code>利用中的<code>nginx.conf</code>配置文件中也配置了接口代理,其代理形式是采纳容器名来拜访。</p><ol><li><p><strong>创立自定义网络</strong>: 为了可能便于快捷拜访到接口地址,须要应用自定义网络的形式来拜访server利用</p><pre><code class=“bash”>docker network create pic-net</code></pre></li><li><p><strong>部署server</strong>: 构建server镜像并创立picServerV2容器</p><pre><code class=“bash”># 进入到server目录cd server# 构建镜像docker build -t pic-server .# 启动并创立容器docker run -d –name picServerV2 -p 4000:4000 –network pic-net pic-server</code></pre><p>部署胜利后拜访: <code>http://yourip:4000</code>拜访后果如下<br/></p></li><li><p><strong>部署client</strong>: 构建client镜像并创立picClientV2容器</p><ul><li>1、确保client/public/global.config.js中的window.uploader_ip = ‘‘为空</li><li>2、打包client单页面利用</li></ul><pre><code class=“bash”>cd clientnpm installnpm run build</code></pre><ul><li>3、执行构建并不输入</li></ul><pre><code class=“bash”># 进入到client目录cd client# 构建镜像docker build -t pic-client .# 启动并创立容器docker run -d –name picClientV2 -p 80:80 –network pic-net pic-client</code></pre><p>部署胜利后能够通过<code>http://yourip:80</code>拜访,如果呈现如下输入后果示意client部署胜利<br/></p><h3>形式三: docker拉取近程镜像部署</h3><p>为了便于部署,本零碎将构建的<code>itchenliang/pic-server-v2</code>和<code>itchenliang/pic-client-v2</code>镜像推送到了DockerHub,能够间接拉取近程镜像来部署。</p></li><li><p><strong>创立自定义网络</strong>: 为了可能便于快捷拜访到接口地址,须要应用自定义网络的形式来拜访server利用</p><pre><code class=“bash”>docker network create pic-net</code></pre></li><li><p><strong>部署server</strong>:</p><ul><li>1、在服务器上新建<code>.env</code>文件来配置数据库</li></ul><pre><code class=“js”># mysql用户名,默认是rootDB_USERNAME=xxx# mysql明码DB_PASSWORD=xxx# 数据库ip,不要应用localhost和127.0.0.1DB_HOST=xxx.xxx.xxx.xxx# 数据库端口,默认3306DB_PORT=3306# 数据库DB_DATABASE=xxx# 程序占用端口APP_PORT=4000# npm镜像源仓库,开端不要加斜杆/,常见的是npm官网镜像源,淘宝镜像源# unpkg: https://unpkg.com/@itchenliang/picture-rollup-mdnice-plugin@1.0.2/dist/index.umd.js# 淘宝: https://registry.npmmirror.com/@itchenliang/picture-rollup-oss-plugin/1.0.12/files/dist/index.jsNPM_REGISTRY=https://registry.npmmirror.com</code></pre><ul><li>2、执行构建命令</li></ul><pre><code class=“bash”>docker run -d –name picServerV2 -p 4000:4000 –env-file .env –network pic-net itchenliang/pic-server-v2</code></pre><p>确保下面命令中创立的容器名称为<code>picServerV2</code>,因为<code>client</code>会通过该名称来拜访后盾接口。</p></li><li><p><strong>部署client</strong>: 执行如下构建命令</p><pre><code class=“bash”>docker run -d –name picClientV2 -p 80:80 –network pic-net itchenliang/pic-client-v2</code></pre></li></ol><h3>形式四: 从零开始装置</h3><p>该形式次要针对于须要进行二次开发或者在本地简略测试性能的用户,以及一些没有应用docker的用户。</p><ol><li><strong>装置node</strong>:返回node官网下载node.exe并装置或者应用nrm进行装置,并且确保装置的node版本为: <code>18.16.0</code></li><li><strong>装置git</strong>:返回Git官网下载git并装置,此步可疏忽。</li><li><strong>克隆代码</strong>:应用<code>git clone</code>命令将代码克隆到本地,或者间接下载压缩包到本地并解压。</li><li><p><strong>执行sql文件</strong>:零碎提供默认初始化数据库sql文件,进入到<code>server/sql</code>目录下找到<code>init.sql</code>,在navicat或者其余工具中执行该sql文件。该sql文件中默认提供了一个管理员账号,不便用户首次应用时登录。</p><pre><code class=“js”>管理员账号: admin@163.com管理员明码: 000000</code></pre></li><li><p><strong>批改数据库连贯</strong>:批改<code>server/.env</code>文件,将数据库连贯服务批改成本人的数据库ip、用户名、明码等。<br/>如果是本地调试则只须要批改<code>.env.dev</code>文件。</p><pre><code class=“js”># mysql用户名,默认是rootDB_USERNAME=xxx# mysql明码DB_PASSWORD=xxx# 数据库ip,不要应用localhost和127.0.0.1DB_HOST=xxx.xxx.xxx.xxx# 数据库端口,默认3306DB_PORT=3306# 数据库DB_DATABASE=xxx# 程序占用端口APP_PORT=4000# npm镜像源仓库,开端不要加斜杆/,常见的是npm官网镜像源,淘宝镜像源# unpkg: https://unpkg.com/@itchenliang/picture-rollup-mdnice-plugin@1.0.2/dist/index.umd.js# 淘宝: https://registry.npmmirror.com/@itchenliang/picture-rollup-oss-plugin/1.0.12/files/dist/index.jsNPM_REGISTRY=https://registry.npmmirror.com</code></pre></li><li><p><strong>依赖装置</strong>:装置server和client依赖</p><pre><code class=“bash”># 前端依赖装置cd clientnpm install# 服务端依赖装置cd servernpm install</code></pre></li><li><strong>我的项目启动</strong>:别离启动client和server端</li><li><p>服务端启动</p><pre><code class=“bash”># 服务端启动cd servernpm run dev</code></pre><p>启动胜利后会呈现如下图所示后果: <br/></p></li></ol><ul><li><p>前端启动: 在运行前端代码前还须要做一步操作,关上<code>client/public/global.config.js</code>文件,批改<code>window.uploader_ip</code>,将上面的<code>http://locahost:3002</code>改成你本地启动的<code>server</code>的ip和端口(如果是部署上线时需进行此步,本地调试可跳过)。</p><pre><code class=“js”>window.uploader_ip = ‘http://localhost:3002’</code></pre><pre><code class=“bash”># 前端我的项目启动cd clientnpm run dev</code></pre><p>启动胜利后会呈现如下图所示后果: <br/></p></li><li><strong>打包部署</strong>:打包部署</li><li><p>服务端打包部署:咱们服务端采纳的是nestjs + typescript开发的,须要打包成js文件</p><pre><code class=“bash”># 服务端构建cd servernpm run build# 将server/dist目录下的所有文件拷贝服务器上,而后执行启动命令node main.js</code></pre></li><li><p>前端打包部署:咱们前端采纳的是vite + vue3 + typescript开发单页面利用,须要打包,并将打包后的dist后果目录下的所有文件拷贝到web服务器上。</p><pre><code class=“bash”># 前端构建cd clientnpm run build</code></pre></li></ul><h3>形式五: 宝塔面板部署</h3><p>待欠缺….</p></article> ...

March 5, 2024 · 1 min · jiezi

关于vue.js:vue组件的生命周期

<article class=“article fmt article-content”><h2>vue2生命周期</h2><p>vue2中生命周期钩子函数大抵分为三个阶段,8个生命周期钩子函数。别离是:<br/>vue2和vue3钩子函数 — 选项式API</p><ol><li>beforeCreate(){} — 创立前,还无法访问组件中的数据</li><li>created(){} — 创立后,能够拜访组件中的数据</li><li>beforeMount(){} — 挂载前,跟created一样能够拜访组件中的数据,但还不能拜访渲染好的dom元素</li><li>mounted(){} — 挂载后,数据和渲染好的dom元素都能够拜访了</li><li>beforeUpdate(){} — 更新前,能够拜访要更新的数据,但无法访问更新后的dom节点</li><li>updated(){} — 更新后,能够拜访更新后的dom节点了</li><li>beforeDestroy(){} — 销毁前,还能够拜访组件中的数据和dom构造</li><li>destroyed(){} — 销毁后,拜访不到组件中的数据和dom构造了。</li></ol><p>三个阶段别离是:</p><ul><li><p>创立阶段</p><ul><li>初始化vue实例,生命周期还没有开始</li><li>初始化外部的一些事件(开始监听数据),这时生命周期开始</li><li>注入数据,开始劫持(这个时候vue实例下面就有了响应式数据)</li><li><p>判断是否有el选项,没有的话,就会始终期待vue实例调用<code>$mounte</code>办法传入el</p><ul><li>如果有,就将<code>template</code>提供的构造编译在渲染函数中</li><li>如果没有:就编译<code>el</code>的<code>outerHTML</code>,让它成为渲染模版</li></ul></li><li>给vue实例创立$el属性,值是编译好的模版构造,并应用编译好的模版构造,将传入的el内容替换掉(就是将编译好的内容,显示在页面中)</li></ul></li><li><p>更新阶段</p><ul><li>vue始终期待数据的更新</li><li>数据更新后,从新渲染页面(异步行为–等所有同步执行实现后再执行异步)</li></ul></li><li><p>销毁节点</p><ul><li>vue始终期待调用 <code>$destroy</code> 销毁办法</li><li>调用办法后就销毁实例,当前再改数据,页面也不会响应了。</li></ul><p></p></li></ul><h2>vue3生命周期</h2><p>vue3钩子函数 — 组合式API</p><ol><li>onBeforeMounte(()=>{}) — 挂载前,跟created一样,能够拜访组件中的数据,然而还不能够拜访渲染好的dom节点</li><li>onMounted(()=>{}) — 挂载后,能够拜访数据 和 渲染好的dem节点了</li><li>onBeforeUpdate(()=>{}) — 更新前,能够拜访要更新的数据(更新前的数据),还不能拜访更新后的数据和节点</li><li>onUpdated(()=>{}) — 更新后,更新后的Dom节点能够拜访了</li><li>onBeforeUnmounte(()=>{}) — 销毁前,还能够拜访数据 和 dom构造</li><li>onUnmounted(()=>{}) — 销毁后,拜访不到数据和dom节点了<br/>ps: 因为<code>setup</code>语法,一开始就曾经能够拜访到响应式数据了,所有没有创立前(beforeCreate) 和 创立后(created)的钩子函数了。</li></ol><p>动静组件没有销毁前后的两个生命周期钩子函数,然而会多出两个显示和暗藏的生命周期钩子函数。</p><ul><li>onActivated(()=>{}) — 显示,组件显示时触发</li><li>onDeactivated(()=>{}) — 暗藏,组件暗藏时触发</li></ul><p>vue3的生命周期 和 vue2的生命周期执行程序是一样。只不过没有了<code>beforeCreate</code> 和 <code>created</code> 这两个生命周期,它们被 <code>setup</code> 替换掉了,就是说 <code>setup</code> 等于 <code>beforeCreat</code> 和 <code>created</code>。<br/>在 <code>setup</code> 中 间接就能够定义响应式数据。</p><p></p><h2>父子组件阶段生命周期钩子函数执行程序</h2><h3>创立阶段</h3><ol><li>父组件创立前</li><li>父组件创立后</li><li>父组件挂载前</li><li>子组件创立前</li><li>子组件创立后</li><li>子组件挂载前</li><li>子组件挂载后</li><li>父组件挂载后</li></ol><h3>更新阶段</h3><ol><li>父组件更新前</li><li>子组件更新前</li><li>子组件更新后</li><li>父组件更新后</li></ol><h3>销毁阶段</h3><ol><li>父组件销毁前</li><li>子组件销毁前</li><li>子组件销毁后</li><li>父组件销毁后</li></ol></article>

March 5, 2024 · 1 min · jiezi

关于vue.js:来看写个丝滑的播放器进度条VueUse能给省多少事

要写一个简略的音频或者视频播放器的进度条还是要思考不少货色的,看看借助于 VueUse 来实现能有多省事~ 首先确定播放器进度条的性能有播放暂停按钮进度条能够追随播放丝滑更新有以后播放工夫和总工夫能够依据播放更新以后工夫能够点击进度条的某一处跳转到指定处进行播放咱们先简略梳理这四个性能,咱们的重心是在这个进度条的渲染和交互上。 嫌子弹飞慢的,间接看最初上任鹅城那段(doge) 依据既定的性能来确定咱们的构造要有风️,要有肉要有一个能够蕴含理论进度条的壳子(风),再来一个另外一种色彩理论进度条的条子(肉),前面再加一个小圆点示意以后播放到哪了。 <div class="process-bar" rounded-8px h-8px flex-1 bg-gray-200 cursor-pointer flex items-center> <div h-full bg-purple-400 rounded-8px :style="{ width: `${playTime / duration * 100}%` }" /> <div w-10px h-10px rounded-full bg-purple-500 ml--6px shadow hover:w-12px hover:h-12px /></div>要有火锅,要有雾这里再来一个 audio 的资源(火锅),而后来个封面(雾) <audio ref="audioRef" src="https://rust-fe-shared.pages.dev/The%20Sun%20Also%20Rises.mp3" @play="onAudioPlay" @loadedmetadata="onLoadedmetadata" @pause="onAudioPause" @ended="onAudioEnded" /><div class="preview-audio-cover" :class="`${playing ? 'motion-safe:animate-spin' : ''}`"> <img w-full src="https://rust-fe-shared.pages.dev/record.png" alt=""> <img class="audio-cover" src="https://rust-fe-shared.pages.dev/cover.webp" alt=""></div>要有美女,要有驴要有一个播放暂停按钮吧(美女),要展现以后工夫和总工夫吧(驴) 正经备注,须要用到图标库:@iconify-json/carbon 配合 UnoCSS 来应用。<div class="play-btn" @click="playOrPause"> <div v-if="playing" m-auto i-carbon:pause-filled /> <div v-else m-auto i-carbon:play-filled-alt /></div><p tabular-nums> {{ fmtTime(playTime) }} / {{ fmtTime(duration) }}</p>起来起来,一起吃一起唱让咱们开始这些实现性能吧 ...

March 3, 2024 · 3 min · jiezi

关于vue.js:vue3组件常用的通信方式父传子子传父父直接获取子pinia

<article class=“article fmt article-content”><p>vue3组件罕用的通信形式有很多,<strong>父传子</strong>*, <strong>子传父</strong>,<strong>父间接获取子ref</strong>,<strong>pinia</strong>,pinia在vue3中替换了vuex,更简洁,方便使用操作。<strong>EventBus公交车</strong>,<strong>provide + inject</strong>等。</p><h3>一、父传子(props)</h3><p>父传子是通过父组件自定义标签增加属性,并传递数据给子组件,子组件接管通过 引入vue插件 解构 <code>defineProps</code>,调用并创立 <code>props</code>,同时指定要接管的数据名称。</p><pre><code> const props = defineProps([‘传递的数据名称’]) </code></pre><p>案例:</p><pre><code>父组件 在views文件夹中创立文件Home.vue<script setup lang=“ts”>// 引入vue插件import { ref } from “vue”// 引入子组件 import Son from “../components/Son.vue”// 定义传递给子组件的数据const title = ref(“我是子组件”)</script><template> <h1>父组件</h1> <!– 应用子组件 –> <Son :title=“title”></Son></template>子组件 在components文件夹中创立Son.vue<script setup lang=“ts”>// 引入vue 解构 须要的办法import { defineProps } from “vue”// 调用defineProps办法并获取父组件传递的数据// const props = defineProps([’title’])const { title } = defineProps([’title’]) // 能够简写 解构</script><template> <!– 渲染父组件传递的数据 –> <h1>{{ title }}</h1></template>路由:import { createRouter, createWebHistory } from ‘vue-router’const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: ‘/’, redirect: “/home” }, { path: ‘/home’, name: ‘about’, component: () => import(’../views/Home.vue’) } ]})export default router</code></pre><p>效果图:<br/></p><h3>二、子传父(emit)自定义事件</h3><p>子传父通过 父组件给子组件标签绑定自定义事件,将事件函数定义在父组件中,子组件中通过从 vue 中解构 <code>defineEmits</code>,调用并创立emit,同时接管父组件给绑定的事件。调用 <code>emit</code>触发父组件给绑定的事件,并传递数据,最初父组件在事件函数中通过参数接管子组件传递的数据。<br/>案例:<br/><strong>父组件</strong></p><pre><code><script setup lang=“ts”>// 引入vue插件import { ref } from “vue”// 引入子组件import Son from “../components/Son.vue”// 定义传递给子组件的数据const title = ref(“我是子组件”)const msg = ref(’’)// 定义事件函数const handleAdd = (item: any) => { msg.value += item}</script><template> <h1>父组件</h1> <!– 应用子组件 title: 传递给子组件的数据 handleAdd:自定义事件 –> <Son :title=“title” @handleAdd=“handleAdd”></Son> <h3>{{ msg }}</h3></template></code></pre><p></p><p><strong>子组件</strong></p><pre><code><script setup lang=“ts”>// 引入vue 解构 须要的办法import { defineProps, defineEmits } from “vue”// 调用defineProps办法并获取父组件传递的数据// const props = defineProps([’title’])const { title } = defineProps([’title’]) // 能够简写 解构// 调用defineEmits办法 并承受父组件给绑定的事件const emit = defineEmits([‘handleAdd’])const handleTitle = () => { emit(“handleAdd”, ‘我是子组件传递的数据’)}</script><template> <!– 渲染父组件传递的数据 –> <h1 @click=“handleTitle”>{{ title }}</h1></template></code></pre><p><br/>效果图:<br/></p><h3>三、ref()</h3><p>ref()办法 从vue中解构出 <code>ref</code>,而后父组件给dome标签或者子组件标签,增加ref属性,值是曾经定义好的<code>ref</code>空数据的变量名称。<br/>子组件从vue中解构出<code>defineExpose</code>,调用并想外裸露你想要获取的数据/办法<br/>父组件通过从vue中解构生命周期<code>onMounted</code>,调用<code>onMounted</code>生命周期在外面 通过调用ref的数据<code>value</code>获取到 dome标签 或 子组件实例对象。<br/>案例:<br/><strong>父组件</strong></p><pre><code><script setup lang=“ts”>// 引入vue插件import { ref, onMounted } from “vue”// 引入子组件import Ref from “../components/Ref.vue”;// 定义refconst myref = ref()onMounted(() => { console.log(myref.value, ‘’); // ref组件定义的数据 console.log(myref.value.message); // 调用 ref组件中暴露出的办法 myref.value.handleAdd()})</script><template> <h1>父组件</h1> <!– 定义ref –> <Ref ref=“myref”></Ref></template></code></pre><p></p><p><strong>子组件</strong></p><pre><code><script setup lang=“ts”>// 引入vueimport { defineExpose, ref } from “vue”// 定义数据const message = ref(“我是Ref子组件中的数据”)// 定义方法const handleAdd = () => { console.log(‘我是Ref子组件中的办法’);}// 通过 defineExpose 将数据办法裸露进来defineExpose({ message, handleAdd})</script><template> 我是ref办法</template></code></pre><p></p><p>效果图:<br/></p><h3>四、pinia</h3><p>Vuex 和 Pinia 是 Vue 3 中的全局状态管理工具,应用这两个工具能够轻松实现组件通信。</p><p>它们都是全局的、所有组件都能够拜访的、存储数据和办法,用来治理组件中的共享状态的仓库。并且可能在整个组件中进行拜访和批改。让咱们更无效的 组织 和 治理 整个组件的状态,使咱们更轻松的开发简单的、大型数据的前端我的项目。</p><p>同时解决了同步异步对调试工具的影响 和 代码的耦合性 还有组件之间数据通信的凌乱问题。</p><ul><li><p>应用pinia 首先咱们须要先下载安装</p><pre><code> npm install pinia</code></pre></li><li>而后须要在 <code>main.js/ts</code> 中配置<br/></li><li>创立仓库文件夹(stores),同时定义仓库文件<br/></li><li><p>仓库文件的内容</p><ul><li>导入</li><li>创立仓库</li><li>导出仓库</li></ul><pre><code>// 导入import { defineStore } from “pinia”;import { ref } from “vue”// 创立仓库const tableStore = defineStore(“table”, () => { // 定义数据 let count = ref(0) // 定义方法 const changeCount = () => { // 数量自增 count.value++; } // 返回 数据 和 办法 return { count, changeCount }})// 导出仓库export default tableStore</code></pre></li></ul></article> ...

February 27, 2024 · 2 min · jiezi

关于vue.js:vue面试

<article class=“article fmt article-content”><p>https://blog.csdn.net/kellywong/article/details/106430977</p><h4>一,js根本</h4><p>1,数据类型:<br/>JS数据类型:JS的根本类型和援用类型<br/>根本类型(单类型): String、Number、boolean、null、undefined。<br/>援用类型:object。蕴含的 Array、function、Date。</p><p>null 和 undefined 有什么区别<br/>undefined 是没有定义的,没有初始化,,null 是定义了然而为空,是不存在的对象。</p><p>判断数据类型:<br/>typeof 不能辨别数组和对象,和 null<br/>instanceof 在判断数组和Data很好用。 判断是否是数组:Array.isArray(arr)。<br/>Object.prototype.toString.call 能够判断根本类型和数组,对象</p><p>2,根本数据类型和援用数据类型区别:<br/>1,内存的调配不一样,<br/>2,参数传递不一样,根本类型数据值不会扭转;援用数据值会扭转旧对象,因为它传的值是内存援用的地址。<br/>3,复制变量时,援用数据类型值可扭转,批改新对象会扭转旧对象;因为复制是内存援用地址,还是专用一块内存。<br/>https://www.cnblogs.com/Mr-Rshare/p/11434186.html</p><p>3,闭包内存泄露解决方案,缩小内存泄露</p><p>1,定时器没有革除<br/>2,意外的应用全局变量,window 对象的数据是不会回收的<br/>3,闭包的应用,理解闭包的预期生命周期和用处<br/>4,缩小过多的console打印,只打印必要的信息进去</p><p>4,Js垃圾回收机制</p><p>垃圾回收机制:找出那些不再持续应用的变量,而后开释其占用的内存</p><p>JS 垃圾回收机制:采纳标记革除法,和援用计数</p><p>5,js面相对象的继承有哪些办法<br/>https://www.cnblogs.com/gaosirs/p/10637609.html</p><p>6,面向对象怎么实现重写,重载<br/>7,js怎么实现父办法一个参数调用一个办法,2个参数调用另外一个办法</p><p>JavaScript 常见的设计模式</p><p>有哪些设计模式:设计模式是解决某个特定场景下的解决方案</p><p>创立型模式:工厂模式, 单例模式,原型模式; 构造模式:组合模式, 代理模式。 行为模式:观察者模式,迭代器模式, 策略模式, 访问者模式,开发者模式</p><p>订阅发布者模式:是一种音讯转递的机制,他由中间人对象,订阅者,发布者组成;订阅者接管音讯,发布者公布音讯。<br/>原理:中间人对象定义一个数组,订阅办法,公布办法。订阅办法:往数组里保留回调函数;公布办法:遍历所有回调,进行调用,同时传入参数。</p><p>工厂模式:创立一个类,实现工厂办法,应用工厂办法创建对象。 工厂模式将对象的创立和实现过程拆散。</p><p>单例模式:一个类只有一个实例,只能创立单个对象,单例类只有惟一的实例。 并提供一个拜访它的全局拜访点。</p><p>原型模式:在原型上创建对象,能够节俭性能和内存空间,缩小反复代码。</p><p>观察者模式:它定义了一种一对多的关系,让多个观察者同时监听一个对象,被监听的对象状态产生扭转就会告诉所有观察者,这样就实现自动更新。</p><p>8,组件的传值</p><p>1,父传子:通过props传值, 子传父:子组件通过 父组件传递的事件newList,把值传给父组件<br/>2,通过在组件定义ref的援用,就能够拿到子组件数据和办法 来传值<br/>3,跨级传递:应用useContext来传值 ; <br/> 3.1 用 provide(povd) / inject 依赖注入,跨层级间接向子组件传递数据:provide定义一个变量,通过inject来接管。<br/> 3.2 订阅发布者模式也能够传参<br/>4,路由地址栏参数拼接也能够传参</p><p>5,Vue地方总线池也能够传参; vuex状态共享也能够传参。</p><p>9,react和vue的区别及优缺点</p><p>1,Vue的思维是响应式的,基于数据可变的。<br/>1.1 模板写法不一样,vue反对在html里写Css和js, 操作Dom不便。还有指令if, v-for,</p><pre><code> 长处: 入门容易,开源组件丰盛,框架功能完善,文档较为具体, 毛病: 插件引入不够标准,代码提醒变弱,不利于保护。</code></pre><p>2,react整体是函数式的思维,数据不可变,单向数据流。<br/>2.2 通过js来操作所有,模板写法在js里写html和css,<br/>长处: 框架功能强大,非常灵活,设计十分标准,开发理念清晰,<br/>毛病: 代码有些繁琐,抉择表达式,父子状态不同步,须要本人写回调同步状态。因为太灵便,容易导致我的项目凌乱。</p><p>10,vue中 keys 的作用是什么</p><p>Keys 是惟一标识</p><p>1,在渲染的时候,会把新dom和旧dom进行比照,如果dom统一,就会间接用旧dom,不便追踪元素,比对元素。<br/>2,应用key值能够给dom增加一个 惟一标识符,让vue强制更新dom。<br/>所以key的作用:能够晋升渲染性能,缩小元素从新渲染,还能够防止数据渲染异样。</p><p>key值在哪些地方用到过,除了v-for循环遍历的时候<br/> 1,v-for语句中应用<br/> 2,雷同父元素下的子元素能够应用key<br/> 3,利用 key 一旦更改元素就会销毁从新创立的个性,实现强制替换元素 或触发残缺的生命周期钩子<br/> 4,在从新渲染的时候更快,能够用来管制组件刷新</p><p>11,为什么虚构 dom 会进步性能(必考)</p><p>虚构 dom 相当于在 js 和实在 dom 两头加了一个缓存,利用 js 算法对dom进行比对,防止了没有必要的 dom 操作,从而进步性能。用 JavaScript 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM树,插到文档当中当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记录两棵树差别把 2 所记录的差别利用到步骤 1 所构建的真正的DOM 树上,视图就更新了。</p><h4>二,webpack</h4><p>1,loader 是什么,有什么用:loader和plugin区别<br/>是 webpack 用于在编译时解析各类文件格式,并输入来,比方:解析css-loader,sass-loader,babel-loader</p><p>Plugin 是什么:<br/>是 webpack 用于在编译过程中利用钩子进行自定义函数,实现编译过程的可控,而Plugin用在解析模板文件,压缩代码,css压缩,打包zip包</p><p>2,webpack常见性能优化</p><p>.缩小不必要的模块依赖</p><p>.缩小不必要的loader解决</p><p>.应用cache-loader进行缓存文件,缓存loader</p><p>.开启多线程打包</p><p>.代码压缩</p><p>https://blog.csdn.net/Mr_RedStar/article/details/123462435</p><p>如果拿到一个上线我的项目想要优化,从什么中央开始着手</p><p>1,首屏进入增加loading,<br/>2,html优化<br/> 删除不必要的正文,应用语义化标签,缩小dom的层级,缩小重排。<br/>3,javaScript优化</p><pre><code> 将javaScript脚本放到页面底部,正当的ajax申请,应用懒加载,代码构造优化,</code></pre><p>4,css优化</p><pre><code> css文件压缩,css层级嵌套不要太多,删除无用的css,异步加载非首屏css </code></pre><p>5,图片优化</p><pre><code> 图片压缩,小图片合成雪碧图 缩小http申请,采纳svg和base64类型图片</code></pre><p>6,webpack构建优化</p><pre><code> 缩小反复和不须要的依赖,缩小不必要的loader解决,模块懒加载,配置压缩css和js代码。</code></pre><p>3,webpage配置什么把es6的代码转为es5</p><p>装置babel-loader就能够</p><p>4,css工程化</p><p>CSS工程化:将代码层次化,容易看出嵌套关系;精简代码,提高效率。</p><p>个别应用SASS和LESS来实现工程化</p><p>SASS:个别应用变量,嵌套,混合,继承等性能</p><h4>三,vue</h4><p>1,生命周期<br/>vue中的create(克rt)和mount的区别<br/>create是初始化阶段,此阶段是数据观测,还没有生成dom,所以无奈获取操作dom<br/>mount挂载实在dom,能够操作dom节点</p><p>1,keep-alive作用<br/>keep-alive能够使组件活着保留状态,防止从新渲染。一旦应用KeepAlive时mouted等生命周期钩子只会第一次进入时调用,当前就不会调用。缩小反复发送申请的</p><p>2,vue之mixin的作用是什么,原理,有什么优缺点。<br/> vue的mixin(混入)就是混入代码<br/> vue之mixin定义:非常简单,它就是一个对象而已,对象蕴含vue组件常见配置,如data,created,mounted。<br/>vue的mixins(混入)是一种将可复用代码和逻辑提取进去,哪个组件须要用时,注入到组件中的形式。通过mixins,能够将一些常见的性能和逻辑抽离进去,不便在多个组件中重复使用。<br/>作用:防止代码反复,实现可复用性能;保护不便,只须要批改一个中央。<br/>长处:进步代码复用,无需传递状态,保护不便。<br/>毛病:存在同名变量和办法,会被组件里变量笼罩。 命名抵触,滥用前期很难保护,不好追溯原</p><p>代替计划: 很多时候要思考用公共组件还是用mixin(混入)</p><p>3,vue插槽是什么,slot插糟有什么作用<br/>插槽就是在组件标签两头, 预留了一个地位,书写dom内容,利用插槽把里面写的dom传到组件里, 并将组件里的内容替换掉 传入的dom<br/>插槽有默认插槽, 和具名插槽;具名插槽:依据插槽名来插入内容。</p><p>作用:是为了不便给子组件传入dom。如果一个场景:有5个页面,这5个页面只有一个区域的内容不一样,你会怎么去写这个5个页面,复制粘贴是一种,在vue中插槽(slot)是更好的做法。</p><p>3.1,react组合,实现vue插槽性能<br/>通过一个办法传入不同的参数,调用这个办法,而后把子组件当参数传进去,传入不同的子组件就显示不同html</p><p>4,本人实现过hooks吗<br/> 自定义 Hook 是一个函数,其名称以 “use” 结尾,封装一些逻辑,能够复用缩小代码冗余,函数外部能够调用其余的 Hook。<br/>6.1,用于解决字符串(url); 数据格式化(日期); 单位转换</p><p>5,vue 数据双向绑定<br/>https://blog.csdn.net/weixin_45410795/article/details/117636493</p><p>1.1,简略的双向绑定:定义一个数据状态值,绑定到value属性上,通过定义一个事件,如input事件,来管制扭转这个数据值,当咱们在input框里输出值,它的data外面的值就会变成什么</p><p>相当于应用v-model,等价于咱们去绑定了:value 和 @input。</p><p>1.2,往深的说:当创立一个Vue实例时,将遍历所有 DOM 对象,并为每个数据属性增加了 get 和 set。 get 和 set 容许 Vue 察看数据的更改并触发更新。</p><p>双向数据绑定原理<br/>第一步视图变动更新数据,用户通过input输入框触发数据的变动。<br/>第二步数据变动更新视图,那么问题来了:data数据变动时怎么去更新相干的视图?<br/>vue采纳数据劫持的形式来做数据绑定的,通过Object. Define(滴凡)Property(怕破挺)()来劫持属性给属性设置set,get,在set和get中增加一些更新数据的办法,就可能实现数据更新到视图。<br/>还须要几个操作:<br/>须要一个监听器observer, 须要一个订阅器dep, 须要一个订阅者watcher</p><p>v-model数据 打印的数据跟页面显示不同步,这个怎么解决<br/>当咱们在vue中用v-model绑定一个变量时,实际上基于组件外部的value和input事件主动创立了一个双向绑定。<br/>然而vue并不会为组件外部对象或数组主动创立响应式属性,这导致批改一般对象和数组,并不会触发v-model绑定的数据,<br/>这时须要手动通知vue某个属性批改了, vue提供了$set办法来解决</p><p>6,如何实现单页面利用,实现vue路由<br/>路由有两种模式,hash哈希模式,history(histr)模式<br/>通常url地址前面有哈希值,当哈希值扭转时,利用浏览器的onhashchange()事件监听,来管制组件的显示和暗藏。就能够实现路由不刷新跳转</p><p>7,vue路由守卫<br/>vue-router提供的导航守卫,次要对路由跳转进行监测,管制他跳转或勾销。次要作用是:如果某个页面没有受权就不能进入,就要重定向到登入页面<br/>router.beforeEach((to, from) =>{next }) 有to, from, next() 3个参数</p><p>8,vue路由实现的原理<br/>路由是实现页面跳转,页面的显示和暗藏性能。<br/>在vue中利用defineProperty数据劫持在原型上初始化一些getter属性,蕴含router信息。<br/>当router触发setter办法时,就会告诉组件。<br/>在初始化的时候,会判断要挂载路由的模式,是hash还是history,再调用hashchange办法,更新路由从新渲染。</p><p>9,路由懒加载<br/>作用:是首屏加载没必要加载整个我的项目文件,路由懒加载就能够实现只加载,以后页面所须要的组件和代码;把路由宰割开来。<br/>只须要把导入组件的形式,改为动静导入</p><p>10,vue-router的原理<br/>1.监听url的变动, 2,匹配路由规定, 3,渲染组件。</p><p>vue-router还提供 $router.push()和 $router.replace()跳转和替换</p><h4>四,</h4><p>1,什么叫事件冒泡,事件捕捉<br/>vue-devtools利用</p><p>2,vue合成事件和原生事件有什么区别<br/>合成事件机制:React并不是将click事件间接绑定在dom下面,而是采纳事件冒泡的模式冒泡到document下面,<br/>在document处监听所有事件,将事件内容封装并交由处理函数运行。这样缩小了内存的耗费</p><p>3,vue diff算法, vue diff和react diff有什么不同<br/> 用 Js 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM 树,插到文档当中<br/>当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟(diff),记录两棵树差别<br/>把差别的局部构建的真正的DOM树上(patch),视图就更新了<br/> diff算法是通过对同层的树节点进行比拟,这样复杂度就很低</p><p>5,vue2.0和 vue3.0的区别<br/>1.性能比2.x快1.2~2倍,在vue3中,diff算法的优化,减少了动态标记,缩小了虚构dom比对<br/>重构了响应零碎:应用代理替换object.defineProperty,能够间接监听数组类型的数据变动<br/>2,按需编译,体积比Vue2.x更小<br/>3,组合API,将逻辑雷同的代码放在一起,不便反复利用<br/>4,更好的TS反对,vue2不适宜应用ts<br/>5,更先进的组件<br/>vue3.0:https://juejin.cn/post/6955129410705948702</p><p>7,vue自定义指令及原理<br/>vue.directive 定义一个指令,vue自定义指令相当于本人封装的一个函数办法,不便在其余中央调用</p><p>9,判断对象是否为空</p><pre><code>var arr = Object.keys(data);alert(arr.length == 0); //true 为空, false 不为空var b = (JSON.stringify(data) == “{}”);alert(b); //true 为空, false 不为空 10, 对象的遍历objet.key().map()for(let key in obj){ console.log(key, obj[key])} </code></pre><p>for in 和 for of的区别</p><p>1.1,for in用来遍历对象,在遍历对象时还会遍历原型上的属性。会导致性能降落。遍历对象还能够用:Object.keys()<br/>1.2,for of 用来遍历有序构造数据:数组,字符串,dom列表,map, set。不能遍历对象。<br/>1.3,for in能够遍历数组,然而失去是下标,并不是数组元素。</p><pre><code>const obj1 = {name:‘joy’,sex:‘male’}for (let key in obj1) { if(obj1.hasOwnproperty(key)) { console.log(key, obj1[key])}}const arr = [1,2,3] for(let value of arr) { console.log(value)}</code></pre><p>ES6的高阶函数: 高阶函数,如 map ,reduce ,filter</p><pre><code>//新的写法: filter / map / reduce // filter中的回调函数有一个要求:必须返回一个bollean值 // true : 当返回true时,函数外部会主动将这次回调的n退出到新的数组中 // false: 当返回fasle时,函数外部会过滤掉这次的n。 let new_nums = nums.filter(function (n) { return n < 100 }) // map 映射函数 let new_nums1 = new_nums.map(function (n) { return n * 3 }) // reduce(func(上一次后果 初始值为默认值,数组的n),默认值=0) 对数组中所有的内容进行汇总。 let new_nums2 = new_nums1.reduce(function (prev,n){ return prev + n },0)//或者能够写成 let new_writeNums = nums.filter(function (n){return n < 100}).map(function(n){return n * 3}).reduce(function(prev,n){return prev + n},0)</code></pre><p>11,BFC是什么,有什么用,如何实现<br/>BFC直译为"块级格式化上下文"。它是一个独立的渲染区域,<br/>作用:革除浮动,实现自适应布局</p><p>12,如何实现12px以下字体<br/>应用transform: scale(.95) 应用图片<br/>13,如何优化scale含糊<br/> 给缩放代码加上transform:translate3d(0,0,0)</p><p>因为不够怯懦错失过什么<br/>https://www.douban.com/gallery/topic/308797/?from=discussing&…<br/>生存中的“I”时刻<br/>https://www.douban.com/gallery/topic/346273/?from=discussing&…<br/>你如何维持情绪稳定<br/>https://www.douban.com/gallery/topic/306654/?from=discussing&…<br/>https://www.douban.com/gallery/topic/312948/?from=discussing&…</p><p>放弃高效的学习办法</p><p>https://www.cnblogs.com/xiao2shiqi/p/15401920.html</p></article> ...

February 27, 2024 · 2 min · jiezi

关于vue.js:掌握-Vue3-中的-setup-函数

Vue.js 经验了从 Vue 2 到 Vue 3 的重大改革,带来了许多引人注目的新个性和性能优化。其中,setup函数无疑是最引人瞩目的新星之一。 一、概览setup函数是 Vue 3 引入的一个新的组件选项,作为组合式 API 核心,它容许开发者在一个空间内应用所有的 composition API。这个函数将在组件创立之前执行,这样就为你提供了定义响应式变量、计算属性、函数等的机会,从而更好地组织和复用代码。 import { ref, computed } from 'vue'export default { setup() { const count = ref(0) const doubleCount = computed(() => count.value * 2) function increment() { count.value++ } return { count, doubleCount, increment } }}在上述代码中,通过setup函数,咱们定义了一个响应式的count变量和一个基于count变量的计算属性doubleCount,以及一个increment办法来扭转count的值。 二、为什么抉择 setup 函数?在 Vue 3 之前,咱们次要通过选项 API(如data、methods、computed等)来组织组件的逻辑。这在简略场景下工作得很好,但随着组件变得越来越简单,代码就开始分布在不同的选项中,导致保护和了解的成本增加。setup函数提供了一个集中处理响应式数据、计算属性和函数等的场合,有助于放弃代码的组织和清晰。 三、应用 setup 的最佳实际适时应用响应式援用和计算属性Vue 3 的响应式零碎是基于 ES6 的 Proxy 实现的,通过ref和reactive这两个 API,你能够十分简洁地定义响应式数据。 把握生命周期钩子的应用setup函数中,Vue 3 提供了一套新的生命周期钩子函数,以on结尾,如onMounted、onUpdated等。理解并正当利用这些钩子函数,可能让你更精准地管制组件的行为。 import { onMounted } from 'vue'export default { setup() { onMounted(() => { console.log('组件挂载实现') }) }}提供明确的返回对象确保setup函数返回一个对象,这个对象中蕴含了所有须要裸露给模板和其余组件选项(如methods)应用的属性和办法。这保障了组件的其它局部能够无缝拜访setup函数内定义的响应式状态和函数。 ...

February 21, 2024 · 1 min · jiezi

关于vue.js:一条龙服务利润新玩法

商业版-钜惠五折:       2024【迎财神】五折流动(截止2月28日)       2024-3-18后 商业版增定价值至8800。一、近期更新介绍上游套餐打包阶梯到账:      阐明:实用于套餐包结算类型;(具体私聊)     【现金流/套餐打包/账期亏损/阶梯到账】套餐打包:上游套餐打包套餐结算;阶梯到账:多套餐包装阶梯应用到账;账期亏损:多套餐未应用结余 ;换卡申请:换卡分类:提醒、运费、禁区;卡列表适配提醒换卡 标记分类;老卡转移新卡:流量、余额、配置、微信告诉(换卡申请)(换卡告诉[运费领取/工单揭示/换卡胜利])未订购-停机/断网:卡列表适配 未订购时 停机/断网 多选;卡列表权限优化: 可见字段及可用性能辨别具体权限;    (全副可见权限)(全副可见权限-卡详情)(起码可见权限)(起码可见权限-卡详情)流量/余额 转移:流量转移:残余转移、多账期已用流量转移;余额转移:老卡余额转移新卡;复制配置:归属客户、套餐分组 等信息;(无可用套餐-套餐转移)

February 19, 2024 · 1 min · jiezi

关于vue.js:手把手教你如何搭建Vue组件库

 前言: 组件设计是通过对性能及视觉表白中元素的拆解、演绎、重组,并基于可被复用的目标,造成规范化的组件,通过多维度组合来构建整个设计方案,將这些组件整顿在一起,便造成组件库。本文咱们次要讲述基于VantCLI的自建组件库。VantCLI是一个基于Vite实现的Vue组件库构建工具,通过VantCLI能够疾速搭建一套性能齐备的Vue组件库。 建设组件库的意义 首先组件库能够给咱们降本提效,其次能够放弃视觉格调对立以及交互统一,能够帮忙咱们疾速构建应用场景,便于多个我的项目后续迭代降级。 视觉格调对立以及交互的一致性,能够缩小用户学习老本造就用户习惯,让产品领有良好的用户体验。比方一个四级地址的抉择组件,在整个产品中应该就一种交互方式,如果一会是滚动抉择,一会是点击抉择,会让用户操作起来比拟焦躁,对立交互能够缩小用户学习老本。 新产品上线后,还须要一直的去欠缺,在迭代过程中可能会新增其余性能,这时候咱们就能够只批改组件库一套代码,所有不同我的项目雷同组件就能够达到了迭代降级的成果。 如何创立组件库 一、梳理组件清单 首先梳理出我的项目中款式雷同的模块,和产品探讨将来会有哪些布局,现有的组件是否可能满足需要,是否须要补充设计方案,清单整顿结束后,将每一个组件建成一个独立工作,像日常需要那样,不便随时更新应用。 二、场景整合 把本人变成产品的深度用户,把现有线上产品残缺体验一遍,绘制用户行为门路,并和需求方沟通了解后续打算,将组件的所有的以后/潜在利用场景总结进去,尽可能不脱漏场景。 三、组件库框架选型 看了开源的Vue3组件库,总结了一些前端目前风行的趋势,列出来多个版本和框架的,本文只探讨Vue3版本。 1、element-plus:经典中的经典,全面反对Vue3 2、tdesign-vue-next:鹅厂优质UI组件,配套工具完美,设计工整,文档清晰 3、arco-design-vue:字节跳动开源UI组件库,大厂逻辑,设计文档完满 4、ant-design-vue:蚂蚁前端UI库,面向企业级中后盾 5、naive-ui:宝藏VueUI库,VueUI新星,从Vue3起步 6、vant:有赞团队开源挪动UI组件库,全面反对Vue3 7、nutui:京东出品,挪动端敌对,面向电商业务场景 8、vuetify:老牌VueUI,基于谷歌的MaterialDesign款式开发 9、varlet-Varlet:一个基于Vue3开发的Material格调挪动端组件库,全面拥抱Vue3生态,由社区建设起来的组件库团队进行保护。 四、组件库搭建 咱们以VantCLI为例来具体分析具体搭建过程: 1、首先确保本地node版本^12.13.0||^14.15.0||>=16.0.0 2、执行以下命令能够疾速创立一个基于VantCLI的我的项目 yarn create vant-cli-app 3、手动装置 # 通过 npmnpm i @vant/cli -D# 通过 yarnyarn add @vant/cli -D# 通过 pnpmpnpm add @vant/cli -D 4、手动配置 ...

February 19, 2024 · 2 min · jiezi

关于vue.js:推荐10个最受欢迎的-Vuejs-UI-库

<article class=“article fmt article-content”><p>在2024年,随着Vue.js的一直遍及和倒退,这个轻量级、易于学习的JavaScript框架在前端开发者中的受欢迎水平日益回升。Vue.js之所以受到青眼,很大一部分起因是其宏大的生态系统,特地是泛滥的UI库,这些库提供了事后构建的组件和工具,帮忙开发者疾速高效地构建出既好看又响应迅速的用户界面。</p><p>让咱们来看看2024年最受欢迎的10个Vue.js UI库,这些库将帮忙你进步开发效率,打造出令人印象粗浅的应用程序。</p><h2>1,Vuetify</h2><p><br/>在Vue.js的泛滥UI库中,Vuetify以其对Google的Material Design准则的精准实现而怀才不遇。它提供了一整套精美的UI组件、布局和主题,使开发者可能轻松构建业余且响应式的Web利用,而无需具备深厚的设计技能。</p><p>截至2024年,Vuetify曾经领有38.6k的星标和7k的分支,这不仅证实了它作为Vue.js开发中风行且疾速成长的Material Design框架的位置,也反映了其在开发者中的宽泛认可和利用。</p><p>Vuetify的特色性能:</p><ul><li><strong>丰盛的组件汇合:</strong> Vuetify提供了80多种预制UI组件,涵盖了从按钮、表单到数据表格和导航抽屉等简直所有你在利用开发中须要的元素。</li><li><strong>响应式设计:</strong> Vuetify的所有组件都是响应式的,确保你的利用在任何设施上,无论是桌面还是挪动端,都能完满展示。</li><li><strong>主题反对</strong>:通过反对主题化,Vuetify容许你轻松扭转利用的整体外观和感觉。你能够创立自定义主题,或应用泛滥预制主题之一。</li><li><strong>国际化:</strong> Vuetify反对国际化,便于开发可能被全世界用户应用的利用。</li><li><strong>沉闷的社区:</strong> Vuetify有一个宏大而沉闷的开发者社区,社区成员总是乐于提供帮忙和解答问题。</li></ul><p>应用Vuetify,即便是没有设计背景的开发者,也能够构建出既好看又实用的Web利用。它的丰盛组件和灵便的主题零碎,加上对响应式设计的人造反对,使得Vuetify成为开发古代Web利用的现实抉择。无论你是在构建企业级利用、电商平台还是集体我的项目,Vuetify都能让你的开发过程更加高效,同时保障最终产品的品质和用户体验。</p><p>地址:https://vuetifyjs.com/en/</p><h2>2,Element UI</h2><p></p><p>Element UI是一个专为Web开发设计的桌面UI工具包,基于Vue.js构建。它提供了一系列UI组件,如按钮、表单、表格等,这些组件旨在帮忙开发者构建响应式且好看的Web利用。Element是开源且收费应用的,领有一个宏大且沉闷的开发者社区。</p><p>在Github上,Element领有53.9k的星标和14.7k的分支,这证实了它作为Vue.js我的项目中受欢迎且宽泛应用的UI组件库的位置。</p><p>Element的特色性能:</p><ul><li><strong>模块化和可定制性:</strong> 提供宽泛的预制UI组件,如按钮、表单、表格等,所有这些都设计得易于集成和定制,以满足你的特定设计需要。</li><li><strong>响应式:</strong> 组件被构建为可能适应不同屏幕大小和设施,确保用户体验的一致性。</li><li><strong>主题化:</strong> 容许你通过调整色彩、字体和其余设计元素轻松创立自定义主题,以匹配你的品牌或我的项目的视觉身份。</li><li><strong>可拜访性:</strong> 在构建组件时思考到了可拜访性,恪守WCAG规范,确保你的网站或利用能够被所有人应用。</li></ul><p>Element UI的设计理念是为开发者提供一个全面、易用、且高度可定制的UI组件库,以便疾速构建高质量的Web利用。无论你是在打造简单的企业级利用,还是简略的信息网站,Element的组件都能让你的开发工作更加顺畅。其对响应式设计的人造反对和对可拜访性的器重,使得应用Element UI开发的利用不仅外观古代,而且用户敌对,确保宽泛的用户群可能无障碍地拜访。</p><p>地址:https://element.eleme.io/#/en-US</p><h2>3,Quasar</h2><p></p><p>Quasar是一个基于Vue.js的开源框架,专为开发跨平台的Web、挪动、桌面以及Electron利用而设计。它以其宏大的可定制Material Design组件库、详尽的API文档以及充满活力的社区而闻名。</p><p>Quasar的特点和性能:</p><ul><li><strong>跨平台开发:</strong> 应用Quasar,你能够一次性编写代码,而后将其部署到多个平台,包含Web、挪动、桌面和Electron利用。</li><li><strong>宏大的组件库:</strong> Quasar内置了70多个高性能、可定制的Material Design组件,你能够在利用中应用这些组件。</li><li><strong>具体的API文档:</strong> Quasar提供了易于学习和应用的详尽API文档。</li><li><strong>充满活力的社区:</strong> Quasar领有一个宏大且沉闷的开发者社区,社区成员总是乐于提供帮忙。</li><li><strong>开源:</strong> Quasar是一个开源框架,这意味着它收费应用和批改。</li></ul><p>Quasar框架的设计理念是提供一套全面的工具和组件,使开发者可能疾速高效地构建和部署跨平台利用。通过Quasar,开发者能够防止为每个平台独自开发和保护代码的繁琐工作,大大提高开发效率。无论是须要构建一个运行在浏览器的Web利用、一个原生感觉的挪动利用、还是一个桌面利用,Quasar都能让这所有变得简略。加之Quasar沉闷的社区反对,开发者在遇到问题时能够疾速失去解答和帮忙,这些都使Quasar成为开发跨平台利用的优选框架。</p><p>地址:https://quasar.dev/</p><h2>4,Bootstrap Vue</h2><p><br/>BootstrapVue是一个基于风行的Bootstrap框架的综合性UI组件库。它提供了超过85个现成的Vue.js组件,以及插件、指令和图标,这些都与Bootstrap v4.6无缝集成。这意味着你能够在Vue.js我的项目中利用Bootstrap成熟的设计准则和响应式个性,而无需编写大量代码。</p><p>在GitHub上,这个仓库领有14.4k星标和1.9k分支,这使其成为应用Vue.js构建响应式、挪动优先我的项目的热门抉择。</p><p>Bootstrap Vue的特色性能:</p><ul><li>宽泛的组件库:包含按钮、表单、表格、卡片、模态框、导航栏等必要的UI元素。</li><li>基于Bootstrap v4.6:提供相熟的Bootstrap类和款式,确保对相熟Bootstrap的开发者来说,一致性和易用性。</li><li>挪动优先设计:组件响应式,并能无缝适应不同屏幕大小,无论在哪种设施上都能提供杰出的用户体验。</li><li>易于定制:通过props和插槽能够自定义组件,让你依据具体需要和设计偏好来调整它们。</li><li>重视可拜访性:专一于可拜访性和WCAG合规性,使你的Web利用可被所有人应用。</li></ul><p>BootstrapVue的设计哲学是简化Vue.js我的项目的开发过程,通过提供一套宽泛的、事后构建的组件,使开发者可能疾速构建响应式和好看的Web利用。通过将Bootstrap的响应式布局和Vue.js的反应式数据绑定联合起来,BootstrapVue为开发者提供了一个弱小、易于应用的工具集,以优化他们的工作流程,并进步我的项目的品质。无论是构建一个简单的企业级利用还是一个简略的集体我的项目,BootstrapVue都可能提供必要的工具,以确保我的项目的胜利。</p><p>地址:https://bootstrap-vue.org/</p><h2>5,iView</h2><p><br/>iView是一个针对Vue.js开发的高质量UI组件库,它提供了丰盛的性能和个性,帮忙开发者构建现代化、响应式和用户敌对的Web利用。</p><p>在Github上,iView领有24k的星标和4.2k的分支,这使它成为基于Vue.js构建企业级UI组件的热门抉择。</p><p>iView的特色性能:</p><ul><li><strong>宽泛的组件库:</strong> 提供70多个预制的UI组件,涵盖了按钮、表单、表格、图表、菜单等多种性能。</li><li><strong>企业级:</strong> 为业余利用设计,以可扩展性和可维护性为出发点构建。</li><li><strong>重视可拜访性:</strong> 遵循可拜访性最佳实际,确保你的利用可被所有人应用。</li><li><strong>挪动敌对:</strong> 组件响应式,设计上能无缝适应不同屏幕尺寸,在所有设施上提供杰出的用户体验。</li><li><strong>TypeScript反对:</strong> 提供可选的TypeScript定义,加强开发者体验和类型平安。</li></ul><p>iView的设计理念是为Vue.js开发者提供一套全面的UI解决方案,使他们可能疾速构建出既好看又实用的Web利用。它的组件库不仅丰盛,还专一于细节和用户体验,特地是在企业级利用开发中,iView的可维护性和扩展性尤为突出。通过对可拜访性的器重以及对挪动设施敌对的设计,iView确保了利用可能笼罩更宽泛的用户群体。</p><p>此外,iView对TypeScript的反对使得开发过程更加顺畅,进步了代码的可维护性和稳定性。无论是在构建高复杂度的企业应用,还是谋求高效开发的集体我的项目,iView都能提供弱小的反对,帮忙开发者实现他们的指标。</p><p>地址:https://www.iviewui.com/</p><h2>6,Keen UI</h2><p><br/>Keen UI是一个轻量级的Vue.js UI库,它以简略的API为特色,受到了Google的Material Design的启发。它为开发者提供了一套可重用和可定制的组件,以减速Web开发,同时遵循洁净和古代的美学。</p><p>在过来一年中,Keen UI在Github上取得了4.1k的星标,这表明它是一个受欢迎且沉闷保护的Vue.js UI库。</p><p>Keen UI的特色性能:</p><ul><li><strong>简略的API:</strong> 提供易于应用的API,最小化配置需要,使所有级别的开发者都能轻松上手。</li><li><strong>宽泛的组件范畴:</strong> 包含按钮、表单、表格、卡片、模态框等根本UI组件的汇合。</li><li><strong>定制化:</strong> 通过props和插槽能够自定义组件,让你依据具体需要定制它们。</li><li><strong>响应式:</strong> 组件可能无缝适应不同屏幕大小,确保你的利用在所有设施上都能出现杰出的外观。</li><li><strong>开源:</strong> 可自在用于集体和商业我的项目。</li></ul><p>地址:https://madewithvuejs.com/keen-ui</p><h2>7,Buefy</h2><p><br/>Buefy是一个收费且开源的UI库,专为Vue.js利用开发设计。它受到了风行的CSS框架Bulma的启发,旨在提供一个轻量级、易于应用且对挪动敌对的框架,用于构建古代Web界面。</p><p>在Github上,Buefy领有9.5k的星标和1.1k的分支,这表明它是一个受欢迎的Vue.js UI库。</p><p>Buefy的特色性能:</p><ul><li><strong>组件:</strong> 提供一套丰盛的组件,涵盖了根本的UI元素,如按钮、表单、导航菜单、模态框、卡片等。</li><li><strong>响应性:</strong> 基于挪动优先准则构建,确保你的利用在所有设施上都能流畅查看和操作。</li><li><strong>定制化:</strong> 组件能够通过props和插槽API轻松定制,让你依据特定需要进行个性化设置。</li><li><strong>可拜访性:</strong> 专一于可拜访性和WCAG合规性,使你的利用能够被所有人应用。</li><li><strong>社区:</strong> 有一个沉闷的社区反对,提供丰盛的资源和帮忙。</li></ul><p>Buefy以其简洁和高效的设计理念吸引了许多Vue.js开发者。通过联合Bulma的CSS框架劣势和Vue.js的反应式个性,Buefy为开发古代Web利用提供了一套残缺的解决方案。无论是构建企业级利用、中小型我的项目还是集体博客,Buefy的轻量级和易用性都能帮忙开发者疾速达成指标,同时放弃利用的响应性和可拜访性。</p><p>地址:https://buefy.org/</p><h2>8,PrimeVue</h2><p></p><p>PrimeVue是一个针对Vue.js开发的综合UI组件库,提供了超过90种可重用且可定制的组件,旨在减速Web开发,同时遵循最佳实际和可拜访性规范。</p><p>在Github上,PrimeVue曾经取得了6.4k的星标和929个分支,确立了其作为Vue.js UI组件库的首选位置。</p><p>PrimeVue的特色性能:</p><ul><li><strong>宏大的组件库:</strong> 提供宽泛的UI组件,笼罩各种性能,包含按钮、表单、表格、图表、菜单等。</li><li><strong>可定制的主题:</strong> 能够抉择预制主题,或应用Theme Designer工具创立本人的主题,该工具容许调整超过500个可定制变量,以取得个性化的外观。</li><li><strong>响应性:</strong> 组件被构建为可能无缝适应不同屏幕大小和设施,确保在桌面、平板和手机上提供平滑的用户体验。</li><li><strong>遵循可拜访性规范:</strong> 遵循Web内容可拜访性指南(WCAG 2.0),确保你的Web利用可被所有人应用,无论能力如何。</li><li><strong>反对TypeScript:</strong> 提供可选的TypeScript定义,以加强开发者体验和进步类型平安。</li></ul><p>PrimeVue通过其丰盛的组件库和高度的可定制性,为Vue.js开发者提供了一个弱小的工具集,帮忙他们疾速构建出既好看又实用的Web利用。无论是须要构建简单的数据驱动型利用、精美的商业网站还是响应式的挪动利用,PrimeVue都能提供必要的UI解决方案。加之其对可拜访性的器重和对TypeScript的反对,使得应用PrimeVue开发的利用不仅用户敌对,而且代码品质高,维护性好。</p><p>地址:https://primevue.org/</p><h2>9,Vue Material Kit</h2><p></p><p>Vue Material Kit是一个基于Material Design构建的收费开源设计零碎,应用Vue.js和Bootstrap 5开发。它是一个对开发者极有价值的工具包,帮忙他们疾速且轻松地创立好看、古代且响应式的Web利用。</p><p>只管在Github上只有351个星标,这显示了一个规模较小但专一的用户根底,Vue Material Kit提供的个性和便利性使它成为开发高质量Web利用的优良抉择。</p><p>Vue Material Kit的特色性能:</p><ul><li><strong>节省时间和致力:</strong> 通过应用预制组件,与从零开始构建相比,你能够节俭大量工夫和致力。</li><li><strong>创立好看且业余的利用:</strong> Vue Material Kit中的所有组件都设计得十分精美和业余,使你的利用看起来更加吸引人。</li><li><strong>疾速入门:</strong> Vue Material Kit易于学习和应用,因而你能够立刻开始构建你的利用。</li><li><strong>高度可定制:</strong> 你能够轻松定制组件以匹配你的品牌或我的项目。</li><li><strong>响应性:</strong> 在所有设施上,从桌面到手机,都能很好地工作。</li></ul><p>Vue Material Kit联合了Material Design的美学准则和Vue.js的灵活性,提供了一个弱小的终点,用于疾速开发高质量的前端我的项目。不论是在谋求优雅设计的集体我的项目还是须要迅速原型设计和开发的商业利用,Vue Material Kit都能提供弱小的反对,使得开发过程更加高效和欢快。</p><p>地址:https://www.creative-tim.com/product/vue-material-kit</p><h2>10,Mint UI</h2><p></p><p>Mint UI是专为构建Vue.js挪动利用而设计的预制UI组件汇合。它旨在通过提供一系列可重用且可定制的组件,这些组件遵循统一的设计语言,从而简化开发过程。</p><p>在GitHub上,Mint UI以16.6k的星标怀才不遇,成为Vue.js开发者寻找UI组件的显著抉择。</p><p>Mint UI的特色性能:</p><ul><li><strong>放慢开发:</strong> 通过应用预制组件,与从头开始构建相比,开发者能够节省时间和致力。</li><li><strong>统一的设计:</strong> 组件遵循对立的设计语言,使利用看起来更加精炼和业余。</li><li><strong>针对挪动优化:</strong> 组件专门为挪动设备设计,确保它们在不同屏幕尺寸和分辨率上看起来并运行良好。</li></ul><p>Mint UI以其针对挪动利用的优化组件和统一的设计理念,为Vue.js开发者提供了构建高品质挪动利用的弱小工具。它不仅能放慢开发流程,还能确保最终产品在视觉上协调一致,用户体验优异。无论是在开发面向消费者的挪动利用,还是企业级挪动解决方案时,Mint UI都是一个值得思考的优良抉择。</p><p>链接:https://madewithvuejs.com/mint-ui</p></article> ...

February 15, 2024 · 1 min · jiezi

关于vue.js:使用easywasmplayer实现视频流播放

easywasmplayer文档地址:https://www.npmjs.com/package/easywasmplayer 一:介绍EasyPlayer.js H5播放器,是一款可能同时反对HTTP、RTMP、HTTP-FLV、HLS(m3u8)视频直播与视频点播等多种协定,反对H.264、H.265、AAC等多种音视频编码格局,反对mse、wasm等多种解码形式,反对Windows、Linux、Android、iOS全平台终端的H5播放器。 二:html+js实现视频流播放<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>EasyWasmPlayer-Demo</title> <script src="./EasyWasmPlayer.js"></script> <style> .box { width:600px; height:400px; } </style> </head><body> <div class="box"> <div id="Player"></div> </div> <script> // 实例化播放器 var Player = new WasmPlayer(null,'Player',callbackFun,{cbUserPtr:this, decodeType:"auto", openAudio:1, BigPlay:false, Height:true}); // 调用播放 Player.play('视频流地址', 1); //播放事件回调 function callbackFun(e) { console.log(e) } </script> </body> </html>三:vue实现视频流播放1:装置easywasmplayernpm install @easydarwin/easywasmplayer --save2:拷贝将@easydarwin/easywasmplayer/EasyWasmPlayer.js和@easydarwin/easywasmplayer/libDecoder.wasm拷贝到我的项目public目录下 3:在public目录下的index.html引入easywasmplayer<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <title>EasyWasmPlayer-Demo</title> <script src="./EasyWasmPlayer.js"></script> </head> <body> <div id="app"></div> </body></html>4:应用easywasmplayer实现视频流播放<template> <div class="box"> <div id="Player"></div> </div></template><script> export default { data() { return { player: '', url: '视频流地址' } }, mounted() { // 实例化播放器 this.player = new WasmPlayer(null, 'Player', this.callbackfun) // 调用播放 this.player.play(this.url, 1) }, methods: { //播放事件回调 callbackfun(e) { console.log('callbackfun', e); } } }</script><style> .box { width:600px; height:400px; }</style>

September 21, 2023 · 1 min · jiezi

关于vue.js:Vue组件懒加载

在当今快节奏的数字世界中,网站性能对于吸引用户和取得成功至关重要。然而,对于像首页这样的页面,在不影响性能的前提下优化性能就成了一项挑战。 这就是 Vue 组件懒加载的用武之地。通过将非必要元素的加载推延到可见时进行,开发人员能够加强用户体验,同时确保登陆页面的疾速加载。 懒加载是一种优先加载要害内容,同时推延加载主要元素的技术。这种办法不仅能缩短页面的初始加载工夫,还能节约网络资源,从而使用户界面更轻量、反馈更灵活。 在本文中,我将向你展现一种简略的机制,应用 Intersection Observer API 在 Vue 组件可见时对其进行懒加载。 Intersection Observer APIIntersection Observer API 是一种功能强大的工具,它容许开发人员无效地跟踪和响应浏览器视口中元素可见性的变动。 它提供了一种异步察看元素与其父元素之间或元素与视口之间交加的办法。它为检测元素何时可见或暗藏提供了性能优越的优化解决方案,缩小了对低效滚动事件监听器的需要,使开发人员可能在必要时有选择地加载或操作内容,从而加强用户体验。 它通常用于实现诸如有限滚动和图片懒加载等性能。 异步组件Vue 3 提供了 defineAsyncComponent,用于仅在须要时异步加载组件。 它返回一个组件定义的 Promise: import { defineAsyncComponent } from 'vue'const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { // ...load component from server resolve(/* loaded component */) })})还能够处理错误和加载状态: const AsyncComp = defineAsyncComponent({ // the loader function loader: () => import('./Foo.vue'), // A component to use while the async component is loading loadingComponent: LoadingComponent, // Delay before showing the loading component. Default: 200ms. delay: 200, // A component to use if the load fails errorComponent: ErrorComponent, // The error component will be displayed if a timeout is // provided and exceeded. Default: Infinity. timeout: 3000})当组件可见时,咱们将应用该性能异步加载组件。 ...

September 20, 2023 · 3 min · jiezi

关于vue.js:Antdv表单校验失败时将页面滚动到错误消息所在位置

遇见超长表单,提交校验失败,咱们心愿页面能够滚动到第一个谬误音讯的所在位置。 this.$refs.refForm.validate((valid) => { if (valid) { //表单校验通过 } else { //表单校验不通过 setTimeout(()=>{ //其余写法 var errors = document.querySelector(".ant-form-explain"); var errors = this.$el.querySelector(".ant-form-explain"); if (errors) { errors.scrollIntoView({ behavior: "instant", block: "center", inline: "nearest" }) } }, 100) return false; }});知识点:1、querySelector 通过选择器字符串匹配文档中的元素,并返回第一个匹配的元素2、scrollIntoView 是一个 DOM 办法,它使得元素滚动到可视区域内。

September 18, 2023 · 1 min · jiezi

关于vue.js:开箱即用开发了一个基于环信IM聊天室的Vue3插件从而快速实现仿直播间聊天窗功能

前言因为看到有局部的需要为在页面层,疾速的引入一个包,并且以简略的配置,就能够疾速实现一个聊天窗口,因而尝试以 Vue3 插件的模式开发一个轻量的聊天窗口。 这次简略分享一下此插件的实现思路,以及实现过程,并形容一下本次插件公布 npm 的过程。 技术栈Vue3pnpmTypescriptVite插件外围目录设计 emchat-chatroom-widget┣ build // 插件打包输入的目录┣ demo // 验证插件demo相干目录┣ scripts // 打包脚本目录┣ src // 插件源代码┃ ┣ components // 组件目录┃ ┣ container // 容器组件目录┃ ┣ EaseIM // 环信IM相干目录┃ ┣ utils // 工具相干目录┃ ┣ index.ts // 插件入口文件┃ ┗ install.ts // 插件初始化文件┣ package.json // 我的项目配置文件┣ vite.config.ts // vite配置文件┗ README.md // 我的项目阐明文档...实现过程确认性能范畴首先确认本次插件实现的性能范畴,从而围绕要实现的性能着手进行开发筹备。 Vue3 框架应用轻量配置、仅配置大量参数即可立刻应用聊天性能页面大小自适应,给定容器宽高,插件外部宽高自适应。仅聊天室类型音讯反对根底文本,表情,图片。临时第一期仅反对这些性能范畴。着手开发1、创立空白我的项目pnpm create vite emchat-chatroom-widget --template vue-ts2、配置eslint pretter 等代码校验、以及代码格调工具。pnpm i eslint eslint-plugin-vue @typescript-eslint/eslint-plugin @typescript-eslint/parser -Dpnpm i prettier eslint-config-prettier eslint-plugin-prettier -D同时也不要忘了创立对应的 .eslintrc.cjs和.prettierrc.cjs ...

September 12, 2023 · 6 min · jiezi

关于vue.js:vue3eslintprerrier

1、应用vite创立一个我的项目 执行命令: yarn create vite ? Project name: 输出你的项目名称?(如: esvue)? Select a framework: 抉择装置的脚手架 (这里选vue) vanillavuereactDone. Now run: cd esvue yarn yarn dev2、装置EsLint yarn add -D eslint3、初始化配置EsLint npx eslint --init3.1、抉择模式: (To check syntax and find problems) You can also run this command directly using 'npm init @eslint/config'.? How would you like to use ESLint? ... To check syntax only To check syntax and find problems To check syntax, find problems, and enforce code style3.2、抉择语言模块: (选JavaScript modules)? What type of modules does your project use? ... ...

September 12, 2023 · 4 min · jiezi

关于vue.js:Vue低代码-走进低代码

一、VUE联合低代码"低代码"是一种疾速开发利用的办法,它使开发者可能通过图形界面和预构建的块进行设计和构建,而不是手动编写大量的代码。这种办法被宽泛用于疾速利用开发、挪动利用开发、业务流程治理和数据库利用开发等畛域。 Vue.js 是一种风行的前端 JavaScript 框架,它使开发者可能构建用户界面和单页利用。然而,Vue.js 自身并不是一个低代码平台,它须要开发者具备肯定的 JavaScript 和 Vue.js 常识能力进行开发。 不过,有一些工具和平台能够联合 Vue.js 和低代码思维,帮忙开发者更快地开发和部署利用。例如: JNPF低代码:这是一个企业级的低代码平台,它容许你应用 Vue.js 作为前端技术来构建简单的利用。JNPF 提供了一套残缺的工具,包含前端开发框架、后端开发框架、数据库设计、用户界面设计、API 治理、业务流程治理等,使得开发者可能通过拖拽和配置等形式进行开发。 通过提供预构建的模块和图形化的界面,升高了开发的复杂性,使得非专业的开发者也能参加到利用开发中来。同时,因为 Vue.js 自身是一个非常灵活和弱小的框架,所以这些工具往往也能满足业余开发者的高阶需要。 二、低代码平台的前端框架采纳Vue的劣势有哪些?1、Vue是组件化开发,缩小代码的书写,使代码易于了解。2、最突出的劣势在于能够对数据进行双向绑定。3、相比拟传统的用超链接进行页面的切换与跳转,Vue应用的是路由,不必刷新页面。4、Vue是单页利用,加载时不必获取所有的数据和dom,进步加载速度,优化了用户体验。5、Vue的第三方组件库丰盛,低代码平台可能取得更多的反对和资源。 三、基于Vue3.0构建的低代码我的项目基于Vue3.0的低代码我的项目都具备易于集成、灵活性强、性能优越、社区反对宽泛等劣势,能够满足不同企业的需要,帮忙开发者疾速构建高质量的业务利用。 JNPF疾速开发平台作为一个十分优良的基于Vue前端框架构建的全栈开发平台。它不仅具备易保护、便部署、高集成、高效率等多方面个性,还面向企业我的项目提供开发服务,提供开发构建、凋谢连贯、部署运维、在线经营的全生命周期能力。同时,它也满足多种云环境部署,私有化部署、全源码反对给予最大的平安保障,能够帮忙企业疾速搭建适宜本身利用场景的产品。 利用地址:https://www.jnpfsoft.com/?sifou 低代码/无代码工具能够帮忙组织以起码的手动编码构建商业智能 (BI) 应用程序。这些低代码/无代码解决方案提供了一套个性和性能,可帮忙设计和开发团队以前所未有的速度构建 BI 利用。 四、应用低代码/无代码工具构建 BI 应用程序的益处放慢利用程序开发过程它非常适合缩小应用程序齐全运行和实现所需的工夫。没有编码教训的用户能够应用弱小的数据可视化和报告性能创立 BI 应用程序,开发人员能够在几分钟内从头到尾创立应用程序,而不是传统的手动编码数周或数月。 更快的后果因为设计利用不须要花工夫编写自定义代码或任何传统的编程语言体验,因而此类工具能够帮忙您更快地取得和查看后果。通过为不同目标创立应用程序,您能够更快地向现有客户或新客户追加销售,它还能够帮忙您的组织发明新的支出起源。 这对于以前没有应用过 BI 软件并且个别不相熟 BI 畛域的组织尤其无益。没有估算或不须要更简单的数据分析平台的中小型企业能够构建用于剖析、报告和数据可视化的自定义应用程序。 更大的灵活性它们提供了一种自在模式的数据构建办法,容许用户在一个对立的视图中收集和合并来自多个不同起源的数据。您能够利用此类工具为您提供的灵活性来开发适宜将要查看它们的受众的组织、部门或集体级别的高影响力 BI 仪表板。 降低成本/节俭资金构建本人的高代码(手动编写代码的传统开发)剖析解决方案的老本很高,均匀须要大概七个月能力实现。预计的均匀老本高达350万美元,其中仅包含开发人员,UI / UX设计师,数据科学家和QA业余人员的薪水。更不用说构建软件解决方案所波及的技术堆栈了。 进步生产力低代码/无代码开发工具弥合了业务用户和 IT 之间的差距。无需期待开发人员满足其业务用户的申请,反之亦然,两者都能够更快地解决理论的业务问题和阻碍,从而更快地影响组织。 通过从组织中打消简单的编码开发,任何人(包含业务领导者)都能够创立本人的应用程序来满足他们的需要,同时进步工作流程的生产力。

September 12, 2023 · 1 min · jiezi

关于vue.js:element单选框组-取消选择

<el-descriptions :column="1" title :labelStyle="{width:'200px'}" border> <el-descriptions-item :key="i" :label="item.attributeName" v-for="(item,i) in mxkzlist"> <el-radio-group size="small" v-if="item.optionType==1" v-model="item.value" > <el-radio @click.native="onRadioChange($event, sitem,item)" v-for="sitem in item.option" :label="sitem" >{{sitem}}</el-radio> </el-radio-group> </el-descriptions-item> </el-descriptions> onRadioChange(e, sitem, item) { let name = e.target.nodeName //加判断就只登程一次,不加要不然会登程两次 input和label都会触发 //如果选中的那个**有值**,循环数组,把数组中选中的那个清空 if (name == 'INPUT') { let ndata = this.$deepClone(this.mxkzlist) if (item.value) { ndata.forEach(itt => { if (itt.id == item.id) { itt.value = '' } }) } this.mxkzlist = ndata } },

September 4, 2023 · 1 min · jiezi

关于vue.js:基于Vue前端框架构建BI应用程序

一、什么是Vue?Vue(Vue.js)是一个轻量级、高性能、可组件化的MVVM库。简而言之,是一个构建数据驱动的web界面的渐进式框架。它采纳MVVM思维,通过数据双向绑定实现数据的动静渲染,同时也反对组件化的开发方式,使开发更加高效和可复用。 二、Vue的次要特点包含:1.响应式编程:Vue会主动对页面中某些数据的变动做出响应,实现数据的双向绑定,让开发者不必再操作dom对象,有更多的工夫去思考业务逻辑。2.组件化的视图:Vue采纳组件化开发方式,使得开发更加高效和可复用,同时也不便了代码的保护和扩大。3.轻量级框架:Vue框架笨重、易于上手,同时也具备良好的性能体现。4.可与其余库或既有我的项目整合:Vue能够与第三方库或其余我的项目整合,如与Bootstrap、ElementUI等UI库配合应用,实现疾速开发。5.虚构DOM:Vue应用虚构DOM进行渲染,这使得其运行效率更高,并可能压缩运行时体积。6.MVVM架构:Vue是一个MVVM框架,通过数据绑定,数据能够在视图和模型之间动静映射,从而实现单页利用的动静渲染。 三、低代码平台的前端框架采纳Vue的劣势有哪些?Vue是组件化开发,缩小代码的书写,使代码易于了解。最突出的劣势在于能够对数据进行双向绑定。相比拟传统的用超链接进行页面的切换与跳转,Vue应用的是路由,不必刷新页面。Vue是单页利用,加载时不必获取所有的数据和dom,进步加载速度,优化了用户体验。Vue的第三方组件库丰盛,低代码平台可能取得更多的反对和资源。基于Vue3.0的低代码我的项目都具备易于集成、灵活性强、性能优越、社区反对宽泛等劣势,能够满足不同企业的需要,帮忙开发者疾速构建高质量的业务利用。 利用地址:https://www.jnpfsoft.com/?sifou JNPF疾速开发平台是一个十分优良的基于Vue前端框架构建的全栈开发平台。它不仅具备易保护、便部署、高集成、高效率等多方面个性,还面向企业我的项目提供开发服务,提供开发构建、凋谢连贯、部署运维、在线经营的全生命周期能力。同时,它也满足多种云环境部署,私有化部署、全源码反对给予最大的平安保障,能够帮忙企业疾速搭建适宜本身利用场景的产品。 四、基于Vue前端框架的低代码构建 BI 应用程序低代码/无代码工具能够帮忙组织以起码的手动编码构建商业智能 (BI) 应用程序。这些低代码/无代码解决方案提供了一套个性和性能,可帮忙设计和开发团队以前所未有的速度构建 BI 利用。应用低代码/无代码工具构建 BI 应用程序的益处: 放慢利用程序开发过程它非常适合缩小应用程序齐全运行和实现所需的工夫。没有编码教训的用户能够应用弱小的数据可视化和报告性能创立 BI 应用程序,开发人员能够在几分钟内从头到尾创立应用程序,而不是传统的手动编码数周或数月。更快的后果因为设计利用不须要花工夫编写自定义代码或任何传统的编程语言体验,因而此类工具能够帮忙您更快地取得和查看后果。通过为不同目标创立应用程序,您能够更快地向现有客户或新客户追加销售,它还能够帮忙您的组织发明新的支出起源。这对于以前没有应用过 BI 软件并且个别不相熟 BI 畛域的组织尤其无益。没有估算或不须要更简单的数据分析平台的中小型企业能够构建用于剖析、报告和数据可视化的自定义应用程序。更大的灵活性它们提供了一种自在模式的数据构建办法,容许用户在一个对立的视图中收集和合并来自多个不同起源的数据。您能够利用此类工具为您提供的灵活性来开发适宜将要查看它们的受众的组织、部门或集体级别的高影响力 BI 仪表板。降低成本/节俭资金构建本人的高代码(手动编写代码的传统开发)剖析解决方案的老本很高,均匀须要大概七个月能力实现。预计的均匀老本高达350万美元,其中仅包含开发人员,UI / UX设计师,数据科学家和QA业余人员的薪水。更不用说构建软件解决方案所波及的技术堆栈了。进步生产力低代码/无代码开发工具弥合了业务用户和 IT 之间的差距。无需期待开发人员满足其业务用户的申请,反之亦然,两者都能够更快地解决理论的业务问题和阻碍,从而更快地影响组织。通过从组织中打消简单的编码开发,任何人(包含业务领导者)都能够创立本人的应用程序来满足他们的需要,同时进步工作流程的生产力。以上内容收集自网络,仅供参考。如果您的企业也有数字化转型需要,无妨试试低代码搭建软件。

September 1, 2023 · 1 min · jiezi

关于vue.js:Vue3创建项目保存配置后删除配置

文件夹门路: C:\Users\本机用户名\.vuerc 把想要删除的之前保留的配置json代码段删掉保留就能够了

September 1, 2023 · 1 min · jiezi

关于vue.js:为什么在Vue3中有了Reactive还需要Ref

在Vue 中应用选项式API ,去申明响应式对象是很简略的。咱们只须要将须要响应式的变量属性放进 data 函数中,并return 进去。 Vue 框架会帮咱们把数据变为响应式,并在模板中可用。 如上面所示。 export defaut { // other data() { return { hello: 'world' } } //... other code}但对于 Composition API,事件就没那么简略了。状态申明必须应用Ref 和 Reactive 函数来实现,这两个函数的行为表现也不一样。 让咱们讨论一下 Vue 3 中产生了什么变动以及为什么咱们须要两个不同的助手。 Vue3 中的响应式实现大家都晓得Vue2 中,是通过Object.defineProperty 实现的依赖收集和响应式解决。但在Vue3 应用了javascript 的Proxy API 齐全重写了响应式外围。 Proxy 是一种更古代更优雅的API 能够实现对一个对象的代理和劫持。 你能够通过下边一段代码来理解Proxy 是如何工作的: const userInfo = { name: "sean", age: 35,};const handler = { get(target, property) { if (property === "name") { const name = target[property] return name.charAt(0).toUpperCase() + name.slice(1); } if (property === "age") { return '--' } return target[property] },};const proxyObj = new Proxy(userInfo, handler);console.log(proxyObj.name) // "Sotis"console.log(proxyObj.age) // "--"handler 内的 get 办法称为 trap ,每次拜访对象的属性时都会调用该办法。 ...

August 28, 2023 · 2 min · jiezi

关于vue.js:小程序分包小程序包大于2M来这教你分包啊

前言原因该大的不大,小程序包超出2M,无奈上传公布 前段时间我的项目迭代时,因版本大降级,导致uniapp打包后小程序后,包体积大于2M。尽管将图片等动态资源压缩,体积大的资源搁置cdn,在不懈的致力下,治标不治本,包体积还是不听话的长到2M以上。憋的切实没方法,遂将小程序分包,彻底解除封印,特来跟大家分享下如何将小程序分包,减小主包大小。 次要指标实现2大重点如何进行小程序分包如个依据分包调整配置文件 猜你想问如何与狗哥分割进行探讨关注公众号【JavaDog程序狗】公众号回复【入群】或者【退出】,便可成为【程序员学习交换摸鱼群】的一员,问题轻易问,牛逼轻易吹。 此群劣势: 技术交换随时沟通任何私活资源收费分享实时科技动态领先通晓CSDN资源收费下载自己所有源码均群内开源,可收费应用 2.踩踩狗哥博客javadog.net 大家能够在外面留言,随便施展,有问必答 猜你喜爱文章举荐【我的项目实战】SpringBoot+uniapp+uview2打造H5+小程序+APP入门学习的聊天小我的项目【我的项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序【模块分层】还不会SpringBoot我的项目模块分层?来这手把手教你!【ChatGPT】手摸手,带你玩转ChatGPT【ChatGPT】SpringBoot+uniapp+uview2对接OpenAI,带你开发玩转ChatGPT 注释三个问题为什么小程序会有2M的限度?用户体验:小程序要求在用户进入小程序前可能疾速加载,以提供良好的用户体验。限度小程序的体积能够确保小程序可能在较短的工夫内下载和启动,防止用户长时间的期待。网络条件:思考到不同地区和网络条件的差别,限度小程序的体积能够确保在低速网络环境下也可能较快地加载和关上小程序,提供更宽泛的用户笼罩。设施存储:一些用户应用的设施可能存储空间无限,限度小程序的体积能够确保小程序能够在这些设施上失常装置和运行。如何解决包过大问题?优化代码,删除掉不必的代码图片压缩或者上传服务器分包加载什么是分包加载?小程序个别都是由某几个性能组成,通常这几个性能之间是独立的,但会依赖一些公共的逻辑,且这些性能个别会对应某几个独立的页面。那么小程序代码的打包,能够依照性能的划分,拆分成几个分包,当须要用到某个性能时,才加载这个性能对应的分包。实操分包步骤1.查看我的项目构造通过上方三个问题,咱们开始具体分包流程,首先看一下分包前我的项目构造及pages.json配置文件 pages.json{ "pages": [ //pages数组中第一项示意利用启动页,参考:https://uniapp.dcloud.io/collocation/pages { "path": "pages/index/index", "style": { "navigationBarTitleText": "uni-app" } }, { "path": "pages/card/index", "style": { "navigationBarTitleText": "uni-app" } }, { "path": "pages/device/index", "style": { "navigationBarTitleText": "uni-app" } }, { "path": "pages/order/index", "style": { "navigationBarTitleText": "uni-app" } }, { "path": "pages/product/index", "style": { "navigationBarTitleText": "uni-app" } } ], "globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8" }, "uniIdRouter": {}}2.剖析主包大小微信开发者工具中,查看【详情】进行剖析,此处本地代码只有一个主包大小399.8KB ...

August 24, 2023 · 1 min · jiezi

关于vue.js:elementui的eldialog和eldrawer当鼠标拖动到遮罩层会触发关闭bug修复

咱们在应用el-dialog和el-drawer时候,当弹框内有表单,用户不小心想复制个内容,拖动光标,最初光标落点在dialog或者drawer的遮罩层,导致弹框敞开,而将用户辛苦填写的内容给革除掉了。这是甲方爸爸忍耐不了的!!!因而就呈现了我这个解决办法!在src目录下,(既和main.js)同级创立一个名为fixMouseOutsideAutoClose.js。如下: src |- ... |- src |- main.js |- fixMouseOutsideAutoClose.js在fixMouseOutsideAutoClose.js文件内写入如下代码: import { Dialog, Drawer } from "element-ui";const DialogPatched = { extends: Dialog, data() { return { wrapperMouseDowned: false, }; }, mounted() { this.$el.onmousedown = (e) => { this.wrapperMouseDowned = e.target.classList.contains("el-dialog__wrapper"); }; }, methods: { handleWrapperClick() { if (!this.closeOnClickModal || !this.wrapperMouseDowned) return; this.handleClose(); }, },};const DrawerPatched = { extends: Drawer, data() { return { wrapperMouseDowned: false, }; }, mounted() { this.$el.onmousedown = (e) => { this.wrapperMouseDowned = e.target.classList.contains( "el-drawer__container" ); }; }, methods: { handleWrapperClick() { if (this.wrapperClosable && this.wrapperMouseDowned) { this.closeDrawer(); } }, },};export default { install(Vue) { Vue.component(Dialog.name, DialogPatched); Vue.component(Drawer.name, DrawerPatched); },};在main.js中引入此文件,且必须在element-ui应用之后在应用。如下: ...

August 23, 2023 · 1 min · jiezi

关于vue.js:记录Vue中比较流行且好用的一些组件

1.剪切板组件,复制文本:vue-clipboard3 npm install --save vue-clipboard3import useClipboard from 'vue-clipboard3';const { toClipboard } = useClipboard();const copyPreviewPath = async (string) => { try { await toClipboard(string); message.success("文件门路复制胜利!"); } catch (e) { console.error(e); message.error("复制失败!您的浏览器不反对复制性能"); } };<div class="icon" @click="copyPreviewPath(files.url)"> <FolderOutlined/></div>2.图片视口懒加载组件:vue3-lazy npm install vue3-lazy -S// 图片懒加载export const lazyPlugin = { install(app) { // 自定义指令: app.directive("img-lazy", { mounted(el, binding) { // el 指令绑定得那个元素 img //bindding: binding.value 指令等于号前面绑定得表达式得值 这里指图片url地址 const { stop } = useIntersectionObserver( el, ([{ isIntersecting }], observerElement) => { if (isIntersecting) { //图片进入视觉入口了 el.src = binding.value; stop(); } } ); }, }); },};import { lazyPlugin } from "@/utils/use-lazy-data.js";<img v-img-lazy="baseUrl + item.url" alt="" :key="item.url" />

August 16, 2023 · 1 min · jiezi

关于vue.js:Vue3中是如何实现数据响应式

副作用函数:指的是会产生副作用的函数; JavaScriptlet val = 1;//全局变量function effect() { val = 2; //批改全局变量,产生副作用}当effect函数执行时,对全局变量val产生了副作用,扭转了其值。 响应式数据: const obj = {text:"hello world"};function effect(){ //effect函数的执行读取obj.text document.body.innerHTML = obj.text;}obj.text = "hello Vue.js";下面的副作用函数effect会设置body的innerText属性,其值为obj.text,第6行代码又批改了text的值,冀望副作用函数从新执行,如果能实现这个指标,那么对于obj就是响应式数据。 如何能力让obj变成响应式数据呢?通过观察咱们发现了两点线索: ▪当副作用函数effect执行时,会触发字段obj.text的读取操作; ▪当批改obj.text的值时,会触发字段obj.text的设置操作;   如果可能拦挡obj对象的读取和设置操作,事件就迎刃而解了。当读取字段obj.text时,咱们能够把副作用函数存储到一个“桶”中。  当设置obj.text时,再把副作用函数effect从“桶”里取出并执行。  依照下面的思路,应用Proxy来实现: //创立一个副作用函数的桶 const bucket = new Set(); //原始数据 const data = { text: "hello world" }; //对原始数据的代理 const obj = new Proxy(data, {   //拦挡读取操作   get(traget, key) {     //将副作用函数effect增加到副作用函数的桶中     bucket.add(effect);     //返回属性值     return traget[key];   },   //拦挡设置操作   set(traget, key, newValue) {     //设置属性值     traget[key] = newValue;     //把副作用函数从桶中取出来并执行     bucket.forEach((fn) => fn());     //返回true代表设置操作胜利     return true;   }, }); 测试用例: ...

July 12, 2023 · 1 min · jiezi

关于vue.js:vue注册全局组件的方法

首先在src下创立一个baseComponents而后创立一个index.js在baseComponents在src/baseComponents/index.js写上面代码 import Vue from 'vue';// 获取指定目录下的所有组件文件const components = require.context('./', false, /\.vue$/);// 遍历组件文件export default Vue => { components.keys().forEach(fileName => { // 提取组件名 const componentName = fileName.replace(/^\.\//, '').replace(/\.\w+$/, ''); // 获取组件选项对象 const componentConfig = components(fileName); // 全局注册组件 Vue.component(componentName, componentConfig.default || componentConfig); });}还要去src/main.js文件写上 import baseComponents from "./baseComponents";// 注册全局组件Vue.use(baseComponents);接下来你就能够在src/baseComponents的文件夹外面减少你想要组件了。比方src/baseComponents/background.vue而后在你须要用的中央间接用<background/>就能够应用了

July 11, 2023 · 1 min · jiezi

关于vue.js:OpenTiny7月8日即将正式发布

流动简介华为开发者大会2023(HDC.Cloud 2023)将于7月7日-9日在东莞拉开帷幕,本届大会以“每一个开发者都了不起”为主题,同时在寰球10余个国家以及中国30多个城市设有分会场,邀请寰球开发者独特探讨AI浪潮之下的新机会和新可能。大会将重点出现华为云在“AI for Industries”方面的最新进展。作为一场面向寰球开发者的年度盛会,HDC.Cloud致力于为寰球开发者打造一个思维碰撞、技术交换、实操竞技的技术殿堂,让开发者全面理解并把握最新的技术动静,为将来技术创新开辟更广大空间。 本次大会将围绕AI、大数据、数据库、PaaS、aPaaS、媒体服务、云原生、平安、物联网、区块链、开源等各个领域的技术热点、最佳实际以及发展趋势等进行深刻解读和分享。 OpenTiny作为前端企业级组件库解决方案,将在本次大会上正式进行公布。同时也将与各位技术专家和各位开发者开展深度的技术交换和探讨,心愿在开源畛域做出本人的一份奉献和力量。 流动议程分论坛一 5大开源我的项目公布与更新多种底层能力助力开发者实现利用翻新 随着企业云原生化率一直增长,以原生形式开发基于云的微服务成了降本提效的重要伎俩。华为云面向开发者开源了华为云前端框架、后端框架、外围组件、基础设施等多种底层能力,帮忙开发者聚焦于业务逻辑的开发,实现业务利用的疾速构建。工夫:7月8日15:40-16:40地点:东莞溪村H8-1C11会议厅听众收益点: 理解华为云开源整体策略和动向理解基于华为云开源我的项目如何高效构建面向业务场景的云原生利用重点开源我的项目关键技术和个性降级理解更多新兴的云原生开源技术创新议程安顿:查看具体议程>>>分论坛二协同开源社区适配华为云服务让每一位开源爱好者享受开源红利 华为云一直汇聚开源力量,吸引了泛滥开源组织,充分发挥平台劣势协同开源社区适配华为云服务,独特为宽广开发者提供了包含但不限于企业级网关、自动化运维监控、微服务框架、多云环境CI\CD、数据可视化等方面的开源计划。工夫:7月8日17:00-18:00地点:东莞溪村H8-1C11会议厅听众收益点: 华为云如何与开源社区合作,华为云如何与开发者实现共创、共享、共赢,华为云在其中表演的角色开源社区与华为云的开源单干停顿,以及在华为云上做的适配加强给开发者和企业带来哪些收益华为云与开源社区的单干模式,以及参加到华为云开发者生态单干带来的时机议程安顿:查看具体议程>>>分论坛三全系列开源套件一键式构建云原生翻新利用为更好减速云原生利用翻新,华为云面向开发者推出集云原生边缘计算、高性能批量计算、多云多集群治理、分布式云原生服务中心、云原生容器运行时等于一体的云原生全系列开源套件,与各行各业搭档携手共进,减速利用翻新。本次分论坛联结搭档分享华为云云原生基础设施各行业利用及云原生开源在边缘AI云机器人技术创新实际,为搭档利用翻新提供多维度价值。工夫:7月9日14:20-15:20地点:东莞溪村H8-1C11会议厅听众收益点: 案例实际:从电信、政务、机器人、AI修建等实际案例理解行业利用技术赋能:深度理解华为云云原生系列开源套件凋谢合作及利用劣势协力并进:携手行业搭档,摸索云原生开源利用翻新有限可能议程安顿:查看具体议程>>>此外,在为期三天的大会中,为了让大家更深刻的理解华为云开源我的项目,华为云开源还设置了实操挑战赛和训练营,欢送对开源感兴趣小伙伴们报名参会~大会具体议程信息:https://developer.huaweicloud.com/HDC.Cloud2023.html购票通道:https://www.vmall.com/product/10086352254099.html OpenTiny精彩看点 7月8日 重磅公布:OpenTiny正式公布,实现跨端、跨框架、跨版本企业级利用前端。7月8日-7月9日 CodeLabs训练营:【试验】应用OpenTiny实现Vue2我的项目平滑降级到Vue3 a、OpenTiny是一个实现了跨端跨框架的组件库,一套代码同时反对Vue2、Vue3,并且提供了丰盛的拓展性和定制性。b、选手须要创立一个Vue2我的项目,并在其中应用OpenTiny的组件,搭建一个反对增删改查的表格和表单利用c、将以上 Vue2 我的项目平滑降级到到 Vue3试验解说工夫:7月8日15:45-16:45&7月9日13:30-14:307月8日-7月9日 极客挑战赛:【赛题】搭建Playground,玩转跨端跨框架组件库:应用@vue/repl和OpenTiny组件(Button / Select / Pager)创立一个 Playground 代码演练场7月8日-7月9日 展台互动:a、面对面沟通:开发者可间接通过与我的项目负责人近距离沟通交流,阐明痛点和需要,取得产品解决方案。b、我的项目详解:技术专家对我的项目内容进行粗浅剖析拆解,帮忙开发者迅速上手,升高学习老本。c、流动交换:依据理论状况,可进行相应的盖章流动,在交换技术的同时取得更多的体验感。其余阐明 OpenTiny 是一套企业级组件库解决方案,适配 PC 端 / 挪动端等多端,涵盖 Vue2 / Vue3 / Angular 多技术栈,领有主题配置零碎 / 中后盾模板 / CLI 命令行等效率晋升工具,可帮忙开发者高效开发 Web 利用。外围亮点: 跨端跨框架: 应用 Renderless 无渲染组件设计架构,实现了一套代码同时反对 Vue2 / Vue3,PC / Mobile 端,并反对函数级别的逻辑定制和全模板替换,灵活性好、二次开发能力强组件丰盛:PC 端有80+组件,挪动端有30+组件,蕴含高频组件 Table、Tree、Select 等,内置虚构滚动,保障大数据场景下的晦涩体验,除了业界常见组件之外,咱们还提供了一些独有的特色组件,如:Split 面板分割器、IpAddress IP地址输入框、Calendar 日历、Crop 图片裁切等配置式组件: 组件反对模板式和配置式两种应用形式,适宜低代码平台,目前团队曾经将 OpenTiny 集成到外部的低代码平台,针对低码平台做了大量优化周边生态齐全: 提供了基于 Angular + TypeScript 的 TinyNG 组件库,提供蕴含 10+ 实用功能、20+ 典型页面的 TinyPro 中后盾模板,提供笼罩前端开发全流程的 TinyCLI 工程化工具,提供弱小的在线主题配置平台 TinyTheme欢送退出 OpenTiny 开源社区。增加微信小助手:opentiny-official 一起参加共建~OpenTiny 官网:https://opentiny.design/OpenTiny 代码仓库:https://github.com/opentiny/欢送进入 OpenTiny 代码仓库 StarTinyVue、TinyNG、TinyCLI~ ...

July 7, 2023 · 1 min · jiezi

关于vue.js:Vue后台管理的通用布局模块

如果是开发一个管理系统,那么后盾除了登录、注册、404等非凡性能页面,其它各工作模块的界面展示模式基本上是固定的。 为放弃界面风格统一,从可保护和松耦合的角度登程,咱们能够在我的项目中创立一个通用的布局模块。 文档构造比方将该模块分为三局部: 顶部组件(显示logo、项目名称、用户信息等);左侧导航组件(显示导航菜单);右侧工作区组件(显示对应的功能模块); 模块的文档构造如下: 各组件代码/src/layout/index.vue <template><div> <top /> <slider /> <app-main /></div></template><script>import { Top, Slider, AppMain } from './components';export default {name: 'Layout',components: { Top, Slider, AppMain,},};</script><style></style>/src/layout/components/Top.vue <template><div>顶部</div></template><script>export default {name: 'LayoutTop',};</script><style></style>/src/layout/components/Slider.vue <template><div>导航菜单</div></template><script>export default {name: 'LayoutSlider',};</script><style></style>/src/layout/components/AppMain.vue <template><section> <transition name="fade-transform" mode="out-in"> <keep-alive> 工作区 <router-view :key="key" /> </keep-alive> </transition></section></template><script>export default {name: 'AppMain',computed: { key() { return this.$route.path; },},};</script><style></style>在模板中应用了<router-view>标签,它会被对应的功能模块替换。 /src/layout/components/index.js export { default as AppMain } from './AppMain.vue';export { default as Top } from './Top.vue';export { default as Slider } from './Slider.vue';这是模块的素颜展示: ...

July 5, 2023 · 1 min · jiezi

关于vue.js:Vue-Nice-Modal让你的-Modal-调用更轻松

前言笔者去年写过一篇 NiceModal:从新思考 React 中的弹窗应用形式,6 月中旬换了工作,技术栈也由 React + TypeScript 切成了 Vue@2.7 + JavaScript :),然而没有发现 @ebay/nice-modal-react 在 vue 生态中的代替计划,故而有了这篇文章。 对于 React 技术栈写过一篇 2021-2022,我的前端最佳实际,有趣味的同学能够参考浏览。如果本文能对你日常开发产生一些新的思考和效率的晋升,那就太好了!笔者在工作中接触 vue 的工夫也就短短半个月,如有设计不当的中央欢送 PR 一起改良。 Vue Nice Modal - GitHub 在开始进入正题之前,先看看一些与弹窗无关的乏味场景 。 一些乏味的实在场景案例一:全局弹窗 上图是掘金的登录弹窗,未登录状态下触发该弹窗展现的机会有很多,比方: 点击 Header 上的登录按钮文章列表页或详情页点赞以及评论文章发沸点、评论沸点以及点赞沸点...开发者往往会基于第三方组件库定义一个 <LoginModal />,而后将其挂载至 Root 组件下。 这样会带来一些问题: <LoginModal /> 外部逻辑在组件渲染的时候就会执行,即便弹窗处于暗藏状态额定的复杂度。因为存在多个触发机会,须要将 setVisible 以及 setOtherLoginData 透传至 <Main /> 外部的多个子组件,你能够抉择通过 props 一层一层的传递进去(鬼晓得有多少层!),也能够引入工具进行状态共享,但不论怎样,这都不是一件容易的事;随着相似的弹窗越来越多,根组件会保护很多弹窗组件的状态...天知道为什么展现一个弹窗须要在多个文件里重复横跳。展现一个弹窗,为什么会变得如此简单? 以上案例来自 @ebay/nice-modal-react,稍作批改除了上述全局弹窗的场景,还有一种场景也很让人头疼。 案例二:存在分支以及依赖关系的弹窗 用户头疼,开发者也头疼弹窗 1 确认弹出弹窗 2,勾销则弹出弹窗 3,弹窗 2 以及 弹窗 3 也存在对应的分支逻辑,子孙满堂轻而易举,若依照惯例申明式弹窗组件的实现,十分恐怖! Vue Nice Modalvue-nice-modal 是一个工具库,能够将 Vue.js 的 modal 组件转换为基于 Promise 的 API。 ...

July 3, 2023 · 3 min · jiezi

关于vue.js:Vue3-组件通信方式

0. 前言不论是 Vue2 还是 Vue3,组件通信形式很重要,不论是我的项目还是面试都是常常用到的知识点。 回顾一下 Vue2 中组件的通信形式: props:能够实现父子组件、子父组件、甚至兄弟组件通信自定义事件:能够实现子父组件通信全局事件总线 $bus:能够实现任意组件通信pubsub:公布订阅模式实现任意组件通信vuex:集中式状态治理容器,实现任意组件通信ref:父组件获取子组件实例 VC,获取子组件的响应式数据以及办法slot:插槽(默认插槽、具名插槽、作用域插槽)实现父子组件通信示例代码地址:https://github.com/chenyl8848/vue-technology-stack-study 1. propsprops 能够实现父子组件通信,在 Vue3 中能够通过 defineProps 获取父组件传递的数据,且在组件外部不须要引入 defineProps 办法能够间接应用。父组件给子组件传递数据 <template> <div class="box"> <h1>props:我是父组件</h1> <Children :money = "money" :info = "info"></Children> </div></template><script lang="ts" setup>import { ref } from "vue";// 引入子组件import Children from "./Children.vue";// 应用 props 实现父子组件通信let money = ref(1000);let info = ref('发零花钱了')</script><style scoped>.box { width: 1000px; height: 500px; background-color: pink;}</style>子组件获取父组件传递数据: <template> <div> <h2>props:我是子组件</h2> <p>接管父组件传值:{{ props.money }}</p> <p>接管父组件传值:{{ props.info }}</p> <!-- 无奈批改 --> <!-- Set operation on key "money" failed: target is readonly. --> <!-- <button @click="updateProps">批改 props 的值</button> --> </div></template><script lang="ts" setup>// 须要应用到 defineProps 办法去承受父组件传递过去的数据// defineProps是 Vue3 提供办法,不须要引入间接应用//数组|对象写法都能够// let props = defineProps(["money", "info"]);let props = defineProps({ money: { // 接收数据的类型 type: Number, default: 0, }, info: { type: String, required: true, },});// props 是只读的,不能批改// let updateProps = () => {// props.money = 3000;// };</script><style scoped></style>留神:子组件获取到 props 数据就能够在模板中应用,然而切记 props 是只读的(只能读取,不能批改)。2. 自定义事件在 Vue 框架中事件分为两种:一种是原生的 DOM 事件,另外一种自定义事件。 ...

July 3, 2023 · 8 min · jiezi

关于vue.js:vue使用antD的table组件slot采用两个vfor出现的奇怪bug

上代码 <template v-for="i in arr1" :slot="i" slot-scope="text, record"> <span @click="jump(i, record)">{{ text }}</span></template><template v-for="i in arr2" :slot="i" slot-scope="text, record"> <span @click="jump(i, record)">{{ text }}</span></template>上述代码段时写在table中的,arr1和arr2是两个齐全不同的数组,值也没有反复的,然而执行的后果是前面的slot失效,后面的slot不失效。把第二个循环的i改成和第一个循环不一样的j就能够了。 推断上述两个v-for造成的是一个作用域,命名反复会笼罩之前的。有点奇怪的bug

June 30, 2023 · 1 min · jiezi

关于vue.js:闲来无事夏天防止花被渴死

扯淡工夫前段时间,办了一张流量卡。有了新的手机号码那就能够薅一波资本主义的羊毛了,所以我在京东上应用0.1大洋包邮的价格喜提了一个多肉,(在此之前我养过挺多的花,所有的都是忘了浇水被渴死了)此次痛并思痛,肯定要让我0.1大洋的的多肉看到明年的太阳。 思路养花简直不必管,只须要两件事短缺的阳光:我当初住的间隔太阳还是挺近的,阳光的事件不必放心。有养分的土和短缺的水: 土比拟好搞定,去小区的花坛外面扣点就行了,次要就是水,常常想不起来去浇水,所以得搞一个能晓得土壤湿度的货色,揭示我浇水。 我的思路如下收集数据-首先手机花盆外面的土壤湿度存储数据-将花盆的湿度进行长久化存储数据展现告诉-页面通过读取长久化存储的信息展现进去,并能够设定一个预警值,在肯定的规定上面告诉到我思路有了就开干收集数据我的这个实现思路也算是传说中的物联网了,毕竟花盆都上网了嘛,当初实现这种的板子有很多,那个便宜来那个就行了。通过百度一下,抉择了ESP8266-NodeMCU + 湿度传感器 作为数据收集形式(为啥抉择这个呢?因为便宜啊,还自带wifi能上网。硬件真便宜,一共20块搞定,还包邮),esp8266能够应用Arduino进行开发,语法跟c差不多,库啥的本人搜搜吧,我也是本人搜的。俺看的是这个教程收集数据次要是干两件事:1. 读取湿度,2. 上报数据代码如下 #include <ESP8266WiFi.h>#include <ESP8266HTTPClient.h>#include <ArduinoJson.h>// 读取温度#define PIN_AO A0 //土壤传感器AO接ESP8266引脚A0//#define PIN_DO 4 //湿度高于设定值时,DO输入高电平,模块提醒灯亮int M0 = 1024; //在空气中AO读取的值最大为1024,代表干燥时的读数int M1 = 164; //浸泡在水里的最小值 464(最小值会扭转),代表100%湿度float i=0;float j=0;#define SERVER_IP "http://局域网ip:3001/sendCurrentTemp"const char* name = "名字"; //这里改成你的设施以后环境下要连贯的接入点名字const char* password = "明码"; //这里改成你的设施以后环境下要连贯的接入点明码// 上报工夫距离int outTime = 1000 * 60 * 5;// int outTime = 1000 * 60;void setup() { // 设置引脚 pinMode(PIN_AO, INPUT); Serial.begin(115200); // 启动串口通信,波特率设置为115200 Serial.println("未连贯"); Serial.println("开始连贯"); WiFi.begin(name, password); Serial.print("正在连接到"); Serial.print(name); while (WiFi.status() != WL_CONNECTED) //断定网络状态 { delay(500); Serial.print("网络连接胜利"); Serial.print("连贯到的接入点名字:"); Serial.println(name); // 告知用户建设的接入点WiFi名 Serial.print("连贯到的接入点明码:"); Serial.println(password); // 显示用户建设的接入点WiFi明码 Serial.print("无线模式胜利开启,网络连接胜利"); } if (WiFi.status() == WL_CONNECTED) { Serial.print("无线IP地址为: "); Serial.println(WiFi.localIP()); }}void loop() { // put your main code here, to run repeatedly: if (WiFi.status() == WL_CONNECTED) { http_post(); WiFi.forceSleepBegin(); // Wifi Off delay(outTime); WiFi.forceSleepWake(); // Wifi On }}void http_post() { //创立 WiFiClient 实例化对象 WiFiClient client; //创立http对象 HTTPClient http; //配置申请地址 http.begin(client, SERVER_IP); //HTTP申请 Serial.print("[HTTP] begin...\n"); // 长度 DynamicJsonDocument doc(96); float data = analogRead(PIN_AO); Serial.println(data); i = data / 1023; j = (1 - i) * 100; Serial.println(j); // 写入以后温度值 doc["temp"] = j; String output; serializeJson(doc, output); //启动连贯并发送HTTP报头和报文 int httpCode = http.POST(output); Serial.print("[HTTP] POST...\n"); //连贯失败时 httpCode时为负 if (httpCode > 0) { //将服务器响应头打印到串口 Serial.printf("[HTTP] POST... code: %d\n", httpCode); //将从服务器获取的数据打印到串口 if (httpCode == HTTP_CODE_OK) { const String& payload = http.getString(); Serial.println("received payload:\n<<"); Serial.println(payload); Serial.println(">>"); } } else { Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str()); } //敞开http连贯 http.end();}存储数据数据存储,得须要一个服务器,我这里正好一个激动生产买的树莓派,就让他当服务器吧(你要有个这个能够不必买esp8266了,间接开干就完了)我的思路,在树莓派上起一个服务,让esp8266能够通过http的协定上报温度,数据展现也能够通过这个服务来获取数据,当然了我还想外网拜访:我这里用的是花生壳,搞了一个内网穿透,这个送1g流量,6块还能给一个https的域名,省了备案的事件。服务简略的来就应用nodejs启动一个服务吧数据库我应用的SQLite,看人家说这个挺小的,还反对关联查问。代码如下 ...

June 29, 2023 · 3 min · jiezi

关于vue.js:vueelement项目中导出时文件名称从后台获取

在做后盾管理系统我的项目时,导出性能后端个别返回文件流或者链接,前端进行相干解决,明天只说文件流相干内容,之前我的项目中所有的文件名称都是前端进行拼接的,像xxxx-20231002122415.xlsx等等,那下载时文件名称如何从后盾获取呢? 1、首先须要后盾配置 在响应标头中咱们能够看到Content-Disposition:attachment;filename=xxxxx.xlsx信息,filename后边的就是后盾返回的文件名称,个别是进行转码的,然而前端个别是拿不到的,须要后端进行配置: response.setHeader("Access-Control-Expose-Headers", "Content-Disposition")2、配置好后,能够看到相应头部有Access-Control-Expose-Headers信息,这个时候能够从header中拿到该信息, // 获取后盾返回的文件名称 const headerFilename = response.headers["content-disposition"] ?.split(";")[1] .split("=")[1];拿到headerFilename后,因为后端是encode过的,所以前端须要decode下,然而有时会呈现乱码状况,而且decode后在其余浏览器可能也存在问题,这里能够一劳永逸的解决。 应用Node.js的iconv-lite解决中文乱码问题。 if (headerFilename) { // 对文件名乱码本义--【Node.js】应用iconv-lite解决中文乱码 let iconv = require("iconv-lite"); iconv.skipDecodeWarning = true; let fileName = iconv.decode(headerFilename, "utf-8"); data.fileName = fileName; }

June 27, 2023 · 1 min · jiezi

关于vue.js:vueG6-图形化

性能形容 x6(注:id为123)1、g6装置 2、自定义元素(平行四边形) 3、新增、编辑、删除 4、关系新增、编辑、删除 5、悬浮展现气泡 6、元素拖拽获取地位 7、元素显示与暗藏 8、悬停关联线高亮线两边元素 9、选中元素,高亮以后元素及关系兄弟节点及线 10、点击空白处,革除标记状态 g6装置npm install --save @antv/g6 初始化画布plugins:存储的为插件容器container:String | HTMLElement,必须,在 Step 1 中创立的容器 id 或容器自身width:图的宽度height:图的高度fitView:视图居中defaultNode:默认元素款式defaultEdge:默认线款式(设置透明度为0.2,避免线太多,看着错乱)this.graph = new G6.Graph({ plugins: ['tooltip'], // 配置 插件 container: "g-container", // String | HTMLElement,必须,在 Step 1 中创立的容器 id 或容器自身 width: 800, // Number,必须,图的宽度 height: 500, // Number,必须,图的高度 fitView: true, defaultNode: { size: [34, 34], style: { fill: "#ffffff", stroke: "rgba(0,0,0,.35)", lineWidth: 2, cursor: "pointer", radius: [2, 2], opacity: 0.2, }, labelCfg: { style: { fontSize: 14, }, position: "bottom", offset: 5, }, }, defaultEdge: { type: "line", color: "#999999", style: { opacity:0.2, cursor: "pointer", endArrow: { path: G6.Arrow.vee(6, 5, 0), d: 0, fill: "red", cursor: "pointer", lineDash: [0], }, }, labelCfg: { autoRotate: true, style: { background: { fill: "#ffffff", stroke: "#000000", padding: [2, 2, 2, 2], radius: 2, cursor: "pointer", }, }, }, }, }, modes: { default: [ { type: "zoom-canvas", enableOptimize: true, optimizeZoom: 0.9, }, { type: "drag-canvas", enableOptimize: true, }, "drag-node", "brush-select", "click-select", ], }, });读取 Step 2 中的数据源到图上this.graph.data(this.data); // 读取 Step 2 中的数据源到图上渲染图this.graph.render(); // 渲染图气泡悬浮提醒(插件)// 提醒 const tooltip = new G6.Tooltip({ offsetX: 10, offsetY: 40, getContent: (e) => { const outDiv = document.createElement("div"); outDiv.style.width = "fit-content"; outDiv.style.height = "fit-content"; const model = e.item.getModel(); if (e.item.getType() === "node") {//判断是元素还是关系线 outDiv.innerHTML = `${model.id}`; } else { const source = e.item.getSource(); const target = e.item.getTarget(); outDiv.innerHTML = `起源:${source.getModel().id}<br/>去向:${ target.getModel().id }`; } return outDiv; }, });自定义元素// 自定义一个名为 quadrilateral 的节点,通过数据type来判断元素 G6.registerNode( "quadrilateral", { draw(cfg, group) { const size = this.getSize(cfg); // 转换成 [width, height] 的模式 const color = cfg.color; const width = size[0]; const height = size[1]; // / 1 \ // 4 2 // \ 3 / const path = [ ["M", -width / 4, 0 - height / 1.5], // 上部顶点 ["L", width / 2, 0 - height / 1.5], // 右侧顶点 ["L", width / 4, 0], // 下部顶点 ["L", -width / 2, 0], // 左侧顶点 ["Z"], // 关闭 ]; const style = { path: path, stroke: color, ...cfg.style }; // 减少一个 path 图形作为 keyShape const keyShape = group.addShape("path", { attrs: { ...style, }, draggable: true, name: "diamond-keyShape", // 在 G6 3.3 及之后的版本中,必须指定 name,能够是任意字符串,但须要在同一个自定义元素类型中放弃唯一性 }); // 返回 keyShape return keyShape; }, afterDraw(cfg, group) { const size = this.getSize(cfg); // 转换成 [width, height] 的模式 const color = cfg.color; const width = size[0]; const height = size[1]; // / 1 \ // 4 2 // \ 3 / const path = [ ["M", -width / 4, 0 - height / 1.5], // 上部顶点 ["L", width / 2, 0 - height / 1.5], // 右侧顶点 ["L", width / 4, 0], // 下部顶点 ["L", -width / 2, 0], // 左侧顶点 ["Z"], // 关闭 ]; const style = { path: path, stroke: color, ...cfg.style }; // 减少一个 path 图形作为 keyShape const keyShape = group.addShape("path", { attrs: { ...style, }, draggable: true, name: "diamond-keyShape", // 在 G6 3.3 及之后的版本中,必须指定 name,能够是任意字符串,但须要在同一个自定义元素类型中放弃唯一性 }); // 返回 keyShape return keyShape; }, }, // 留神这里继承了 'single-node' "rect" );新增从内部拖拽到画布上,先获取画布的地位坐标point = this.graph.getPointByClient(e.clientX, e.clientY)新增元素(rect为正方形)this.graph.addItem("node", { x: point.x,//x坐标 y: point.y,//y坐标 label: "name", type: "rect", id:'123', size: [100, 100],//大小 style: {//款式 lineWidth: 2, stroke: "#00BBEF", fill: "#DAF3FF", }, nodeStateStyles: {//状态款式 selected: {//选中款式 lineWidth: 1, stroke: "#00BBEF", }, hover: {//悬浮款式 lineWidth: 1, stroke: "#00BBEF", }, }, });设置选中状态this.graph.setItemState(item, "selected", true);勾销选中状态this.graph.setItemState(item, "selected", false);设置悬浮状态this.graph.setItemState(item, "hover", true);勾销悬浮状态this.graph.setItemState(item, "hover", false);编辑更新元素this.graph.updateItem("123", //id{ x: point.x,//x坐标 y: point.y,//y坐标 label: "name", type: "rect", id:'123', size: [100, 100],//大小 style: {//款式 lineWidth: 2, stroke: "#00BBEF", fill: "#DAF3FF", }, nodeStateStyles: {//状态款式 selected: {//选中款式 lineWidth: 1, stroke: "#00BBEF", }, hover: {//悬浮款式 lineWidth: 1, stroke: "#00BBEF", }, }, });删除this.graph.removeItem('123')关系线新增this.graph.addItem("edge", { label: "name", type: "line", id:'edge123', target:'node1',//源 source:'node2',//指标 style: {//款式 lineWidth: 2, lineDash:[8]//虚线 }, nodeStateStyles: {//状态款式 selected: {//选中款式 lineWidth: 1, stroke: "#00BBEF", }, hover: {//悬浮款式 lineWidth: 1, stroke: "#00BBEF", }, }, });编辑更新关系this.graph.updateItem("edge123", //id{ label: "name", type: "line", id:'edge123', target:'node1',//源 source:'node2',//指标 style: {//款式 lineWidth: 2, lineDash:[8]//虚线 }, nodeStateStyles: {//状态款式 selected: {//选中款式 lineWidth: 1, stroke: "#00BBEF", }, hover: {//悬浮款式 lineWidth: 1, stroke: "#00BBEF", }, }, });删除关系this.graph.removeItem('edge123')拖拽元素// 拖动node节点 this.graph.on("node:dragend", (ev) => { console.log(ev); let{x,y} = ev.item.getModel() })元素显示与暗藏//node为元素节点,123为元素的idlet node = this.graph.findById('123')//暗藏node.hide()//显示node.show()悬停关联线高亮线两边元素先监听关联线鼠标移入事件,再监听移除事件鼠标移入时,高亮线及两边元素鼠标移出时,勾销线及两边元素高亮//鼠标悬停线,高亮相干元素 this.graph.on("edge:mouseenter", (e) => { e.stopPropagation(); const source = e.item.getSource(); const target = e.item.getTarget(); //高亮 this.graph.setItemState(source, "hover", true); this.graph.setItemState(target, "hover", true); this.graph.setItemState(e.item, "hover", true); //设置层级最前显示(避免被笼罩) source.toFront() target.toFront() e.item.toFront() //因为初始化了线通明的为0.2,所有这里把透明度设置1,不便查看 this.graph.updateItem(e.item,{ style:{opacity:1} }) });//鼠标悬停线,勾销高亮相干元素 this.graph.on("edge:mouseleave", (e) => { e.stopPropagation(); const source = e.item.getSource(); const target = e.item.getTarget(); //勾销高亮 this.graph.setItemState(source, "hover", false); this.graph.setItemState(target, "hover", false); this.graph.setItemState(e.item, "hover", false); this.graph.updateItem(e.item,{ style:{opacity:0.2} }) });选中元素,高亮以后元素及关系兄弟节点及线1、设置所有元素透明度0.22、高亮过后点击元素,透明度为13、判断线的源数据和指标数据是否和以后点击的节点有关系,有则高亮,无则显示暗度this.graph.on("node:click",ev=>{ if(!ev) return let {id} = ev.tem.getModel() this.graph.setItemState(id,'selected',true) ev.item.toFront(); //用于存储id,革除之前的状态 this.positionId = id //设置所有元素透明度0.2 this.graph.getNodes().forEach(node=>{ this.graph.updateItem(node,{style:{opacity:0.2}}) }) //高亮以后点击元素 this.graph.updateItem(ev.item,{style:{opacity:1}}) //元素居中 this.graph.focusItem(ev.item) //高亮关联线及节点 this.graph.getEdges().forEach(edge=>{ if(edge.getSouce() === ev.item){ this.graph.updateItem(edge.getTarget(),{style:{opacity:1}}) this.graph.updateItem(edge,{style:{opacity:1}}) edge.toFront() }else if(edge.getTarget() === ev.item){ this.graph.updateItem(edge.getSouce(),{style:{opacity:1}}) this.graph.updateItem(edge,{style:{opacity:1}}) edge.toFront() }else{ this.graph.updateItem(edge,{style:{opacity:0.2}}) } })})点击空白处,革除标记状态this.graph.on("canvas:click",()=>{ this.graph.getNodes().forEach(node=>{ if(this.positionId){ //设置所有元素透明度0.2 this.graph.updateItem(node,{style:{opacity:0.2}}) } this.graph.clearItemStatus(node) }) this.graph.getEdges().forEach(edge=>{ if(this.positionId){ //关联线0.2 this.graph.updateItem(edge,{style:{opacity:0.2}}) } this.graph.clearItemStatus(edge) })})

June 27, 2023 · 4 min · jiezi

关于vue.js:在vue中style的用法

一 原生用法`style="width: 100%; margin-top: 20px"` 二 三元表达式 <a :style="{color:(index==0?arr.conFontColor:'#000')}" :href="con.subTitleHref" target="_self">{{con.subTitle}}</a>三 函数用法 <div :style="{ height: tableRowHeight(item) }" class="tableRowCox"> {{ item.id ? item.id : "--" }} </div>四 变量用法 <div :style="{ height:conFontHeight}"> {{ item.id ? item.id : "--" }} </div>

June 27, 2023 · 1 min · jiezi

关于vue.js:vue3fastapi-关于用户模块的思考

对于 Python 生态,Django 有自带的用户模块,然而 fastapi 是没有的 所以,用户这一块,就须要咱们本人实现了 怎么实现呢? 用户模块有这么几个点: 注册登录登出认证咱们离开来讲

June 24, 2023 · 1 min · jiezi

关于vue.js:vue-文档摘要1

vue composition API Composition API: Lifecycle Hooks onBeforeMount 1

June 23, 2023 · 1 min · jiezi

关于vue.js:手牵手带你实现minivue-京东云技术团队

1 前言随着 Vue、React、Angularjs 等框架的诞生,数据驱动视图的理念也深入人心,就 Vue 来说,它领有着双向数据绑定、虚构dom、组件化、视图与数据相拆散等等造福程序员的长处,那 Vue 的双向数据绑定实现原理是什么样的,如果让咱们本人去实现一个这样的双向数据绑定要怎么做呢,本文就与大家分享一下 Vue 的绑定原理及其简略实现 2 核心技术大家都晓得 Vue2 双向绑定是基于 ES5的 Object.defineProperty 办法+公布订阅者模式实现的 那咱们首先简略理解一下这两个模块都是做什么的,在 Vue 中充当了什么角色 2.1 Object.defineProperty用来在对象上定义或者批改一个属性值,实现数据劫持,为批改数据后去调用视图更新做筹备 const obj = {} let age = 18 Object.defineProperty(obj, 'age',{ get() { return age }, set(newVal) { age = newVal + 1 }, enumerable: true }) console.log(obj.age) // 18 obj.age = 20 console.log(obj.age) // 212.2 公布订阅者模式此模式简略来讲就是分为公布和订阅两个概念,订阅意思就是咱们会定义很多个订阅者,每个订阅者都会有本人的 update 办法,把须要更新的订阅者放到数组中,而公布就代表告诉订阅者去顺次执行其 update 办法,从而实现数据更新 // 定义放订阅者的数组function Dep() { this.subs = []}// 定义寄存订阅者的办法Dep.prototype.addSub = function(sub) { this.subs.push(sub)}// 定义公布的办法Dep.prototype.notify = function(sub) { this.subs.forEach(sub => { // 顺次告诉订阅者去执行update办法 sub.update() })}写到这里咱们就把公布和订阅筹备好了,然而还短少订阅者,且订阅者要保障提供一个 update 办法才行,那咱们不禁想到是否去创立一个构造函数,通过这个构造函数创立的实例都会有 update 办法呢 ...

June 19, 2023 · 3 min · jiezi

关于vue.js:asposewordsAsposeWords-for-Java模板语法详细剖析

前言原因aspose-words模板语法再理解垂死病中惊坐起,小丑竟是我本人。对于aspose-words的应用本狗自认为已炉火纯青,遂在新的迭代工作中自告奋勇,并在小姐姐背后吹了一个大牛,分分钟解决完事。 蜜汁自信起源:本狗之前对于aspose-words文章,大家可审阅【屎上最全vue-pdf+Springboot与aspose-words整合,开箱即用】 然而在实操中,打脸来的如此痛彻心扉。对于aspose-words模板标签如if等使用不纯熟,所以特来钻研aspose-words的官网文档,把握aspose-words模板罕用语法,特来与大家分享。 次要指标实现3大重点1. aspose-words**官网文档**2. aspose-words罕用**模板标签**3. aspose-words**我的项目实操**疾速链接公众号:JavaDog程序狗在公众号,发送【aspose】 ,无任何套路即可取得 猜你想问如何与狗哥分割进行探讨1.关注公众号【JavaDog程序狗】公众号回复【入群】或者【退出】,便可成为【程序员学习交换摸鱼群】的一员,问题轻易问,牛逼轻易吹。 此群劣势: 技术交换随时沟通任何私活资源收费分享实时科技动态领先通晓CSDN资源收费下载自己所有源码均群内开源,可收费应用2.踩踩狗哥博客javadog.net 大家能够在外面畅所欲言,随便施展,有问必答 猜你喜爱文章举荐【比照】ChatGPT Plus与ChatGPT实操比照体验 【我的项目实战】SpringBoot+vue+iview打造一个极简集体博客零碎 【我的项目实战】SpringBoot+uniapp+uview2打造H5+小程序+APP入门学习的聊天小我的项目 【我的项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序 【模块分层】还不会SpringBoot我的项目模块分层?来这手把手教你! 【ChatGPT】手摸手,带你玩转ChatGPT 【ChatGPT】SpringBoot+uniapp+uview2对接OpenAI,带你开发玩转ChatGPT 注释aspose-words官网文档https://docs.aspose.com aspose-words罕用模板标签官网文档地址 https://docs.aspose.com/words/java/template-syntax/ 咱们挑3个罕用标签作为示例,其余可自行摸索 1.Using Conditional Blocks(应用条件块) // 通过if标签进行逻辑显隐操作,conditional_expression1是判断条件<<if [conditional_expression1]>>template_option1<<elseif [conditional_expression2]>>template_option2...<<else>>default_template_option<</if>>理论模板中应用 <<if [data.getRecommend().getInformationDepartment()!=null]>><<[data.getRecommend().getInformationDepartment()]>><<else>>信息科感觉同志十分好,批准举荐<</if>>代码解析模板语法意思是如果data.getRecommend().getInformationDepartment()有值就展现,没值则展现【信息科感觉同志十分好,批准举荐】 2.Using Variables(应用变量) // 定义一个s变量为"hello",并输入这个hello<<var [s = “Hello!”]>><<[s]>>理论模板中应用 <<var [s = “人力资源部批准”]>><<[s]>>代码解析模板语法意思是定义一个变量s值为【人力资源部批准】,并输入 3.Merging Table Cells Dynamically(动静合并表单元格) // 应用cellMerge进行合并value1值雷同的列数据<<cellMerge>><<[value1]>>理论模板中应用 <<foreach [item in data.getRecommend().getListPresident()]>> <<cellMerge>> <<[item.getName()]>> <<cellMerge>> <<[item.getSuggest()]>><</foreach>>代码解析模板语法意思将<<cellMerge>>置于想要合并的项,如果数据统一则会合并单元格 我的项目实操展现 总结本文通过Aspose.Words for Java模板语法详细分析,通过Using Conditional Blocks(应用条件块);Using Variables(应用变量);Merging Table Cells Dynamically(动静合并表单元格) 三个模板标签语法进行实操,跟大家介绍一下Aspose.Words for Java中的文档查找办法及如何应用模板语法。感兴趣的博友能够看下我上一篇的文章【屎上最全vue-pdf+Springboot与aspose-words整合,开箱即用】,心愿也能帮到你。 ...

June 16, 2023 · 1 min · jiezi

关于vue.js:高效开发从这里开始人人都能看得懂的快速开发框架

基于Thinkphp和Vue的,前后端拆散的,能够生成前后端代码的,疾速开发框架是一款专为开发者设计的高效开发框架。它基于Thinkphp和Vue技术栈,实现了前后端拆散架构,能够帮忙开发者疾速搭建网站或利用。此外,该框架还具备主动生成前后端代码的性能,极大地提高了开发效率。无论是集体开发者还是企业团队,都能够借助这款框架轻松应答各种开发需要。 SimplestAdmin能够生成前后端残缺的代码,无论是通过数据库表,还是通过表单自定义,都能够一键生成代码; SimplestAdmin能够很好的解决多表关联业务的开发,无论是一对一、一对多还是多对一都能够通过定义关联或者SQL语句主动生成代码; SimplestAdmin反对表单页面,数据表页面,并且内置了泛滥罕用表单和操作方法,能够满足大部分需要的开发; SimplestAdmin次要面向小程序APP开发的利用场景,能够十分不便的开发API,无论是通过表格还是表单,甚至通过复制后端的菜单,都能够一键生成API接口和文档; SimplestAdmin次要面向Web开发前后端程序员和技术爱好者,为了升高学习难度,除了表单化设计开发界面外,咱们还坚定不移的谋求零碎架构的精简和优化,同时基于Thinkphp和Vue框架的低劣基因,零碎具备优良的可扩展性,零碎以“菜单”为外围概念,通过定义字段和办法,别离实现存储和操作数据,概念形象活泼易于了解,适宜初学者疾速把握Web开发,并且通过代码生成服务,对立了开发标准,进步了开发效率。 如果您心愿疾速开发小程序,APP、企业信息管理系统,或者心愿疾速把握Web开发技术,Simplest Admin将是您的最佳抉择!

June 15, 2023 · 1 min · jiezi

关于vue.js:Vuex-介绍

Vuex 介绍原文链接:https://note.noxussj.top/?source=sifo 什么是 Vuex?Vuex 是一个专为 Vue.js 利用程序开发的状态管理模式。它采纳集中式存储管理利用的所有组件的状态,并以相应的规定保障状态以一种可预测的形式发生变化。 你齐全能够了解 vuex 中的状态 state 就是和选项 data 简直截然不同,惟一不同的是选项 data 是定义在组件内的,不同组件之间拜访须要传来传去。而 vuex 中的 state 是全局的,在任何组件内,只须要通过 this.$store.state.$variable 就能拜访了。 Vuex 能够让 Vue 实例内的所有组件共享同一个状态(变量)。因为是共享的,所以多个组件如果同时对一个变量进行间接批改 this.$store.state.$variable = $value,那就会特地容易出问题。而且也毁坏了单向数据流的模式。 装置在咱们应用脚手架搭建我的项目的时候,默认是没有帮咱们装置的。须要本人手动进行装置。装置的 Vuex 插件时须要留神版本信息,Vue2.0 应用的是 vuex3.x ,而 Vue3.0 应用的是 vuex4.x。 通过命令装置 vuex 插件 yarn add vuex@3.6.2 开始应用每一个 Vuex 利用的外围就是 store(仓库)。store 基本上就是一个容器,它蕴含着你的利用中大部分的状态 state 。 Vuex 和单纯的全局对象有以下两点不同 Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地失去高效更新。你不能间接扭转 store 中的状态。扭转 store 中的状态的惟一路径就是显式地提交 (commit) mutation。这样使得咱们能够不便地跟踪每一个状态的变动,从而让咱们可能实现一些工具帮忙咱们更好地理解咱们的利用。根底案例1.创立 store 文件,并且实例化 Vuex.Store。 ...

June 15, 2023 · 1 min · jiezi

关于vue.js:前端数据缓存技术选型及应用技巧

前言在开发过程中很多场景都须要用到前端把数据缓存在端上的能力 业务枚举、标签、配置信息应用利用期间产生的利用/配置数据单用户根底信息依据用户隔离的缓存数据随业务流动增长的数据缓存非凡场景的二进制、媒体数据前端开发者经常会抉择用localStorage来存储须要缓存到前端的数据,然而并不是所有的场景都适宜用这个来治理缓存,滥用还会导致因缓存数据动作失败产生线上问题。 针对不同业务场景,咱们应该抉择不同的计划去缓存数据。本文就针对最常见的存储计划和场景做一些分类和介绍一些在 Vue/React 中的高阶用法,助力前端开发体验和利用的稳定性。同时,缓存键的命名和治理也是值得关注的。 前端缓存计划除了 cookie,咱们个别会有以下几种抉择: 个性sessionStoragelocalStorageindexedDB长久时效以后会话期永恒永恒存储空间5MB5MB依赖可用磁盘空间同步/异步同步同步异步针对不同的个性咱们能够得悉存储到sessionStorage和localStorage中的数据因为存储空间无限都应合乎以下个性: 缓存数据条目必须可控,不可存储累积性/爆发性增长性质的数据单个条目数据不可过大,因而不适宜存储二进制类的数据(例如大文本、图片、音视频等文件)而对于indexedDB,则更适宜存储大文件和数据条目追随业务操作增长的场景。须要留神的是,存取操作都是异步的。 确定不同场景缓存计划针对业务枚举、标签类的,这类的信息往往都是字典数据,数据量不大并且更新不频繁,更新前后改变也不大,这类信息是能够存储到localStorage中的应用利用期间产生的利用/配置数据:这个数据量不大的状况下就能够应用sessionStorage,否则应该思考其余状态治理计划,比方pinia单用户的根底信息这类信息个别状况是用户在登陆胜利之后后端返回的信息,这类信息条目确定,也适宜存储到localStorage依据用户隔离的缓存数据:这个如果用localStorage就不合乎咱们说的数据条目必须可控准则,应该存储到indexedDB中随业务流动增长的数据缓存:这个毋庸置疑应该抉择应用indexedDB,localStorage迟早会爆非凡场景的二进制、媒体数据:这个也应该抉择应用indexedDB标准在一个利用中对于所有缓存的key都应该集中管理,数量多了之后要做分级管理,用枚举来治理,防止随处用随处起名的坏习惯。 咱们能够独自把我的项目应用到的常量独自保护, 从一个进口裸露进来 ├── src│ ├── modules│ │ ├── constant│ │ │ └── cache.ts // 缓存相干│ │ │ └── index.ts // 进口举个子: // cache.tsexport enum CacheKeyEnum { USER_INFO = 'user-info', // ...}// index.tsexport * from './cache'// 应用import { CacheKeyEnum } from '~/modules/constant'function getUserCacheInfo() { return localStorage.getItem(CacheKeyEnum.USER_INFO)}这样在我的项目中对立治理key会让我的项目更易于保护。 在我的项目中更繁难、优雅的操作缓存Vue得益于@vueuse,咱们能够用useStorage办法把对sessionStorage和localStorage的操作简化并且和Vue的响应零碎联合: 第一个参数为缓存的key,对应setItem的第一个参数,第二个参数为初始数据,返回值为一个Ref类型的对象,能够间接操作state.value = { hello: "hello", greetinf: "Hi" }响应式更改缓存中的值,上面是一些文档中的例子: import { useStorage } from '@vueuse/core'// bind objectconst state = useStorage('my-store', { hello: 'hi', greeting: 'Hello' })// bind booleanconst flag = useStorage('my-flag', true) // returns Ref<boolean>// bind numberconst count = useStorage('my-count', 0) // returns Ref<number>// bind string with SessionStorageconst id = useStorage('my-id', 'some-string-id', sessionStorage) // returns Ref<string>// delete data from storagestate.value = nullReact同样的在React中也有相似的库react-use,其中也有useLocalStorage,对应的用法: ...

June 15, 2023 · 2 min · jiezi

关于vue.js:vue3-要区分生产环境和测试环境请求不同的后端接口如何统一配置管理

chatGPT QA 日志 在Vue 3中,你能够应用环境变量和Webpack配置来辨别生产环境和测试环境,并且申请不同的后端接口。以下是一种常见的配置管理办法: 创立不同的环境配置文件: 在你的Vue我的项目的根目录下,创立一个.env文件,用于存储全局环境变量。创立.env.production文件,用于存储生产环境的配置。创立.env.development文件,用于存储开发环境的配置。配置环境变量: 在.env.production文件中,设置生产环境的配置,例如: VUE_APP_API_URL=生产环境的API地址在.env.development文件中,设置开发环境的配置,例如: VUE_APP_API_URL=开发环境的API地址应用环境变量: 在Vue组件中,你能够通过process.env拜访环境变量。例如,在发送申请的中央,你能够这样应用: import axios from 'axios';const apiUrl = process.env.VUE_APP_API_URL;// 应用apiUrl发送申请axios.get(apiUrl + '/data') .then(response => { // 解决响应 }) .catch(error => { // 处理错误 });配置Webpack: 在Vue CLI我的项目中,Webpack用于构建和打包你的代码。你能够在Webpack配置文件中依据环境变量来设置不同的配置。关上vue.config.js文件(如果不存在,则在我的项目根目录下创立它)。在configureWebpack选项中,依据process.env.NODE_ENV来辨别生产环境和开发环境。例如: module.exports = { configureWebpack: { // 生产环境的配置 production: { // ... }, // 开发环境的配置 development: { // ... } }};这样,你就能够依据环境变量来对立配置和治理申请的后端接口。在生产环境中,Vue组件将应用生产环境的API地址发送申请,在开发环境中则应用开发环境的API地址。 Q:怎么设定以后用 .env.production文件还是应用 .env.development文件? A:在Vue CLI中,默认的构建命令会依据不同的环境主动加载相应的.env文件。默认状况下,.env.production文件会在生产环境下加载,而.env.development文件会在开发环境下加载。 如果你应用npm run build命令构建我的项目,则会主动加载.env.production文件中的环境变量。 如果你应用npm run serve命令启动开发服务器,则会主动加载.env.development文件中的环境变量。 如果你心愿手动指定应用特定的环境文件,能够应用--mode标记。例如: # 应用生产环境配置构建npm run build -- --mode production# 应用开发环境配置启动开发服务器npm run serve -- --mode development在上述命令中,--之后的内容被视为参数传递给npm run命令。--mode指定了要应用的环境模式,这将决定加载哪个.env文件。 ...

June 12, 2023 · 1 min · jiezi

关于vue.js:eldatepicker-动态日期范围

Vue2 & element ui <el-date-picker type="daterange" :picker-options="pickerOptions"let _minTime;let _maxTime;let timeRange = 10 * 24 * 60 * 60 * 1000;export default { data() { return { pickerOptions:{ onPick(time) { if (!time.maxDate) { _minTime = time.minDate.getTime() - timeRange; _maxTime = time.minDate.getTime() + timeRange; } else { _minTime = null; _maxTime = null; } }, disabledDate(time) { if (_minTime && _maxTime) { return time.getTime() < _minTime || time.getTime() > _maxTime; } } } }; } ……};Vue3 & element plus ...

June 8, 2023 · 1 min · jiezi

关于vue.js:uniapp主题切换功能的第二种实现方式scss变量require

在上一篇 “uniapp主题切换性能的第一种实现形式(scss变量+vuex)” 中介绍了第一种如何切换主题,但咱们总结出一些不好的中央,例如扩展性不强,保护起来也艰难等等,那么接下我再给大家介绍另外一种切换主题的办法“scss变量+require”的形式 在介绍如何应用前,先看下最初的成果,以便大家能更好的了解,上面是效果图: 除了图上的这个页面切换了外,整体我的项目都有主题色的切换,具体成果可扫码自行查看。 接下来具体介绍下第二种实现形式 实现原理定义两套主题色(多套再本人加)theme-dark.scss、theme-light.scss,每套主题色保护着本人的色彩,通过require动静引入scss的模式引入以后主题,从而达到切换主题的目标 第一步:创立不同主题色创立白天与夜晚模式 创立白天模式common/theme/theme-dark.scss /* 切换主题次要切换的是 整体背景色、区块背景色、文字色彩等 */// 页面主题.theme-page{ background-color: #333 !important; // 文字色彩 .theme-color{ color: #FFF !important; } // 区块主题色 .theme-block{ background-color: #FFFFFF !important; .theme-color{ color: #000 !important; } }}// 如果想独自给集体核心设置一个主题色.theme-user-page{ background-color: #1a1a1a !important; // 文字色彩 .theme-color{ color: #FFF !important; } // 区块主题色 .theme-block{ background-color: #FFFFFF !important; .theme-color{ color: #000 !important; } }}创立夜间模式common/theme/theme-light.scss /* 切换主题次要切换的是 整体背景色、区块背景色、文字色彩等 */// 页面主题.theme-page{ background-color: #FFF !important; // 文字色彩 .theme-color{ color: #333 !important; } // 区块主题色 .theme-block{ background-color: #999 !important; .theme-color{ color: #333 !important; } }}// 如果想独自给集体核心设置一个主题色.theme-user-page{ background-color: #F2F2F2; // 文字色彩 .theme-color{ color: #666 !important; } // 区块主题色 .theme-block{ background-color: #999 !important; .theme-color{ color: #000 !important; } }}货色多了的状况,例如有5套主题色,离开不是很好保护,所以 ...

June 7, 2023 · 3 min · jiezi

关于vue.js:数据流问题

前置常识单向数据流Vue 的单向数据流:指数据个别从父组件传到子组件,子组件没有权力间接批改父组件传来的数据,即子组件从 props 中间接获取的数据,只能申请父组件批改数据再传给子组件。父级属性值的更新会上行流动到子组件中 refs 参考连贯refs的负面影响1refs操作的负面影响2 我的项目存在问题数据流向不明确数据流向不明确 nexttick1.多余的nexttick,有些中央并不需要,并且援用了就会多一个异步 变量办法排查如果一个办法或属性,是要父组件通过$ref去操作,并且在子组件没有调用或发送事件,那么在排查这个办法或属性是否多余时,就很麻烦,得依据子组件的信息向全局搜寻。如遇是单向数据流哪么只须要查找子孙组件(全局注册组件除外) 模板模板 新旧比照新旧比照

June 6, 2023 · 1 min · jiezi

关于vue.js:diff算法核心原理精讲

大家好,我是爱水文的苏学生,一名从业5年+的前端爱好者,致力于用最艰深的文字分享前端常识的酸菜鱼 github与好文手撕vue响应式一文搞懂vue编译器原理与实现手写vue响应式之Object类型的解决typescript中如何优雅的扩大第三方库的类型据说你还在应用原生localStorage?npm包插件化方案设计与实现前言不论是vue2中实现的双端比拟算法,还是vue3中优化过的疾速比拟算法,它们的外围痛点都是相通的:存在哪些必须要解决的问题 咱们只有通晓了实现diff要解决哪些问题,能力在实现过程中去一点点优化 为什么要有diff这世界就是一个因果轮回,没有平白无故的爱,你可能喜爱他有钱,也可能心愿他能给你工作中带来帮忙,又或者,他总是能逗你笑,反正,总要图点什么 因为操作虚构dom带来的性能损耗肯定是大于间接操作实在dom的,所以才要尽可能的缩小虚构dom操作的次数以达到性能更优 由此diff算法诞生 什么是diff当须要对一组节点进行更新时,为了以最小的性能开销实现更新操作,须要对新旧两组节点进行比拟,用于比拟的算法就是diff算法 比照假如有如下两组新旧节点 const olds = { type:"div", el:"DOM援用", children:[ {type:"p",children:"a"}, {type:"p",children:"b"}, {type:"p",children:"c"}, ]}const news = { type:"div", el:"DOM援用", children:[ {type:"p",children:"d"}, {type:"p",children:"e"}, {type:"p",children:"f"}, ]}no diff在无diff的状况下,因为框架只能追溯到文件级别,咱们不得不卸载全副的旧节点,而后后从新去挂载全副的新节点,伪代码如下 function patchChildren(n1,n2){ if(n1 && Array.isArray(n1.children)){ for(let i=0;i<n1.children.length;i++){ n1.el.removeChild(n1.children[i]) } } if(n2 && Array.isArray(n2.children)){ for(let i=0;i<n2.children.length;i++){ n2.el.removeChild(n2.children[i]) } }}能够看到,咱们遍历新旧节点别离进行for循环,一共进行了3次卸载操作和三次增加操作,3+3实践上就是6次 diff先别急,咱们先剖析下示例节点的特点: 1-更新前后的标签元素不变,都是p标签 2-只有p标签的子节点在发生变化 能够看出,只有p标签的子节点不诚实,始终在变,所以咱们要做的是找到哪些不安分的点替换掉,老实人自当留下来好好为公司发明价值才对,为此,只须要进行三次dom操作就够了,我掐指一算,6除以3,好家伙,性能间接翻倍 伪代码如下,咱们新增了patch函数来对新旧子节点进行比对,该函数会仅在发现不同节点时才会执行dom操作 function patchChildren(n1, n2) { if (n2 && Array.isArray(n2.children)) { const oChildrens = n1.children || []; const nChildrens = n2.children; for (let i = 0; i < nChildrens.length; i++) { patch(oChildrens[i], nChildrens[i]); } }}外围原理解说确认遍历主体在比照章节中,咱们通过一个可能算得上比拟糟粕的例子阐明了diff能够更快,但忘了规定一个前置条件了:新旧节点的数量变动雷同。 ...

June 6, 2023 · 3 min · jiezi

关于vue.js:自动化回归测试平台-AREX-前端架构演变史-Tabs-动态组件设计

AREX (http://arextest.com/)是一款开源的基于实在申请与数据的自动化回归测试平台,利用 Java Agent 技术与比对技术,通过流量录制回放能力实现疾速无效的回归测试。同时提供了接口测试、接口比对测试等丰盛的自动化测试性能。 在这个系列中,咱们将会介绍 AREX 前端架构的演变过程,以及在演变过程中遇到的问题和解决方案,一来作为开发过程的教训分享,二来不便大家对 AREX 源码的了解以及二次开发。 Tabs 动静组件设计Tabs organize content across different screens, data sets, and other interactions —— Material DesignTab 组件在前端开发中有着宽泛的利用场景,它可能满足各种不同的需要,如数据展现、导航菜单、表单填写、产品分类、菜单展现、图片幻灯片等多种场景。在 AREX 中也有大量应用 Tabs 组件的场景,其中最具代表性的是 AREX 主工作区。在这篇文章中,我将会介绍 AREX 主工作区中 Tabs 动静组件的设计思路和实现迭代过程。 主工作区是 AREX 的外围性能区域,用户在这里实现 API 调试、录制用例回放、环境治理、利用配置等一系列工作。因为提供的性能泛滥,用户应用流程非线性,常常须要在多个功能模块之间切换,为了提供良好的用户体验和高效的操作形式,AREX 主工作区采纳了 Tab 组件来组织和展现主工作区的不同性能页面模块。 用户在主工作区借助 Tabs 疾速地切换到所需的性能页面,同时 Tabs 在切换时对性能页面进行缓存,防止了频繁地从新初始化性能页面的操作,进步了用户的体验和应用效率。这看起来是一个理所应当且很简略的性能,毕竟 Tabs 自身的性能已在 UI 框架中实现,然而在理论的过程中还是碰到了一些问题。 1.0 —— 原始的条件渲染在 AREX 的晚期版本中,Tabs 组件采纳的是 Ant Design 4.23.0 之前的 JSX 拼接写法。Tabs 组件实现的简化代码如下: <Tabs activeKey={activePane} onEdit={handleTabsEdit} onChange={setActivePane}> {panes.map((pane) => ( <Tabs.TabPane key={pane.key} tab={genTabTitle(pane)} > {pane.paneType === PaneTypeEnum.Replay && ( <Replay data={pane.data as ApplicationDataType} /> )} {pane.paneType === PaneTypeEnum.ReplayCase && ( <ReplayCase data={pane.data as PlanItemStatistics} /> )} </Tabs.TabPane> ))}</Tabs>主工作区中的 panes 负责保护各个性能页面的品种、名称、页面初始化参数等数据,并由全局状态进行治理。当新增或敞开性能页面时,触发 panes 的更新操作。 ...

June 5, 2023 · 3 min · jiezi

关于vue.js:SpringBootVue3Element-Plus-打造分布式存储系统

download:SpringBoot+Vue3+Element Plus 打造分布式存储系统Vue开发仿社交小程序随着社交网络的遍及,社交小程序逐步成为人们日常生活中必不可少的一部分。本篇文章将介绍如何应用Vue框架开发一个仿社交小程序。 技术选型在开始开发之前,咱们须要抉择适合的技术。本文将应用以下技术:Vue.js:一个风行的JavaScript框架。uni-app:基于Vue.js的跨平台开发框架。LeanCloud:一个云服务提供商,用于存储用户数据和公布利用。 创立我的项目首先,咱们须要装置uni-app脚手架工具。关上命令行界面,输出以下命令:npm install -g @vue/cli @vue/cli-initnpm install -g uni-cli而后,通过以下命令创立uni-app我的项目: uni init --default my-project接下来,进入我的项目目录并启动调试服务器: cd my-projectnpm run dev:mp-weixin当初,咱们能够通过微信开发者工具关上我的项目并查看成果。 实现性能在本文中,咱们将实现以下性能:用户登录/注册公布动静查看动静列表点赞/评论3.1 用户登录/注册首先,咱们须要在LeanCloud上创立利用,并且增加一个用户表用于存储用户信息。而后,咱们能够应用uni-app提供的登录组件实现用户登录/注册性能。 <template> <view> <input v-model="username" placeholder="用户名"></input><input v-model="password" placeholder="明码"></input><button @click="login">登录</button><button @click="register">注册</button></view></template> <script>export default { data() { return { username: '', password: ''};}, methods: { login() { // 调用LeanCloud接口进行登录},register() { // 调用LeanCloud接口进行注册}}};</script>3.2 公布动静接下来,咱们须要实现公布动静的性能。咱们能够在LeanCloud上创立一个动静表用于存储动静信息。而后,咱们能够应用uni-app提供的上传图片组件实现上传图片的性能。 <template> <view> <textarea v-model="content" placeholder="说点什么吧"></textarea><input type="file" @change="uploadImage"></input><button @click="submit">公布</button></view></template> <script>export default { data() { return { content: '', image: null};}, methods: { uploadImage(event) { const file = event.target.files[0]; // 调用LeanCloud接口上传图片并获取图片URL},

June 2, 2023 · 1 min · jiezi

关于vue.js:vue3-中使用-Options-API-风格data-中的值都会自动添加响应式吗

是的,官网文档中写了:https://cn.vuejs.org/guide/essentials/reactivity-fundamentals... Vue 将在创立新组件实例的时候调用此函数,并将函数返回的对象用响应式零碎进行包装。相同,如果应用的是 Composition API, 就须要增加 reactive 这些了

May 30, 2023 · 1 min · jiezi

关于vue.js:vue项目使用可选链报错

目前我的项目vue的template模版外面用可选链的时候会报错,相干配置和插件增加后就能够应用了 // vue template模版中反对可选链应用 config.module .rule('vue') .use('vue-loader') .tap(options => { options.compiler = require('vue-template-babel-compiler'); return options; })

May 30, 2023 · 1 min · jiezi

关于vue.js:黑马Vue3-ElementPlus-Pinia-小兔鲜电商项目2023版满面尘灰烟火色

download:黑马Vue3 + ElementPlus + Pinia 小兔鲜电商我的项目2023版Vue3 + Pinia:构建高效响应式状态管理系统Vue3 是最近公布的最新版本的Vue.js前端框架。它具备许多新性能,例如更好的性能、更好的类型推断和更好的可维护性。而Pinia是一个轻量级的Vue.js 状态治理库,它基于Vue3 的响应式API开发,提供了一种优雅且简略的形式来治理您的应用程序的状态。 什么是Pinia?Pinia是一个基于Vue3的状态治理库。 它与Vuex相似,然而更加轻量,易于应用,并且利用了Vue3新的响应式API。Pinia通过应用强类型并充分利用TypeScript中的类型推断来确保更好的代码品质和类型安全性。 如何应用Pinia?Pinia的应用非常简单。 首先,咱们须要装置Pinia: shnpm install pinia而后,在咱们的Vue应用程序中创立Pinia实例: javascriptimport { createPinia } from 'pinia' const pinia = createPinia()当初,咱们能够在任何中央应用咱们的Pinia实例。让咱们开始定义咱们的第一个store: javascriptimport { defineStore } from 'pinia' export const useCounterStore = defineStore({ id: 'counter', state: () => ({ count: 0,}), actions: { increment() { this.count++},},})在这里,咱们定义了一个计数器store,它具备一个名为count的状态和一个名为increment的操作。要应用该store,请应用以下内容: javascriptimport { useCounterStore } from './stores/counter' export default { setup() { const counter = useCounterStore()return { counter,}},}当初,咱们能够在Vue组件内应用counter,并调用increment函数来减少计数器的值: <template> <div> ...

May 30, 2023 · 1 min · jiezi

关于vue.js:VUE中的指令

指令原文链接:https://note.noxussj.top/?source=sifo 指令 (Directives) 是带有 v- 前缀的非凡 attribute。指令 attribute 的值预期是单个 JavaScript 表达式。指令的职责是,当表达式的值扭转时,将其产生的连带影响,响应式地作用于 DOM。 v-show次要作用是显示暗藏元素,通过 display: none 的形式。当表达式成立时,不做任何解决,然而表达式不成立时,则会给元素增加 display: none 属性。 <template> <div class="home"> <span v-show="age > 100">Hello World</span> </div></template><script>export default { data() { return { age: 80 } }}</script> v-if次要作用是显示暗藏元素,和 v-show 相似,然而 v-if 在条件不成立时,不会在 DOM 中渲染该元素。 <template> <div class="home"> <span v-if="age > 100">Hello World</span> </div></template><script>export default { data() { return { age: 80 } }}</script> v-for次要遍历对象或数组,并返回以后项和索引,当然也能够遍历数字以及字符串。应用 v-for 的时候必须要把 key 属性带上,并且 key 是作为惟一值。其中 item 代表每一项的值,index 代表每一项的索引值,这两者都是能够自定义命名的。in list 代表须要遍历的变量名称。 ...

May 28, 2023 · 2 min · jiezi

关于vue.js:Vue3PiniaViteTS-还原高性能外卖APP项目爆竹声中一岁除

Vue3+Pinia+Vite+TS 还原高性能外卖APP我的项目download:3w zxit666 com随着挪动互联网的遍及,外卖成为了古代生存中不可或缺的一部分。对于外卖平台来说,用户体验和性能是至关重要的因素。Vue3与其弱小的性能优化使其成为外卖平台开发的不二抉择。 Vue3与性能Vue3的性能优化从多个方面动手。首先,Vue3引入了新的响应式零碎,利用Proxy代理进行数据劫持,使得对于深度嵌套的数据结构的读取速度大幅晋升,并且升高了内存应用。其次,Vue3还从新设计了虚构DOM算法,比起Vue2,渲染性能进步了30%以上。 此外,Vue3还引入了动态树晋升(Static Tree Hoisting)技术,能够将动态节点在编译时晋升到父级缩小运行时的操作,同时也可能更好地与Webpack等打包工具配合应用,进一步晋升性能。 外卖利用中的性能问题对于外卖利用,其中的性能问题次要集中在以下几个方面: 列表渲染外卖利用中,菜单、店铺列表等都须要进行列表渲染。如果应用Vue2中的v-for指令,在列表数量很大的状况下,性能会受到较大影响。Vue3中引入的懒加载和虚构滚动技术能够无效解决这一问题。 图片加载在外卖利用中,图片是不可或缺的一部分。然而图片过多或者过大都会影响性能。Vue3中能够应用Image组件,对于图片进行懒加载解决,并且反对WebP格局的图片,能够进一步减小图片体积,进步加载速度。 页面切换外卖利用中,频繁的页面切换会使用户体验变得很差。Vue3中的路由懒加载和Keep-Alive组件能够将页面间的切换速度变得更快,并且保障页面之间的状态不会因为从新渲染而产生扭转。 Vue3在外卖利用中的利用利用Vue3的弱小性能优化,在外卖利用中能够带来以下益处: 更快的加载速度通过利用Vue3中的动态树晋升、懒加载、虚构滚动等技术,能够大幅提高利用的加载速度,让用户取得更好的体验。 更晦涩的滑动成果通过应用Image组件进行图片懒加载,并且联合虚构滚动技术,能够让滑动更为晦涩。 更好的用户体验通过应用路由懒加载和Keep-Alive组件,能够缩小页面切换工夫,并且保障状态的不变性,给用户带来更好的体验。 在外卖利用中,Vue3的弱小性能优化尤为重要。通过正当地利用Vue3中的技术,能够让外卖平台具备更好的用户体验和更高的性能。

May 27, 2023 · 1 min · jiezi

关于vue.js:给我关于-vue3-使用-Composition-API-或者-Options-API-的代码样例

Q:“Vue 3 中应用的是 Composition API” 这句话是什么意思?A:"Vue 3 中应用的是 Composition API" 这句话指的是在 Vue 3 版本中引入了一种名为 Composition API 的新的组合式 API 格调。 在 Vue 2 中,应用的是 Options API,其中将组件的选项(如 data、methods、computed 等)别离定义在不同的对象中。这种形式在解决较小的组件时十分不便,但在解决简单的业务逻辑和代码重用方面可能会导致代码难以保护和组织。 为了解决这个问题,Vue 3 引入了 Composition API,它容许开发者依据性能逻辑组织代码,而不是依照选项类型组织。这样,能够更灵便、更直观地组织组件逻辑,并进步代码的可维护性和可重用性。 Composition API 基于函数式编程的思维,通过应用一组函数来组合逻辑相干的代码,而不是将逻辑分布在不同的选项中。开发者能够应用函数式编程的个性,如定义响应式状态、计算属性、生命周期钩子、事件处理等,来编写和治理组件的逻辑。 通过 Composition API,开发者能够更好地组织和复用代码,缩小冗余和反复,同时提供更好的代码可读性和维护性。 须要留神的是,尽管 Vue 3 举荐应用 Composition API,但 Vue 2 中的 Options API 依然是可用的,并且在某些状况下依然是适合的抉择,特地是在迁徙现有的 Vue 2 我的项目到 Vue 3 时。 Q:给我对于 vue3 应用 Composition API 或者 Options API 的代码样例 A:当应用 Vue 3 时,你能够抉择应用 Composition API 或 Options API 来编写代码。上面我将为你提供一个应用 Composition API 的代码样例和一个应用 Options API 的代码样例。 ...

May 21, 2023 · 1 min · jiezi

关于vue.js:vue3-中的使用-ref-和-reactive-定义变量有什么区别该如何选择

在 Vue 3 中,应用 ref 和 reactive 都能够用于定义和治理响应式变量,但它们有一些区别,实用于不同的场景。 ref: ref 用于定义根本类型的响应式变量,如数字、字符串、布尔值等。ref 返回一个包装后的对象,能够通过 .value 属性来拜访和批改变量的值。ref 能够用于在模板中间接应用,不须要应用 .value。示例: import { ref } from 'vue';const count = ref(0); // 定义一个名为 count 的响应式变量,并初始化为 0console.log(count.value); // 读取变量的值,输入: 0count.value++; // 批改变量的值,自增 1console.log(count.value); // 输入: 1reactive: reactive 用于定义简单对象或数据结构的响应式变量。reactive 返回一个响应式的代理对象,能够间接拜访和批改对象的属性。reactive 对整个对象进行响应式转换,因而对于嵌套的属性也是响应式的。示例: import { reactive } from 'vue';const user = reactive({ name: 'John', age: 30,});console.log(user.name); // 读取变量的值,输入: 'John'user.age++; // 批改变量的值,年龄自增 1console.log(user.age); // 输入: 31如何抉择 ref 还是 reactive 取决于你的需要和数据结构: ...

May 21, 2023 · 1 min · jiezi

关于vue.js:atable-在使用了-columns-的情况下怎么在添加额外的一列

<template> <a-table :columns="columns" :data-source="data" class="components-table-demo-nested"> <template #operation> <a>Publish</a> </template> <template #expandedRowRender> <a-table :columns="innerColumns" :data-source="innerData" :pagination="false"> <template #status> <span> <a-badge status="success" /> Finished </span> </template> <template #operation> <span class="table-operation"> <a>Pause</a> <a>Stop</a> <a-dropdown> <template #overlay> <a-menu> <a-menu-item>Action 1</a-menu-item> <a-menu-item>Action 2</a-menu-item> </a-menu> </template> <a> More <down-outlined /> </a> </a-dropdown> </span> </template> </a-table> </template> </a-table></template><script>import { DownOutlined } from '@ant-design/icons-vue';import { defineComponent } from 'vue';const columns = [ { title: 'Name', dataIndex: 'name', key: 'name', }, { title: 'Platform', dataIndex: 'platform', key: 'platform', }, { title: 'Version', dataIndex: 'version', key: 'version', }, { title: 'Upgraded', dataIndex: 'upgradeNum', key: 'upgradeNum', }, { title: 'Creator', dataIndex: 'creator', key: 'creator', }, { title: 'Date', dataIndex: 'createdAt', key: 'createdAt', }, { title: 'Action', key: 'operation', slots: { customRender: 'operation', }, },];const data = [];for (let i = 0; i < 3; ++i) { data.push({ key: i, name: 'Screem', platform: 'iOS', version: '10.3.4.5654', upgradeNum: 500, creator: 'Jack', createdAt: '2014-12-24 23:12:00', });}const innerColumns = [ { title: 'Date', dataIndex: 'date', key: 'date', }, { title: 'Name', dataIndex: 'name', key: 'name', }, { title: 'Status', key: 'state', slots: { customRender: 'status', }, }, { title: 'Upgrade Status', dataIndex: 'upgradeNum', key: 'upgradeNum', }, { title: 'Action', dataIndex: 'operation', key: 'operation', slots: { customRender: 'operation', }, },];const innerData = [];for (let i = 0; i < 3; ++i) { innerData.push({ key: i, date: '2014-12-24 23:12:00', name: 'This is production name', upgradeNum: 'Upgraded: 56', });}export default defineComponent({ components: { DownOutlined, }, setup() { return { data, columns, innerColumns, innerData, }; },});</script>很简略,定义列的时候,就定义好,而后加上 customRender ...

May 19, 2023 · 2 min · jiezi

关于vue.js:vueelementPlus-table自动滚动

依赖"vue": "^3.2.45","element-plus": "^2.2.21" 组件 <el-table ref="table" :height="tableHeight" :data="list" border stripe > <el-table-column align="center" ></el-table-column> <el-table-column align="center" ></el-table-column> <el-table-column align="center" ></el-table-column></el-table>代码 export default { data() { return{ time:'' } }, computed:{ tableHeight(){ let h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; return h-28 } }, mounted() { this.autoScroll(); }, beforeUnmount() { if (this.timer) { clearInterval(this.timer); } }, methods:{ autoScroll(init) { this.$nextTick(() => { const t = 50 const box = this.$el.querySelector('.el-scrollbar__wrap') const content = this.$el.querySelector('.el-table__body') this.timer = setInterval(() => { this.rollStart(box, content) }, t) }) }, rollStart(box, content) { if (box.scrollTop >= (content.scrollHeight - box.offsetHeight)) { box.scrollTop = 0 } else { box.scrollTop++ } } }}成果 ...

May 19, 2023 · 1 min · jiezi

关于vue.js:npm-install-会把-devDependencies-一起安装吗

默认状况下,npm install 命令会装置 package.json 文件中的所有依赖项,包含 dependencies 和 devDependencies。这意味着开发依赖项(devDependencies)也会被装置。 如果你只想装置生产环境依赖项,而不装置开发依赖项,能够应用 --production 标记。例如: npm install --production这将只装置 dependencies 中列出的依赖项,并跳过装置 devDependencies。 另外,如果你应用的是 npm 5.0 或更高版本,devDependencies 会默认被装置。但你能够应用 --only=production 标记来跳过开发依赖项的装置。例如: npm install --only=production这样只会装置 dependencies 中的依赖项。 须要留神的是,在开发过程中,通常会须要装置并应用开发依赖项,例如构建工具、测试库等。而在部署生产环境时,能够通过上述办法跳过装置开发依赖项,只装置生产依赖项,以缩小我的项目的体积和依赖项数量。

May 18, 2023 · 1 min · jiezi

关于vue.js:Vue全局公共服务类mixin

首先,简略介绍下mixin: Mixin是面向对象程序设计语言中的类,提供了办法的实现。其余类能够拜访mixin类的办法而不用成为其子类 Mixin类通常作为功能模块应用,在须要该性能时“混入”,有利于代码复用又防止了多继承的简单 在Vue中,mixin(混入),提供了一种非常灵活的形式,来散发 Vue 组件中的可复用性能。 实质其实就是一个js对象,它能够蕴含咱们组件中任意性能选项,如data、components、methods、created、computed等等咱们只有将共用的性能以对象的形式传入 mixins选项中, 当组件应用 mixins对象时所有mixins对象的选项都将被混入该组件自身的选项中来在Vue中咱们能够部分混入跟全局混入 部分调用: data(){ return:{} }, created() { this.hello() }, methods: { hello () { console.log('hello from mixin!') } }全局调用: 首先,创立一个文件夹mixin并在外面创立一个js文件,例如index.js data(){ return:{ name:'hello' }},mounted(){},created(){},method:{}局挂载实现mixin后,在页面中咱们能够间接调用mixin内定义的办法体,以及data内的属性

May 16, 2023 · 1 min · jiezi

关于vue.js:vue项目中使用unicode引入iconfont动态生成图标的问题

vue我的项目中,采纳unicode引入iconfont,如果动态写图标是能够失常渲染的<i class="iconfront">&#734;</i>然而如果从接口获取数据,间接渲染字符串<i class="iconfront">{{myIcon}}</i> 最初发现应用v-html渲染就能够了<i class="iconfront" v-html="myIcon"></i>

May 15, 2023 · 1 min · jiezi

关于vue.js:script-中定义函数有几种写法为什么有的用-methods-有的用-const

在 Vue 的组件中,有几种常见的形式来定义函数: 应用 methods 对象:您能够在组件的 methods 对象中定义函数。这种形式能够在组件的模板中间接调用这些函数。例如:<script>export default { methods: { handleClick() { // 解决点击事件的逻辑 }, },};</script>应用一般的 JavaScript 函数定义:您能够在 <script> 标签中间接编写 JavaScript 函数,并在须要的中央调用它们。这种形式能够灵便地定义和应用函数。例如:<script>function handleClick() { // 解决点击事件的逻辑}export default { // ...};</script>应用 computed 计算属性:如果您心愿定义一个依据其余数据动静计算得出的函数,能够应用 computed 计算属性。计算属性会依据依赖的数据主动进行更新,而不须要手动调用。例如:<script>export default { data() { return { count: 0, }; }, computed: { doubledCount() { return this.count * 2; }, },};</script>应用 const 申明:如果您只须要在组件的作用域内定义一个函数,并且不须要在模板中间接调用它,能够应用 const 申明一个函数。这种形式次要实用于外部应用的辅助函数。例如:<script>const helperFunction = () => { // 辅助函数的逻辑};export default { // ...};</script>在编写 Vue 组件时,依据您的需要和函数的应用场景,能够抉择适宜的函数定义形式。methods 和一般 JavaScript 函数是最罕用的形式,能够在模板中间接应用。computed 计算属性实用于依据其余数据进行计算的状况。const 申明实用于组件外部的辅助函数或公有函数,不须要在模板中调用。 ...

May 15, 2023 · 1 min · jiezi

关于vue.js:Ant-Design-Vue-定制主题

计划一:全局引入在main.ts中引入组件库款式 @import '~ant-design-vue/dist/antd.less'; // 引入官网提供的 less 款式入口文件@import 'your-theme-file.less'; // 用于笼罩下面定义的变量计划二:按需引入通过less 的modifyVars属性vite.config.js css: { preprocessorOptions: { less: { modifyVars: { //放到一个文件中 hack: 'true; @import "@/styles/theme.less"', //间接应用变量 'primary-color': '#1DA57A', 'link-color': '#1DA57A', 'border-radius-base': '2px', }, javascriptEnabled: true } },},这种办法要留神的是,组件是通过unplugin-vue-components插件来加载的,所以还要配置如下 Components({ dirs: ["src/components"], resolvers: [AntDesignVueResolver({ sideEffect: true, importStyle: 'less' })],}),参考文章:官网 具体参考此文章

May 15, 2023 · 1 min · jiezi

关于vue.js:Ant-Design-Vue-使用-atable-的时候指定列的时候可以使用

Ant Design Vue 应用 a-table 的时候,指定列的时候,能够应用 { title: 'Action', key: 'action', slots: { customRender: 'action', },},其中的 slots 是什么用法? 在 Ant Design Vue 中,a-table 的 columns 属性用于指定表格的列信息。而 slots 属性能够让咱们在表格的某些列中插入自定义的内容。具体来说,slots 属性用于指定特定列的插槽名,以及与该插槽名相关联的自定义渲染函数。 在你提供的代码中,slots 属性的作用是指定 customRender 插槽名,并将其关联到名为 action 的自定义渲染函数。这样,当 Ant Design Vue 渲染表格时,会主动调用该函数并将表格中以后行的数据作为参数传入,最终生成该列对应的内容。在这个例子中, action 列中的内容就是自定义渲染函数 customRender 返回的内容。 须要留神的是,在应用 slots 属性时,须要在模板中应用对应的插槽标签(如 template #customRender)来定义自定义渲染函数的内容。

May 12, 2023 · 1 min · jiezi

关于vue.js:Ant-Design-Vue-的-slots-是干嘛的

在 Ant Design Vue 中,slots 是用来定义组件内容的一种形式。它容许你在组件外部插入一些额定的内容或者批改组件的一部分内容。 在 Ant Design Vue 中,有两种类型的 slots:默认 slot 和命名 slot。 默认 slot 能够了解为组件的次要内容,也是组件的默认展现内容。它是通过在组件外部应用 <slot> 标签定义的,用于在父组件中插入内容。比方,在 <a-table> 组件中,表格的列内容就是通过默认 slot 定义的: <a-table :columns="columns"> <!-- 省略表格数据 --></a-table>命名 slot 则是依据名称来定义组件的内容,这些名称能够由组件的开发者自行定义。命名 slot 是通过在组件外部应用 <template> 标签定义的,用于在父组件中插入特定名称的内容。比方,在 <a-table> 组件中,能够通过 slots 属性来定义一些特定名称的 slot,比方 customRender: <a-table :columns="columns"> <template #customRender="{ text }"> <a-tooltip>{{ text }}</a-tooltip> </template> <!-- 省略表格数据 --></a-table>在下面的例子中,咱们定义了一个名为 customRender 的 slot,用于在表格列中渲染自定义的内容。当 Ant Design Vue 渲染 <a-table> 组件时,会将 customRender slot 的内容插入到对应的表格列中。 应用 slots 能够使 Ant Design Vue 的组件更加灵便,能够通过插入自定义的内容来满足不同的需要。同时,也能够通过定义特定名称的 slot 来加强组件的性能。 ...

May 12, 2023 · 1 min · jiezi

关于vue.js:基于Vue指令系统实现输入框过滤文本数字

官网文档 一个自定义指令由一个蕴含相似组件生命周期钩子的对象来定义。钩子函数会接管到指令所绑定元素作为其参数。指令的定义对象能够提供几种钩子函数: const myDirective = { // 在绑定元素的 attribute 前 // 或事件监听器利用前调用 created(el, binding, vnode, prevVnode) { // 上面会介绍各个参数的细节 }, // 在元素被插入到 DOM 前调用 beforeMount(el, binding, vnode, prevVnode) {}, // 在绑定元素的父组件 // 及他本人的所有子节点都挂载实现后调用 mounted(el, binding, vnode, prevVnode) {}, // 绑定元素的父组件更新前调用 beforeUpdate(el, binding, vnode, prevVnode) {}, // 在绑定元素的父组件 // 及他本人的所有子节点都更新后调用 updated(el, binding, vnode, prevVnode) {}, // 绑定元素的父组件卸载前调用 beforeUnmount(el, binding, vnode, prevVnode) {}, // 绑定元素的父组件卸载后调用 unmounted(el, binding, vnode, prevVnode) {}}钩子参数el:指令绑定到的元素。这能够用于间接操作 DOM。binding:一个对象,蕴含以下属性。 ...

May 11, 2023 · 4 min · jiezi

关于vue.js:通过打包命令中的参数读取不同的系统参数

常常能够在一些我的项目中看到增加了不少的环境变量配置文件,在package.json文件中增加了不少的打包命令。有没有办法实现通过打包命令带上环境参数实现读取不同的参数呢?我想是可行的,在此简略的实现了一下, 首先第一点须要通过node自带的child_process模块读取打包命令中的相干参数 在我的项目根目录中新建build.js文件,在该文件中退出一下代码 const { exec } = require("child_process");const os = require("os");const argv = JSON.parse(process.env.npm_config_argv);const cooked = argv.cooked;const idx = 2;// 通过npm or yarnconst tool = cooked[3] || "npm";const argv1 = process.argv;// 获取打包命令前面的参数process.env.VUE_APP_SYS_ENV = cooked[idx] || argv1[idx] || "default";// 执行打包命令通过shell 脚本命令const shellBuild = () => { exec(`sh build.sh ${tool}`, (error, stdout, stderr) => { console.log(stdout); console.log(stderr); if (error !== null) { console.log(`exec error: ${error}`); } });};// 间接应用node中child_process的exec办法执行打包命令const notShellBuid = () => { let shell = "npm run build"; if (tool === "yarn") shell = "yarn build"; exec(`${shell}`, (error) => { if (error !== null) { console.log(`exec error: ${error}`); } });};if (os.platform() === "win32") { notShellBuid();} else { console.log(os.platform()); shellBuild();}以下是shell 脚本的打包命令可展现打包时长 ...

May 10, 2023 · 1 min · jiezi

关于vue.js:vue项目部署后提示用户有新版本

你可能在浏览器见到过下面这种UI,这是在vue我的项目从新build在服务端部署后,浏览器刷新页面弹出的提醒,这时如果用户点击更新就会重载页面,革除之前的缓存获取最新内容。这是怎么产生的呢?你可能会想到上面的形式: 服务端编译重新部署保护一个版本号,客户端通过轮询检测和本地存储的是否雷同,发现更新的版本就弹框提醒(毛病 耗电。尤其是在挪动端)通过在html中做版本标记...websocket长连贯像客户端推送版本更新(繁琐)service worker通过观察截图左下角的红框,能够看出这个网站采纳形式是 注册了 service worker。 当刷新页面后之前注册的 service worker 的 updated(){} 生命周期中监听到有新的内容可供更新,触发更新弹框,提醒用户更新。 这种形式只需前端解决,不须要服务端做任何工作。只有每次build后从新在服务端部署,有文件产生变动,就能够被service worker发现。 这篇文章就来记录一下怎么做。 引入cli-plugin-pwa参考 vue我的项目引入pwa使网页利用可装置 在下面的根底上,向下进行。 在registerServiceWorker.js增加事件触发/* eslint-disable no-console */import { register } from 'register-service-worker'if (process.env.NODE_ENV === 'production') { register(`${process.env.BASE_URL}service-worker.js`, { ready () { console.log( 'App is being served from cache by a service worker.\n' + 'For more details, visit https://goo.gl/AFskqB' ) }, registered () { console.log('Service worker has been registered.') }, cached () { console.log('Content has been cached for offline use.') }, updatefound () { console.log('New content is downloading.') }, updated (registration) { console.log('New content is available; please refresh.') document.dispatchEvent( new CustomEvent('swUpdated', { detail: registration }) ) }, offline () { console.log('No internet connection found. App is running in offline mode.') }, error (error) { console.error('Error during service worker registration:', error) } })}在updated() {} 中增加swUpdated自定义事件,而后在ReloadPrompt.vue组件中监听事件,有更新时弹出 提醒用户更新。 ...

May 9, 2023 · 2 min · jiezi

关于vue.js:vue项目引入pwa使网页应用可安装

最近在应用vue我的项目时看到一个这样的成果,如图:当初其实有很多网站都反对把网页装置到电脑或手机(IOS Safari反对较好),如下图装置后的成果: 这些都是网页利用。 接下来介绍一下如何让你的vue2我的项目变得能够装置。增加cli-plugin-pwa给现有的vue我的项目增加,应用上面命令: vue add pwa执行完之后会主动在package.json增加"@vue/cli-plugin-pwa","register-service-worker" 依赖。 并且在我的项目src目录下生成registerServiceWorker.js和service-worker.js文件: // registerServiceWorker.js/* eslint-disable no-console */import { register } from 'register-service-worker'if (process.env.NODE_ENV === 'production') { register(`${process.env.BASE_URL}service-worker.js`, { ready () { console.log( 'App is being served from cache by a service worker.\n' + 'For more details, visit https://goo.gl/AFskqB' ) }, registered () { console.log('Service worker has been registered.') }, cached () { console.log('Content has been cached for offline use.') }, updatefound () { console.log('New content is downloading.') }, updated () { console.log('New content is available; please refresh.') }, offline () { console.log('No internet connection found. App is running in offline mode.') }, error (error) { console.error('Error during service worker registration:', error) } })}// service-worker.js 略有改变 以你本人的为准// install new service worker when ok, then reload page.self.addEventListener("message", msg => { if (msg.data && msg.data.type === 'SKIP_WAITING'){ self.skipWaiting() }})而且还会在public/img/icons下生成实用于个平台装置的默认图标,能够本人生成替换即可。 ...

May 9, 2023 · 2 min · jiezi

关于vue.js:vue3-ts-echarts封装一个通用echarts组件20版

闲时基于上次封装的图表组件做了一层优化,话不多说,间接上代码吧Step-1: 新建一个config.ts文件export const config = { labelKey: "name", valueKey: "value",};export type chartDataItemType = { [key: string]: string | number;};// 以后反对显示的图表类型(折线,柱形)export type chartSupportType = "line" | "bar";export type chartDataType = { name: string; data: chartDataItemType[]; type: chartSupportType; labelKey?: string; valueKey?: string; options?: any;};export type chartOptionsType = { [key: string]: any;};// 根底图例色彩数据export const baseColorArr = [ "#3CD7D7", "#F9CB28", "#A089FF", "#5CC4FF", "#FF9292", "#5CC4FF", "#FF8AEC", "#FFB35B",];// 暗影区域色彩数据export const areaColorArr = [ "#C5F3F3", "#FDEFBF", "#dcd3ff", "#bde7ff", "#ffd3d3", "#bde7ff", "#ffd0f7", "#ffe0bd",];// 图例顶部字体大小export const defaultLabelFontsize = 8;export const getColor = (index, type: "default" | "area" = "default") => { const colorArr = type === "default" ? baseColorArr : areaColorArr; const colorIndex = index % colorArr.length; return colorArr[colorIndex];};// 图表底部滚动条默认款式export const defaultDataZoomOptions: any[] = [ { type: "slider", show: true, xAxisIndex: [0], start: 0, end: 30, textStyle: { color: "#ccd7d7", }, },];// 获取滚动条款式export const getDataZoom = (seriesLength, showZoomLength) => { if (seriesLength > showZoomLength) { return defaultDataZoomOptions; } else { return []; }};// 获取折线图、柱形图根底配置export const getLineBarBaseOptions = (seriesLength, showZoomLength = 7) => { return { tooltip: { trigger: "axis", axisPointer: { type: "shadow", }, }, grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true, }, yAxis: { type: "value", }, dataZoom: getDataZoom(seriesLength, showZoomLength), };};// 获取折线系列配置export const getLineSeriesOptions = (index) => { return { tooltip: { trigger: "axis", }, areaStyle: { color: getColor(index, "area"), }, smooth: true, label: { show: true, //开启显示 position: "top", //在上方显示 //数值款式 color: getColor(index, "default"), fontSize: defaultLabelFontsize, }, };};// 获取柱形系列配置export const getBarSeriesOptions = (index) => { return { barWidth: 10, label: { show: true, //开启显示 position: "top", //在上方显示 //数值款式 color: getColor(index, "default"), fontSize: defaultLabelFontsize, }, itemStyle: { borderRadius: [6, 6, 0, 0], }, };};Step-2: 新建一个index.vue文件<!--/*** Author: 前端小高* Date: 2023-05-08 14:58* Desc: MyChart 文件形容*/--><template> <div ref="chartDom" class="chart-dom"></div></template><script name="MyChart" lang="ts" setup>import { ref, computed, watch, onMounted, onBeforeUnmount, PropType, nextTick } from "vue";import * as ECharts from "echarts";import { debounce } from "lodash";import { baseColorArr, chartDataType, chartOptionsType, chartSupportType, chartDataItemType, getLineBarBaseOptions, getLineSeriesOptions, getBarSeriesOptions, config,} from "./config";const props = defineProps({ color: { type: Array as PropType<string[]>, default: () => { return baseColorArr; }, }, // 超过该数字时显示滚动条 showZoomLimit: { type: Number, default: 7, }, // 坐标轴是否两边留白 isBoundaryGap: { type: Boolean, default: false, }, baseOptions: { type: Object as PropType<chartOptionsType>, default: () => { return {}; }, }, data: { type: Array as PropType<chartDataType[]>, require: true, },});const emits = defineEmits(["chart-click"]);const initSeriesData = () => { if (props?.data?.length) { getXAxisDataArr(); const tempSeriesArr = props?.data.map((item: chartDataType, index: number) => { const chartOptions = getSeriesItemOptions(item, index); return { name: item.name, data: getValueArr(item.data, item?.valueKey), type: item.type, ...chartOptions, }; }); const tempLegendDataArr = props?.data.map((item: chartDataType) => item.name); legendDataArr.value = tempLegendDataArr; seriesArr.value = tempSeriesArr; }};const getXAxisDataArr = () => { const labelName = props?.data?.[0]?.labelKey || config.labelKey; const xDataArr = props?.data?.[0]?.data.map((item) => item[labelName]); dataArr.value = xDataArr as string[];};const callbackMap = { line: getLineSeriesOptions, bar: getBarSeriesOptions,};const getSeriesItemDefaultOptions = (type: chartSupportType = "line") => { return callbackMap[type];};const getChartBaseOptions = () => { return getLineBarBaseOptions;};const getSeriesItemOptions = (chartItem: chartDataType, index = 0) => { const cb = getSeriesItemDefaultOptions(chartItem.type); const defaultOptions = cb(index); if (chartItem?.options) { const mergeOptions = Object.assign({}, defaultOptions, chartItem?.options); return mergeOptions; } else { return defaultOptions; }};const getBaseChartOptions = () => { const cb = getChartBaseOptions(); const baseOptions = cb(dataArr.value.length, props.showZoomLimit); if (props?.baseOptions) { const mergeOptions = Object.assign({}, baseOptions, props?.baseOptions); return mergeOptions; } else { return baseOptions; }};const getValueArr = (arr: chartDataItemType[], valueKey?: string) => { const keyName = valueKey ? valueKey : config.valueKey; return arr.map((item) => Number(item[keyName]));};const resizeHandler = () => { chartExample.resize();};const resizeHandlerOrigin = debounce(resizeHandler, 300);const dataArr = ref<any[]>([]);const seriesArr = ref<any[]>([]);const legendDataArr = ref<string[]>([]);const getOptions = computed(() => { const baseOptions = getBaseChartOptions(); const options = { color: props.color, ...baseOptions, legend: { data: legendDataArr.value, }, xAxis: { type: "category", data: dataArr.value, boundaryGap: props.isBoundaryGap, axisTick: { alignWithLabel: true, }, }, series: seriesArr.value, }; return options;});watch( () => props.data, () => { init(); }, { deep: true, });const chartDom = ref();let chartExample: any = null;const initChart = () => { if (chartExample) { // 若存在图表实例,则先执行销毁操作 chartExample.dispose(); } nextTick(() => { chartExample = ECharts.init(chartDom.value); const options = getOptions.value; chartExample.setOption(options, true); initResizerListener(); initChartEvent(); });};const initResizerListener = () => { window.removeEventListener("resize", resizeHandlerOrigin); window.addEventListener("resize", resizeHandlerOrigin);};const initChartEvent = () => { cancelClickEvent(); chartExample.on("click", (params) => { emits("chart-click", params); });};const cancelClickEvent = () => { chartExample.off("click");};const init = () => { initSeriesData(); initChart();};onMounted(() => { init();});onBeforeUnmount(() => { cancelClickEvent(); window.removeEventListener("resize", resizeHandlerOrigin); chartExample.dispose();});</script><style lang="scss" scoped>.chart-dom { height: 300px;}</style>Step-3:页面下的援用形式<!--/*** Author: 前端小高* Date: 2023-05-08 14:55* Desc: ChartComp 图表组件*/--><template> <my-chart :data="dataArr"></my-chart></template><script name="ChartComp" lang="ts" setup>import { ref } from "vue";import { chartDataType } from "@/common/MyChart/config";const dataArr = ref<chartDataType[]>([ { name: "测试数据列1", type: "line", data: [ { name: "1.1", value: 1, }, { name: "1.2", value: 2, }, { name: "1.3", value: 3, }, { name: "1.1", value: 1, }, ], },]);</script>页面展现成果如下 ...

May 8, 2023 · 4 min · jiezi

关于vue.js:基于-Vue-的实时通信平台

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 用 Vue.js 开发出 Web 端的实时交流平台,能够进行一对一聊天、多人群聊,聊天能够发送文字、表情、小文件,用户能够批改增加根本信息、签名、批改裁剪头像,用户能够创立群聊搜寻其余用户来增删本人的好友和群组成员,还有公布动静让好友理解本人过后的动静想法。页面设计采纳响应式网页设计,智能地依据用户行为以及应用的设施环境进行绝对应的布局。具体设计见md文件。 1 绪论1.1 现状剖析1.1.1 国外现状:国外风行的社交软件次要是 Facebook 和 Twitter,尽管国内的咱们因为种种原因很少人会应用这两款软件,但这两款软件仍然吸引了寰球不同人群的青睐。截至 2012 年,Facebook 共累计 9 亿用户,而 Twitter 则累计 1.2 亿用户。 1.1.2 国内现状:当代社交软件堪称百花齐放,QQ、微信、抖音、微博,每款软件都在各自的畛域不停地吸引属于本人的用户。QQ 能够说是国内最长命最有影响的设计聊天软件了,倒退至今被人们认为两极化,要么是学生网恋基地,要么是下班交换发文件场合。除了文字交换,社交软件还有其它办法流传信息,比方抖音的短视频和微博的沙雕图和段子。 当初国内应用最多的实时聊天软件是微信和 QQ,特点是次要是进行通信,发送语音,图片甚至视频。受限于是 Web 端可能要放弃局部性能,不过还是会实现发送文字、表情、图片等基本功能。当初大部分实时聊天软件都有公布动静的性能,像 QQ 的 QQ 空间,微信的朋友圈目标是让用户分享本人和好友的动静,减少互动性和真实性。而且还有让用户批改头像,批改空间背景图片的性能,让用户对本人的账号更有归属感。 1.2 选题背景及意义1.2.1 选题背景:随着互联网的倒退和智能手机的遍及,人们在网络上聊天通信已成为日常,通常状况下咱们会在电脑端装置客户端和在手机装置 app 聊天,但如果在没有聊天软件时须要紧急通信只能破费工夫和流量下载软件,而这时如果有像微信网页版这样的 Web 端利用就能够解决问题了。 所以我想做一个像微信网页版的实时交流平台。应用 Vue.js 开发出 Web 端的实时交流平台,能够进行一对一聊天、多人群聊,聊天能够发送文字、表情、小文件,用户能够批改增加根本信息、签名、批改裁剪头像,用户能够创立群聊搜寻其余用户来增删本人的好友和群组成员,还有公布动静让好友理解本人过后的动静想法。页面设计采纳响应式网页设计,智能地依据用户行为以及应用的设施环境进行绝对应的布局。

May 8, 2023 · 1 min · jiezi

关于vue.js:uniapp-用-Server-Sent-EventSSE长请求

1.创立eventsource.js文件(eventsource.js的代码在最初面)2.引入 import { EventSourcePolyfill } from "@/utils/eventsource.js";3.调用 getPresentMsg(){ let _this = this; let url = 'http://192.168.110.183:90' this.source = new EventSourcePolyfill( url + "/worship/memPresentRecord/presentMsg?type=0&memorialId="+this.memorial.id, { headers: { // Authorization: "Bearer " + getToken(), "Content-Type": "text/event-stream;charset=UTF-8", "Cache-Control": "no-cache", Connection: "keep-alive", }, //重连工夫距离,单位:毫秒,默认45000毫秒,这里设置为10分钟 heartbeatTimeout: 10 * 60 * 1000, } ); this.source.onopen = () => { console.log(1, "NOTICE建设连贯"); }; this.source.onmessage = (e) => { // _this.scrollMessage = e.data; let presentId =JSON.parse( e.data).presentId if( presentId){ let obj=jipinList.find(item=>{ return item.id ==presentId }) _this.toSacrifice(obj) } }; this.source.onerror = (e) => { if (e.readyState == EventSource.CLOSED) { console.log(3, "NOTICE连贯敞开"); } else if (this.source.readyState == EventSource.CONNECTING) { console.log(4, "NOTICE正在重连"); //从新设置header // this.source.headers = { // Authorization: "Bearer " + getToken(), // }; } else { console.log(5, e); } }; },eventsource.js的代码/** @license ...

May 8, 2023 · 2 min · jiezi

关于vue.js:使用vite构建Vue3组件库发布npm包

应用vite构建Vue3组件库,公布npm包在国内用vue框架开发的是十分之多的,应用vue开发组件封装是一个很普片的事件了,封装好一个组件能够在我的项目的任意中央去应用,咱们还能够从npm仓库下载他人封装的组件进行应用,比方element-ui,vant等组件库,然而因为不同的公司,不同的网站格调,是咱们在开发中还是得本人封装本人的组件,要想在不同我的项目上应用本人封装的组件,不可能去旧我的项目复制组件代码到新的我的项目外面去。所以咱们能够将组件上传到npm仓库,应用的时候间接从npm装置应用。1.创立根底的vite 脚手架npm create vite vite-demo(项目名称) --template vue 而后如下图所示,我的项目名为vite-demo 而后抉择vue框架,抉择vue 2.革新vite-dome创立好根本我的项目后,用本人相熟的编程软件关上艳羡,在控制台输出npm i装置相干的包并对文件进行革新 如下图: 3.组件封装3.1创立组件文件在src\components文件加下新建一个muk-ui用于寄存所有的组件文件,在muk-ui文件夹中创立一个button组件如图所示 3.2编写组件留神这里我是用了less布局,所以要下载less包,npm i less装置less包。要想前面导出的时候应用name属性,必须定义name属性,因为setup语法糖不反对定义name属性,所以咱们能够定义两个script标签,也能够不必setup语法糖,还能够应用插件解决,这里就不说是什么插件了,放个连贯本人去看<script setup>/** * 接管传过来的值 * * @param size 定义按钮的大小 可选值为 'large' | 'middle' | 'small' | 'mini' * @param type 定义按钮的类型 默认不填 */defineProps({ size: { type: String, default: "middle", }, type: { type: String, default: "default", },});</script><script>export default { name: "MukButton",};</script><template> <button class="muk-btn" :class="[size, type]"> <!-- 定义插槽用于让用户自定义按钮你们的内容 --> <slot></slot> </button></template><style scoped lang="less">.muk-btn { appearance: none; border: none; outline: none; background: #fff; text-align: center; border: 1px solid transparent; border-radius: 4px; cursor: pointer;}.large { width: 240px; height: 50px; font-size: 16px;}.moddle { width: 180px; height: 50px; font-size: 16px;}.small { width: 100px; height: 32px;}.mini { width: 60px; height: 32px;}.default { border-color: #e4e4e4; color: #666;}.primary { border-color: skyblue; background: skyblue; color: #fff;}.plain { border-color: skyblue; color: skyblue; background: lighten(skyblue, 50%);}.gray { border-color: #ccc; background: #ccc; color: #fff;}</style>3.3导出组件在src\components\muk-ui文件夹下新建index.js用于导出组件 ...

April 28, 2023 · 2 min · jiezi

关于vue.js:你到底懂不懂-Transition-组件

前言欢送关注同名公众号《熊的猫》,文章会同步更新!<Transition> 作为一个 Vue 中的内置组件,它能够将 进入动画 和 来到动画 利用到通过 默认插槽 传递给指标元素或组件上。 兴许你有在应用,然而始终不分明它的原理或具体实现,甚至不分明其外部提供的各个 class 到底怎么配合应用,想看源码又被其中各种引入搞得七荤八素... 本篇文章就以 Transition 组件为外围,探讨其外围原理的实现,文中不会对其各个属性再做额定解释,毕竟这些看文档就够了,心愿可能给你带来帮忙!!! Transition 内置组件触发条件<Transition> 组件的 进入动画 或 来到动画 可通过以下的条件之一触发: 由 v-if 所触发的切换由 v-show 所触发的切换由非凡元素 <component name="x"> 切换的动静组件扭转非凡的 key 属性再分类其实咱们能够将以上状况进行 再分类: 组件 挂载 和 销毁 v-if 的变动<component name="x"> 的变动key 的变动组件 款式 属性 display: none | x 设置 v-show 的变动【扩大】v-if 和 v-for 一起应用时,在 Vue2 和 Vue3 中的不同在 Vue2 中,当它们处于同一节点时,v-for 的优先级比 v-if 更高,即 v-if 将别离反复运行于每个 v-for 循环中,也就是 v-if 能够失常拜访 v-for 中的数据在 Vue3 中,当它们处于同一节点时,v-if 的优先级比 v-for 更高,即此时只有 v-if 的值为 false 则 v-for 的列表就不会被渲染,也就是 v-if 不能拜访到 v-for 中的数据六个过渡机会 总结起来就分为 进入 和 来到 动画的 初始状态、失效状态、完结状态,具体如下: ...

April 28, 2023 · 4 min · jiezi

关于vue.js:ISM-Web组态监控软件

ISM Web组态软件采纳Vue+Go语言开发,通过浏览器操作组态工具、浏览组态画面,实现工程治理、组态编辑、工业设施采集以及组态运行三大性能。通过实现图元组态、可视化图表组态、数据库组态的配置与关联,实现基于Web服务的实时数据监控与服务端的多用户拜访等。采纳规范HTML5技术,基于B/S架构进行开发,反对WEB端出现,反对在浏览器端实现便捷的人机交互,简略的拖拽即可实现可视化页面的编排设计。反对Windows、Centos等其余基于Linux内核的零碎。具备安装简单、操作不便、性能实用等特点。 官方网站: http://www.ismctl.com/ 在线体验:http://demo.ismctl.com:8081/ 愿景打造国内收费组态软件新篇章。愿所有中小企业都能应用到收费组态软件,赋能数据可视化。 提供价值为企业可视化赋能:高效快捷的可视化工具,把有形的数据变成有意义、清晰可见的展现;数据驱动显示,让咱们更专一业务自身,进步生产力;0代码就能够实现实时的数据采集、数据动效。

April 28, 2023 · 1 min · jiezi

关于vue.js:项目实战SpringBootvueiview打造一个极简个人博客系统

我的项目介绍集体极简博客【集体极简博客】是一个实用于初学者学习的博客零碎,其中蕴含文章分类、写文章、标签治理、用户治理等根底性能,代码简洁正文欠缺,易上手学习。技术栈基于SpringBoot+MybatisPlus+vue+iview等更多优良组件及前沿技术开发,正文丰盛,代码简洁,开箱即用。极其适宜尝试全栈开发及实战练手训练也能够当作毕业设计进行二次开发,是个轻松学习的好机会。 <p align="center"> <p align="center"> <a href="https://cn.vuejs.org/"> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2cbacee30e364a079bc858c759e35be8~tplv-k3u1fbpfcp-zoom-1.image" alt="iview"> </a> <a href="https://www.uviewui.com/"> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1be593e8e6ff4596998f36c336ac5cbc~tplv-k3u1fbpfcp-zoom-1.image" alt="iview"> </a> <a href="https://shiro.apache.org/"> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/139b927a083d4748b5114e3c5d85b0b4~tplv-k3u1fbpfcp-zoom-1.image" alt="shiro"> </a> <a href="http://spring.io/projects/spring-boot"> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/09465b4cc1094e68b870996769876b8b~tplv-k3u1fbpfcp-zoom-1.image" alt="spring-boot"> </a> <a href="http://mp.baomidou.com"> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d85f9c1d28564a9dad89e9b662a23790~tplv-k3u1fbpfcp-zoom-1.image" alt="mybatis-plus"> </a> <a href="http://hutool.cn/"> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/24ad29ffa17b45358ff0b9359ca4c05b~tplv-k3u1fbpfcp-zoom-1.image" alt="mybatis-plus"> </a> <a href="./LICENSE"> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b12324744e654191adb46ed5465dc6fd~tplv-k3u1fbpfcp-zoom-1.image" alt="license Apache 2.0"> </a></p></p> 疾速链接公众号:JavaDog程序狗关注公众号,发送 【blog】或【博客】,无任何套路即可取得 体验地址拜访地址集体极简博客 http://myblog.javadog.net 猜你喜爱文章举荐【我的项目实战】SpringBoot+uniapp+uview2打造H5+小程序+APP入门学习的聊天小我的项目 【我的项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序 【模块分层】还不会SpringBoot我的项目模块分层?来这手把手教你! 【ChatGPT】手摸手,带你玩转ChatGPT 【ChatGPT】SpringBoot+uniapp+uview2对接OpenAI,带你开发玩转ChatGPT 猜你想问1.如何熟练掌握全栈技术2.如何将学到的常识利用理论我的项目关注公众号【JavaDog程序狗】,任何留言发问我都会一一回复,如果有须要能够间接分割我,有问必答 次要功能模块️模块思维导图 web前端页面首页用户通过域名根门路拜访,如http://myblog.javadog.net/,查看首页文章列表,以时间轴模式展现已公布的文章 文章详情用户通过文章列表点击后,跳转文章详情,其中蕴含文章题目、分类、标签、公布工夫等 ⛄admin后盾治理用户拜访http://myblog.javadog.net/#/admin,如果登录受权过则跳转后盾,否则跳转登录注册页 注册未创立后盾用户时,填入用户名、明码、确认明码进行注册 登录已创立后盾用户时,填入用户名、明码进行登录 首页登陆后默认关上【admin欢送页】,前期可依据访问量进行首页大屏剖析图展现迭代 文章所有文章点击【所有文章】,展现所有文章列表,列表蕴含题目、状态、分类、标签、拜访、公布工夫等,操作列中蕴含预览、编辑、删除等按钮 分类目录点击【分类目录】,左侧展现所有表单名称、形容,可新增更新;右侧展现分类列表 写文章点击【写文章】,其中蕴含markdown编辑器,文章题目,点击【公布】后,弹出文章设置,表单包含文章题目、分类、标签、摘要,可点击公布或者抉择搁置草稿箱 标签点击【标签】,左侧展现表单标签名、色彩,可新增更新;右侧平铺展现标签 用户个人资料点击【个人资料】,左侧展现个人信息表单包含头像、昵称、性别、出生日期、简介,可进行更新;右侧展现批改密码表单包含原始明码、新密码、确认明码,可进行明码批改 组件后端组件插件版本用处jdk1.8java环境lombok1.18.16代码简化插件maven3.6.3包管理工具druid1.1.24JDBC组件hutool5.7.20Java工具类库mybatis-plus3.4.1基于 MyBatis 加强工具mysql8.0 / 5.7数据库前端组件插件版本用处vue^2.6.10渐进式的 JavaScript 框架iview^4.0.2一套基于 Vue.js 的高质量UI 组件库vue-router^3.0.6为 Vue.js 提供富裕表现力、可配置的、不便的路由vuex^3.2.0一个专为 Vue.js 利用程序开发的状态管理模式 + 库vue-color^2.8.1色彩选择器插件moment^2.29.4js工具库axios^1.3.2一个基于promise的网络申请库core-js^3.27.2JavaScript 的模块化规范库mavon-editor^2.10.4基于 Vue 的 Markdown 编辑器组件代码结构图后端代码 ...

April 26, 2023 · 1 min · jiezi

关于vue.js:使用Ref还是Reactive

我喜爱Vue 3的Composition API,它提供了两种办法来为Vue组件增加响应式状态:ref和reactive。当你应用ref时到处应用.value是很麻烦的,但当你用reactive创立的响应式对象进行重构时,也很容易失落响应性。 在这篇文章中,我将阐释你如何来抉择reactive以及ref。 一句话总结:默认状况下应用ref,当你须要对变量分组时应用reactive。Vue3的响应式在我解释ref和reactive之前,你应该理解Vue3响应式零碎的基本知识。 如果你曾经把握了Vue3响应式零碎是如何工作的,你能够跳过本大节。很可怜,JavaScript默认状况下并不是响应式的。让咱们看看上面代码示例: let price = 10.0const quantity = 2const total = price * quantityconsole.log(total) // 20price = 20.0console.log(total) // ⚠️ total is still 20在响应式零碎中,咱们冀望每当price或者quantity扭转时,total就会被更新。然而JavaScript通常状况下并不会像预期的这样失效。 你兴许会嘀咕,为什么Vue须要响应式零碎?答案很简略:Vue 组件的状态由响应式 JavaScript 对象组成。当你批改这些对象时,视图或者依赖的响应式对象就会更新。 因而,Vue框架必须实现另一种机制来跟踪局部变量的读和写,它是通过拦挡对象属性的读写来实现的。这样一来,Vue就能够跟踪一个响应式对象的属性拜访以及更改。 因为浏览器的限度,Vue 2专门应用getters/setters来拦挡属性。Vue 3对响应式对象应用Proxy,对ref应用getters/setters。上面的伪代码展现了属性拦挡的基本原理;它解释了外围概念,并疏忽了许多细节和边缘状况: function reactive(obj) { return new Proxy(obj, { get(target, key) { track(target, key) return target[key] }, set(target, key, value) { target[key] = value trigger(target, key) }, })}proxy的get和set办法通常被称为代理陷阱。 这里强烈建议浏览官网文档来查看无关Vue响应式零碎的更多细节。 reactive()当初,让咱们来剖析下,你如何应用Vue3的reactive()函数来申明一个响应式状态: import { reactive } from 'vue'const state = reactive({ count: 0 })该状态默认是深度响应式的。如果你批改了嵌套的数组或对象,这些更改都会被vue检测到: ...

April 24, 2023 · 4 min · jiezi

关于vue.js:vue3-模板编译-把-vmodel-默认改为-vmodelvalue

前言在 Vue3 中,v-model 指令默认绑定到组件的 modelValue 属性上。 但如果咱们想要的是默认绑定到 value 属性呢?咱们能够应用 AST(形象语法树) 转换来实现这一点。 在线演示 vite.config.ts import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import { transformModel } from './transformModel'export default defineConfig({ plugins: [ vue({ template: { compilerOptions: { nodeTransforms: [transformModel] } } }) ]}) transformModel.ts import { NodeTransform, findDir, createSimpleExpression } from '@vue/compiler-core'const ELEMENT = 1export const transformModel: NodeTransform = node => { if (node.type != ELEMENT) return const VModel = findDir(node, 'model') // v-model 没有传入绑定的属性,则将属性绑定到 value // e.g. v-model => v-model:value // e.g. v-model:xxx => v-model:xxx if (VModel && VModel.arg == null) { VModel.arg = createSimpleExpression('value', true, undefined, 3) }} 以上就是残缺代码了 ...

April 24, 2023 · 1 min · jiezi

关于vue.js:vue3-模板编译-我竟把-vif-和-vfor-的优先级改回来了不信你看-

家喻户晓,在 vue3 中 v-if 总是优先于 v-for 失效 然而,在某些状况下,咱们可能更心愿 v-for 的优先级更高,以便在渲染组件之前先遍历数据列表。 尽管 vue3 并没有提供间接批改指令优先级的办法,然而咱们能够应用 AST(形象语法树) 转换来实现这一点。 在线演示 vite.config.ts import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import { transformForIf } from './transformForIf'export default defineConfig({ plugins: [ vue({ template: { compilerOptions: { nodeTransforms: [transformForIf] } } }) ]}) transformForIf.ts import { remove } from '@vue/shared'import { NodeTransform, findDir, findProp } from '@vue/compiler-core'const ELEMENT = 1// 创立 template 节点export const createTemplateNode = (props: BaseElementNode['props'], children: BaseElementNode['children'], loc: BaseElementNode['loc']): TemplateNode => ({ type: ELEMENT, tagType: TEMPLATE, tag: 'template', props: props.filter(e => e), children, codegenNode: undefined, ns: 0, isSelfClosing: false, loc})export const transformForIf: NodeTransform = node => { if (node.type != ELEMENT) return node.children.forEach((child, i) => { if (child.type != ELEMENT) return const VFor = findDir(child, 'for') if (!VFor) return const VIf = findDir(child, 'if') if (!VIf) return const key = findProp(child, 'key') remove(child.props, VFor) remove(child.props, VIf) remove(child.props, key) const templateIf = createTemplateNode([VIf], [child], VIf.loc) const templateFor = createTemplateNode([VFor, key], [templateIf], VFor.loc) node.children[i] = templateFor })} 以上就是残缺代码了 ...

April 24, 2023 · 1 min · jiezi

关于vue.js:vue预览word-excel

html <elTable :columns="columns" :download="true" :dataContent="dataContent" :detail="false" @goDetail="goDetail" @download="download" @tname="tname" /> <a-modal :visible="showModel1" title="附件预览" width="900px" wrapClassName="modalyl" maskClosable="true" @cancel="close1" > <div id="center-file" class="center-file" style="margin: auto"></div> </a-modal> <a-modal :visible="showModel2" title="附件预览" width="1200px" wrapClassName="modalyl" @cancel="close2" > <div class="table-html-wrap" v-html="tableHtml"></div> </a-modal>子组件html<div class="elTable"> <a-table v-if=" defaultExpandAllRows ? dataContent && dataContent.content && dataContent.content.length > 0 : true " :columns="columns" :data-source="dataContent.content" :defaultExpandAllRows="defaultExpandAllRows" :scroll="{ y: '100%' }" bordered :pagination=" dataContent && dataContent.content && dataContent.content.length > 10 ? pagination : false " :rowClassName="tableRowClassName" :rowKey=" (record, index) => { return record.pc; } " :customRow="customRowClick" @change="handleTableChange" > <a slot="templateName" slot-scope="text, record" @click="tname(record)">{{ record.templateName }}</a> </a-table> tname(item: any) { this.$emit('tname', item); }jsimport XLSX from 'xlsx';import { defaultOptions, renderAsync } from 'docx-preview';columns: any = [ { title: '模版名称', dataIndex: 'templateName', key: 'templateName', scopedSlots: { customRender: 'templateName' }, ellipsis: true, }] async tname(item: any) { let option = qs.stringify({ templateId: item['id'], }); if (item.objectName.indexOf('docx') !== -1) { let option = qs.stringify({ templateId: item['id'], }); this.showModel1 = true; let res: any = await api.downLoadTemplate(option); document.getElementById('center-file').innerHTML = ''; let blob = new Blob([res], { type: 'application/docx' }); renderAsync(blob, document.getElementById('center-file'), null, { className: 'docx', // 默认和文档款式类的类名/前缀 inWrapper: false, // 启用围绕文档内容渲染包装器 ignoreWidth: false, // 禁止页面渲染宽度 ignoreHeight: false, // 禁止页面渲染高度 ignoreFonts: false, // 禁止字体渲染 breakPages: true, // 在分页符上启用分页 ignoreLastRenderedPageBreak: true, //禁用lastRenderedPageBreak元素的分页 experimental: false, //启用试验性功能(制表符进行计算) trimXmlDeclaration: false, //如果为真,xml申明将在解析之前从xml文档中删除 debug: false, // 启用额定的日志记录 }); } else if (item.objectName.indexOf('xlsx') !== -1) { this.showModel2 = true; let res: any = await api.downLoadTemplate1(option); this.tableHtml = ''; let workbook = XLSX.read(new Uint8Array(res), { type: 'array' }); var worksheet = workbook.Sheets[workbook.SheetNames[0]]; var innerHTML = XLSX.utils.sheet_to_html(worksheet); this.tableHtml = innerHTML; } else { this.$message.error('此附件暂不反对预览,请下载后查看'); } }

April 21, 2023 · 2 min · jiezi

关于vue.js:element-plus-vue3中回车enter键-点击button

写法element plus或者说vue3曾经废除了.naive的写法,在vue3中须要新写监听器 依据材料:https://blog.csdn.net/cqlcqlcui123/article/details/130141190,能够这样实现,只不过材料是composition格调的API,如果想要用选项式API(vue2那种),能够有如下: export default { methods: { enter_up(e){ console.log('in enter up') if (e.keyCode == 13 || e.keyCode == 100) { console.log('success') } }, }, mounted(){ window.addEventListener('keydown', this.enter_up) }, unmounted(){ window.removeEventListener('keydown', this.enter_up, false) }}<el-button type="primary" @keydown.enter="enter_up()">enter success</el-button>补充vue3的API格调: https://blog.csdn.net/m0_49271518/article/details/127464168https://cn.vuejs.org/guide/extras/composition-api-faq.html#mo...

April 21, 2023 · 1 min · jiezi

关于vue.js:npm-ERR-Could-not-resolve-dependency-npm-ERR-peer

问题:npm install:Could not resolve dependency:peer... 解决办法:https://blog.csdn.net/q375537943/article/details/126508268

April 19, 2023 · 1 min · jiezi

关于vue.js:Vue3相关源码Vuex源码解析

本文基于Vuex 4.1.0版本源码进行剖析文章内容应用简略的源码展现Vuex的用法,并且基于用法中所波及到的源码进行剖析 介绍上面的介绍摘录于Vuex官网文档,总结起来就是Vuex是一个具备响应式和肯定规定的全局数据管理对象Vuex 是一个专为 Vue.js 利用程序开发的状态管理模式 + 库。它采纳集中式存储管理利用的所有组件的状态,并以相应的规定保障状态以一种可预测的形式发生变化 const Counter = { // 状态 data () { return { count: 0 } }, // 视图 template: ` <div>{{ count }}</div> `, // 操作 methods: { increment () { this.count++ } }}createApp(Counter).mount('#app')这个状态自治理利用蕴含以下几个局部: 状态,驱动利用的数据源;视图,以申明形式将状态映射到视图;操作,响应在视图上的用户输出导致的状态变动。以下是一个示意“单向数据流”理念的简略示意: 然而,当咱们的利用遇到多个组件共享状态时,单向数据流的简洁性很容易被毁坏: 多个视图依赖于同一状态。来自不同视图的行为须要变更同一状态。对于问题一,传参的办法对于多层嵌套的组件将会十分繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,咱们常常会采纳父子组件间接援用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式十分软弱,通常会导致无奈保护的代码。 因而,咱们为什么不把组件的共享状态抽取进去,以一个全局单例模式治理呢?在这种模式下,咱们的组件树形成了一个微小的“视图”,不论在树的哪个地位,任何组件都能获取状态或者触发行为! 通过定义和隔离状态治理中的各种概念并通过强制规定维持视图和状态间的独立性,咱们的代码将会变得更结构化且易保护。 初始化示例import { createApp } from 'vue'import { createStore } from 'vuex'const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... }}// 创立一个新的 store 实例const store = createStore({ state () { return { count: 0 } }, mutations: { increment (state) { state.count++ } }, modules: { a: moduleA }})// store.state.a // -> moduleA 的状态const app = createApp({ /* 根组件 */ })// 将 store 实例作为插件装置app.use(store)createStore:创立store从上面代码能够晓得,能够分为4个局部: ...

April 18, 2023 · 10 min · jiezi

关于vue.js:极简windows下vuejs打包用Nginx部署http服务

做法首先在vue我的项目下npm run build,在我的项目目录会呈现dist文件夹。 而后下载Nginx,看其官网是http服务和反向代理服务的实现程序。解压后能够看到目录构造中有一个html目录,删掉原有的,复制进去dist目录的所有内容(是dist文件外面的内容,不是dist文件夹)。 而后能够双击nginx.exe,在浏览器拜访localhost:80就能够了。 解释能够看到Nginx很简略,就是一个服务程序。下载解压后,能够看到conf目录是Nginx的配置文件夹、logs是运行日志,html是网页的根目录,只有放入vue打包好的html就能够了。 不过大家显然都在Linux下应用http服务了,不过操作都差不多。 当然除了这种“双击运行”,windows下官网也给了old style命令:

April 17, 2023 · 1 min · jiezi

关于vue.js:想到头秃也想不到Vue3复用组件还可以这么hack

前言无论是 vue 还是 react,当遇到多处反复代码的时候,咱们都会想着如何复用这些代码,而不是一个文件里充斥着一堆冗余代码。 实际上,vue 和 react 都能够通过抽组件的形式来达到复用,但如果遇到一些很小的代码片段,你又不想抽到另外一个文件的状况下,相比而言,react 能够在雷同文件外面申明对应的小组件,或者通过 render function 来实现,如: const Demo: FC<{ msg: string}> = ({ msg }) => { return <div>demo msg is { msg } </div>}const App: FC = () => { return ( <> <Demo msg="msg1"/> <Demo msg="msg2"/> </> )}/** render function的模式 */const App: FC = () => { const renderDemo = (msg : string) => { return <div>demo msg is { msg } </div> } return ( <> {renderDemo('msg1')} {renderDemo('msg2')} </> )}但对于 .vue 模板 来说,没法像 react 一样在单个文件外面申明其余组件,如果你要复用代码,那就只能通过抽离组件的形式。 ...

April 17, 2023 · 4 min · jiezi

关于vue.js:vue2和vue3-通过函数调用一个组件

实现一个简略的弹窗组件: vue2 函数式组件写法,通过extend办法:创立ui.vue文件,寄存咱们的组件,如下:<template> <div class="dialog"> <div class="dialog-body"> <div class="dialog-content"> 你好 </div> <div class="dialog-footer" @click="close">敞开</div> </div> </div></template><script></script><style lang="scss" scoped> .dialog { width: 100vw; height: 100vh; position: fixed; top: 0; left: 0; background-color: rgba($color: #000000, $alpha: 0.2); &-body { width: 500px; height: 300px; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); background-color: #fff; border-radius: 4px; padding: 10px; } &-content { height: 250px; } &-footer { height: 50px; } }</style>同级目录下创立一个index.js,内容如下; import UI from "./ui.vue"import Vue from "vue"function openDialog() { let install = null return new Promise((resolve, reject) => { const UIconstructor = Vue.extend(UI) install = new UIconstructor({ methods: { close(e) { document.body.removeChild(install.$el) resolve(e) }, }, }).$mount(); document.body.appendChild(install.$el) })}export default openDialog在其余页面间接引入调用openDialog即可 ...

April 14, 2023 · 1 min · jiezi

关于vue.js:Vue2管理系统一键配置crud提升效率300

本文次要基于element-ui深度封装,旨在疾速实现列表查问、增删改查、弹窗表单。能够看到上面残缺示例中蕴含了 Vue2后盾管理系统中日常基本功能,代码量却非常少,可复用性十分高,6点上班美滋滋。github地址 不断更新保护,如果对你有帮忙,帮忙加个star~ 一、残缺示例 蕴含列表table、分页、搜寻条件查问、新增、编辑、删除<mx-crud :data="tableList" :option="listOption" :page="page" :table-loading="loading" @size-change="sizeChange" @current-change="currentChange" @search-change="searchChange" @row-save="addFun" @row-update="updateFun" @row-del="rowDel" @custom-add="rowCustomAdd" @custom-view="rowCustomView" @custom-edit="rowCustomEdit" @search-reset="resetList"> <template v-slot:zdy="{ row }"> {{ row.id }} </template> <template v-slot:menu="{ row }"> menu插槽{{row}} </template></mx-crud>listOption() { return { isShowmenu: true, // 操作栏配置-是否显示操作栏 isViewBtn: true, // 操作栏配置-是否显示查看 isEditBtn: true, // 操作栏配置-是否显示编辑 isDelBtn: true, // 操作栏配置-是否显示删除 exportBtn: true, // 操作栏配置-导出 exportRecordBtn: true, // 操作栏配置-导出记录 align: "center", // 表格列配置-对齐形式 index: true, // 表格列配置-索引 customAdd: false, // 自定义新增 customView: true, // 自定义查看 customEdit: false, // 自定义编辑 titleAliasEdit: "自定义title", column: [ { label: "姓名1", labelAlias: "自定义label别名", // 弹窗表单配置 - 自定义label别名 prop: "name", search: true, // 表格列配置-是否搜寻 width: 200, // 表格列配置-宽度 rules: { required: true, message: "请输出", trigger: ["blur", "change"], }, }, { label: "自定义列", prop: "zdy", slot: true, // 表格列配置-自定义列 viewDisplay: false, // 弹窗表单配置-查看是否显示 editDisplay: false, // 弹窗表单配置-编辑是否显示 addDisplay: false, // 弹窗表单配置-新增是否显示 }, { label: "多选框", prop: "selectType", // multiple: true, search: true, type: "select", // 搜寻-定义类型 rules: { required: true, message: "请抉择", trigger: ["blur", "change"], }, dicData: [ { label: "紧急布告", value: 1, }, { label: "上线布告", value: 2, }, { label: "业务布告", value: 3, }, ], formatter: (row) => { // 表格列配置-筛选 const map = new Map([ [1, `紧急布告`], [2, `上线布告`], [3, `业务布告`], ]); return map.get(row.selectType); }, }, { label: "工夫", prop: "date", search: true, type: "date", // 搜寻-定义类型 format: "yyyy-MM-dd", valueFormat: "yyyy-MM-dd", rules: { required: true, message: "请抉择", trigger: ["blur", "change"], }, }, { label: "状态formatter", prop: "status", viewDisplay: false, // 弹窗表单配置-查看是否显示 editDisplay: false, // 弹窗表单配置-编辑是否显示 addDisplay: false, // 弹窗表单配置-新增是否显示 formatter: (row) => { // 表格列配置-筛选 const map = new Map([ [1, `<i class="class1"></i> 未开始`], [2, `<i class="class2"></i> 胜利`], [3, `<i class="class3"></i> 已实现`], ]); return map.get(row.status); }, }, { label: "列暗藏", prop: "lyc", viewDisplay: false, // 弹窗表单配置-查看是否显示 editDisplay: false, // 弹窗表单配置-编辑是否显示 addDisplay: false, // 弹窗表单配置-新增是否显示 hide: true, // 表格列配置-列暗藏 }, { label: "日期2", prop: "date2", hide: true, viewDisplay: false, // 弹窗表单配置-查看是否显示 editDisplay: false, // 弹窗表单配置-编辑是否显示 addDisplay: false, // 弹窗表单配置-新增是否显示 align: "left", // 表格列配置-对齐形式 }, { label: "地址3", prop: "address", overHidden: true, // 表格列配置-内容超出暗藏 width: 100, // 表格列配置-宽度 rules: { required: true, message: "请输出", trigger: ["blur", "change"], }, }, ], }; },详情示例二、属性办法介绍这些属性办法应用频率较高,办法和属性都是在组件里抛出,当咱们须要某些性能和配置时,增加即可 ...

April 12, 2023 · 5 min · jiezi

关于vue.js:vue3reactivity响应式

vue3相比于vue2有了显著的性能晋升,而最间接的就是从Object.defineProperty换成了proxy做数据劫持,而effect是响应式零碎的外围,响应式零碎又是vue3中的外围。 最根本的响应式就是我扭转一个值,另一个值也主动做出变动。 此时咱们执行一下文件会看到达到了咱们想要的目标。当然这并不是咱们最终想要的,咱们看一下vue3是如何做的。在vue3中reactivity能够作为一个独自的模块下载。 effect函数执行了两次,在第一次传入匿名函数的时候执行了一次 在之后a变量的值发生变化的时候又执行了一次。 当初咱们本人来实现一个响应式零碎。响应式最重要的就是收集依赖和触发依赖。1.创立一个类用来收集和触发依赖 2.在申明变量时触发收集操作 这时候就和vue3中的ref很像了。当初能够优化一下。将在收集依赖时手动调用depend办法改为在get办法中调用,在变量从新赋值时手动调用notice办法改为在set中调用。 3.创立一个reactive函数,return一个Proxy对象 在Proxy中应用get来拦挡取值行为并return出对应后果。这里咱们应用的是ES6新的Reflect函数。相干文档点击这里,总之Reflect.get(target,key)相当于target[key]。 4.创立全局map用于存储所有的对象与依赖关系 5.设置set办法拦挡赋值行为并触发依赖 6.应用effectWatch办法保留依赖 这就实现了一个根本的reactive办法,实现了响应式关系。全副代码: // let a = 10;// let b;// update()// function update() {// b = a + 10;// console.log(b)// }// a = 20;// update();// vue3的reactivity模块// const { reactive, effect } = require("@vue/reactivity");// let a = reactive({// value: 10,// });// let b;// effect(() => {// b = a.value + 10;// console.log(b);// });// a.value = 20;// 响应式库let currentEffect; // 全局依赖class Dep { constructor(val) { this.effects = new Set(); // 依赖列表 this._val = val; } get value() { this.depend(); return this._val; } set value(newVal) { this._val = newVal this.notice() } // 收集依赖 depend() { if (currentEffect) this.effects.add(currentEffect) } // 触发依赖 notice() { this.effects.forEach((effect) => { effect() }) }}// 收集依赖function effectWatch(effect) { currentEffect = effect; // 绑定依赖时先触发一次依赖 effect(); currentEffect = null;}// const dep = new Dep(10)// let b;// effectWatch(() => {// b = dep.value + 10;// console.log(b)// })// dep.value = 20;// vue3 proxyconst targetMap = new Map(); // 存储所有的依赖映射关系function getDepta(target, key) { let depsMap = targetMap.get(target) // 获取对象的所有依赖 if (!depsMap) { depsMap = new Map() targetMap.set(target, depsMap) } let dep = depsMap.get(key) // 获取对应key的所有依赖 if (!dep) { dep = new Dep(); depsMap.set(key, dep) } return dep;}function reactive(obj) { return new Proxy(obj, { get(target, key) { const dep = getDepta(target, key); dep.depend() // 收集依赖 return Reflect.get(target, key) }, set(target, key, value) { const dep = getDepta(target, key); const relust = Reflect.set(target, key, value) // 触发依赖 dep.notice(); return relust; } })}const user = reactive({ age: 19, aaa: 30})let b, c;effectWatch(() => { console.log('reactive') b = user.age + 10 console.log(b)})effectWatch(() => { console.log('reactive1111') c = user.aaa - 5 console.log(c)})user.age = 20user.aaa = 20

April 10, 2023 · 2 min · jiezi

关于vue.js:史上最详细的-Vue-3-渲染过程与-diff-图解

前言大家好,我是 Miyue,人称“小米”(不是那个小米)~ 从上一篇 从 CreateApp 开始学习 Vue 源码 中,根本理解了 createApp() 与 app.mount() 两个办法的起源和大抵执行过程,这里仍然以上文的流程图来进行回顾: 所以在创立好利用 app 后执行 mount 函数,通过 createVNode 将咱们的入口组件 App.vue 转换成 VNode 树,最初应用 patch() 函数将 VNode 树转换为实在 Dom 渲染到页面上。 而 Vue 3 的 diff 算法,与 Vue 2 一样,仍然在 patch 过程中。 那么首先,先来看一下 VNode 的生成吧~ createVNode - 生成虚构节点createVNode,即创立一个 VNode 虚构节点对象。 它最多接管 5 个参数(当然在 createApp 的时候只有一个 App.vue),其中 type 能够是一个字符串,也能够是一个 class 组件或者一般组件,甚至能够是一个 VNode 对象。 所以首先会对 type 进行解决,在没有传入 type 或者指定为 v-ndc 时,会主动转成 正文节点 类型,而后判断是否曾经是一个 VNode 对象;如果是的话,则返回对传入 VNode 的拷贝对象(除了局部属性之外,其余属性都是浅层拷贝)。 ...

April 10, 2023 · 11 min · jiezi

关于vue.js:Vue3-Transition-踩坑记

前言系列首发于公众号『前端进阶圈』 ,若不想错过更多精彩内容,请“星标”一下,敬请关注公众号最新消息。Vue3 Transition 踩坑记背景我原本想尝试新版本的个性,后果踩了个大坑。在这里分享一下我的教训,心愿能让大家少走弯路上代码<template> <!-- 谬误写法 --> <Transition><!-- xxxx --></Transition></template><script setup></script>上述代码错误信息:乏味的是,官网文档 中并没有提到 Transition 子元素不能蕴含正文。踩坑历程第一步:看到 Cannot read properties of undefined (reading 'loc'),习惯性(Uncaught (in promise) ReferenceError: xxxxx is not defined) 地在本地 Transition.vue 页面中寻找 loc 变量,后果没有找到。而后我在全局查找,还是没有找到 loc 变量。(其实这一步是多余的,因为错误信息 [plugin:vite:vue] Cannot read properties of undefined (reading 'loc'),并不是因为本地文件没有 loc 变量导致的,而是因为源码外部插件报的谬误。)第二步:查看源码 warnTransitionChildren.ts。 编译前编译后查看源码得悉,Transition 组件内必须蕴含 一个元素或 只有一个根元素的组件 且不能是正文, 能力通过运行时编译。第三步:尝试批改。在 Transition 组件里蕴含一个元素,发现它通过了。第四步: 看单测源码 warnTransitionChildren.spec.ts,对于喜爱深刻理解的同学能够看一下。总结Transition 组件 子元素不能蕴含正文,这会导致无奈通过运行时编译,导致组件不能正确渲染。(我踩了半小时的坑,不要跟我一样)模板编译中,Transition 子元素不容许多个组件或元素,否则编译不通过,依据单测源码得悉,如果须要多个分支,能够应用 v-if, v-if-else 来确定具体分支。Transition 子元素的组件中能够蕴含正文,然而不要蕴含太多,不然会影响渲染效率。心愿大家能从我的教训中取得一些播种,防止反复踩坑。特殊字符形容:问题标注 Q:(question)答案标注 R:(result)注意事项规范:A:(attention matters)详情形容标注:D:(detail info)总结标注:S:(summary)剖析标注:Ana:(analysis)提醒标注:T:(tips) 往期举荐:前端面试实录HTML篇前端面试实录CSS篇JS 如何判断一个元素是否在可视区域内?Vue2、3 生命周期及作用?排序算法:QuickSort箭头函数与一般函数的区别?这是你了解的CSS选择器权重吗?JS 中 call, apply, bind 概念、用法、区别及实现?罕用位运算办法?Vue数据监听Object.definedProperty()办法的实现为什么 0.1+ 0.2 != 0.3,如何让其相等?聊聊对 this 的了解?JavaScript 为什么要进行变量晋升,它导致了什么问题? ...

April 9, 2023 · 1 min · jiezi

关于vue.js:js变量的传递

变量的两种类型根本类型: undefined、Null、Boolean、Number、String五种 (简略的数据段);援用类型: object (由多个值形成),也就是咱们说的"对象" 从复制后果看两种变量的个性根本类型变量的复制 : 将前一变量赋值给后一变量时,只是将前一个变量的值赋给后一个变量,之后两个变量从新赋值互不影响,如下: var a=3var b=a b=4console.log(a)//b的从新赋值不影响a,此时a还是原值3援用类型变量的复制 : 将前一变量赋值给后一变量时,是将前一个变量的指针给后一个变量,两个变量用的是同一个指针,指向的是同一个地址,是同一个值。无论哪个变量扭转这同一个值,另一变量的指针的值跟着扭转,两个变量从新赋值相互影响,如下: var a={d:3}var b=a b.d=4console.log(a.d)//给b.d从新赋值为4,因a.d指针也指响这个地址,所以a.d的值也是4由上可知:根本类型变量复制的是变量的正本,而援用类型变量复制的是指针 变量的定义(宣告)和赋值函数中形参和局部变量同名ps: 在咱们本人写代码中,个别不会做这样的蠢事。 js对形参在变量对象中是如何保留的呢,请看标准:

April 7, 2023 · 1 min · jiezi

关于vue.js:Vue2-diff-算法图解

前言看 Vue 2 的源代码曾经很久了,从用 flow 到现在应用 TypeScript,我每次都会关上它的源代码看一看,然而每次都只看到了 数据初始化 局部,也就是 beforeMount 的阶段,对于如何生成 VNode(Visual Dom Node, 也能够间接称为 vdom) 以及组件更新时如何比拟 VNode(diff)始终没有认真钻研,只晓得采纳了 双端 diff 算法,至于这个双端是怎么开始怎么完结的也始终没有去看过,所以这次趁写文章的机会认真钻研一下。如果内容有误,心愿大家能帮我指出,非常感谢~ 什么是 diff ?在我的了解中,diff 指代的是 differences,即 新旧内容之间的区别计算;Vue 中的 diff 算法,则是通过一种 简略且高效 的伎俩疾速比照出 新旧 VNode 节点数组之间的区别 以便 以起码的 dom 操作来更新页面内容。 此时这里有两个必须的前提: 比照的是 VNode 数组同时存在新旧两组 VNode 数组所以它个别只产生在 数据更新造成页面内容须要更新时执行,即 renderWatcher.run()。 为什么是 VNode ?下面说了,diff 中比拟的是 VNode,而不是实在的 dom 节点,置信为什么会应用 VNode 大部分人都比较清楚,笔者就简略带过吧~ 在 Vue 中应用 VNode 的起因大抵有两个方面: VNode 作为框架设计者依据框架需要设计的 JavaScript 对象,自身属性绝对实在的 dom 节点要简略,并且操作时不须要进行 dom 查问,能够大幅优化计算时的性能耗费在 VNode 到实在 dom 的这个渲染过程,能够依据不同平台(web、微信小程序)进行不同的解决,生成适配各平台的实在 dom 元素在 diff 过程中会遍历新旧节点数据进行比照,所以应用 VNode 能带来很大的性能晋升。 ...

April 7, 2023 · 5 min · jiezi

关于vue.js:在-Vue-中控制表单输入

Vue中v-model的思路很简略。定义一个可响应式的text(通常是一个ref),而后用v-model="text"将这个值绑定到一个input上。这就发明了一个双向的数据流: 用户在输入框中输出,text会发生变化。text发生变化,输入框的值也随之变动。让咱们看看如何在Vue 3中应用v-model来管制表单输出。 绑定表单输出让咱们实现一个组件,渲染一个初始值为Unknown的输出表单。用户在输出表单中引入的值会在屏幕上渲染进去。 v-model很适宜实现这样一个组件。将v-model与输出表单连接起来须要两个简略的步骤: const text = ref():作为v-model可响应式的值。v-model="text":将v-model增加到调配有text的输出表单标签中。<script setup>import { ref } from 'vue'const text = ref('Unknown') // Step 1: create data bus</script><template> <!-- Step 2: assign data bus to v-model --> <input v-model="text" type="input" /> <div>{{ text }}</div></template>输出表单蕴含初始值Unknown。在输出表单里输出一些货色:输出值和屏幕上的文本都会更新。 v-model="text" 在Vue中属于双向绑定数据。第一个方向的流动产生在初始化过程中。输出值被初始化为Unknown,也就是text的初始值。 第二个方向的流动产生在给输出表单键入值的时候。v-model承受输入框的值,并用它来更新text。 v-model与v-bind在Vue中,v-bind是另一种数据绑定机制: <input v-bind:value="text" type="text" />能够简写为: <input :value="text" type="text" />v-model和:value的不同之处是什么?<input :value="value" />是一种单向数据流机制。 为了了解两者的不同之处,让咱们将先前的例子从v-model="text"改为:value="text": <script setup>import { ref } from 'vue'const text = ref('Unknown')</script><template> <input :value="text" type="input" /> <div>{{ text }}</div></template>输出表单的初始值为Unknown。 ...

April 4, 2023 · 3 min · jiezi

关于vue.js:golangvue3-实现-在web展示-k8s机器的podsvcingress

golang 后盾代码package mainimport ( "context" "fmt" "k8s.io/client-go/tools/clientcmd" "net/http" "os/user" "github.com/gin-gonic/gin" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes")func CorsMiddleware() gin.HandlerFunc { return func(context *gin.Context) { method := context.Request.Method // 因为是内网环境,所以能够间接把所有域名设置进去,然而按理来说不能这样 context.Header("Access-Control-Allow-Origin", context.GetHeader("Origin")) context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token") context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type") context.Header("Access-Control-Allow-Credentials", "true") if method == "OPTIONS" { context.AbortWithStatus(http.StatusNoContent) } context.Next() }}func main() { u , _ := user.Current() home := u.HomeDir k8sConfig, err := clientcmd.BuildConfigFromFlags("", fmt.Sprintf("%s/.kube/config", home)) // 应用 kubectl 默认配置 ~/.kube/config if err != nil { fmt.Printf("%v", err) return } // 创立一个k8s客户端 clientset, err := kubernetes.NewForConfig(k8sConfig) if err != nil { panic(any(err)) } // 创立 Gin 路由器 r := gin.Default() r.Use(CorsMiddleware()) r.GET("/api/namespaces", func(c *gin.Context) { // 获取所有 Namespace 下的 Pod 列表 podList, err := clientset.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // 将 Pod 列表转换为 JSON 格局并返回给前端 c.JSON(http.StatusOK, podList) }) // 定义获取 Pod 列表的 API 接口 r.GET("/api/pods", func(c *gin.Context) { // 获取所有 Namespace 下的 Pod 列表 podList, err := clientset.CoreV1().Pods("").List(context.Background(), metav1.ListOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // 将 Pod 列表转换为 JSON 格局并返回给前端 c.JSON(http.StatusOK, podList) }) // 定义获取 Service 列表的 API 接口 r.GET("/api/services", func(c *gin.Context) { // 获取所有 Namespace 下的 Service 列表 serviceList, err := clientset.CoreV1().Services("").List(context.Background(), metav1.ListOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // 将 Service 列表转换为 JSON 格局并返回给前端 c.JSON(http.StatusOK, serviceList) }) // 定义获取 Ingress 列表的 API 接口 r.GET("/api/ingresses", func(c *gin.Context) { // 获取所有 Namespace 下的 Ingress 列表 ingressList, err := clientset.ExtensionsV1beta1().Ingresses("").List(context.Background(), metav1.ListOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // 将 Ingress 列表转换为 JSON 格局并返回给前端 c.JSON(http.StatusOK, ingressList) }) r.GET("/api/pods/:namespace", func(c *gin.Context) { namespace := c.Param("namespace") pods, err := clientset.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"pods": pods.Items}) }) r.GET("/api/services/:namespace", func(c *gin.Context) { namespace := c.Param("namespace") services, err := clientset.CoreV1().Services(namespace).List(context.Background(), metav1.ListOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"services": services.Items}) }) r.GET("/api/ingresses/:namespace", func(c *gin.Context) { namespace := c.Param("namespace") ingresses, err := clientset.ExtensionsV1beta1().Ingresses(namespace).List(context.Background(), metav1.ListOptions{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"ingresses": ingresses.Items}) }) // 启动 Gin 服务器 if err := r.Run(":8080"); err != nil { panic(any(err)) }}ingress获取有点问题 ...

March 31, 2023 · 4 min · jiezi

关于vue.js:Vuejs-滑动拼图验证码实现笔记

背景对于验证码的应用场景还是十分多的,很多网站上的验证码堪称是形形色色,上面是我应用Vue.js实现滑动拼图验证码做的一个笔记。 成果展现 筹备工作拜访KgCaptcha网站,注册账号后登录控制台,拜访“无感验证”模块,申请开明后零碎会调配给利用一个惟一的AppId、AppSecret。提供后端SDK来校验token(即平安凭据)是否非法 ,目前反对PHP版、Python版、Java/JSP版、.Net C#版。拜访Vue.js中武官网,复制Vue.js插件链接。留神:先HTML头部初始化行为验证码,而后HTML底部初始化Vue.js,否则KgCaptcha的js局部函数与被Vue.js发生冲突,导致生效。实现代码<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><!--头部引入Vue.js插件--><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!--头部引入Vue.js插件--><!--头部引入行为验证码js插件--><script id="KgCaptcha" src="captcha.js?appid=XXX"></script><script> kg.captcha({ // 绑定元素,验证框显示区域 bind: "#captchaBox", // 验证胜利事务处理 success: function(e) { console.log(e); kg.$('#token').value = e['token']; }, // 验证失败事务处理 failure: function(e) { console.log(e); }, // 点击刷新按钮时触发 refresh: function(e) { console.log(e); } });</script><!--头部引入行为验证码js插件--></head><body> <div id="app"> <!--自定义内容、Vue组件--> token: <input name="token" id="token" /> <!--行为验证码组件--> <div id="captchaBox"></div> <!--行为验证码组件--> <button type="button">提交</button> <!--自定义内容、Vue组件--> </div></body><!--底部运行Vue.js代码--> <script> var app = new Vue({ el: '#app',})</script><!--底部运行Vue.js代码--> </html>最初SDK开源地址:https://github.com/KgCaptcha,顺便做了一个演示:https://www.kgcaptcha.com/demo/

March 31, 2023 · 1 min · jiezi

关于vue.js:vue局部安装和全局安装

vue2.0和vue3.0当初都在用,所以脚手架版本就不能全局装置了,不然不同版本切换比拟麻烦。先卸载之前版本进入管理员模式----//卸载3.0之前的版本 npm uninstall -g vue-cliyarn global remove vue-cli----//卸载3.0之后的版本(能够对立应用此指令卸载) npm uninstall -g @vue/cliyarn global remove @vue/cli`vue2.0最新部分装置:npm install vue-cli@2.9.6vue3.0部分装置: npm install @vue/cli(不加-g,代表是部分装置,反之npm install -g @vue/cli为全局装置)或者 npm init -y 生成package.json文件而后在 npm install -D @vue/cli3.0脚手架:npm create vue@3 或 npm create《我的项目名》2.0脚手架:npm create vue@2

March 28, 2023 · 1 min · jiezi

关于vue.js:尤大不会说-Rap-的前端不是好前端写一个-vrap-指令

最近上网多了,倒是乏味的事件也变得多了起来,Vue 的作者尤雨溪也整了段花活,给咱们Rap了一段,其实唱歌自身不是很惹眼的事件,然而本是一位十分厉害的开发人员,同时又有比拟"时尚"的说唱喜好,的确是反差感很大,哈哈! 既然尤大都整了,那咱们也来整一小段。让你的输入框也Rap起来,如何? 看看成果先: 计划计划是这样子,咱们实现跳动的CSS非常简单,无非是利用 keyframes 给输入框外部的元素套上动画,但如何管制每一个输入框外部的字符,才是比拟辣手的,不过也不算简单,尝试下以下两种计划: 生成一个新的 div,替换本来属于 input 的地位,拷贝 input 的字符组成 div 的外部元素间接应用可编辑的 div,管制其外部元素的输出款式即可先筹备一个看起来不唠的网页,根本构造明确了,咱们就进行接下来的的试验: <input class="input" placeholder="请输出你的 freestyle"><style> body { display: flex; justify-content: center; align-items: center; background: #7ec699; flex-direction: column; height: 100vh; } .input { background: #fff; width: 500px; height: 50px; outline: none; border: 5px solid #81d59f; text-align: center; line-height: 50px; border-radius: 25px; font-size: 16px; }</style> 鸠占鹊巢咱们在 input 输出实现之后,监听其失焦事件,创立的 div 完全符合 input 的所有款式,再次点击以后 div 的时候,从新替换回来并聚焦,咱们把这一招能够称为 "鸠占鹊巢" 式! 如何复制以后元素的所有的款式十分重要,这是咱们须要冲破的点! ...

March 28, 2023 · 3 min · jiezi

关于vue.js:vue项目部署到阿里云服务器windows-Nginx代理

我的项目形成:前端:vue+vant-ui,数据库:mysql,后端:node.js 部署形式:nginx代理 一,首先要领有本人的服务器,阿里,腾讯都能够,我用的是阿里的 购买形式省略... 购买实现后,会跳到实例界面,也就是你的服务器实例 倡议先进行运行,改明码后再重启, 重启后,按下win+r,输出mstsc, 近程连贯你的服务器; 地址就是你的服务器的公网地址 用户名windows零碎的是Administrator 明码是你本人设置的明码, 点击确定后,就进入服务器端了 关上浏览器,下载nginx; 下载NGINX for Windows 下载地址:http://nginx.org/en/download.html; 下载好了,间接全副解压,留神门路别带中文,不然启动nginx时会报错 接着,先不必管服务器,去打包我的项目,npm run build; 跑完后,会在你的我的项目里生成一个dist文件夹 而后把dist文件夹发送到你的服务器上,放在html这个文件夹内 发送形式能够具体百度一下,我这边目前应用的MobaXterm工具,抉择RDP进行连贯 接着回来批改conf文件夹下的nginx.conf文件,也就是配置nginx; 留神:坑来了:复制这个地址后,你失去的地址是这样的:C:\ngx\nginx-1.20.2\nginx-1.20.2\html\dist, 所有‘\’一律要改为‘\’因为‘\’会本义,改为如上图所示; 还有记得把 nginx.conf里的 实现了以上工作后,回到这个界面注:如果在nginx中有转发配置,能够参考这篇文章:nginx各种代理配置 点击nginx.exe,关上,你会发现只是一闪而过,别在意,nginx启动就是这样的 咱们能够在工作管理器查看有没有启动; 只有看到这个就阐明启动胜利了 接着,回到你的阿里云控制台,实例这里去配置平安组,也就是凋谢你的端口,让外网可能拜访。 点击手动增加,增加8080端口;,保留。 而后重启nginx;

March 27, 2023 · 1 min · jiezi

关于vue.js:对于Vue3和Ts的心得和思考

作者:京东物流 吴云阔 1 前言Vue3曾经正式公布了一段时间了,各种生态曾经成熟。最近应用taro+vue3重构冷链的小程序,通过了一段时间的开发和应用,有了一些本人的思考。 总的来说,Vue3无论是在底层原理还是在理论开发过程中,都有了很大的提高。 从源码层面来说,应用Proxy代替Object.defineProperty的API,一个是代理的对象,一个是递归监控的属性,从而在性能上有了很大的提高,并且,也解决了对象动静属性减少、数组扭转监听上的缺点;对diff算法进行优化,减少了动态标记,大大提高了Vue的执行效率;还有动态晋升、事件监听缓存等一系列晋升效率的伎俩。 从利用层面来说,次要的扭转是将option API改成了composition API(组合式API),在业务中摈弃data、methods、生命周期函数隔离开的开发方式,使代码绝对于业务有更强的聚合性,在代码开发、代码浏览、代码保护方面对于开发者都是更加敌对。 对于typescript有了更好的反对,咱们晓得,对于大型的前端我的项目来说,应用typescript的类型校验,能使前端我的项目有更强的健壮性,这也使得Vue3对于大型项目的开发提供了更强的质量保证。 2 组合式API所谓的组合式API,将Vue2中的data、methods、生命周期、数据监听等option,都封装成钩子函数,而后组合到setup函数中,其外围就在于setup函数。setup函数存在的意义,就是为了应用这些新增的组合式API,并且这些API只能在setup函数中应用。 setup函数执行的机会是,props初始化之后,beforeCreate函数执行之前,所以在执行setup时,还没有初始化Vue实例,因而在setup中不能应用this对象。setup函数的返回值会被注入到Vue实例中,供Vue组件应用,所以任何数据想在Vue组件的模板中应用,必须在setup函数中return进来。 组合式API的组合,体现在两个层面。第一层的意思是,将某一业务相干数据和解决逻辑放到一起,这是一种关注点的聚合,更不便咱们编写代码、解决业务逻辑,并且能更聚焦业务逻辑,更不便咱们看代码。第二层面的意思,当某个组件的业务逻辑足够简单,setup中的代码足够大的状况下,咱们能够在setup外部,进一步提取相干的一块业务,使代码逻辑更加清晰,做到了进一步的聚合作用。 如上面代码所示,将业务代码块A抽出来,则代码块A中return进去的数据就能够在组件中应用: // 组件import functionA from 'A'export default defineComponent({name: 'componentName',setup() {...functionA()}})// 代码块Aexport default () => {return {a: 1}}3 响应式API在Vue3中响应式API,次要体现在ref和reactive两个函数。对于响应式API,想说两个问题,第一个是为什么要减少响应式API,第二个是响应式API函数ref和reactive的异同点。 3.1 为什么减少响应式API在Vue2中所有数据都写在data的option中,data中的数据都是响应式的,这样产生的一个问题是,有些常量数据自身不须要监听,从而造成了资源的节约。所以在Vue3中减少了响应式API,只须要对须要动静更新dom的数据进行响应式,不须要动静更新dom的数据不进行响应式解决,从很大水平上节俭了资源。这里我感觉须要留神的是,写代码的时候肯定要认真思考一下,哪些数据须要进行响应式绑定,哪些数据不须要进行响应式绑定,而不是一股脑的全给绑定上,这样即便代码逻辑不能很清晰易懂,并且也会影响执行效率(写惯了Vue2的同学须要留神)。 3.2 ref和reactive的异同点在理解了为什么要减少响应式API后,咱们发现Vue3提供了两个响应式API函数,ref和reactive。为什么会提供两个API呢? 一个不就能够了吗?那么这两个API之间的区别是什么呢? 在应用层面,ref绑定的数据,须要应用[data].value进行数据更改。而reactive绑定的数据须要应用[data].[prpoerty]的形式进行数据更改。在应用场景方面,个别的,单个的一般数据,咱们应用ref来定义响应式。而简单数据,如:表单数据对象、某一模块的一组数据等,应用reactive来定义响应式。 那么,对象是不是必须用reactive来定义呢? 其实不是的,都能够。官网说法是:能够依据本身习惯应用不同的API。其实,我感觉,他们是有各自的应用场景的,ref更强调的是数据Value的扭转,reactive更强调的是数据中某一属性的扭转。 4 treeShaking思维当 Javascript 我的项目达到肯定体积时,将代码分成模块会更易于治理。然而,当这样做时,咱们最终可能会导入实际上未应用的代码。Tree Shaking 是一种通过打消最终文件中未应用的代码来优化体积的办法。 Vue3应用了tree shaking的办法,将组件以及其所有的生命周期函数等办法进行离开,如果在组件中应用的代码将不会呈现在最终的打包文件中,如此,会缩小大大Vue3我的项目的打包体积。由此造成的一个后果就是,应用办法的不同。 4.1 生命周期函数的应用办法 import { defineComponent, ref, onMounted } from 'vue';export default defineComponent({name: 'Gift',setup() {const counter = ref(0);onMounted(() => {// 解决业务,个别进行数据申请})return {counter}}})4.2 Vuex的应用办法import { useStore } from "vuex";import { defineComponent, ref, computed } from 'vue';export default defineComponent({name: 'Gift',setup() {const counter = ref(0);const store = useStore();const storeData = computed(() => store); // 配合computed,获取store的值。return {counter,storeData}}})4.3 Router的应用办法import { useStore } from "vuex";import { useRouter } from "vue-router";import { defineComponent, ref, computed } from 'vue';export default defineComponent({name: 'Gift',setup() {const counter = ref(0);const router = useRouter();const onClick = () => {router.push({ name: "AddGift" });}return {counter,onClick}}})5 对于Typescript的应用这一部分是对于Ts的内容,不过它与Vue3的开发非亲非故。Vue3整体是应用Ts写的,因而,开发Vue3的我的项目须要应用Ts,所以,咱们还是要理解TS的。 ...

March 27, 2023 · 1 min · jiezi

关于vue.js:vue项目依赖报错-TypeError-thisgetOptions-is-not-a-function

运行他人的我的项目提醒报错: Syntax Error: TypeError: this.getOptions is not a function 解决方案:node: v14.17.0npm: 6.14.13(蛮写,重点是其余四项要匹配版本)"node-sass": "^4.14.1","sass-loader": "^8.0.2","vue-loader": "^15.3.0"

March 24, 2023 · 1 min · jiezi

关于vue.js:超级酷炫的3D-城市模型

3D 城市模型!原文链接:https://note.noxussj.top/?source=sifo 预览地址:https://3d.noxussj.top/ 设施要求 倡议应用 1920 * 1080 分辨率进行拜访。以后利用对电脑性能要求较高,特地是显卡。如果关上后没有 60 fps 就代表你的电脑跑不动了介绍3D 可视化城市模型,应用的技术栈有 vue.js + three.js + glsl。蕴含的性能有圆形扫描、平面扫描、横向扫描、社区高亮、地图飞线、高空线路等等。 将来打算会接入实在数据,以及增加以后城市标志性修建,并且进行炫酷的渲染。最初还会接入 AI 语音辨认来管制场景,例如戴着耳机,而后说一声放烟花,那么场景内就会有烟花进去。 提供了色调面板,能够管制整个场景特效的色彩。 开发环境要求倡议应用 node v14 的版本进行装置依赖包。倡议通过 yarn 进行装置依赖包,而不是 npm。学习付费提供源码学习,须要的能够分割博主哦 632922356@qq.com。 局部代码截图反对凋谢局部代码进去给大家观看一下,能够更深刻直观的理解到 3D 我的项目的代码是怎么样的。 原文链接:https://note.noxussj.top/?source=sifo

March 23, 2023 · 1 min · jiezi

关于vue.js:vmodel另类用法实现父子组件数据双向绑定

此文次要诠释v-model另外一种用法,用于双向绑定父子组件的传递的值。v-model其实就是:1.给子组件的 value 传个变量2.监听子组件的input事件,并且把传过来的值赋给父组件的变量上面是验证示例: <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script> </head> <body> <div id="app"> <father></father> </div> <script> var oApp = document.getElementById('app'); //子组件 var Child = Vue.extend({ props:{ value:{ type:String, default:"555555" } }, methods: { testVModel() { this.$emit("input","子组件传过来的值") } }, mounted(){ }, template: `<div id='child'>我是子组件 <p>value:{{value}}</p> <button @click="testVModel">传值</button> </div> ` }) //父组件 var Father = Vue.extend({ data() { return { a: "2224442", b:"2224442" } }, components:{ "child":Child }, template: "<div id='father'><p>我是父组件</p>" + "<p>父组件扭转前的值{{b}}----扭转后的值----{{a}}</p>" + "<child v-model='a'></child></div>" }); var vm = new Vue({ el: '#app', components:{ "father":Father, } }); </script> </body></html>参考链接:https://blog.csdn.net/weixin_53312997/article/details/126478859 ...

March 22, 2023 · 1 min · jiezi