关于vue3:记录Vue3-Elementplus-时间控件时间限制

template <el-date-picker v-model="timing" type="datetime" :disabled-date="disableConfig" :disabled-hours="disabledHours" :disabled-minutes="disabledMinutes" :disabled-seconds="disabledSeconds"/>限度以后工夫之前的工夫 /* 限度天 */export const disableConfig = (time) => { return time.getTime() < Date.now()}/* 限度时 */export const disabledHours = () => { const arrs = [] for (let i = 0; i < 24; i++) { // 限度之前 < 之后 > ,上面同理 if (new Date().getHours() <= i) continue; arrs.push(i) } return arrs;}/* 限度分 */export const disabledMinutes = () => { const arrs = [] for (let i = 0; i < 60; i++) { if (new Date().getMinutes() <= i) continue; arrs.push(i) } return arrs;}/* 限度秒 */export const disabledSeconds = () => { const arrs = [] for (let i = 0; i < 60; i++) { if (new Date().getSeconds() <= i) continue; arrs.push(i) } return arrs;}限度之后的工夫 ...

August 18, 2022 · 1 min · jiezi

关于vue3:vue3集成markdown

Markdown 语法简洁,并且对于图片,图表、数学式都有反对,许多博客网站都宽泛应用 Markdown 来撰写文章。解析markdown字符串vue3-markdown-it LiveDemo 上边的这个NPM package能够很不便的集成到vue3的我的项目中,用来解析Markdown文本。 反对: 锚点定位换行emoji代码块语法高亮html标签toc...装置npm install vue3-markdown-it --save在你的页面中引入即可: <template> <div> <Markdown :source="source" /> </div></template><script>import Markdown from 'vue3-markdown-it';export default { components: { Markdown }, data() { return { source: '# Hello World!' } }}</script>代码高亮装置highlight.js npm install highlight.js --save导入highlight的款式文件: <template> <div> <Markdown :source="source" /> </div></template><script>import Markdown from 'vue3-markdown-it';import 'highlight.js/styles/a11y-dark.css';export default { components: { Markdown }, data() { return { source: '# Hello World!' } }}</script>这是如果内容中蕴含代码块,就会渲染出相似上面的成果: 能够到上面的地址去查看所有反对的主题:https://github.com/highlightj...

August 17, 2022 · 1 min · jiezi

关于vue3:vue3-elmenu-elementplus多级菜单递归写法

源码 https://github.com/ohoherror/... menuItem.js外围:判断菜单还有没有children,有children就递归,没有就展现菜单名 <template> <template v-for="item in arrList"> <el-menu-item v-if='!item.children' @click="toMenu(item)" :key="'/' + item.url" :index="'/' + item.url"> <span>{{ item.name }}</span> </el-menu-item> <el-sub-menu :index="item.menuId.toString()" v-else> <template #title><span>{{ item.name }}</span></template> <menu-item :arrList="item.children" @toMenu="toMenu"></menu-item> </el-sub-menu> </template></template><script setup>import { pathArr } from '@/router/routes'import menuItem from './menuItem.vue'import { useRouter } from 'vue-router'import { useStore } from 'vuex';//vue3 props的获取const props = defineProps({ arrList: Array,});const router = useRouter()let store = useStore()const toMenu = (ele) => { let checkedList = store.state.tabList console.log(checkedList) if (pathArr().includes('/' + ele.url)) { let ids = checkedList.map(ele => ele.menuId) //判断tabs是否存在该菜单 if (!ids.includes(ele.menuId)) { checkedList.push(ele) } store.commit('setTabList', checkedList) router.push({ path: '/' + ele.url }) } else { ElMessage.error('暂无组件') }}</script>leftNav.js 左侧菜单总列表 ...

August 17, 2022 · 2 min · jiezi

关于vue3:vue3-keepalive使用

源码能够参考 https://github.com/ohoherror/... 在写公共layout时,应用el-tabs,切换菜单,应用keep-alive不能做到缓存 <el-row> <el-col :span="24"> <el-button @click="loginOut" class="float-right mb-10 ">退出</el-button> </el-col> <el-col :span="24"> <el-tabs @tab-click="handleClick" v-model="editableTabsValue" closable type="card" class="demo-tabs" @tab-remove="removeTab"> <el-tab-pane v-for="item in editableTabs" :key="item.menuId" :label="item.name" :name="item.name"> <router-view v-slot="{ Component, route }"> <keep-alive> <component :is="Component" v-if="(route.meta && route.meta.keepAlive)" :key="router.name" /> </keep-alive> <component :is="Component" :key="router.name" v-if="!(route.meta && route.meta.keepAlive)" /> </router-view> </el-tab-pane> </el-tabs> </el-col> </el-row>起初把keep-alive放在app.vue外面就能够做到缓存了 <div id="app"> <!-- 路由进口 --> <!-- 路由匹配到的组件将渲染在这里 --> <div> <el-container> <el-aside width="200px" v-if="state.showMenu"> <leftNav></leftNav> </el-aside> <el-container> <el-header v-if="state.showMenu"> <topNav></topNav> </el-header> <el-main class="mt-20"> <router-view v-slot="{ Component, route }"> <keep-alive> <component :is="Component" v-if="(route.meta && route.meta.keepAlive)" :key="router.name" /> </keep-alive> <component :is="Component" :key="router.name" v-if="!(route.meta && route.meta.keepAlive)" /> </router-view> </el-main> </el-container> </el-container> </div> </div>

August 17, 2022 · 1 min · jiezi

关于vue3:vuei18n国际化语言在项目中的使用

为什么要国际化?前端国际化:利用要服务于不同的地区的用户,所以利用不能繁多语言;利用要能让不同地区的人无障碍应用就须要实现国际化。目前在各大商城我的项目中,对于国际化语言的需要越来越高了,其中最多的就是vue我的项目应用i18n插件实现多语言切换性能,最近有幸我刚好做了这方面的业务,上面是我对vue-i18n国际化语言的一点总结与记录 注释我的项目中通常通过抉择语言,或者标签的切换来展现不同的语言,管制语言的配置信息在locale中。 1.引入多语言首先在main.js中进行引入并注册vue-i18n,引入中文语言包和英文语言包(依据开发需要引入语言包) //main.js//多语言引入import VueI18n from 'vue-i18n'import en from './locale/en.json' //英文import zhHans from './locale/zh-Hans.json' //中文Vue.use(VueI18n)let i18nConfig = { locale: uni.getLocale(),// 获取已设置的语言 messages: { en, 'zh-Hans': zhHans, }}const app = new Vue({ ...App, i18n,})app.$mount();2.语言包文件创立json文件,放入你须要的语言,我的项目中咱们应用了中文和英文,能够依据开发的需要创立须要的语言文件,留神每个语言包中的字段名要保持一致。 zh-Hans.json,en.json的构造如下 //zh-Hans.json{ "home": "首页"}//en.json{ "home": "home"}3.设置默认语言这里设置的是默认语言为中文,能够依据开发语言自行设置 header['cb-lang'] = uni.getStorageSync('locale') ? uni.getStorageSync('locale') :'zh_cn'4.在页面中应用应用$t('字段名')在html中获取,应用this.$t('字段名')在js中获取 <template> <view> <text>{{$t('home')}}</text> <view v-text="$t(`home`)"></view> </view> </template> <script> export default { data() { return { home: this.$t(`home`) } } }</script>5.在页面中切换语言通过事件触发,点击切换语言,管制locale的值,调用对应的语言包,这里是通过点击图标切换语言(我的项目中只用到两种语言),应用多种语言时也能够通过抉择语言来管制切换,判断目前应用的语言,点击图标后将另一个语言赋给locale,而后将该语言存储在本地缓存中 <view class="message"> <view hover-class="none" @click="locale()"> <view v-if="$i18n.locale == 'zh-Hans'" class="iconfont icon-jinbi_o"></view> <view v-if="$i18n.locale == 'en'" class="iconfont icon-yue"></view> </view></view>methods: { locale(){ if(this.$i18n.locale=='zh-Hans'){ this.$i18n.locale = 'en'; uni.setStorageSync('locale', 'en_us') }else if(this.$i18n.locale=='en'){ this.$i18n.locale = 'zh-Hans'; uni.setStorageSync('locale', 'zh_cn') } },}遇到的问题1.切换语言申请头语言不扭转调试的时候,不刷新页面,config.js只能触发一次,然而request.js外面这个申请办法每次都会触发,所以在request.js里把批改的cb_lang加上就会及时触发,这样调用接口后,后端就能够返回不同的语言数据了 ...

August 12, 2022 · 1 min · jiezi

关于vue3:Vue3Vite26TypeScriptantdesignvueeggjs-一键构建管理前后台管理系统

Bag疾速开发管理系统、门户网站、博客零碎框架,提供根底的框架,疾速搭建企业产品,响应式开发,你能够将它利用在任何须要服务端治理的利用。如:开发管理系统的 API 接口、门户网站博客、企业外部的业务管理、ERP、CMS、APP 的后盾等技术选型Bag管理系统采纳Vue3、Vue-Router4、Vuex4、Ant-Design-Vue、Vite、TypeScript、Egg.js、Mysql构建 Bag门户博客前台采纳Vue3、Vue-Router4、Vite 、Pinia、Element-plus、Equal-Vue、Bootstrap、Vite、TypeScript、Egg.js、Mysql构建,按需加载模块,内置丰盛UI 一键装置疾速开发,内置集成后盾零碎、也阔以自定义后盾APInpm i vue-bag-admin --save 利用import {createApp} from 'vue'import install from 'vue-bag-admin'import 'vue-bag-admin/lib/style.min.css'import App from './App.vue'import 'vue-bag-admin/mock/admin' // 如果后盾服务,不必此mock数据createApp(App).use(install)开发npm run dev开源地址文档地址,Github源码 演示地址超级管理员账户:用户名:superadmin ,明码:123456 管理员账户:用户名:admin ,明码:123456 管理系统演示、门户博客前台演示 次要性能用户治理:系统管理员调配用户角色和角色权限角色治理:创立权限管制的次要对象,能够给角色调配不同api权限和菜单权限菜单治理:实现用户动静菜单配置,实现不同角色不同菜单富文本编辑器:MarkDown编辑器性能嵌入疾速表单:一键开发CURD,配置化条件搜寻示例疾速API:基于Egg开发,增删改查API根本样列接口设计:模型创立,关联查问,一键接入权限指令:组件权限指令封装网络配置:根底axios封装,申请重连、谬误勾销,动静配置状态治理:丰盛的Vuxe和Pinia任意抉择路由配置:嵌套路由,动静路由可动静配置,疾速出现全局配置:站点根本配置背景图片、Login、Slogan等等....预览后盾 前台

August 12, 2022 · 1 min · jiezi

关于vue3:优秀的你才能遇到优秀的世界-Bag管理系统框架

Bag疾速开发管理系统、门户网站、博客零碎框架,提供根底的框架,疾速搭建企业产品,响应式开发,你能够将它利用在任何须要服务端治理的利用。如:开发管理系统的 API 接口、门户网站博客、企业外部的业务管理、ERP、CMS、APP 的后盾等技术选型Bag管理系统采纳Vue3、Vue-Router4、Vuex4、Ant-Design-Vue、Vite、TypeScript、Egg.js、Mysql构建 Bag门户博客前台采纳Vue3、Vue-Router4、Vite 、Pinia、Element-plus、Equal-Vue、Bootstrap、Vite、TypeScript、Egg.js、Mysql构建,按需加载模块,内置丰盛UI 装置npm i vue-bag-admin --save在线演示管理员账户:用户名:admin ,明码:123456 超级管理员账户:用户名:superadmin ,明码:123456 文档地址、管理系统演示、门户博客前台演示 次要性能用户治理:系统管理员调配用户角色和角色权限角色治理:创立权限管制的次要对象,能够给角色调配不同api权限和菜单权限菜单治理:实现用户动静菜单配置,实现不同角色不同菜单富文本编辑器:MarkDown编辑器性能嵌入疾速表单:一键开发CURD,配置化条件搜寻示例疾速API:基于Egg开发,增删改查API根本样列接口设计:模型创立,关联查问,一键接入权限指令:组件权限指令封装网络配置:根底axios封装,申请重连、谬误勾销,动静配置状态治理:丰盛的Vuxe和Pinia任意抉择路由配置:嵌套路由,动静路由可动静配置,疾速出现全局配置:站点根本配置背景图片、Login、Slogan等等......疾速开发管理系统、门户博客前台代码都是同一安装包、应用同一个服务适用人群正在以及想应用框架疾速开发网站零碎,有过前端开发教训 1 年+ 相熟 Vue.js 技术栈,应用它开发过几个理论我的项目,酷爱技术,爱学习,想进阶和晋升的同学 环境Vite官网文档、Vite官网中文文档 Vite 须要 Node.js 版本 >= 12.2.0。然而,有些模板须要依赖更高的 Node 版本能力失常运行,当你的包管理器收回正告时,请留神降级你的 Node 版本。1、Vite创立我的项目装置Vue程序的模板,下一代前端开发与构建工具# npm 6.xnpm create vite@latest my-vue-app --template vue# npm 7+, extra double-dash is needed:npm create vite@latest my-vue-app -- --template vue# yarnyarn create vite my-vue-app --template vue# pnpmpnpm create vite my-vue-app --template vue2、Vue CLI创立我的项目Vue CLI官网文档,Vue.js 开发的规范工具npm install -g @vue/cli 而后就能够应用vue命名vue create my-vue-app装置依赖cd my-vue-appnpm install装置cnpm?> 如果装置过慢、应用cnpm装置 ...

August 10, 2022 · 2 min · jiezi

关于vue3:Vue30正式版-TS-仿知乎专栏企业级项目内置文档资料

download:Vue3.0(正式版) + TS 仿知乎专栏企业级我的项目内置文档资料在理论开发中,对树形JSON数据处理的业务场景十分常见;而且这些数据必然是多层级的,那么很重要的一点就是要做到递归。特地是在动静路由筛选和树形构造数据筛选中。正所谓,“工欲善其事,必先利其器”。所以本文总结几种用于解决失去咱们业务中所需的真正数据的办法。二.实现办法 “splice”办法 (不举荐): 阐明:这种办法只适应于唯一性的条件(比方:过滤唯一性id)的场景。如果是用在筛选树形数据或者路由菜单(比方:过滤hidden为true)的场景,会因为其实正向删除index值,故导致第一次除外的每次遍历递归的index值不精确,所以删除的值也是不对的,故不举荐。 代码实现: //只实用于唯一性的id的递归过滤function filterData(arr, id) { arr.forEach((item, index) => { if (item.id === id) { arr.splice(index, 1) } if (item.children && item.children.length) { filterData(item.children, id) } })}

August 7, 2022 · 1 min · jiezi

关于vue3:基于-Vue3-打造前台中台通用提效解决方案完整无密内置文档资料

download:基于 Vue3 打造前台+中台通用提效解决方案残缺无密内置文档资料分布式消息通信之Kafka的实现原理消息中间件次要解决的就是分布式零碎之间消息传送的问题,它能够屏蔽各种平台以及协定之间的个性,实现应用程序之间的协同。举个非常简略的例子,就拿一个电商平台的注册功能来简略分析下,用户注册这一个服务,不单单只是insert一条数据到数据库外面就完事了,还需要发送激活邮件、发送新人红包或者积分、发送营销短信等一系列操作。假如说这外面的每一个操作,都需要消耗1s,那么整个注册过程就需要耗时4s才能响应给用户。 Java中使用kafka进行通信依赖<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>2.0.0</version> </dependency>复制代码发送端代码public class Producer extends Thread { private final KafkaProducer<Integer, String> producer; private final String topic; public Producer(String topic) { Properties properties = new Properties(); properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.13.102:9092,192 .168.13.103:9092,192.168.13.104:9092"); properties.put(ProducerConfig.CLIENT_ID_CONFIG, "practice-producer"); properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class.getName()); 生产端代码 properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); producer = new KafkaProducer<Integer, String>(properties); this.topic = topic; } @Override public void run() { int num = 0; while (num < 50) { String msg = "pratice test message:" + num; try { producer.send(new ProducerRecord<Integer, String>(topic, msg)).get(); TimeUnit.SECONDS.sleep(2); num++; } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } public static void main(String[] args) { new Producer("test").start(); }}复制代码生产端代码public class Consumer extends Thread { ...

August 6, 2022 · 2 min · jiezi

关于vue3:vue3简易实现响应式原理

1.前言之前听有人吐槽,说面试让实现一个繁难vue3。咱们先不说这题离不离谱,简略剖析下,如果遇到了该怎么思考。首先vue分为以下几个局部 响应零碎渲染器(mount,patch,domdiff)组件化编译器编译器不可能写进去组件化代码比拟多 波及vnode 而且不是必不可少的渲染器能够用innerhtml简化代替因而还是考响应式原理。 2.简略实现让咱们40行代码实现一个超级简化的vuedemo <!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"> <title>Document</title></head><body> <script>let activeEffect = undefined const map = new WeakMap() const effect = (fn)=>{ activeEffect = fn fn() activeEffect = undefined}const track = (t,k)=>{ // activeEffect 入set if(!activeEffect) return //防止执行fn的时候又反复track(只在执行effect时收集) if(!map.has(t)){ map.set(t,new Map()) } if(!map.get(t).has(k)){ map.get(t).set(k,new Set()) } const deps = map.get(t).get(k) deps.add(activeEffect)}const trigger = (t,k)=>{ // 取对应的effect 执行 if(map.get(t)){ if(map.get(t).get(k)){ let deps = map.get(t).get(k) deps.forEach(fn => { fn() }); } }}const reactive = (t)=>{ return new Proxy(t,{ get(t,k){ track(t,k) return t[k] }, set(t,k,v){ t[k] = v trigger(t,k) console.log('属性变动了') }, })}const obj = reactive({name:'fyy'})effect(()=>{ document.body.innerHTML = `${obj.name}` //在effect外面执行渲染逻辑,从而利用响应式,数据更新->视图更新 console.log('render')})setTimeout(()=>{ obj.name = 'fyy123'},1000) </script></body></html>2.1 proxyvue3采纳proxy形式代理一个对象,相较vue2的defineproperty有以下几个益处, ...

August 3, 2022 · 3 min · jiezi

关于vue3:vue2-vue3-学习笔记vue2-vue3-vmodel-语法区别

vue3对v-model的语法进行了改变。vue2 中有两种形式实现数据的双向绑定(组件与内部数据的双向绑定),一种是应用v-model,另一种是应用v-bind.sync修饰符。两者在应用上没有太大的区别。所以在vue3中,舍弃了.sync的写法,并且将v-model的写法向.sync的写法凑近。 vue2中的v-model,次要是进行value属性的绑定和input事件的派发。如果想要更改 prop 或事件名称,则须要在 ChildComponent 组件中增加 model 选项。 <ChildComponent v-model="pageTitle" />// 等价于<ChildComponent :value="pageTitle" @input="pageTitle = $event" />vue2中的.sync, //子组件this.$emit('update:title', newValue)//父组件<ChildComponent :title.sync="pageTitle" />//等价于<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />vue3中的v-model, //子组件this.$emit('update:modelValue', newValue)<ChildComponent v-model="pageTitle" />// 等价于<ChildComponent :modelValue="pageTitle" @update:modelValue="pageTitle = $event"/>能够看到vue3中的v-model和vue2中.sync修饰符的写法简直统一。原来的默认的数据绑定也由value改为modelValue,事件绑定由原来的input改为@update:modelValue。vue3中,如果不想应用默认的model名称或者想应用多个v-model,能够进行命名。 //父组件<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" :content="pageContent" @update:content="pageContent = $event"/>//子组件this.$emit('update:title', newValue1);this.$emit('update:content', newValue2);留神:绑定的model名称和update事件名称要统一

August 3, 2022 · 1 min · jiezi

关于vue3:如何开发一款基于-ViteVue3-的在线Excel表格系统上

明天,葡萄带你理解如何基于Vite+Vue3实现一套纯前端在线表格零碎。在正式开始我的项目介绍之前,首先咱们首先来介绍一下Vite和Vue3。 Vue32020年09月18日Vue.js 3.0公布,经验了两年工夫的对细节的一直优化与调整,终于在往年2月正式成为新的默认版本。其作者尤雨溪将Vue3的指标形容为:1、更快2、更小3、更易于保护4、原生指标更容易5、开发更轻松只看上述内容,你可能感触不到Vue3到底优化了什么。这里咱们将它和Vue2来比照一下,为大家具体阐明它的优越之处。 性能的晋升在官网文档中针对Vue2和Vue3之间的性能差别有具体的数据介绍: 1、SSR速度进步了2~3倍2、Update性能进步1.3~2倍其中性能晋升的重要一点是Vue3中对diff算法进行了优化。在Vue2中,每当数据发生变化,就会生成一个新的DOM树,并新DOM树与旧的DOM树进行比照,来判断节点异同,并进行更新。但残缺遍历过程须要将两棵树所有节点进行比拟,但理论状况中并不是所有节点内容都会变动,这就造成了性能的节约。Vue3新增了动态标记,仅对标记了的节点进行比照并进一步更新,无需再遍历整个节点,实现了性能晋升。 组合式APIVue2应用选项型API(Options API),这种形式下将代码宰割为不同的属性:data、computed、methods 等,这些办法属性各司其职。举个例子,当咱们想实现一个列表视图性能,须要在data中写此性能相干的数据,在methods中写相干的逻辑判断和后端交互办法等;如果还心愿有搜寻和筛选,或者更多的性能,那么逻辑关注点会越来越多,导致组件变得难以了解和保护。(下图为示例组件) 组合式API(Composition API)正是为了解决本来Vue2我的项目中代码逻辑扩散、不易了解和保护的问题。它应用办法(function)进行代码宰割,使代码更为简洁。 生命周期函数变更与Vue2相比,Vue3中生命周期函数也产生了变更,总结如下: 有须要的同学能够截图保留,以备不时之需。 按需打包模块在Vue我的项目中有泛滥API和模块,但在一个我的项目中咱们并不会用到全部内容, Vue3的按需打包模块,能够大幅度压缩打包后的内容体积。依据官网比照示例,Vue2中如果仅写了Hello Word,未用到任何模块API,打包后大小约为32KB;而Vue3同理,打包后大小约为13.5KB,能够显著看出降级后的Vue3相较于Vue2打包体积大幅减小。说完了Vue3的改良,接下来咱们来看看Vite又有什么亮眼之处。 Vite在Vue3正式公布之前,尤雨溪就提到做了一个新的前端构建工具-Vite。其自己更是对Vite青睐有加,引得Webpack开发者直喊大哥: Vite到底有什么样的魔力呢?它做到了本地疾速开发启动: 疾速冷启动,而不须要期待打包操作即时的模块热更新真正的按需编译,不必期待整个我的项目编译实现、在应用Webpack时,会经验剖析依赖 => 编译打包 => 交给开发服务器渲染 整个过程。也就是说,须要先打包,之后将打包后果提供给服务器进行加载。特地是随着模块的一直增多,打包的体积越来越大,造成热更新速度显著拖慢。而Vite间接略过了打包步骤,间接启动开发服务器,申请具体的模块时再对该模块进行实时编译,大大提高了启动速度。 尤雨溪自己也在微博发言解释了其原理:“Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,齐全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件反对,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则能够把同一份代码用 rollup 打。尽管当初还比拟毛糙,但这个方向我感觉是有后劲的,做得好能够彻底解决改一行代码等半天热更新的问题。”(Vite具体的实现原理可参考文章:https://juejin.cn/post/684490...) 到这里咱们曾经具体为大家介绍了Vue3降级的亮眼性能和Vite的劣势,在下局部中咱们会以我的项目实例登程,为大家介绍如何如何开发一款基于 Vite+Vue3 的在线表格零碎。感兴趣的小伙伴们不要错过~

July 27, 2022 · 1 min · jiezi

关于vue3:Vue3x-新特性总结

Vue3.x 官网注:新版vue3的setup语法糖更为简洁,详见 Vue3 script setup 语法糖,超爽体验一、Composition API 简介Vue2 时的形式在代码很少的时候,逻辑构造还是蛮清晰的,然而随着组件性能越来越多,代码量越来越大,整体内容全副放在其中必定会显得臃肿。因为每个功能模块的代码会散落散布在各个地位,让整个我的项目的内容难以浏览和保护。如下图: 而到了 Vue3,它会依据逻辑性能来进行组织,把同一个性能的不同代码都放在一起,或者把它们独自拿进去放在一个函数中,所以 Composition API 又被称为基于函数组合的API: 1. setup 函数setup 函数是 Vue3 中新增的函数,它是咱们在编写组件时,应用 Composition API 的入口。同时它也是 Vue3 中新增的一个生命周期函数,会在 beforeCreate 之前调用。因为此时组件的 data 和 methods 还没有初始化,因而在 setup 中是不能应用 this 的。所以 Vue 为了防止咱们谬误的应用,它间接将 setup 函数中的 this 批改成了undefined。并且,咱们只能同步应用setup函数,不能用async将其设为异步。 setup 函数接管两个参数 props和 context, 语法为:setup(props,context){} propsprops 外面蕴含父组件传递给子组件的所有数据。在子组件中应用 props 进行接管。 props 是响应式的, 当传入新的 props 时,会及时被更新。因为是响应式的, 所以不能够应用 ES6 解构,解构会打消它的响应式。 父组件: <template> <!-- 父组件向子组件传递数据 --> <Sub :name="name" :age="age" /></template><script>import { ref } from 'vue'import Sub from './Sub.vue'export default { setup () { const name = ref('张三'); const age = ref(20) return { name, age } }, components: { Sub },}</script>子组件(Sub.vue): ...

July 20, 2022 · 7 min · jiezi

关于vue3:vue3国际化语言包在js文件中的使用

main.tsapp.use(i18n) js中应用 <script setup lang="ts">import { getCurrentInstance, ComponentInternalInstance } from "vue"const { appContext } = getCurrentInstance() as ComponentInternalInstancelet msg = appContext.config.globalProperties.$t("message")console.log(msg)</script>模板中应用$t('message')

July 19, 2022 · 1 min · jiezi

关于vue3:Prop验证

组件能够为 props 指定验证要求。 为了定制 prop 的验证形式,你能够为 props 中的值提供一个带有验证需要的对象,而不是一个字符串数组。 定义组件Vue.component('component_name') 指定propsprops:{ // 根底的类型查看 (`null` 和 `undefined` 会通过任何类型验证)propA: Number,// 多个可能的类型propB: [String, Number],// 必填的字符串propC: { type: String, required: true},// 带有默认值的数字propD: { type: Number, default: 100},// 带有默认值的对象propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return { message: 'hello' } }},// 自定义验证函数propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 }indexOf() 办法可返回某个指定的字符串值在字符串中首次呈现的地位,若没找到则返回-1. 验证失败当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的正告。type 能够是上面原生结构器: ...

July 19, 2022 · 1 min · jiezi

关于vue3:使用vue3搭建自己的视频处理工具

前言因为最近写货色的时候想把视频转成gif,网上轻易搜了一下在线转换的网站,后果不仅要登微信,上传完之后还不给下载,很烦,于是决定本人写一个。尽管说必定有收费的网站能够用,然而本着学习的心态,加上本人做的话也自在,想要什么加什么,不必受约束,而且这些在线转换大多要微信关注公众号,这一点我很烦,收费就收费,免费就免费,非让我专一公众号,我非常承受不了。 于是去github上搜了,发现ffmpeg这个库,性能很弱小,能够做视频和音频的解决,目前我只须要做格局转换,不过也就是说前面能够基于他做更多的性能,比方简略的剪辑。临时不谈,先从简略做起,思考的太多就不想搞了,先满足目前的需要。 介绍我是用vue写的,因为vue真的很不便很快,我看到也有人用react写的,能够去看这个我的项目video-to-gif 我的我的项目地址成果展现 这个gif展现图就是这个我的项目生成的,看着很卡是因为为了放大上传的大小,我只给了3帧,所以看着非常卡。 留神有一个中央须要留神,须要在vite外面配置这个货色,如同是和跨域无关,有趣味的本人去搜,我也不是很明确,反正要是不写就会给你一个谬误。 export default defineConfig({ server: { headers: { "Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Embedder-Policy": "require-corp", } }}Error: SharedArrayBuffer could not be used.也是因为要设置headers,将打包后的动态页面间接用作github pages时就会失去这个谬误,须要启动服务去设置headers,所以想要体验的话临时须要clone我的项目到本地跑,前面我会部署在服务器上,想要体验的话能够关注本我的项目。 git clone https://github.com/shellingfordly/my-tools.gitcd my-toolspnpm ipnpm run devopen http://localhost:3080/代码转换的外围代码就是调用ffmpeg提供的api,将文件传给它,配置输入的各种参数。 页面上就做一个文件上传,和一个配置的input就行,其实还是挺简略的,启动服务就能够间接在网页上用了 export async function useFFmpeg( file: File, config: ConfigType, progressFn: ProgressCallback = () => {}) { const ffmpeg = await loadFFmpeg(); const { fetchFile } = getFFmpeg(); ffmpeg.setProgress(progressFn); const { width: defaultWidth, height: defaultHeight, duration, } = await getVideoSize(file); const { frameRate = 25, width = defaultWidth, height = defaultHeight, rangeStart = 0, rangeEnd = duration, fileType, } = config; ffmpeg.FS("writeFile", file.name, await fetchFile(file)); await ffmpeg.run( "-i", file.name, "-r", `${frameRate}`, "-ss", `${rangeStart}`, "-to", `${rangeEnd}`, "-vf", `scale=${width}:${height},fade=t=in:st=${rangeStart}:d=0.05`, `output.${fileType}` ); return ffmpeg.FS("readFile", `output.${fileType}`).buffer;}

July 13, 2022 · 1 min · jiezi

关于vue3:Vue3中响应式原理reactive模拟实现

reactivereactive是Vue3中提供实现响应式数据的办法.在Vue2中响应式数据是通过defineProperty来实现的.而在Vue3响应式数据是通过ES6的Proxy来实现的 reactive参数必须是对象(json/arr)如果给reactive传递了其余对象,默认状况下批改对象,界面不会自动更新,如果想更新,能够通过从新赋值的形式. 这里应用Reflect来实现Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目标(1) 将Object对象的一些显著属于语言外部的办法(比方Object.defineProperty),放到Reflect对象上。现阶段,某些办法同时在Object和Reflect对象上部署,将来的新办法将只部署在Reflect对象上。也就是说,从Reflect对象上能够拿到语言外部的办法。(2) 批改某些Object办法的返回后果,让其变得更正当。比方,Object.defineProperty(obj, name, desc)在无奈定义属性时,会抛出一个谬误,而Reflect.defineProperty(obj, name, desc)则会返回false。(3) 让Object操作都变成函数行为。某些Object操作是命令式,比方name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。(4)Reflect对象的办法与Proxy对象的办法一一对应,只有是Proxy对象的办法,就能在Reflect对象上找到对应的办法。这就让Proxy对象能够不便地调用对应的Reflect办法,实现默认行为,作为批改行为的根底。也就是说,不论Proxy怎么批改默认行为,你总能够在Reflect上获取默认行为。阮一峰ES6有介绍 代码实现 const isObject = (val) => val !== null && typeof val === "object";const convert = (target) => (isObject(target) ? reactive(target) : target);const hasOwnProperty = Object.prototype.hasOwnProperty;const hasOwn = (target, key) => hasOwnProperty.call(target, key);export function reactive(target) { if (!isObject(target)) return target; const handler = { get(target, key, receiver) { // 收集依赖 console.log("get", key); const result = Reflect.get(target, key, receiver); return convert(result); }, set(target, key, value, receiver) { const oldValue = Reflect.get(target, key, receiver); let result = true; if (oldValue !== value) { result = Reflect.set(target, key, value, receiver); // 触发更新 console.log("set", key, value); } return result; }, deleteProperty(target, key) { const hadKey = hasOwn(target, key); const result = Reflect.deleteProperty(target, key); if (hadKey && result) { // 触发更新 console.log("delete", key); } return result; }, }; return new Proxy(target, handler);}测试代码 ...

July 11, 2022 · 1 min · jiezi

关于vue3:vue封装x6为原生组件

antv-x6-vuegithub地址: antv-x6-vue 核心思想因为x6次要面向编辑场景,所以对每一个节点有更多的交互逻辑。所以,将x6的Shape形象成组件,每一个组件负责管理本人的生命周期。针对简单的自定义图形,利用x6反对渲染vue组件@antv/x6-vue-shape的性能,同时利用slots将节点渲染交给以后组件,将图形相干逻辑交给x6。 import { VueShape as VueShapeContainer } from '@antv/x6-vue-shape';cell.value = new VueShapeContainer({ id, width, height, primer, useForeignObject, // 这里将本人的slots中的内容强行放到画布中去 // 这样图构造的交互还有一些操作逻辑交给x6 // 通过vue绘制的组件渲染和组件外部交互逻辑交给用户 component: component ? component : () => h('div', {key: id, class: 'vue-shape'}, slots.default ? slots.default({props, item: cell}) : null), ...otherOptions,})graph.addCell(cell.value) 提供useVueShape,能够很容易的自定义一个vue组件定制进去的节点。提供useCellEvent,能够比拟不便的给以后节点绑定事件。 const CustomNode = defineComponent({ name: 'CustomNode', props: [...VueShapeProps, 'otherOptions'], inject: [contextSymbol], setup(props, context) { // 间接传递props给useVueShape,watch的时候不能监听到变动 const cell = useVueShape(() => props, context) useCellEvent('node:click', (e) => context.emit('click', e), { cell }) return () => null }})提供useTeleport,优化x6-vue-shape默认创立多个App导致渲染性能问题。同时避免出现节点数据更新不及时问题。装置yarn add antv-x6-vueComponents[x] 提供Graph容器以及GraphContext.useContext获取x6的graph对象。能够利用这个对象操作画布,绑定事件。[x] 包装Shape作为vue组件+应用x6-vue-shape封装自定义组件,裸露的组件有:类shape 名称形容Noderect等同于Shape.RectEdgeedge等同于Shape.EdgeVueShapevue-shape应用@antv/x6-vue-shape渲染的自定义vue组件的容器,能够将slots.default内容渲染到节点内。Shape.Rectrect矩形。Shape.Circlecircle圆形。Shape.Ellipseellipse椭圆。Shape.Polygonpolygon多边形。Shape.Polylinepolyline折线。Shape.Pathpath门路。Shape.Imageimage图片。Shape.HTMLhtmlHTML 节点,应用 foreignObject 渲染 HTML 片段。Shape.TextBlocktext-block文本节点,应用 foreignObject 渲染文本。Shape.BorderedImageimage-bordered带边框的图片。Shape.EmbeddedImageimage-embedded内嵌入矩形的图片。Shape.InscribedImageimage-inscribed内嵌入椭圆的图片。Shape.Cylindercylinder圆柱。Shape.Edgeedge边。Shape.DoubleEdgedouble-edge双线边。Shape.ShadowEdgeshadow-edge暗影边。另外提供帮忙函数 ...

July 8, 2022 · 2 min · jiezi

关于vue3:vue封装echarts为原生组件

vuechartsgithub地址: vuecharts 我的项目设计官网团队Baidu EFE team有出一个vue封装的echarts库vue-echarts 。然而这个库和本人在vue外面封装没有啥太大区别。仍旧解脱不了针对一个图表写一个微小的配置文件。参考BizCharts对G2这个库的封装形式,对echarts进行了封装。相对而言API更方便使用应用ts-transformer-keys,从echarts导出的XXOption主动生成vue组件props装置yarn add vuecharts3Components我的项目定义的组件蕴含在下图中,每一个都是一个vue的Component。具体的组件反对的配置信息参考:https://echarts.apache.org/zh... (能够通过名字首字母小写后搜寻到对应的配置我的项目) DEMOimport 'echarts'import Echarts from 'vuecharts3'const { Chart, Title, Tooltip, Line, Bar, Legend, Grid, XAxis, YAxis } = Echartsexport default defineComponent({ components: { Chart, Title, Tooltip, Bar, Line, Legend, Grid, XAxis, YAxis, }, setup() { return {} }})// template<template> <div class="container"> <Chart> <Grid :top="100" /> <Legend :data="['data1', 'data2']" :top="65" /> <Title text="顶部题目" subtext="顶部小标题" left="center" :top="10" /> <Title text="底部题目" top="bottom" left="center" /> <Bar name="data1" :data="[0.32, 0.45, 0.2]" /> <Bar name="data2" :data="[0.2, 0.5, 0.3]" /> <Line name="data2" :data="[0.2, 0.5, 0.3]" /> <YAxis /> <XAxis :data="['x1', 'x2', 'x3']" /> <Tooltip trigger="axis" /> </Chart> <h2>Heatmap必须搭配VisualMap</h2> <Chart> <Tooltip position="top" /> <Grid top="10%" height="50%" /> <XAxis :data="hours" /> <YAxis :data="days" type="category" /> <VisualMap :calculable="true" orient='horizontal' left='center' bottom="15%" :min="0" max="10" /> <Heatmap name="Punch Card" :data="data" :label="{show: true}" :emphasis="{itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)'}}" /> </Chart> </div></template> ...

July 8, 2022 · 2 min · jiezi

关于vue3:elementplus-重置表单的js写法

<el-from ref="formRef"> <!-- code --></el-from><script>import { ref, unref } from 'vue'const formRef = ref(null)const resetForm = () => { let form = unref(formRef)//这个是重要的一步 form.resetFields()}</script>

July 5, 2022 · 1 min · jiezi

关于vue3:Vue-3-自定义指令-骨架屏

前言骨架屏是页面的一个空白版本,通常会在页面齐全渲染之前,通过一些灰色的区块大抵勾画出轮廓,待数据加载实现后,再替换成实在的内容。 目前支流 UI库 都有骨架屏,如 Element-UI、Antd 能够看到应用起来非常简单,只须要一行代码即可 // element<el-skeleton />// antd<a-skeleton />但这样不够灵便,对于谋求个性化的页面就不太行了, 起初~ 我想了想,能不能给 节点 打 标记,而后依据 标记 主动生成对应骨架屏呢? 后果还真给我想进去了! 用 指令 先看成果 o((>< ))o ~ 实现原理咱们 自定义2个指令,别离叫做 skeleton、skeleton-item // skeleton.tsimport { reactive, watchEffect, h, render } from 'vue'const state = reactive({ // 加载状态 loading: false, // 应用了 v-skeleton-item 指令的节点保留在这里 list: []})watchEffect(() => { // 创立 vnode const children = state.list.map((el) => h('div', { style: { position: 'absolute', top: el.getBoundingClientRect().top + 'px', left: el.getBoundingClientRect().left + 'px', width: el.getBoundingClientRect().width + 'px', height: el.getBoundingClientRect().height + 'px', background: '#e5e5e5', borderRadius: getComputedStyle(el).borderRadius, }, }) ); // 创立 div 容器 const container = h('div', children) // 将 div容器 渲染到 body 中 render(state.loading ? container : null, document.body)})const Skeleton = { mounted(el, binding) { state.loading = binding.value }, updated(el, binding) { state.loading = binding.value }, unmounted(el) { state.loading = false }}const SkeletonItem = { mounted(el, binding) { // 保留 el state.list.push(el) }, unmounted(el) { // 删除 el const i = state.list.indexOf(el) if (i == -1) return state.list.splice(i, 1) }}// 注册这2个指令export default { install: app => { app.directive('skeleton', Skeleton) app.directive('skeleton-item', SkeletonItem) }}export { Skeleton, SkeletonItem }点击(在线运行)示例代码 ...

June 25, 2022 · 2 min · jiezi

关于vue3:Vue3中的teleport节点传送

Vue3 teleport官网文档地址:https://vuejs.org/guide/built... Vue3中的teleport API极大不便了在Vue3业务逻辑中操作挪动Dom地位。 简略举例<script setup lang="ts"> // 管制节点 let teleportToTarget = ref<string>('#idtest');</script><template> <div id="idTest">id节点1</div> <div class="main">main节点1</div> <div class="main">main节点2</div> <teleport :to="teleportToTarget"> <div>传送节点</div> </teleport></template>1.当teleportToTarget 为#idTest时,节点会被传输到 #idTest 节点中,等同于// let teleportToTarget = ref<string>('#idtest');<template> <div id="idTest"> id节点1<div>传送节点</div> </div> <div class="main">main节点1</div> <div class="main">main节点2</div></template>2.当teleportToTarget 为.main时,节点会被传输到 .main时 节点中,多个class同名,默认会传输到第一个节点中。等同于// let teleportToTarget = ref<string>('.main');<template> <div id="idTest">id节点1</div> <div class="main"> main节点1 <div>传送节点</div> </div> <div class="main">main节点2</div></template>3.当teleportToTarget 为body时,节点会被传输到html元素的body节点开端中。// let teleportToTarget = ref<string>('body'); 4.删除节点须要动静删除节点,只须要用v-if动态控制节点存在,dom节点会动静追随teleportToTargetShow布尔值动静是否存在。 <script setup lang="ts"> // 管制节点 let teleportToTarget = ref<string>('#idtest'); // 控制传输节点是否存在 let teleportToTargetShow = ref<boolean>(true);</script><teleport v-if="teleportToTargetShow" :to="teleportToTarget"> <div>传送节点</div></teleport>

June 22, 2022 · 1 min · jiezi

关于vue3:Vue3中的Composables组合式函数Vue3实现minxins

Vue3中的Composables是什么\Vue3中的Composables 简略了解其实就是类React Hooks式的组合式函数封装办法。\Vue官网称为Composables 组合式函数。 1.抽离复用逻辑时Vue2写法(1)Vue2 中的mixins混入器写法毛病 (Vue3 optionsApi写法同理) 新建minxins.js文件 案例 //minxins.js 文件export default{ data(){ return{ message:'混入对象', name:'zhangsan000' } }, methods: { logMessage() { console.log('打印message', this.message); } }}应用组件 // 应用import minxins from "./common/minxins";import minxins1 from "./common/minxins1"; // 举例import minxins2 from "./common/minxins2"; // 举例export default{ mixins: [minxins, minxins1, minxins2], //可混入多个文件 data(){ return{ message:'混入对象新的', bar:'bar', } }, created(){ this.logMessage(); // 打印 '混入对象新的' console.log('created组件钩子被调用') }, 一个简略Vue2 (或Vue3optionsApi写法) minxins混入器案例很直观的看出 毛病: 当应用了多个minxins时, property来自哪个 mixin变得不清晰,这使追溯实现和了解组件行为变得艰难。命名抵触会笼罩。隐式的跨 minxin交换:多个minxin须要依赖共享的 property键名来进行相互作用,这使得它们隐性地耦合在一起。而一个组合式函数的返回值能够作为另一个组合式函数的参数被传入,像一般函数那样。(2)Vue3 composition API写 法写 minxins 类性能// composables\useHelloWorldData.tsimport { ref, onMounted, onUnmounted } from 'vue'export function useHelloWorldData() { let message = ref<string>('混入对象'); let name = ref<string>('zhangsan000'); const logMessage = (): void => { console.log(message.value); }; onMounted(() => { }); onUnmounted(() => { }); return { message, name, logMessage }}应用 ...

June 12, 2022 · 2 min · jiezi

关于vue3:Vue3中使用各类字体图标的正确姿势本地SVGIconfontFontAwesomeElementPlus

前言最近,在我的项目的开发中,咱们布局了一个 Icon 组件,咱们心愿通过这个组件,能间接同时应用多种图标库的图标(一种语法,实现有限的图标扩大和高度兼容性)并且,实现该 Icon 之后,理当还有一个图标选择器,能够加载出不同图标库的所有可用图标,不便间接抉择应用,残缺代码在文末提供。 本文续Icon组件篇持续对其中的 图标选择器 进行具体介绍。 咱们的Icon和Icon选择器组件,实现了以下罕用图标库的反对,如果还有其它你喜爱的图标库,能够参考咱们的实现形式,自行加上即可。 本地SVG图标:间接将svg文件放入指定的文件夹内,实现主动加载该文件夹所有的svg,并利用Icon组件间接应用,无需手动import。ElementPlus的icon,首先应用官网提供的办法全局注册,而后和Icon组件整合,实现语法的兼容性。Iconfont(阿里巴巴矢量图标库),实现了主动载入Font clas(css链接,载入后即可通过class来应用对应的字体图标),实现Icon组件的语法兼容性,而后主动解析出Font class内的所有图标名称,以供图标选择器应用。FontAwesome,这是一款很罕用的图标库,蕴含了675个图标,Icon组件实现了主动加载,语法兼容;并且主动解析所有图标名称,以供图标选择器应用。 具体实现残缺目录构造├─src│ │ App.vue│ │ main.ts| | vite.config.ts│ ├─assets│ │ └─icons 寄存本地SVG文件的文件夹│ ├─components│ │ ├─icon│ │ ├─svg│ │ │ ├─index.ts 加载本地SVG文件的实现│ │ │ ├─index.vue svg显示组件的实现│ │ ├─index.vue Icon 组件的实现│ │ └─selector.vue 图标选择器组件的的实现| ├─utils│ │ ├─iconfont.ts字体图标辅助函数库│ │ └─common.ts公共辅助函数库复制代码本文次要介绍 /src/components/icon/selector.vue 也就是图标选择器的实现。如文首的示意图,图标选择器最难的点,是获取到各个图标库中所有图标的名称,咱们接下来将对此性能的实现,进行具体介绍。获取本地图标名称列表在实现Icon组件时,咱们曾经导入了所有的本地SVG文件的内容到我的项目内,导入后,页面退出的svg元素相似这样: 能够看到,咱们曾经应用data-icon-name属性,将所有的图标名称记录了下来,当初只需获取该属性值再进行简略解决即可,咱们在/src/utils/iconfont.ts文件中,定义了获取本地图标名称列表的函数:export function getLocalIconfontNames() { return new Promise<string[]>((resolve, reject) => { nextTick(() => { let iconfonts: string[] = [] let svgEl = document.getElementById('local-icon') if (svgEl?.dataset.iconName) { iconfonts = (svgEl?.dataset.iconName as string).split(',') } if (iconfonts.length > 0) { resolve(iconfonts) } else { reject('No Local Icons') } })})} ...

June 10, 2022 · 1 min · jiezi

关于vue3:在-Vue3-Element-Plus-中生成动态表格动态修改表格多级表头合并单元格

本文完整版:《在 Vue3 + Element Plus 中生成动静表格,动静批改表格,多级表头,合并单元格》 在 Vue 中,表格组件是应用频率及复杂度排名第一的组件,前端常常须要依据后盾返回的数据动静渲染表格,比方动静表格如何生成,因为表格的列并不是固定的,在未知表格具体有哪些列的场景下,前端如何动静渲染表格数据。又或者须要把表格单元格进行合并解决,比方第一列是日期,须要把雷同的日期进行合并,这样表格看起来会更加清晰。 本文手把手教你如何在 Vue3 + Element Plus 中创建表格、生成动静表格、创立动静多级表头、表格行合并、列合并等问题。 如果你正在搭建后盾管理工具,又不想解决前端问题,举荐应用卡拉云 ,卡拉云是新一代低代码开发工具,可一键接入常见数据库及 API ,无需懂前端,仅需拖拽即可疾速搭建属于你本人的后盾管理工具,一周工作量缩减至一天,详见本文文末。 通过本文你能够学到 如何在 Element Plus 中生成动静表格如何在 Element Plus 中动静批改表格如何在 Element Plus 中创立动静多级表头先来展现个「动静批改表格」的最终效果图吧 Vue3 + Element Plus 配置环境先应用 vue-cli 初始化利用,这里咱们抉择 vue3 的版本: vue create kalacloud-vue3-element-plus-table// ORnpx vue create kalacloud-vue3-element-plus-table而后装置 UI 框架 Element Plus: npm install element-plus --save// ORyarn add element-plus装置实现后,在我的项目里导入 ElementPlus,批改 main.js 如下: import { createApp } from 'vue'import ElementPlus from 'element-plus'import 'element-plus/dist/index.css'import App from './App.vue'const app = createApp(App)app.use(ElementPlus)app.mount('#app')导入后,就能够启动我的项目了,执行以下命令: ...

June 8, 2022 · 10 min · jiezi

关于vue3:vitevue3项目配置二级访问目录

批改router,减少base地址const router = createRouter({ // 批改地位:createWebHistory('/二级目录/') history: createWebHistory('/admin/'), routes: [], scrollBehavior() { return { top: 0 }; },});减少base配置,加载动态资源(vite.config.ts)export default defineConfig({ // 新增base base: process.env.NODE_ENV === 'production' ? '/admin/' : '', plugins: [vue(), vueJsx(), svgLoader({ svgoConfig: {} })], server: {}});批改nginxlocation /admin { try_files $uri $uri/ /admin/index.html;}

June 8, 2022 · 1 min · jiezi

关于vue3:vue30与vue20的不同点总结

这里总结一些3.x的变更,不便查阅1. 全局Api相干(1) 全局api改为应用应用程序实例 import { createApp } from 'vue'const app = createApp({})Vue.config -> app.configVue.use() -> app.use // 注册插件一些更改点: Vue.config.productionTip 移除Vue.extend 移除// 结构器相干// vue2.xconst Profile = Vue.extend({ // 生成组件结构器 template: 'xxx', data() { return {} }})new Profile().$mount(dom)// vue3.x, 移除组件结构器,改用createApp挂载const Profile = { template: 'xxxxx', data() { return {} }}Vue.createApp(Profile).mount(dom)---------------------------------// 继承相干3.x 应用 组合式 API 来代替继承与 mixin, 或应用extends选项代替Vue.extend(2) 全局Api tree-shaking(webpack打包时去除无用代码,优化打包体积) 全局 API(不全局扭转行为)以及一些外部api 应用具名导出, 有利于反对tree-shaking的打包工具打包时去除未应用的全局api, 晋升性能例如:Vue.nextTick() -> import { nextTick } from 'vue'Vue.set() ...

June 6, 2022 · 3 min · jiezi

关于vue3:基于-Vue3-打造前台中台通用提效解决方案完整无密

download:基于 Vue3 打造前台+中台通用提效解决方案残缺无密超极速优化:网络开发中的申请合并!需要如果我有大量的物联网设施,比如说100万台。如果这些设施均匀每10秒产生一个申请,那么QPS就是10W,这对于任何公司来说都是一个不小的规模了。波及到交易等有变更的需要,为了实现幂等操作,通常会提前申请一个交易号(或者说token),来进行惟一的交易申请。这样,实现一个交易,须要至多发动两个申请。一个是申请token,一个是拿着token做交易。尽管说生成token很快,但它是从网络上传输的。且不说当初都是异步模型,就拿网络提早来说,就是一个大的问题。它可能硬生生的把服务质量给降了上来,减少了不确定性,也减少了编码的复杂性。有什么方法来放慢这个过程吗?从HTTP中学习教训大多数人都晓得,TCP有三次握手和四次挥手的机制。这种简短的对话尽管保障了连贯的可靠性,但却损失了不少性能。HTTP从一到三各个版本,都是在尽量减少HTTP连贯的个数,也在缩小交互的次数。在比拟早的HTTP1.0实现中,如果须要从服务端获取大量资源,会开启N条TCP短链接,并行的获取信息。但因为TCP的三次握手和四次挥手机制,在连贯数量减少的时候,整体的代价就变得比拟大在HTTP/1.1中,通过复用长连贯,来改善这个状况,但问题是,因为TCP的音讯确认机制和程序机制以及流量控制策略的起因,资源获取必须要排队应用。一个申请,须要期待另外一个申请传输结束,能力开始HTTP/2采纳多路复用,多个资源能够共用一个连贯。但它解决的只是应用层的复用,在TCP的传输上仍然是阻塞的,前面的资源须要期待后面的传输结束能力持续。这就是队头阻塞景象(Head-of-line blocking)QUIC,也就是HTTP3,形象出了一个stream(流)的概念,多个流,能够复用一条连贯,那么滑动窗口这些概念就不必作用在连贯上了,而是作用在stream上。因为UDP只管发送不论胜利与否的个性,这些数据包的传输就可能并发执行。协定的server端,会解析并缓存这些数据包,进行组装和整顿等。因为形象出了stream的概念,就使得某个数据包传输失败,只会影响单个stream的准确性,而不是整个连贯的准确性。申请黏贴其实,咱们参考TCP的三次握手就能够了。TCP的握手和挥手流程都差不多,但为什么握手是三次,但挥手是四次呢?起因就是TCP把SYN和ACK两个报文,合并成一个返回了。 咱们能够把token看作是序列号,而后把它黏贴在失常的申请里返回就能够了。比方,原来的申请是。一、获取tokenrequest: /getTokenresponse: { "token": "12345"} 复制代码二、提交申请request: /postOrder{ "token": "12345","other": {}} response:{ "status": 200} 复制代码合并后的申请是。request: /postOrder{ "token": "12345","other": {}} response:{ "status": 200,"token": "12346"} 复制代码只须要在每次申请返回的时候,不管胜利还是失败,都附加一个新的token到客户端。客户端缓存这个token,而后发动下个申请。通过这个办法,就能够把两个申请合并为1个申请,实现咱们的优化指标。End在网络编程中,缩小网络交互是一个十分重要的优化,尤其是在弱网环境中。尽管这个技巧很简略,但它很难被想到。优化成果也是微小的,毕竟缩小了一次网络交互。 它有一个嘹亮的名字,那就是三连环。意味着前后申请的连接,永一直环。

May 31, 2022 · 1 min · jiezi

关于vue3:图解vue30编译器核心原理

概览Vue.js作为目前最风行的前端框架之一,一些概念和原理还是须要咱们前端开发人员理解与深刻了解的。 Vue.js波及的知识点很多,一些重要概念,例如:如何应用proxy实现响应式effect,虚构DOM的Diff算法及演变过程(双端Diff算法、疾速Diff算法等),渲染器原理的实现,编译器、解析器的工作原理,动静节点、动态晋升等等; 当初重点采纳图解步骤剖析一下编译器的简略工作原理; 编译器概念编译器其实就是一段JavaScript代码程序,它将一种语言(A)编译成另外一种语言(B),其中前者A通常被叫做源代码,后者B通常被叫做为指标代码。例如咱们vue的前端我的项目的.vue文件个别即为源代码,而编译后dist文件里的.js文件即为指标代码;这个过程就被称为编译(compile) 要害概念次要波及的概念: DSL 畛域特定语言AST 形象语法树(Abstract Syntax Tree)无限状态机深度优先算法 简略流程一个规范的编译器流程如下图所示:Vue.js作为DSL,其编译流程会与上图有所不同,对于Vue.js来说,源代码就是组件的模板代码,而指标代码就是可能在浏览器(或其余平台)平台上运行的JavaScript代码。 Vue的编译器Vue.js的指标代码其实就是渲染函数(render函数)。详情而言,Vue.js编译器首先对模板进行词法剖析、语法分析,而后失去模板的形象语法树(AST)。随后将模板AST转换成JavaScript AST,最初再转换成JavaScript代码,及渲染函数。一个简略的Vue.js模板编译器的工作流如下: 简略如下:模板代码 <div> <h1 id="vue">vue_compiler</h1></div>指标的AST const ast = { type: 'Root', children: [ { type: 'Element', tag: 'div', children: [ { type:'Element', tag: 'h1', props: [ { type: 'Attribute', name: 'id', content: 'vue' } ], children: [ { type: 'Text', content: 'vue_compiler' } ] } ] } ]}指标代码 function render() { return h('div', [ h('h1', {id: 'vue'}, 'vue_compiler') ])}由以上代码能够看出,AST其实就是一个具备层级构造的对象,模板的AST与模板具备雷同的嵌套构造。每一颗AST都有一个逻辑上的根节点,其类型为Root,而模板中真正的根节点则作为Root节点的children存在。 ...

May 30, 2022 · 2 min · jiezi

关于vue3:Vue3Nuxt3打造SSR网站应用0到1实现服务端渲染网盘分享

download:Vue3+Nuxt3打造SSR网站利用,0到1实现服务端渲染【网盘分享】RabbitMq消息丢失原因及其解决打算 一、RabbitMQ消息丢失原因 1.1、消费者丢失消息消费者将数据发送到rabbitmq的时候,可能因为网络问题导致数据就在半路给搞丢了。 1.使用事务(性能差) RabbitMQ 客户端中与事务机制相干的方法有三个: channel.txSelect 、channel.txCommit 和 channel.txRollback。channel.txSelect 用于将以后的信道设置成事务模式,channel.txCommit 用于提交事务,channel.txRollback 用于事务回滚。在通过 channel.txSelect 方法开启事务之后,咱们便可能公布消息给 RabbitMQ 了,如果事务提交胜利,则消息肯定到达了 RabbitMQ 中,如果在事务提交执行之前因为 RabbitMQ异样崩溃或者其余原因抛出异样,这个时候咱们便可能将其捕捉,进而通过执行channel.txRollback 方法来实现事务回滚。注意这里的 RabbitMQ 中的事务机制与大多数数据库中的事务概念并不相同,需要注意分别。 事务确实能够解决消息发送方和 RabbitMQ 之间消息确认的问题,只有消息胜利被RabbitMQ 接收,事务才能提交胜利,否则便可在捕捉异样之后进行事务回滚,与此同时可能进行消息重发。然而使用事务机制会“吸干”RabbitMQ 的性能。 2.发送回执确认(推荐) 消费者将信道设置成 confirm(确认)模式,一旦信道进入 confirm 模式,所有在该信道下面公布的消息都会被指派一个唯一的 ID(从 1 开始),一旦消息被投递到所有匹配的队列之后,RabbitMQ 就会发送一个确认(Basic.Ack)给消费者(蕴含消息的唯一 ID),这就使得消费者通晓消息已经正确到达了目的地了。如果消息和队列是可持久化的,那么确认消息会在消息写入磁盘之后收回。RabbitMQ 回传给消费者的确认消息中的 deliveryTag 蕴含了确认消息的序号,此外 RabbitMQ 也可能设置 channel.basicAck 方法中的 multiple 参数,示意到这个序号之前的所有消息都已经失去了处理,注意辨别这里的确认和生产时候的确认之间的异同。 注意要点: 事务机制和 publisher confirm 机制两者是互斥的,不能共存。 事务机制和 publisher confirm 机制确保的是消息能够正确地发送至 RabbitMQ,这里的“发送至 RabbitMQ”的含意是指消息被正确地发往至 RabbitMQ 的交换器,假如此交换器没有匹配的队列,那么消息也会丢失。 1.2、RabbitMQ弄丢了数据-开启RabbitMQ的数据持久化 为了防止rabbitmq自己弄丢了数据,这个你必须开启rabbitmq的持久化,就是消息写入之后会持久化到磁盘,哪怕是rabbitmq自己挂了,复原之后会主动读取之前存储的数据,一般数据不会丢。除非极其罕见的是,rabbitmq还没持久化,自己就挂了,可能导致大量数据会丢失的,然而这个概率较小。 设置持久化有两个步骤,第一个是创建queue的时候将其设置为持久化的,这样就可能保障rabbitmq持久化queue的元数据,然而不会持久化queue里的数据;第二个是发送消息的时候将消息的deliveryMode设置为2,就是将消息设置为持久化的,此时rabbitmq就会将消息持久化到磁盘下来。必须要同时设置这两个持久化才行,rabbitmq哪怕是挂了,再次重启,也会从磁盘上重启复原queue,复原这个queue里的数据。 而且持久化可能跟消费者那边的confirm机制配合起来,只有消息被持久化到磁盘之后,才会告诉消费者ack了,所以哪怕是在持久化到磁盘之前,rabbitmq挂了,数据丢了,消费者收不到ack,你也是可能自己重发的。 ...

May 12, 2022 · 1 min · jiezi

关于vue3:基于-Vue3-打造前台中台通用提效解决方案吾爱

download:基于 Vue3 ,打造前台+中台通用提效解决方案 复制下哉ZY:https://www.97yrbl.com/t-1411.htmlJSPJSP在理论开发中,次要是作为MVC模型中的V(View)层呈现的。当然,View层的渲染技术除了JSP,还有FreeMaker、Velocity等。JSP作为页面模板,在后端通过MVC框架渲染成HMTL,而后再发送到客户端(例如浏览器)来出现。这也就是咱们常说的“前后端不拆散”,“混合式”开发。而以后,包含很多的公司,以及大部分互联网公司。要么曾经摈弃这种模式,要么正在摈弃的路上,而转向彻底的“前后端拆散”。在“前后端拆散”模式下,后端只负责提供服务接口(例如REST),而前端(例如HTML5)通过接口发送/获取,出现数据(例如JSON格局)。这样,在后端,原来的MVC框架,某种意义上曾经演变为MC框架。因而,与V(View)相干的所有模板技术都失去了学习的必要,其中当然也包含JSP。**所以,起初的Java学习者,我的倡议是:“齐全能够放弃对JSP的学习。”Struts在Java后端开发中,MVC模型还是支流。而Struts作为一个MVC框架,单从技术上来说,还是很优良的。然而,当初Spring切实是太强势了,越来越成为Java开发中的“一站式”工具包,其中的一个利器就是Spring MVC。望名知意,Spring MVC也是一个MVC框架。而且因为它是Spring的亲儿子,天然和Spring符合的十分完满。同时,在设计之初,Spring MVC就参照了其余MVC框架的优缺点(包含Struts),所以用起来十分爽。因而,在MVC框架畛域,Spring MVC大有一统天下的趋势。因而当初,很多公司,老的Struts我的项目还在保护。但新的我的项目开发,更多转向了Spring MVC。因而,如果你是Java老手,正在学习中,我的倡议是:“不要再学习Struts了,从Spring MVC开始吧!”

May 12, 2022 · 1 min · jiezi

关于vue3:基于-Vue3-打造前台中台通用提效解决方案吾爱fen享

download:https://www.sisuoit.com/2915....需要对于须要前端实现无痛刷新Token,无非就两种: 申请前判断Token是否过期,过期则刷新申请后依据返回状态判断是否过期,过期则刷新 解决逻辑实现起来也没多大差异,只是判断的地位不一样,外围原理都一样: 判断Token是否过期没过期则失常解决过期则发动刷新Token的申请拿到新的Token保留从新发送Token过期这段时间内发动的申请重点: 放弃Token过期这段时间发动申请状态(不能进入失败回调)把刷新Token后从新发送申请的响应数据返回到对应的调用者 实现 创立一个flag isRefreshing 来判断是否刷新中创立一个数组队列retryRequests来保留须要从新发动的申请判断到Token过期isRefreshing = false 的状况下 发动刷新Token的申请刷新Token后遍历执行队列retryRequestsisRefreshing = true 示意正在刷新Token,返回一个Pending状态的Promise,并把申请信息保留到队列retryRequests中 import axios from "axios";import Store from "@/store";import Router from "@/router";import { Message } from "element-ui";import UserUtil from "@/utils/user";// 创立实例const Instance = axios.create();Instance.defaults.baseURL = "/api";Instance.defaults.headers.post["Content-Type"] = "application/json";Instance.defaults.headers.post["Accept"] = "application/json";// 定义一个flag 判断是否刷新Token中let isRefreshing = false;// 保留须要从新发动申请的队列let retryRequests = [];

May 12, 2022 · 1 min · jiezi

关于vue3:基于-Vue3-打造前台中台通用提效解决方案无密

复制URL链接下哉:https://www.666xit.com/3494/第一次Composition API在vue3.2中,正式反对了script setup的写法,这样能够大大简化组件的代码量,缩小一些反复操作,我认为当你写vue3时,应该把这当作默认写法。 在vue3.2之前,个别会这样写。 <script> export default { setup(props,ctx){ const a = ref(0) //必须return能力在template中应用,这里就存在一个反复操作的问题,每次都得cv,万一遗记就得查看 return { a } } }</script>那么当初,咱们能够这样写,比照一下,缩小了多少行代码呢<script setup> const a = ref(0)</script>PS:之后的代码我会省略script setup,默认都在script setup标签下。兴许你会感觉这样就更简略了,其实恰恰相反,CompositionAPI其实要求你对逻辑解决有更清晰的意识,对于封装有更高的要求,否则,你一样会写成比以前更丑的代码。例如: const a = ref(0) const b = ref('') const c = ref(true) const d = reactive({}) const actionA = ()=>{a.value++} const actionC = ()=>{c.value=!c.value} const actionB = ()=>{b.value += 'test' } const actiond = async ( )=> { const res = await ajax(`url`) d.a = res.a d.b = res.b d.c = res.c } const resetD = ()=>{ Object.keys(d).forEach(key=>delete d[key]) }这一堆代码其实就是当你没有思考逻辑,没有想过封装的时候,像流水账一样间接写进去的代码,这些代码真的比optionsApi更好浏览吗,当然不。这里更加凌乱,你很难一眼看出某个函数用的是哪个变量,程序凌乱,这时候须要封装,须要组合,这也是CompositionAPI的含意之一。 ...

May 12, 2022 · 1 min · jiezi

关于vue3:基于-Vue3-打造前台中台通用提效解决方案网盘链接

download:基于 Vue3 打造前台+中台通用提效解决方案(网盘链接)Java 16 新个性:instanceof增强 instanceof这个关键词,次要用来判断某个对象是不是某个类的实例。 比如,有时候咱们要处理一个类似这样的数据集: Map<String, Object> data = new HashMap<>();data.put("key1", "aaa");data.put("key2", 111);复制代码这个Map中的Value值因为可能是不同的对象,所以定义的是Object。这个时候,当咱们get进去的时候,就需要去判断和转换之后再去处理。 比如,咱们取出key1的value,而后截取一段字符串的操作,就需要这样写: Object value =data.get("key1");if (value instanceof String) { String s = (String) value; System.out.println(s.substring(1));}复制代码先判断获取的value是否是String,再做强制类型转换,而后再对字符串进行操作。这是传统的写法,而在Java 16的增强之后,对于instanceof的判断以及类型转换可能合二为一了,所以改进后的写法可能如下: Object value =data.get("key1");if (value instanceof String s) { System.out.println(s.substring(1));}复制代码是不是简略不少呢?如果没用过的话,连忙操作试试看吧! Tips:该功能经历了2个Preview版本(JDK 14中的JEP 305、JDK 15中的JEP 375),最终定稿于JDK 16中的JEP 394。

May 11, 2022 · 1 min · jiezi

关于vue3:基于Vue3ViteTS二次封装elementplus业务组件

download:基于Vue3+Vite+TS,二次封装element-plus业务组件一个Java注解@Recover搞定俊俏的循环重试代码 使用背景在实际我的项目中其中一部分逻辑可能会因为调用了内部服务或者等待锁等情况下出现不可预料的异样,在这个时候咱们可能需要对调用这部分逻辑进行重试,代码外面次要就是使用for循环写一大坨重试的逻辑,各种硬编码,各种辣眼睛的补丁。 特地是针对重试的逻辑,到处都有。所以我决定用一个重试组件spring-retry优化一波。它的出现,解决掉这部分俊俏的代码! 2开始上代码首先引入依赖: org.springframework.retryspring-retry1.3.2复制代码因为该组件是依赖于 AOP 给你的,所以还需要引入这个依赖(如果你其余 jar 包中引用过了,当然也就不需要再次引用了): org.springframework.bootspring-boot-starter-aop2.6.1复制代码开启重试:@SpringBootApplication@EnableRetrypublic class ApplicationStarter { public static void main(String[] args) { SpringApplication.run(ApplicationStarter.class); }}复制代码Controller层@RestControllerpublic class TestController {@Autowiredprivate IRecursiveCallService recursiveCallService; @GetMapping("test2")public Object test2() { return recursiveCallService.testService();}}复制代码Service层public interface IRecursiveCallService { /** * 测试service * * @return */List testService();}复制代码Service层具体实现@Servicepublic class RecursiveCallServiceImpl implements IRecursiveCallService { @Override@Retryable(recover = "testService3")public List testService() { System.out.println("到此一游!"); System.out.println(1 / 0); return null;}@Recoverpublic List testService1() { System.out.println("谬误的返回"); return Collections.singletonList("S");}@Recoverpublic List testService2(String i) { System.out.println("正确的返回"); return Collections.singletonList(1);}@Recoverpublic List testService3() { System.out.println("正确的返回2"); return Collections.singletonList(2);}} ...

May 10, 2022 · 1 min · jiezi

关于vue3:vue3axios项目使用mockjs请求404

问题还原我的项目中引入mockjs配置好测试,申请报404谬误 我的项目框架vue3.2+ts+webpack+axios+mockjsnode: 14vuecli:4.5操作步骤1.新建一个vue3我的项目vue create 我的项目名2.装置axiosnpm i axios3.装置mockjsnpm i --save-dev mockjs npm i --save-dev @types/mockjs4.mock接口mock列表数据 // src/mock/index.tsimport Mock from "mockjs";const { item } = Mock.mock({"item|6": [ { id: "@id", label: "@csentence(1,2)", value: "@sentence(1)", "status|1": ["published", "draft", "deleted"], time: "@datetime", pageNum: "@integer(0,100)", "active|1": [true, false], },],});官网文档有具体的语法规定5.拦挡axios申请// src/mock/index.ts// 获取mock的响应数据const getResponse = (url: string,type: string,data: {}[],condition: boolean) => {return { url, type: type || "get", response: (config: any) => { console.log(config, type); return condition ? { code: 200, success: true, message: "申请数据胜利", content: { total: data.length, data, }, } : { code: 500, success: false, message: "申请数据失败", }; },};};const mocks = [getResponse("/api/list", "get", item, true),getResponse("/api/productList", "post", item, true),];export const mockXHR = () => {for (const i of mocks) { Mock.mock(new RegExp(i.url), i.type || "get", i.response);}};6.全局调用mian.ts内调用7.测试申请封装申请api ...

May 7, 2022 · 1 min · jiezi

关于vue3:vitetsvue32-项目内使用导入本地图片require报错

问题形容:列表渲染中蕴含图片,图片资源放在我的项目本地动态文件夹内,默认列表数据定义在一个独自ts文件内,导入进以后页面模板内应用报错框架:vite+ts+vue3.2尝试计划:1.间接应用内部引入门路 ×这里应用别名还是相对路径都无奈解析正确图片地址 2.应用require() ×在vue2我的项目中JS文件内应用require()能够解析图片门路,这里TS不反对require(), 参考网上有答案说npm i @type/node --save -dev,装置完这个包后应用仍报错,欢送斧正 3.应用import() √应用import()须要思考异步问题,新造一个变量接管或者原始数据中多加一个键 4.应用new URL() √这个办法用起来就简略很多,vite官网上有详细描述 5..vue文件内间接援用图片 √相干链接import.meta.url: https://vitejs.cn/guide/asset...;

May 1, 2022 · 1 min · jiezi

关于vue3:快速开发后台管理系统vuebagadmin

vue-bag-admin应用Vue3+Vite2.6+TypeScript+ant-design-vue构建,提供根底的框架,疾速搭建企业级中后盾产品,响应式治理后盾零碎,应用构建依赖包的模式,开发只需引入依赖即可在线体验,教程文档 一键配置,疾速开发 动静扩大页面和配置定制 跨平台 PC、手机端、平板️ 后端路由动静渲染 开源版本反对收费商用装置npm i vue-bag-admin -save应用App.vue<template> <router-view></router-view></template>main.jsimport { createApp } from 'vue'import App from './App.vue'import install from 'vue-bag-admin'import 'vue-bag-admin/lib/style.css'import 'vue-bag-admin/mock' // 进入mock数据createApp(App).use(install).mount('#app')

April 24, 2022 · 1 min · jiezi

关于vue3:vue3vitetselementplus搭建项目二

上期咱们装置了vite,代码治理到git,还有应用eslint验证,接下来咱们在我的项目中装置vuex,router,scss、别名设置等 一、vueRouter 官网:https://router.vuejs.org/guid... 1、装置 npm install vue-router@42、装置好之后,咱们在src目录下新建router目录,在router下新建index.ts文件 index.ts文件内容 import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'const routes: RouteRecordRaw[] = [ { path: '/', name: 'home', component: () => import('../views/home/index.vue') }, { path: '/login', name: 'login', component: () => import('../views/login/index.vue') }]const router = createRouter({ history: createWebHashHistory(), // 路由模式 routes // 路由规定})export default router这块须要留神的是:(1)、history: createWebHashHistory(),调用的是办法,应用的是hash模式(2)、history: createWebHistory(),应用的是h5的history模式(3)、为了规范化typescript开发,减少路由对象RouteRecordRaw类型限度,益处:容许在根底路由外面减少开发者自定义属性,然而有时须要扩大一些字段来定制利用。(4)、因为设置了默认门路是home/index.vue,所以在app.vue中要设置入口 3、援用在main.ts中引入 import router from './router'createApp(App).use(router).mount('#app')二、vuex 官网: https://vuex.vuejs.org/zh/ind... 1、装置 npm install vuex@next --save2、在src目录下新建store目录,在store目录下新建index.ts, import { InjectionKey } from 'vue'import { createStore, useStore as baseUseStore, Store } from 'vuex'export interface State { count: number }export const key: InjectionKey<Store<State>> = Symbol('')// Create a new store instance.export const store = createStore<State>({ state: { count: 0 }})// 定义本人的 `useStore` 组合式函数export function useStore () { return baseUseStore(key)}3、在main.ts中引入 ...

April 23, 2022 · 1 min · jiezi

关于vue3:vue3vitetselementplus搭建项目

一、装置vite vite中武官网https://vitejs.cn/ Vite 须要 Node.js 版本 >= 12.0.0。npm装置: npm init vite@latestyarn装置: yarn create vite装置的时候要求输出项目名称,本人命名一个即可,输完回车。 抉择vue 应用vue+ts开发 而后依照提醒先进入我的项目,装置依赖。 启动我的项目 二、将代码提交到git上 在github上新建一个我的项目,填写本人项目名称和抉择我的项目共有或者公有等。 在dos命令窗口或者vscode命令窗口进入我的项目,输出git init 查看git status 增加所有文件 git add . commit到主分支 git commit -m 'init'将本地仓库和近程仓库连接起来 git remote add origin git@github.com:yourname/仓库名.git 将代码推送到近程仓库 git push -u origin master三、装置eslint 应用npm装置 npm install eslint --save-dev 应用npx装置 npx eslint --init装置时会有一些初始化配置,下图能够作为参考。 eslint配置完之后在.eslintrc.js文件中配置vue3应用的标准 在node_modules -> eslint-plugin-vue -> lib -> configs -> 有个vue3-strongly-recommended.js文件,这个文件是强烈推荐应用的一个标准。 ...

April 19, 2022 · 1 min · jiezi

关于vue3:vue3tsvite-问题汇总全局配置7

解决全局变量ts报错新建全局文件globle.d.ts //解决全局sysConfig ts报错declare let sysConfig: any;解决全局eslint报错.eslintrc.js module.exports = { ...globals:{sysConfig:'readonly'...

April 19, 2022 · 1 min · jiezi

关于vue3:vuevitets项目按需要引入vant或elementPlus等ui插件时抽离成单独的-js-文件

感觉自己写代码有强迫症,每当看到一个文件乱哄哄的就不难受,为了文件代码好看所以将main.ts中无关引入vant的代码分离出来: main.ts import { createApp } from 'vue'import App from './App.vue'import router from './router'import vant from './vant'export const app = createApp(App)app.use(router)app.use(vant)app.mount('#app')src目录下新建vant文件夹,而后上面新建index.ts,内容如下: import { Form, Field, CellGroup, Button } from 'vant'export default { install: function (Vue: any) { Vue.use(Form) Vue.use(Field) Vue.use(CellGroup) Vue.use(Button) },}element同理

April 15, 2022 · 1 min · jiezi

关于vue3:vue3源码学习之reactive实现

vue3 源码最近崔哥的mini-vue非常火啊,曾经飙到5.9k的star了。 看来大家都很卷,我也不能落后,这是我学习之后实现的mini-vue,蕴含了mini-vue代码的实现,学习笔记和一些思考。 后续我会继续更新学习笔记和思维导图,目前写了reactive,画了effect的思维导图。 reactive 思维导图 createReactiveObject创立响应式对象参数 target 指标对象proxyMap 缓存 mapbaseHandlers 解决对象步骤 获取曾经存在的代理对象,性能优化创立代理对象,设置缓存function createReactiveObject(target, proxyMap, baseHandlers) { const existingProxy = proxyMap.get(taget); // 应用缓存优化 if (existingProxy) { return existingProxy; } const proxy = new Proxy(taget, baseHandlers); proxyMap.set(taget, proxy); return proxy;}baseHandlersmutableHandlersreactive 的解决对象,非只读 isReadonly = false,非浅响应 shallow = falseconst get = createGetter();const set = createSetter();export const mutableHandlers = { get, set,};readonlyHandlersreadonly 的解决对象,只读 isReadonly = true,非浅响应 shallow = falseconst readonlyGet = createGetter(true);export const readonlyHandlers = { get: readonlyGet, set(target, key) { // 不能更改 console.warn(`${target} of ${key} can't be setted, it's a readonly object`); return true; },};shallowReadonlyHandlersshallowReadonly 的解决对象,只读 isReadonly = true,浅响应 shallow = true,set 与 readonlyHandlers 统一const shallowReadonlyGet = createGetter(true, true);export const shallowReadonlyHandlers = Object.assign({}, readonlyHandlers, { get: shallowReadonlyGet,});createGetter生成 get 函数function createGetter(isReadonly = false, shallow = false) { return (target, key, receiver) => { if (key === ReactiveFlags.IS_REACTIVE) { // 判断是否为 readonly 对象 return !isReadonly; } else if (key === ReactiveFlags.IS_READONLY) { // 判断是否为 reactive 对象 return isReadonly; } // 如果不是只读对象,收集依赖 // 只读对象不能更改,所以不须要收集 if (!isReadonly) { track(target, "get", key); } // 获取属性值 const res = Reflect.get(target, key, receiver); // 只对最外层最响应式,不执行嵌套对象的响应式转换 if (shallow) { return res; } // 执行嵌套对象的响应式转换 if (isObjectOrArray(res)) { return isReadonly ? readonly(res) : reactive(res); } return res; };}createSetter生成 set 函数function createSetter() { return (target, key, value, receiver) => { // 设置属性值 const res = Reflect.set(target, key, value, receiver); // 触发 依赖 trigger(target, "set", key); return res; };}工具函数isProxy 判断是否是 reactive 或者 readonly 类型isReactive 是否是 reactive 类型isReadonly 是否是 readonly 类型

April 13, 2022 · 2 min · jiezi

关于vue3:Vue设计与实现笔记持续更新

一、框架设计概览申明式与命令式(Declarative vs Imperative)申明式和命令式是两种编程范式。vue/react 是申明式的,jquery那样间接操作dom是命令式 Alright here’s a metaphor.Declarative Programming is like asking your friend to draw a landscape. You don’t care how they draw it, that’s up to them.Imperative Programming is like your friend listening to Bob Ross tell them how to paint a landscape. While good ole Bob Ross isn’t exactly commanding, he is giving them step by step directions to get the desired result.申明式就像你通知你敌人画一幅画,你不必去管他怎么画的细节命令式就像依照你的命令,你敌人一步步把画画进去 换言之 命令式编程:命令“机器”如何去做事件(how),这样不论你想要的是什么(what),它都会依照你的命令实现。申明式编程:通知“机器”你想要的是什么(what),让机器想出如何去做(how)。在放弃可维护性的同时让性能损失最小化。Vue3的设计思路二、响应式零碎

April 10, 2022 · 1 min · jiezi

关于vue3:Vue3发布这么久了还不会用Vite构建项目

本次构建的我的项目技术栈: Vite+Vue3+Volar+Pinia+Vue-Router+TS+JSX+Scss+Script setupVite: 下一代前端开发与构建工具,极速的热更新开发体验★★★★★Vue3.2: 超多的黑魔法Volar: Vue3必备开发神器Pinia: 新一代的轻量状态管理器Vue-Router4: Vue3的官网路由<Script setup> 语法糖,更简洁的语法、更好的开发体验Vue3 + TS + JSX,一个重度React + TS + JSX用户的Vue我的项目解决方案 应用vite创立vue3我的项目# npm 6.xnpm create vite@latest my-vue-app --template vue-ts# npm 7+, extra double-dash is needed:npm create vite@latest my-vue-app -- --template vue-ts# yarnyarn create vite my-vue-app --template vue-ts# pnpmpnpm create vite my-vue-app -- --template vue-ts配置VSCode开发环境禁用 vetur插件// 通过门路 `Code -> Preferences -> Settings` 中关上vscode配置文件"vetur.validation.template": false装置 Volar相干插件Vue Language Features和 TypeScript Vue Plugin装置 eslint插件,并对VSCode进行配置 "editor.formatOnSave": true, "eslint.autoFixOnSave": true, "eslint.validate": [ "javascript", "javascriptreact", { "language": "html", "autoFix": true }, { "language": "vue", "autoFix": true }, { "language": "typescript", "autoFix": true }, { "language": "typescriptreact", "autoFix": true } ],装置 prettier插件,配置通用的 prettier规定 /* prettier的配置 */ "prettier.printWidth": 300, // 超过最大值换行 "prettier.tabWidth": 2, // 缩进字节数 "prettier.useTabs": false, // 缩进不应用tab,应用空格 "prettier.semi": true, // 句尾增加分号 "prettier.trailingComma": "none", // #在对象或数组最初一个元素前面不加逗号 "prettier.singleQuote": true, // 应用单引号代替双引号工具配置vscode里的ESlint插件和Prettier插件会优先以我的项目的配置文件(如.prettierrc.json)为准,所以咱们为我的项目创立适宜我的项目的自定义规定: ...

April 9, 2022 · 5 min · jiezi

关于vue3:Vue3Nuxt3打造SSR网站应用0到1实现服务端渲染MKW

1.分页次要字段download : https://www.97yrbl.com/t-1376.html分页次要字段包含 pageSize 每页条数、pageNum 第几页、startRow 以后开始页编号、endRow 以后完结页编号、total 总数量。次要是依据前端分页的参数,进行解决后,返回前端正确的数据,其实是一个很常见且简略的性能。然而是十分也是十分重要的。 pageSize 每页条数pageNum 第几页startRow 以后开始页编号endRow 以后完结页编号total 总数量计算 3.startRow 和 endRow封装成一个函数/* 分页公共函数*/module.exports = handlePages = (pageNum, pageSize, total) => { let startRow = total > 0 ? ((pageNum - 1) * pageSize + 1) : 0; let endRow = pageNum * pageSize <= total ? pageNum * pageSize : total; return { pageNum, pageSize, recordCounts:total, startRow, endRow }}2.接口函数中应用该函数从前端传参中获取,分页所须要的数据。 let { nickname, name, role, pageSize, pageNum } = ctx.request.body; //此处进行解决 let pageNum1 = (pageNum - 1) * pageSize//获取用户信息列表async getAllUserList(ctx) { let { nickname, name, role, pageSize, pageNum } = ctx.request.body let res = [] let pageNum1 = (pageNum - 1) * pageSize let total = (await User.getAllUserListTotal())[0].recordCounts if (!nickname && !name && !role) { res = (await User.getAllUserListNotCond(pageSize, pageNum1)) } else { res = (await User.getAllUserList(nickname, name, role, pageSize, pageNum1)) } ctx.body = { code: 0, data: res.map(v => { if (v.password) { delete v.password } return v }), //分页所有的参数 ...handlePages(pageNum, pageSize, total) } }3.分页中的MySql语句依据分页查询数据库的数据//依据分页查问用户列表async getAllUserListNotCond(pageSize, pageNum) { return await query(`SELECT * FROM user LIMIT ${pageNum},${pageSize}`)}mySql获取数据库数据总条数//获取用户信息列表的总条数async getAllUserListTotal() { return await query(`SELECT COUNT(*) as recordCounts FROM user`)}

April 5, 2022 · 1 min · jiezi

关于vue3:Vue3ElementPlusKoa2-全栈开发后台系统吾爱

前言:下载ZY课程:Vue3+ElementPlus+Koa2 全栈开发后盾零碎吾爱 备用链接:https://www.sisuoit.com/1964.html 应用String类型对BigDecimal进行初始化Java在java.math包中提供的API类BigDecimal,用来对超过16位无效位的数进行准确的运算。在bigDecimal初始化时,不要应用double或者float类型的值传入结构器,比照可知,test2依然会呈现精度问题,而在创立BigDecimal对象时,参数为字符串就不会呈现精度问题所以总结如下 在进行BigDecimal数值比拟时不要应用equals进行比拟应用equals进行比拟会比拟值的大小和精度的大小,即0.00和0.000是不相等的,要应用compareTo()来进行比拟。 进行计算时须要保障参加计算的值不能为null在应用BigDecimal类型进行计算时,进行加、减、乘、除、比拟大小时,肯定要保障参加计算的两个值不能为空,否则会抛出java.lang.NullPointerException异样。

March 29, 2022 · 1 min · jiezi

关于vue3:vue3-中隐藏的-API

在理论我的项目中,咱们通常会封装一些工具类,如判断数组、对象、函数等…… 然而在 vue3 曾经内置了很多罕用的工具函数,因而咱们不用再反复造轮子 camelize 转骆驼 import { camelize } from "vue";camelize("foo-bar"); // fooBar hyphenate 大写字母用 - 连贯 import { hyphenate } from "@vue/shared";hyphenate("HelloWorld"); // hello-world capitalize 首字母大写 import { capitalize } from "vue";capitalize("hello world"); // Hello world remove 删除数组指定的元素 import { remove } from "@vue/shared";const arr = ['aaa', 'bbb', 'ccc', 'ddd', 'eee']remove(arr, 'bbb') // ['aaa', 'ccc', 'ddd', 'eee']remove(arr, 'eee') // ['aaa', 'ccc', 'ddd']remove(arr, 'aaa') // ['ccc', 'ddd'] ...

March 28, 2022 · 2 min · jiezi

关于vue3:基于Vue3ViteTS二次封装elementplus业务组件吾爱fen享

前言:download:基于Vue3+Vite+TS,二次封装element-plus业务组件 复制下载课程:https://www.97yrbl.com/t-979.htmlMVVM的介绍MVVM,一种更好的UI模式解决方案 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM - 科普MVCM: Model 数据模型(专门用来操作数据,数据的CRUD)V:View 视图(对于前端来说,就是页面)C:Controller 控制器(是视图和数据模型沟通的桥梁,用于解决业务逻辑)MVVM组成MVVM ===> M / V / VMM:model数据模型V:view视图VM:ViewModel 视图模型劣势比照MVC模式,将应用程序划分为三大部分,实现了职责拆散在前端中常常要通过 JS代码 来进行一些逻辑操作,最终还要把这些逻辑操作的后果当初页面中。也就是须要频繁的操作DOMMVVM通过数据双向绑定让数据主动地双向同步 `V(批改数据) -> MM(批改数据) -> V`数据是外围Vue这种MVVM模式的框架,不举荐开发人员手动操作DOMVue中的MVVM尽管没有齐全遵循 MVVM 模型,Vue 的设计无疑受到了它的启发。因而在文档中常常会应用 vm (ViewModel 的简称) 这个变量名示意 Vue 实例学习Vue要转化思维不要在想着怎么操作DOM,而是想着如何操作数据!!!起步 - Hello Vue装置:npm i -S vue<!-- 指定vue治理内容区域,须要通过vue展现的内容都要放到找个元素中 通常咱们也把它叫做边界 数据只在边界外部解析--> <div id="app">{{ msg }}</div><!-- 引入 vue.js --><script src="vue.js"></script><!-- 应用 vue --><script> var vm = new Vue({ // el:提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载指标 el: '#app', // Vue 实例的数据对象,用于给 View 提供数据 data: { msg: 'Hello Vue' } })</script>Vue实例留神 1:先在data中申明数据,再应用数据留神 2:能够通过 vm.$data 拜访到data中的所有属性,或者 vm.msg ...

March 27, 2022 · 1 min · jiezi

关于vue3:Vue3Nuxt3打造SSR网站应用0到1实现服务端渲染吾爱fen享受

1.1 为什么要学习 Vue下崽课程ZY:https://www.97yrbl.com/t-1376...如果从事实(找工作)的角度登程,学好 Vue 你能够找到一份称心的前端工作,而没有把握 Vue 则很难找到一份称心的前端工作(须要补充的是,除了 Vue,当初不少岗位对“小程序”也有要求)。 1.2 Vue 的特点Vue(读音 /vju/,相似于 view)是一套用于构建用户界面的渐进式 JavaScript 框架: 全称是 Vue.js 或 Vuejs;什么是渐进式框架呢? 渐进式框架意味着咱们能够在我的项目中一点点地引入和应用 Vue,而不肯定须要全副应用 Vue 来开发整个我的项目。你能够抉择应用(或不应用) Vue 的某局部性能,你也能够只在我的项目的某个模块中应用 Vue。 1.3 Vue 和 React 等框架的比照目前前端最风行的三大框架:Vue、React、Angular。 Angular:入门门槛较高,并且国内市场占有率较低。但不否定其自身是十分优良的框架,它的很多设计思维与 Node 框架 nest.js 类似,而且它们基本上都要用 TypeScript 开发。React:国内外的市场占有率都较高。作为前端工程师也是必须学习的一个框架。大公司大我的项目在以前也更偏向于应用 React 开发,因为相对来说 React 可能更加的灵便,一些 Vue2 可能没法做的场景 React则能够做(当然,当初 Vue 从 2 版本升级到 3 版本后,有了 Composition API,也非常灵活了)。Vue:在国内市场占有率最高,简直所有的前端岗位都会对 Vue 有要求。1.3.2 谁是最好的前端框架这里不给出论断,因为就像人们争执谁是世界上最好的语言一样,争执这个问题没有意义。 但咱们无妨从事实的角度先剖析一下,学习哪门语言更容易找工作(哪门语言市场占有率更高)? 找后端的工作:优先举荐 Java,其次是 Go,再次是 Node(JavaScript),可能不举荐 PHP、C#;找前端的工作:优先举荐 JavaScript(TypeScript),其次是 Flutter,再次是 Android(Java、Kotlin)、iOS(OC、Swift);其它方向:算法工程师、游戏开发、人工智能等等。那么,就前端来说,学习了 HTML、CSS、JavaScript 之后,哪一个框架更容易找到工作? 如果去国外找工作,优先举荐 React,其次是 Vue 和 Angular,不举荐 jQuery 了;如果在国内找工作,优先举荐、必须学习 Vue,其次是 React,再次是 Angular,不举荐 jQuery 了。

March 26, 2022 · 1 min · jiezi

关于vue3:手把手创建Vue3组件库

动机当市面上支流的组件库不能满足咱们业务需要的时候,那么咱们就有必要开发一套属于本人团队的组件库。 环境开发环境: vue 3.0vue/cli 4.5.13nodeJs 12.16.3npm 6.14.4步骤创立我的项目应用 vue-cli 创立一个 vue3 我的项目,假如我的项目名为 custom-npm-ui $ vue create custom-npm-ui手动抉择设置。 布局目录├─ build // 打包脚本,用于寄存打包配置文件│ ├─ rollup.config.js ├─ examples // 原 src 目录,改成 examples 用于示例展现│ ├─ App.vue│ ├─ main.ts├─ packages // 新增 packages 目录,用于编写寄存组件,如button│ ├─ SubmitForm│ │ ├─ src/│ │ ├─ index.ts│ ├─ index.ts├─ typings // 新增 typings 目录, 用于寄存 .d.ts 文件,把 shims-vue.d.ts 挪动到这里│ ├─ shims-vue.d.ts├─ .npmignore // 新增 .npmignore 配置文件├─ vue.config.js // 新增 vue.config.js 配置文件将 src 目录改为 examples ,并将外面的 assets 和 components 目录删除,移除 App.vue 里的组件援用。 ...

March 23, 2022 · 8 min · jiezi

关于vue3:JeecgbootVue3-v100-首版本重磅发布开源低代码平台项目介绍

我的项目介绍Jeecgboot-Vue3 采纳 Vue3.0、Vite、 Ant-Design-Vue、TypeScript 等新技术计划,包含二次封装组件、utils、hooks、动静菜单、权限校验、按钮级别权限管制等性能。 是在 Vben-Admin 根底上研发的,适宜于JeecgBoot的新版前端VUE3框架。以后版本:v1.0.0 | 2021-03-21 新版个性全新的VUE3技术栈,不只追赶技术潮流,更兼备大型项目劣势。提供了具体的零根底入门视频,不懂vue3的也可疾速入门。非在Vue2版上简略降级,而是齐全重写,力求每行代码的精美。源码下载切换Vue3路由:http://vue3.jeecg.com/2671576Github: https://github.com/jeecgboot/...https://github.com/jeecgboot/...码云: https://gitee.com/jeecg/jeecg...https://gitee.com/jeecg/jeecg...技术文档 官方网站: http://www.jeecg.com在线演示:http://boot3.jeecg.com开发文档:http://vue3.jeecg.com代码生成:http://vue3.jeecg.com/2677352入门视频:JeecgBoot-Vue3 零根底入门视频教程_哔哩哔哩_bilibili装置与应用Get the project codegit clone https://github.com/jeecgboot/jeecgboot-vue3.gitInstallation dependenciescd jeecgboot-vue3yarn installrunyarn servebuildyarn build入门必备本我的项目须要肯定前端基础知识,请确保把握 Vue 的基础知识,以便能解决一些常见的问题。 倡议在开发前先学一下以下内容,提前理解和学习这些常识,会对我的项目了解十分有帮忙。Vue3 文档:https://vuejs.org/TypeScript:https://www.typescriptlang.orgVue-router:https://next.router.vuejs.orgAnt-Design-Vue:Ant Design VueVben文档:https://vvbin.cn/doc-nextEs6:https://es6.ruanyifeng.comVitejs:https://vitejs.devPinia(vuex代替计划): https://pinia.vuejs.org/introduction.htmlVue-RFCS:https://github.com/vuejs/rfcsVue2迁徙到3:「链接」浏览器反对本地开发举荐应用Chrome 最新版浏览器,不反对Chrome 80以下版本。生产环境反对古代浏览器,不反对 IE。

March 22, 2022 · 1 min · jiezi

关于vue3:Vue3Nuxt3打造SSR网站应用0到1实现服务端渲染

download:Vue3+Nuxt3打造SSR网站利用,0到1实现服务端渲染备:https://www.97yrbl.com/t-1376... 库和框架的区别咱们所说的前端框架与库的区别?Library库,实质上是一些函数的汇合。每次调用函数,实现一个特定的性能,接着把控制权交给使用者代表:jQueryjQuery这个库的外围:DOM操作,即:封装DOM操作,简化DOM操作Framework框架,是一套残缺的解决方案,应用框架的时候,须要把你的代码放到框架适合的中央,框架会在适合的机会调用你的代码框架规定了本人的编程形式,是一套残缺的解决方案应用框架的时候,由框架管制所有,咱们只须要依照规定写代码 次要区别You call Library, Framework calls you外围点:谁起到主导作用(管制反转) 框架中管制整个流程的是框架应用库,由开发人员决定如何调用库中提供的办法(辅助)好莱坞准则:Don't call us, we'll call you.框架的侵入性很高(从头到尾) MVVM的介绍MVVM,一种更好的UI模式解决方案从Script到Code Blocks、Code Behind到MVC、MVP、MVVM - 科普MVCM: Model 数据模型(专门用来操作数据,数据的CRUD)V:View 视图(对于前端来说,就是页面)C:Controller 控制器(是视图和数据模型沟通的桥梁,用于解决业务逻辑)MVVM组成MVVM ===> M / V / VMM:model数据模型V:view视图VM:ViewModel 视图模型 劣势比照MVC模式,将应用程序划分为三大部分,实现了职责拆散在前端中常常要通过 JS代码 来进行一些逻辑操作,最终还要把这些逻辑操作的后果当初页面中。也就是须要频繁的操作DOMMVVM通过数据双向绑定让数据主动地双向同步 `V(批改数据) -> MM(批改数据) -> V`数据是外围Vue这种MVVM模式的框架,不举荐开发人员手动操作DOMVue中的MVVM尽管没有齐全遵循 MVVM 模型,Vue 的设计无疑受到了它的启发。因而在文档中常常会应用 vm (ViewModel 的简称) 这个变量名示意 Vue 实例学习Vue要转化思维不要在想着怎么操作DOM,而是想着如何操作数据!!!**起步 - Hello Vue装置:npm i -S vue**<!-- 指定vue治理内容区域,须要通过vue展现的内容都要放到找个元素中 通常咱们也把它叫做边界 数据只在边界外部解析--> <div id="app">{{ msg }}</div><!-- 引入 vue.js --><script src="vue.js"></script><!-- 应用 vue --><script> var vm = new Vue({ // el:提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载指标 el: '#app', // Vue 实例的数据对象,用于给 View 提供数据 data: { msg: 'Hello Vue' } })</script>

March 21, 2022 · 1 min · jiezi

关于vue3:vue3tsvite-问题汇总vite打包分析5

1、打包优化过程1.目前 vite2.x 是基于 rollup 打包的,而不是 esbuild,详见这里2.应用 rollup-plugin-visualizer(相似webpack的插件:webpack-bundle-analyzer) 进行打包剖析,打包之后,会在根目录默认生成一个 report.html 文件 后续内容今天实现

March 17, 2022 · 1 min · jiezi

关于vue3:Vue3Nuxt3打造SSR网站应用0到1实现服务端渲染吾爱

download:Vue3+Nuxt3打造SSR网站利用,0到1实现服务端渲染无密基础知识本章不会介绍java语言自身,置信大家对此已有足够相熟。绝对的,会从工程利用角度,解说几个有意思的技术点。 1.1 由源码到apk源代码是如何经验多重解决,最终出现在apk中,理解这个过程,有助于咱们认清java代码腐化的一些起因。从apk构建视角来看,java(kotlin)代码残缺处理过程如下: 上述流程中,无论是java还是kotlin代码,都会首先编译为jvm字节码。这里须要留神,app/子工程中的local jar、flat aar,以及通过内部依赖形式引入的jar、aar,都是间接蕴含编译好的jvm字节码,这会带来如下优劣势: 【劣势】无需再进行由源码到字节码的编译,在代码完全相同状况下,工程的模块化(jar/aar)水平越高,越可能缩短整体apk构建耗时;【劣势】提前编译好的jvm字节码,不会再进行源码编译期各项查看,容易呈现代码间援用关系不匹配状况,具体后文「不兼容援用」局部会详述。此外,对于jvm和Dalvik字节码,一个最外围的区别是:前者的指令,基于栈,后者基于寄存器。基于寄存器的劣势,次要是运行时指令执行性能的晋升。此外,jvm字节码,每个类位于独立.class文件,而dalvik字节码,所有类均位于同一(几)个dex文件,可能更好的复用代码数据,因而存储占用更低。1.2 应用java8java8是一个比拟有代表性的java语言版本,在Android中应用java8,这个话题自身会比较复杂。首先,从java8新内容来看,次要分为新语言个性和新API;其次,从编码到运行的整个链路来看,波及编译工具链、设施预装jdk、设施vm(Dalvik/Art)三个局部的反对;此外,Android自身应用的jdk并不是规范的oracle jdk或openjdk,而是进行了一些定制后的子集。 java8新语言特性,有一些波及到新的jvm指令集,这些须要运行时vm可能反对。否则,就须要在编译工具链中,可能应用兼容的指令集来替换这些新指令集的性能,这个过程就是大家相熟的“脱糖”,AndroidGradlePlugin3.0及以上版本,曾经对此实现了较好的反对。因为Android零碎中Art虚拟机,直到8.0版本,才齐全实现对java8新指令集的反对,因而当apk构建的minSdkVersion设置为26(8.0)以下时,会触发脱糖解决

March 16, 2022 · 1 min · jiezi

关于vue3:Vue3Nuxt3打造SSR网站应用0到1实现服务端渲染wu密

download:Vue3+Nuxt3打造SSR网站利用,0到1实现服务端渲染0、问题背景用 Spring Boot 框架的小伙伴应该都晓得,Spring Boot 有个次要的 applicaiton 配置文件,那就会波及到敏感配置信息,比方各种中间件的连贯用户名明码信息、以及各种第三方的 KEY、密钥等。 这种敏感信息如果间接放在配置文件中必定是不平安的,甚至在很多行业及领域(比方:领取畛域)都是不合规的,所以须要爱护 Spring Boot 中的敏感配置信息。 所以,你还在让你的 Spring Boot 零碎裸奔吗?如果是,那无妨看看本文中栈长分享的 4 种办法,让你的零碎不再裸奔! 1、配置核心(反对主动解密)我感觉还得看大家的架构状况,如果应用了外置的第三方配置核心(反对主动解密的那种),就能够把所有的配置信息存储在配置核心,比方 Spring Cloud 生态中的配置核心,那么能够应用自带的加、解密机制爱护敏感信息: spring: datasource: username: '{cipher}t1s293294187a31f35dea15e8bafaf7774532xxcc20d6d6dd0dfa5ae753d6836'须要加密的内容以 {cipher} 结尾标识,并留神要应用单引号包起来,具体的细节能够参考《Spring Cloud 配置核心内容加密》这篇文章,Spring Boot 配置文件就只存储一些无关紧要的配置。 大家用的哪款配置核心呢?领取配置加解密吗?欢送分享! 如果没有用到配置核心呢? 比如说传统的 Spring Boot 的 MVC 我的项目,所有的代码、配置都简直在同一个我的项目中,Spring Boot 中的外围配置文件就是 application.yml`(.properties)`文件,那要怎么爱护敏感配置信息呢?持续往下看! 2、数据库机制能够把所有配置信息存储到数据库,系统启动的时候全副加载进内存。存储的时候,敏感信息以对称加密算法进行加密存储,而后加载的时候主动解密到内存。 这是最传统的配置管理办法,其实你也能够了解为一个原始的、繁难的配置核心,只是性能不那么弱小而已,因为当初很多配置核心就是把配置放在数据库中进行存储,而后提供一系列的配置管理性能。 这里的数据库能够是关系数据库(MySQL、Oracle)、内存数据库(Redis、Zookeeper)等,这是广泛用的比拟多的中间件技术。 3、自定义加解密机制这时候也要看应用的水平,如果只是简略的数据库连接池信息,那么能够思考应用现有零碎中的对称加密算法,再联合连接池数据源类实现自定义加解密机制,比方咱们能够模拟 Spring Cloud 加密机制: 先用零碎已有的对称加密算法对数据库连贯信息加密: spring: datasource: username: '{cipher}t1s293294187a31f35dea15e8bafaf7774532xxcc20d6d6dd0dfa5ae753d6836'

March 16, 2022 · 1 min · jiezi

关于vue3:Vue3Nuxt3打造SSR网站应用0到1实现服务端渲染

dowload:Vue3+Nuxt3打造SSR网站利用,0到1实现服务端渲染0、问题背景用 Spring Boot 框架的小伙伴应该都晓得,Spring Boot 有个次要的 applicaiton 配置文件,那就会波及到敏感配置信息,比方各种中间件的连贯用户名明码信息、以及各种第三方的 KEY、密钥等。 这种敏感信息如果间接放在配置文件中必定是不平安的,甚至在很多行业及畛域(比方:领取畛域)都是不合规的,所以须要爱护 Spring Boot 中的敏感配置信息。 所以,你还在让你的 Spring Boot 零碎裸奔吗?如果是,那无妨看看本文中栈长分享的 4 种办法,让你的零碎不再裸奔! 1、配置核心(反对主动解密)我感觉还得看大家的架构状况,如果应用了外置的第三方配置核心(反对主动解密的那种),就能够把所有的配置信息存储在配置核心,比方 Spring Cloud 生态中的配置核心,那么能够应用自带的加、解密机制爱护敏感信息: spring: datasource: username: '{cipher}t1s293294187a31f35dea15e8bafaf7774532xxcc20d6d6dd0dfa5ae753d6836'须要加密的内容以 {cipher} 结尾标识,并留神要应用单引号包起来,具体的细节能够参考《Spring Cloud 配置核心内容加密》这篇文章,Spring Boot 配置文件就只存储一些无关紧要的配置。 大家用的哪款配置核心呢?领取配置加解密吗?欢送分享! 如果没有用到配置核心呢? 比如说传统的 Spring Boot 的 MVC 我的项目,所有的代码、配置都简直在同一个我的项目中,Spring Boot 中的外围配置文件就是 application.yml(.properties)文件,那要怎么爱护敏感配置信息呢?持续往下看! 2、数据库机制能够把所有配置信息存储到数据库,系统启动的时候全副加载进内存。存储的时候,敏感信息以对称加密算法进行加密存储,而后加载的时候主动解密到内存。 这是最传统的配置管理办法,其实你也能够了解为一个原始的、繁难的配置核心,只是性能不那么弱小而已,因为当初很多配置核心就是把配置放在数据库中进行存储,而后提供一系列的配置管理性能。 这里的数据库能够是关系数据库(MySQL、Oracle)、内存数据库(Redis、Zookeeper)等,这是广泛用的比拟多的中间件技术。 3、自定义加解密机制这时候也要看应用的水平,如果只是简略的数据库连接池信息,那么能够思考应用现有零碎中的对称加密算法,再联合连接池数据源类实现自定义加解密机制,比方咱们能够模拟 Spring Cloud 加密机制: 先用零碎已有的对称加密算法对数据库连贯信息加密: spring: datasource: username: '{cipher}t1s293294187a31f35dea15e8bafaf7774532xxcc20d6d6dd0dfa5ae753d6836'

March 16, 2022 · 1 min · jiezi

关于vue3:Vue3响应式原理

指标vue3响应式源码解析 Vue3的数据响应与劫持是基于古代浏览器所反对的代理对象Proxy实现的。上面的例子简略阐明vue3的响应式数据的原理,即通过Proxy对象别离对get和set劫持,在 取值和赋值两头 别离插⼊劫持的⽅法,即 track 和 trigger ——依赖的跟踪和副作⽤的触发。 const initData = {value: 1}const proxy = new Proxy( initData, // 被代理对象 { // handler对象 get(target, key) { // 进行 track return target[key] } set(target, key, value) { // 进行trigger return Reflect.set(target, key, value); } })// proxy 即 间接拜访批改对象// 也能够称为响应式数据(reactive/ref)根本阐明track: 收集依赖trigger: 触发副作用函数代码剖析通过上面的vue3实例代码运行,逐渐剖析源码。 // setupimport {ref, reactive, effect, computed} from "vue"export default { ... setup(props, context) { const countRef = 0; const number = reactive({ num: 1 }) effect(() => { console.log(countRef.value) }) const increment = () => { countRef.value++ } const result = computed(() => number.num ** 2) return { countRef, number, result, increment } }}先用流程图简略的形容下下面代码的执行过程: ...

March 13, 2022 · 7 min · jiezi

关于vue3:vue3tsvite-问题汇总四

1、@vueuse/core 工具库官网地址:https://vueuse.org/guide/#installation 概念:它是为Vue 2和3服务的一套Vue Composition API的常用工具集,是目前世界上Star最高的同类型库之一。它的初衷就是将所有本来并不反对响应式的JS API变得反对响应式,省去程序员本人写相干代码援用

March 11, 2022 · 1 min · jiezi

关于vue3:vue3项目中配置viteconfigts时使用path模块报错

通过$ npm create vite@latest创立vite我的项目的时候,在vite.confog.ts文件中增加alias别名时,想要引入node的path模块,会报错 起因:path模块是node.js内置的性能,然而node.js自身并不反对ts 解决方案:装置@types/node npm install @types/node -D残缺代码 import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import { resolve } from 'path'export default defineConfig({ plugins: [vue()], resolve: { // 配置别名 alias: { "@": resolve(__dirname, "src"), "@c": resolve(__dirname, "src/components"), } }})

March 5, 2022 · 1 min · jiezi

关于vue3:vue3tsvite-问题汇总二

1、pinia 学习

March 4, 2022 · 1 min · jiezi

关于vue3:那些Vue3实用的小知识结尾更精彩

接上一篇,咱们持续来看一下那些vue3中实用的小常识!1 directives指令自定义指令,拜访到dom节点 directive:{ "focus":{ mounted(el,binding){ // el 以后指令所在的 dom // binding指令相干信息 // binding.value 指令的值 } }}钩子函数 created:创立beforeMount:父组件挂载前mounted:挂载后beforeUpdate:更新前2 components组件1.组件:一个小的性能分区意义:简单我的项目拆分简略的组件,让团队开发更高效,组件是能够重复使用的模块了解:组件其实就是个小的Vue,具备data,methods,watch,computed组件的定义 const steper = {template:`<span>...</span>`}组件注册 components:{steper}组件的应用 <steper></steper>2.组件的参数传递01 父传子props<steper :value="5">steper外部应用(只读,不能批改) props:{value:{type:Number,default:1}}this.value 02 子传父emit事件在steper外部 this.$emit("numchange",this.num)numchange事件名称,this.num 事件值父组件 <steper @numchange="w1=$event">$event 就是子组件通过numchange传递过去的值 this.num 3.插槽<step> 嵌套内容 </step>能够通过slot获取组件的嵌套内容 <slot></slot>4.命名插槽<step> <template v-slot:pre> pre插槽内容 </template></step><slot name="pre"></slot>5.插槽的作用域子 <slot item="item">父 <step> <template v-slot:default="scope"> {{scope.item}} </template></step>3 动画 <transtion>Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡成果的组件,主动对显示与暗藏的元素增加类名 1.动画过渡进入整个过程 .v-enter-active进入开始状态 .v-enter-from进入完结状态 .v-enter-to来到的过程 .v-leave-active来到开始状态 .v-leave-from来到完结状态 .v-leave-to2.transitionmode模式分为in-out和out-in自定义进入class名称 .enter-active-class自定义来到class名称 .leave-active-class3.列表过渡咱们会应用 <transition-group> 组件实现列表过渡 tag 包裹标签名.v-move正在挪动的的元素4 节点援用ref能够应用 ref attribute 为子组件或 HTML 元素指定援用 ID ...

March 2, 2022 · 1 min · jiezi

关于vue3:一起学习Vuex-40的状态管理Vite

本文目录简略介绍vite,搭建vite我的项目。装置vuexVuex根底介绍应用Vuex插件引入 1.简略介绍vite,搭建vite我的项目1.1什么是vite?Vite是一种新型前端构建工具,可能显著晋升前端开发体验。它次要由两局部组成: 一个开发服务器,它基于 原生 ES 模块 提供了 丰盛的内建性能,如速度快到惊人的 模块热更新(HMR)。一套构建指令,它应用 Rollup 打包你的代码,并且它是预配置的,可输入用于生产环境的高度优化过的动态资源。Vite 意在提供开箱即用的配置,同时它的 插件 API 和 JavaScript API 带来了高度的可扩展性,并有残缺的类型反对。Vite 将会应用 esbuild 预构建依赖。Esbuild 应用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。 1.2初始化vitenpm init vite@latest1.3新建第一个vite我的项目 Vuex 是一个专为 Vue.js 利用程序开发的状态管理模式 + 库。它采纳集中式存储管理利用的所有组件的状态,并以相应的规定保障状态以一种可预测的形式发生变化。 2.装置vuexnpm install vuex@next --save3.Vuex根底介绍3.1 vuex每一个 Vuex 利用的外围就是 store(仓库)。“store”基本上就是一个容器,它蕴含着你的利用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同: Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地失去高效更新。 你不能间接扭转 store 中的状态。扭转 store 中的状态的惟一路径就是显式地提交 (commit) mutation。这样使得咱们能够不便地跟踪每一个状态的变动,从而让咱们可能实现一些工具帮忙咱们更好地理解咱们的利用。 次要蕴含五个局部:State、Getters、Mutations、Actions、Module。 3.1.1 State概念Vuex 应用繁多状态树——是的,用一个对象就蕴含了全副的利用层级状态。至此它便作为一个“惟一数据源 (SSOT)”而存在。这也意味着,每个利用将仅仅蕴含一个 store 实例。繁多状态树让咱们可能间接地定位任一特定的状态片段,在调试的过程中也能轻易地获得整个以后利用状态的快照。 ...

February 11, 2022 · 5 min · jiezi

关于vue3:用vitelerna配合verdaccio发布自己的前端包

前言年前做了一个相似于用户画像的我的项目,性能比拟独立,而且可能被很多我的项目作为一个功能模块嵌入,所以很天然的就想到把这个我的项目做成一个组件输入。vue-cli提供库打包模式,所以我每次开发完只须要将打包后的文件拷贝到其余我的项目就能够高兴地应用了。然而随着要援用这个模块的我的项目增多,和这个我的项目本身的开发迭代,这种手动拷贝的形式就太蠢了。显然我须要一套成熟的包治理计划,然而因为种种原因我又不能将代码公布到公共的npm上,只能在公司的测试服务器上搭建公有npm仓库。 上面我将一步一步地记录如果开发一个本人的前端包,如何搭建一个公有npm仓库,并上传本人的前端包,最初下载并援用本人的前端包。 一、应用lerna治理包lerna是什么我就不介绍了,如果你还不晓得就去看一下官网文档 全局装置lerna npm install lerna -g 初始化我的项目 创立一个文件夹,并进入该文件夹执行以下命令: lerna init 实现后,手动增加.gitignore文件,我的项目目录如下: ├── .gitignore├── lerna.json├── package.json└── packages创立包 lerna create @dede/app 创立包这里,你能够通过屡次create命令创立过个包进行开发、治理。 实现后我的项目构造如下: ├── .gitignore├── lerna.json├── package.json└── packages └── app ├── README.md ├── __tests__ │   └── app.test.js ├── lib │   └── app.js └── package.json二、应用vite+vue3开发包我在理论我的项目中用的是vue-cli+vue2,这里我用vite+vue3来做演示,毕竟vite是真的快啊! 进入到/dede-cli/packages/app目录,执行: npm create vite@latest code -- --template vue-ts 胜利当前依据vite文档里库打包章节进行配置: // vite.config.tsimport { defineConfig } from 'vite'const path = require('path')import vue from '@vitejs/plugin-vue'export default defineConfig({ plugins: [vue()], build: { outDir: './../dist', lib: { entry: path.resolve(__dirname, 'packages/index.ts'), name: 'app', fileName: (format) => `app.${format}.js` }, rollupOptions: { // 确保内部化解决那些你不想打包进库的依赖 external: ['vue'], output: { // 在 UMD 构建模式下为这些内部化的依赖提供一个全局变量 globals: { vue: 'Vue' } } } }});因为我应用的是vue-ts模板,所以还须要装置一下@types/node: ...

February 1, 2022 · 2 min · jiezi

关于vue3:记录Vue3-中使用-vuei18n-多语言

一、踩坑记录开始时候在网上收罗一大堆的相干帖子,都是通知你怎么用,却不说一些细节要点,导致前面装置应用呈现了一系列的谬误浪费时间。特此记录一下。 cnpm install vue-i18n //只实用于 vue2 的版本cnpm install vue-i18n@next // vue3 装置这版Vue3版 vue-i18n:传送门>>> 二、应用计划一、创立 i18n 文件夹,文件中蕴含三个文件。1、index.js(主入口) import { createI18n } from 'vue-i18n'import zh from './zh'import en from './en'const i18n = createI18n({ // 如果本地有语言标识就采纳本地,没有就依据浏览器语言默认标识显示语言 locale: localStorage.getItem('locale') || navigator.language.slice(0, 2), messages:{ zh, en }});export default i18n;2、zh.js(中文翻译) export default { home:{ name:"首页" }}3、en.js(英文翻译) export default { home:{ name:"Home" }}4、在 main.js 中引入 import vueI18n from './i18n'const app = createApp(App);app.use(vueI18n)app.mount('#app')5、在页面中应用 <div>{{ $t('home.name') }}</div>6、语言切换 //为什么要引入文件应用,而不是间接解构 Vue 原型上的 i18n 应用上面会说。import i18n from "@/i18n/index";function seleLanguage(index){ const idx = ['zh','en'][index] || 'zh'; localStorage.setItem("locale",idx); i18n.global.locale = idx;}三、留神要点1、要装置的是 vue-i18n@next 而不是 vue-i18n;2、多语言依据环境应该是检测地区 IP 段确定地区语言,然而图不便就采纳了浏览器语言标识。(临时没发现什么问题)3、切换时通过测试,如果应用定义在 vue 原型上的 i18n 刷新后会经常性找不到,弄其它货色后再切换语言会失败,故此间接引入 i18n 会更不便。 ...

January 21, 2022 · 1 min · jiezi

关于vue3:从Vue30的watchEffect没有触发ref数组变化说起

Vue3.0退出了watchEffect,刚好我的项目应用到了,很好用,然而发现了一个景象:watchEffect没有触发ref的数组变动,间接上代码。 <script setup>import { ref, watchEffect } from 'vue';const list = ref([1,2,3])watchEffect(() => { console.log(list.value)})setTimeout(() => { list.value.push(4)}, 5000)</script>代码执行,setTimeout后,console.log没有从新执行。 为什么呢?因为网上根本查不到有用的材料,我去翻了源码。找到了起因,上代码(我做了简洁化解决) function ref(value) { return createRef(value, false);}function createRef(rawValue, shallow) { if (isRef(rawValue)) { return rawValue; } return new RefImpl(rawValue, shallow);}class RefImpl { constructor(value, _shallow) { this._value = _shallow ? value : toReactive(value); } get value() { trackRefValue(this); return this._value; } set value(newVal) { newVal = this._shallow ? newVal : toRaw(newVal); if (hasChanged(newVal, this._rawValue)) { this._rawValue = newVal; this._value = this._shallow ? newVal : toReactive(newVal); triggerRefValue(this, newVal); } }}看代码能够看进去,ref理论执行了createRef办法,该办法返回了一个RefImpl的实例。也就是说,ref理论返回了一个RefImpl的实例。该RefImpl类劫持了get,set,做了解决。换句话说,ref其实在肯定水平上,是没有应用Proxy的,并不是像网上文章所说:"Vue3其实都在用Proxy,所有数据都是靠Proxy去实现响应的"。(当然,toReactive办法外面应用了)看到了这一步,咱们发现,其实list是RefImpl的一个实例,这个实例在push过程中,并不会触发set,所以天然无奈执行console.log ...

January 9, 2022 · 1 min · jiezi

关于vue3:Vue3-的8种组件通信方式

Vue3 组件通信形式 props$emitexpose / ref$attrsv-modelprovide / injectVuexmitt Vue3 通信应用写法 1. props 用 props 传数据给子组件有两种办法,如下 办法一,混合写法 // Parent.vue 传送<child :msg1="msg1" :msg2="msg2"></child><script>import child from "./child.vue"import { ref, reactive } from "vue"export default { data(){ return { msg1:"这是传级子组件的信息1" } }, setup(){ // 创立一个响应式数据 // 写法一 实用于根底类型 ref 还有其余用途,上面章节有介绍 const msg2 = ref("这是传级子组件的信息2") // 写法二 实用于简单类型,如数组、对象 const msg2 = reactive(["这是传级子组件的信息2"]) return { msg2 } }}</script>// Child.vue 接管<script>export default { props: ["msg1", "msg2"],// 如果这行不写,上面就接管不到 setup(props) { console.log(props) // { msg1:"这是传给子组件的信息1", msg2:"这是传给子组件的信息2" } },}</script>复制代码办法二,纯 Vue3 写法(语法糖)// Parent.vue 传送<child :msg2="msg2"></child><script setup> import child from "./child.vue" import { ref, reactive } from "vue" const msg2 = ref("这是传给子组件的信息2") // 或者简单类型 const msg2 = reactive(["这是传级子组件的信息2"])</script>// Child.vue 接管<script setup> // 不须要引入 间接应用 // import { defineProps } from "vue" const props = defineProps({ // 写法一 msg2: String // 写法二 msg2:{ type:String, default:"" } }) console.log(props) // { msg2:"这是传级子组件的信息2" }</script>留神:如果父组件是混合写法,子组件纯 Vue3 写法的话,是接管不到父组件里 data 的属性,只能接管到父组件里 setup 函数里传的属性。 ...

January 7, 2022 · 4 min · jiezi

关于vue3:chrome-extension-v3-示例pnpm-vite-elementplus-typescript

背景我的项目中应用的chrome extension是v2版本的,不反对一些新个性,比方办法的promise化。 同时心愿对框架进行整体的降级,以储备踩坑教训 性能基于之前的开发痛点,心愿新的我的项目如下 框架: 包治理:pnpmvue 3typescript打包工具:viteui组件库:element-plusbackground | popup | content | page 4方同时反对: 热更新代码复用互通能力,并反对promise现状首先找到了个库 vite-plugin-chrome-extension[]()惋惜2个库都无奈启动咱们的我的项目,可能是因为manifest v3自身也在疾速迭代中,甚至在我开发的短短工夫内,mv3就反对了popup的script module个性。因而插件开发者跟不上chrome的api更新速度十分失常。 要做的事件打包不过插件的思路是能够借鉴的,对我比拟重要的中央是: 对 background | popup | content | page 别离进行打包。然而vite临时不反对我的项目中不同文件多种打包形式,所以利用rollup-plugin来达到目标。对于咱们的我的项目,须要对不反对script module的模块儿content | page采纳iife打包模式 const outputs = (await build.generate({ format: "iife" })).output;bridge因为background | popup | content | page是相互隔离的,因而想对获取对方数据或者告诉对方须要借助chrome.runtime模块儿。然而这种模块儿不反对返回值,因而咱们对这个模块儿进行了封装,可能反对4方通信,用法大略如下 // content.jsimport api from '@/utils/api';api.onMessage('server:fetch-iframe-src', async ({ data, sender }: any) => { const iframeEl = window.document.querySelector('iframe'); if (iframeEl) { const src = iframeEl.src; const urlObj = new URL(src); return { src, host: urlObj.hostname }; } return null;});// popup.htmlimport api from '@/utils/api';const { data } = await api.sendTabMessage('server:fetch-iframe-src') as any;const iframeHost = data.data?.host;实现也有可能前面随着mv3的迭代,可能进一步简化vite的配置,将来可期。 ...

January 1, 2022 · 1 min · jiezi

关于vue3:反向操作我让-vuereactivity-支持非-Proxy-环境

背景咱们都晓得 vue3 重写了响应式代码,应用 Proxy 来劫持数据操作,分离出来了独自的库@vue/reactivity,不限于vue 在任何 js 代码都能够应用 然而正因为应用了Proxy,Proxy还无奈用polyfill来兼容,就导致了不反对Proxy的环境下无奈应用,这也是 vue3 不反对 ie11 的一部分起因 本文内容:重写了 @vue/reactivity 的劫持局部,来兼容不反对 Proxy 的环境 通过本文能够一些内容: 响应式原理@vue/reactivity 和 vue2 响应式的区别在改写中遇到的问题及解决方案代码实现利用场景及限度源码地址:reactivity 次要为 defObserver.ts 文件 响应式在开始之前咱们先对 @vue/reactivity 的响应式有个简略的理解 首先是对一个数据进行了劫持 在 get 获取数据的时候去收集依赖,记录本人是在哪个办法里调用的,假如是被办法 effect1 调用 在 set 设置数据的时候就拿到 get 时候记录的办法,去触发 effect1 函数,达到监听的目标 而 effect 是一个包装办法,在调用前后将执行栈设置为本人,来收集函数执行期间的依赖 区别vue3 相比 vue2 的最大区别就是应用了 Proxy Proxy能够比Object.defineProperty有更全面的代理拦挡: 未知属性的get/set劫持 const obj = reactive({});effect(() => { console.log(obj.name);});obj.name = 111;这一点在Vue2中就必须应用set办法来赋值 数组元素下标的变动,能够间接应用下标来操作数组,间接批改数组length const arr = reactive([]);effect(() => { console.log(arr[0]);});arr[0] = 111;对 delete obj[key] 属性删除的反对 ...

December 14, 2021 · 3 min · jiezi

关于vue3:Vue3ElementPlusAdmin-基于Vue3ElementPlus的后台管理系统

vue3-element-plus-admin介绍vue3-element-plus-admin是一个基于 vue3, vite2, element-plus, vuex-module-decorators, vue-router-next, typescript 的后盾管理系统 仓库Github vue3-element-plus-admin 预览vue3-element-plus-admin浏览地址 依赖Vue3Vue-Router-NextVuex-Module-DecoratorsViteTypeScriptElement-PlusMock.jsaxios参考我的项目vue-vben-admin 一个基于composition-api+ts的后盾模板vue-element-admin 一个后盾前端解决方案,它基于 vue 和 element-ui实现

December 8, 2021 · 1 min · jiezi

关于vue3:记录Vue3高德地图自定义弹窗中的事件

·/* 1.弹窗,不要在 content 里定义 html 内容不然所有内容的数据都会是循环的最初一个 2.应用 infowindow.setContent(windowPopup); 设置弹窗的模板*/infowindow = new AMap.InfoWindow({ isCustom: true,//开启自定义弹窗 //content: contents, anchor: "bottom-center", offset: new AMap.Pixel(10, -10),});/* 1.把外部办法赋值给 window 2.把数据的 key 赋值给自定义属性,点击事件时候获取自定义属性的 key 给以后数据*///弹窗模板<div class="link_btn" data-num=${i} onclick="$detailsAction()">查看详情</div>//查看详情window.$detailsAction = function detailsAction() { const num = document.querySelector('.link_btn').getAttribute('data-num') const datas = state.pointList[+num] getData(datas); getVideoCode(); getEchartsAction(); state.infowindow.close(); state.realtime.maxDerail = true; state.realtime.minDerail = 1;}·/* 异步加载地图插件 / 地区查问 -- 点位聚合 */AMap.plugin(["AMap.DistrictLayer", "AMap.MarkerClusterer"],()=>{ let disProvince = new AMap.DistrictLayer.Province({ zIndex: 12, adcode: ["130000"], depth: 2, styles: { fill: function (properties) { let adcode = properties.adcode; return getColorByAdcode(adcode); }, "province-stroke": "#09b8bf", "city-stroke": "#09b8bf", "county-stroke": "#09b8bf", //线条色彩 }, }); disProvince.setMap(map); })/* 高德地图异步加载 */export default function MapLoader() { return new Promise((resolve, reject) => { if (window.AMap) { resolve(window.AMap); } else { var script = document.createElement("script"); script.type = "text/javascript"; script.async = true; script.src = "http://webapi.amap.com/maps?v=1.4.15&callback=initAMap&key=5df63594d41cda1654066cca8fd5836b&plugin=AMap.Object3DLayer,AMap.DistrictSearch,AMap.Geocoder"; script.onerror = reject; document.head.appendChild(script); } window.initAMap = () => { resolve(window.AMap); }; }); }

December 4, 2021 · 1 min · jiezi

关于vue3:基于Vue3ViteTS二次封装elementplus业务组件

download:基于Vue3+Vite+TS,二次封装element-plus业务组件引子看了一个库的源码,外面用到了 WebGL ,就开始找 WebGL 的材料。发现相干的知识点很多,依照本人的了解习惯进行了整顿记录。 OriginMy GitHub 简介WebGL 是一个跨平台、收费的开放式 Web 规范,用于基于 OpenGL ES 的高级 3D 图形 API 。可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需应用插件。在 JavaScript 中能够通过 HTML5 的 Canvas 元素应用。WebGL 1.0 基于 OpenGL ES 2.0,WebGL 2.0 基于 OpenGL ES 3.0 。目前浏览器反对状况见Can I use WebGL ? WebGL 官网相干疏导资源见这里,感觉浏览加载有些慢,独自下载了一份到 Github : WebGL 1.0、WebGL 2.0。 OpenGL ES 是一个跨平台、收费的 API ,用于在嵌入式和挪动零碎(包含控制台、手机、设施和车辆)上渲染高级 2D 和 3D 图形。它是 OpenGL 的子集。 OpenGL 是业界最宽泛采纳的 2D 和 3D 图形 API ,为各种计算机平台带来了数千种应用程序。它独立于窗口零碎和操作系统。OpenGL 公开了最新图形硬件的所有性能。 ...

December 3, 2021 · 1 min · jiezi

关于vue3:vue3webpackelementplus修改主题色的坑

咱们的我的项目没有应用vite,用的是webpack工具依照element-plus文档笼罩了scss变量,然而在main文件引入时报错tff文件无奈找到,找了一圈之后发现须要在重写scss变量的文件同级创立一个fonts文件应该有loader能够解决这个问题,不过工夫短没细看,如果你有好的方法解决这个问题,能够在下方评论。而后就遇到了最大的坑,他不失效。。最初发现是文档的错(不论了,先甩锅)在文档的全局引入的例子中,让咱们引入了css文件然而这个文件是css变量,会笼罩scss设置的变量,须要去掉引入index.css,在笼罩scss变量的文件中引入主题款式这样主题色就批改胜利了

December 1, 2021 · 1 min · jiezi

关于vue3:elementplus-Icon图标统一导入及注册

element-plus官网提醒,Icon图标正在向SVG Icon迁徙,之前应用的Font Icon行将被弃用。 装置 $ yarn add @element-plus/icons# 或者$ npm install @element-plus/icons根底应用 在须要加载图标的页面内按需引入所需图标。(ps:这里官网文档并没有具体阐明) <template> <el-icon> <setting /> </el-icon></template><script setup lang="ts">import { Setting } from '@element-plus/icons'</script>对立导入并注册 //main.ts文件import * as ElIconModules from '@element-plus/icons'const app = createApp(App)// 对立注册Icon图标for (const iconName in ElIconModules) { if (Reflect.has(ElIconModules, iconName)) { const item = ElIconModules[iconName] app.component(iconName, item) }}ps:应用ts,当数组下标为字符串时,会报错。解决办法:在tsconfig.json内增加如下规定: "suppressImplicitAnyIndexErrors": true在组件中间接应用点击图标,复制相应的icon,粘贴到要加载的地位,间接应用。 <el-icon><alarm-clock /></el-icon>动静应用 例如:想要在el-menu组件中动静应用Icon图标,应用动静组件<component :is="***" />即可实现。 // router.jsconst routes = [ { path: '/dashboard', component: Layout, meta: { title: '首页', icon: 'HomeFilled' }, children: [] }]// MenuItem.vue<template> <template v-for="menu in menuList" :key="menu.path"> <el-sub-menu v-if="menu.children && menu.children.length" :index="menu.path"> <template #title> <el-icon> <component :is="menu.meta.icon" /> </el-icon> <span>{{ menu.meta.title }}</span> </template> <menu-item :menu-list="menu.children"></menu-item> </el-sub-menu> <el-menu-item v-else :index="menu.path" style="color: #f4f5f5"> <el-icon> <component :is="menu.meta.icon" /> </el-icon> <template #title>{{ menu.meta.title }}</template> </el-menu-item> </template></template>

November 29, 2021 · 1 min · jiezi

关于vue3:Vue3-和-Vue2-的-多种组件通信方式梳理

Vue3 通信应用写法 1. props 办法一,混合写法 // Parent.vue 传送<child :msg1="msg1" :msg2="msg2"></child><script>import child from "./child.vue"import { ref, reactive } from "vue"export default { data(){ return { msg1:"这是传级子组件的信息1" } }, setup(){ // 创立一个响应式数据 // 写法一 实用于根底类型 ref 还有其余用途,上面章节有介绍 const msg2 = ref("这是传级子组件的信息2") // 写法二 实用于简单类型,如数组、对象 const msg2 = reactive(["这是传级子组件的信息2"]) return { msg2 } }}</script>// Child.vue 接管<script>export default { props: ["msg1", "msg2"],// 如果这行不写,上面就接管不到 setup(props) { console.log(props) // { msg1:"这是传给子组件的信息1", msg2:"这是传给子组件的信息2" } },}</script>办法二,纯 Vue3 写法 ...

November 23, 2021 · 6 min · jiezi

关于vue3:Vue升级32的方法以及解决方案

问题由来尤大在8月的时候在微博里推送更新,我就没留神。我认为不就是简略的npm install @vue/cli -g嘛。大不了就uninstall重新安装不就完了后果发现我创立我的项目后提醒3.0.0并非3.2.21此时咱们从头开始。 卸载卸载以后vue,c盘默认地位即可.我不晓得你是2还是3 npm uninstall vue-cli -g//或者npm uninstall @vue/cli -g装置C盘默认全局装置 npm install -g @vue/cli//或者cnpm i -g @vue/cli创立我的项目到时候问你是要2还是3,选3即可, 然而没用你创立后还是3.0.0 vue create xxxxx 更新此时咱们先不要cnpm run serve运行,先做一件事装置以后我的项目的vue 和 compiler-sfc cd xxxxxcnpm i vuecnpm i @vue/compiler-sf -D此时咱们认真看看,世界如此美妙,代码如此渺小。

November 12, 2021 · 1 min · jiezi

关于vue3:解决vite创建的vue3项目中按需引入vant问题

我是应用vite创立的vue-ts模板的我的项目,装置vant依照官网的配置babel.config.js组件款式并没有失效 而采纳官网的手动引入款式也无奈失效 import 'vant/lib/datetime-picker/style/less';反而会间接报错 最初在es文件中引入款式才失效 import "vant/es/datetime-picker/style";最终成果

November 12, 2021 · 1 min · jiezi

关于vue3:Source-Code-Reading-for-Vue-3-How-does-hasChanged-work

Hey, guys! The next generation of Vue has released already. There are not only the brand new composition API, much more powerful and flexible reactivity system, first-class render function, but also the natural performance with building off the modern browsers. There have been tens of hundreds of posts and tutorials which are about Vue 3 and source code analysis even. This series is about the source code reading, but includes the related technology explanations. If it's your jam, please stay tune;) ...

November 9, 2021 · 4 min · jiezi

关于vue3:vue3-axios安装及使用

装置应用npm装置 $ npm install axios封装axios/* * @Author: Axios封装 * @Date: 2020-12-08 10:39:03 * @LastEditTime: 2021-10-22 11:34:08 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: \blogs-s\src\api\index.ts */import axios from 'axios';import qs from "qs";import store from "@/store/index";import router from '@/router/index';import { dataList } from '@/components/aspin/data';import { message } from 'ant-design-vue';import { storage } from '../storage/storage';//数据申请字符axios.defaults.baseURL = process.env.VUE_APP_API_URL, // 如果申请话费了超过 `timeout` 的工夫,申请将被中断 axios.defaults.timeout = 5000;// 示意跨域申请时是否须要应用凭证axios.defaults.withCredentials = false;// axios.defaults.headers.common['token'] = AUTH_TOKENaxios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';// 容许跨域axios.defaults.headers.post["Access-Control-Allow-Origin-Type"] = "*";// 申请拦截器axios.interceptors.request.use(function (config) { if ( config.method === "post" || config.method === "put" || config.method === "delete" ) { // qs序列化 config.data = qs.parse(config.data); } // 若是有做鉴权token , 就给头部带上token if (storage.get(store.state.Roles)) { store.state.Roles config.headers.Authorization = storage.get(store.state.Roles); } return config;}, error => { message.error(error.data.error.message); return Promise.reject(error.data.error.message);})// 响应拦截器axios.interceptors.response.use(function (config) { dataList.show = true if (config.status === 200 || config.status === 204) { setTimeout(() => { dataList.show = false }, 400) return Promise.resolve(config); } else { return Promise.reject(config); }}, function (error) { if (error.response.status) { switch (error.response.status) { case 400: message.error("收回的申请有谬误,服务器没有进行新建或批改数据的操作==>" + error.response.status) break; // 401: 未登录 // 未登录则跳转登录页面,并携带以后页面的门路 // 在登录胜利后返回以后页面,这一步须要在登录页操作。 case 401: //重定向 message.error("token:登录生效==>" + error.response.status + ":" + store.state.Roles) storage.remove(store.state.Roles) storage.get(store.state.Roles) router.replace({ path: '/Login', }); break; // 403 token过期 // 登录过期对用户进行提醒 // 革除本地token和清空vuex中token对象 // 跳转登录页面 case 403: message.error("用户失去受权,然而拜访是被禁止的==>" + error.response.status) break; case 404: message.error("网络申请不存在==>" + error.response.status) break; case 406: message.error("申请的格局不可得==>" + error.response.status) break; case 410: message.error("申请的资源被永恒删除,且不会再失去的==>" + error.response.status) break; case 422: message.error("当创立一个对象时,产生一个验证谬误==>" + error.response.status) break; case 500: message.error("服务器产生谬误,请查看服务器==>" + error.response.status) break; case 502: message.error("网关谬误==>" + error.response.status) break; case 503: message.error("服务不可用,服务器临时过载或保护==>" + error.response.status) break; case 504: message.error("网关超时==>" + error.response.status) break; default: message.error("其余谬误谬误==>" + error.response.status) } return Promise.reject(error.response); } else { // 解决断网的状况 // eg:申请超时或断网时,更新state的network状态 // network状态在app.vue中管制着一个全局的断网提醒组件的显示暗藏 // 对于断网组件中的刷新从新获取数据,会在断网组件中阐明 store.commit('changeNetwork', false); } })export default axiosmain.ts:全局应用import axios from './utils/http/axios'全局应用// 全局ctx(this) 上挂载 $axiosapp.config.globalProperties.$api = axios#### 封装应用 ...

October 27, 2021 · 4 min · jiezi

关于vue3:在Vue30ts中如何使用h函数

我要做的是一个菜单成果,是用的jsx语法,开发应用的是Vue3.0+ts开发的间接用模板编写<a-menu v-model:selectedKeys="selectedKeys" mode="inline" theme="light"> <a-menu-item key="1"> <pie-chart-outlined/> <span>工作台</span> </a-menu-item> <a-sub-menu key="sub3"> <template #title> <span> <desktop-outlined/> <span>系统配置</span> </span> </template> <a-sub-menu key="sub4" title="权限治理"> <a-menu-item key="7"> 菜单列表 </a-menu-item> </a-sub-menu> </a-sub-menu> <a-sub-menu key="sub2"> <template #title> <span> <user-outlined/> <span>User</span> </span> </template> <a-menu-item key="4">Bill</a-menu-item> </a-sub-menu></a-menu>应用tsx编写数据结构 const defaultMenu = [ { name: '首页', router: '/home', icon: 'HomeFilled', isShow: 1, id: 1 }, { name: '组件库', router: '', isShow: 1, id: 2, children: [ { name: 'Markdown编辑器', router: '/markdown', icon: 'HomeFilled', isShow: 1, id: 3, }, { name: '文件上传', router: '/fileUpload', icon: 'UploadOutlined', isShow: 1, id: 4, children:[ { name: '图片上传', router: '/fileUploadImg', icon: 'UploadOutlined', isShow: 1, id: 6, } ] }, ] }, { name: '对于', router: '/about', icon: 'UserOutlined', isShow: 1, id: 5, },]import {computed, defineComponent, h, ref} from 'vue'import {useStore} from 'vuex'export default defineComponent({ name: 'yxs-menu-slider', setup() { const store = useStore(); const selectedKeys = ref<string[]>(['1']); // 设置默认选中 const menuList = computed(() => store.getters.menuList); // 等于上述的 defaultMenu 构造,我只不过放在了store return { selectedKeys, menuList } }, render(ctx: any) { const deepMenu = function (list: Array<any>) { let html = null; return list.filter((item: any) => item.isShow).map((item: any) => { if (item.children && item.children.length) { html = h( <a-sub-menu key={item.id}></a-sub-menu>, {}, { title: () => { // 插槽地位 title return <span>{item.name}</span> }, default: () => { // 默认内容 let children = item.children.map((todo: any) => { return <a-menu-item key={todo.id}>{todo.name}</a-menu-item> }) return children && deepMenu(item.children) // 递归 } } ) } else { html = h( <a-menu-item key={item.id}></a-menu-item>, {}, { default: () => { return <span>{item.name}</span> } } ) } return html; }) } const children = deepMenu(ctx.menuList); return ( <div class="yxs-menu-slider"> <a-menu v-model:selectedKeys={ctx.selectedKeys} mode="inline" theme="light"> {children} </a-menu> </div> ) }})应用注册调用即可<template> <YxsMenuSlider/></template><script lang="ts"> import YxsMenuSlider from './components/menu/index.tsx' export default defineComponent({ name: 'Slider', components: { YxsMenuSlider } })</script>成果如下下面半截是模板,上面tsx模板 ...

October 16, 2021 · 3 min · jiezi

关于vue3:Vue3使用-Ant-Design-Vue

一.引入Ant Design Vuevue 我的项目请自行创立1.我的项目增加npm i --save ant-design-vue@next -S2.main.js 增加 ant-design-vue 组件 import { createApp } from 'vue'import Antd from 'ant-design-vue';import App from './App.vue'import router from './router'import store from './store'import 'ant-design-vue/dist/antd.css';import './index.css'// 本教程采纳的是全局引入组件库createApp(App).use(router).use(store).use(Antd).mount('#app')二.遇到问题问题1:Error: Cannot find module 'babel-plugin-import'提醒找不到 babel-plugin-import解决:增加babel-plugin-importnpm install babel-plugin-import --save 问题2:我的项目运行没有报错,然而不显示内容,关上调试报错: Uncaught ReferenceError: Antd is not defined at eval (main.ts?bc82:8) at Module../src/main.ts (app.js:1206) at __webpack_require__ (app.js:854) at fn (app.js:151) at Object.1 (app.js:1279) at __webpack_require__ (app.js:854) at checkDeferredModules (app.js:46) at app.js:994 at app.js:997解决形式: babel.config.js 增加 ...

October 14, 2021 · 1 min · jiezi

关于vue3:vue3使用echarts5封装组件无法显示

1.开发环境 vue3+echarts52.电脑系统 windows10专业版3.在应用vue3+echarts5开发的过程中,咱们依据我的项目的须要有时候须要封装一些组件,上面我来分享一下如何实现。4.废话不多说,间接上代码: // 曲线组件<template> <div :id="CurveList.DatasList.id" style="width: 36rem; height: 20rem" class="Qu" ></div></template><script lang="ts">import { defineComponent, reactive, onMounted } from "vue";import * as echarts from "echarts";export default defineComponent({ name: "Curve", props: { Datas: { type: Object } }, setup(props) { const CurveList = reactive({ DatasList: props.Datas }); // console.log(CurveList.DatasList); // console.log(CurveList.DatasList?.con); // console.log(CurveList.DatasList?.id); const Xdata: any[] = CurveList.DatasList?.Xdata; const lineData1: any[] = CurveList.DatasList?.lineData1; const lineData2: any[] = CurveList.DatasList?.lineData2; const lineData3: any[] = CurveList.DatasList?.lineData3; const option = reactive({ title: { text: "曲线显示" }, xAxis: { type: "category", boundaryGap: false, data: Xdata, axisLine: { itemStyle: { lineStyle: { color: "#000", width: 1 //这里是为了突出显示加上的 } } } }, yAxis: { type: "value", splitLine: { lineStyle: { // 应用深浅的距离色 color: ["#000"] } }, nameTextStyle: { color: ["#000"] }, axisLine: { lineStyle: { color: "#000", width: 1 //这里是为了突出显示加上的 } } }, series: [ { type: "line", data: lineData1, itemStyle: { lineStyle: { color: "#FF0033" } }, showSymbol: false }, { type: "line", data: lineData2, itemStyle: { lineStyle: { color: "#0099FF" } }, showSymbol: false }, { type: "line", data: lineData3, itemStyle: { lineStyle: { color: "#3CC4A9" } }, showSymbol: false } ] }); onMounted(() => { const QuDom = document.getElementById( CurveList.DatasList?.id ) as HTMLElement; console.log(QuDom); const myChart = echarts.init(QuDom); myChart.setOption(option); }); return { CurveList }; }});</script><style lang="stylus" scoped></style>5.在对应的组件中应用: ...

October 8, 2021 · 2 min · jiezi

关于vue3:Vite-because-the-content-contains-invalid-JS-syntax

Vue3 在采纳 compositionAPI 时候,Vite编译报错: [vite] Internal server error: Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension. 我遇到的报错起因是因为: async setup(props) { // setup后面用async 异步关键字需注意阻塞危险 await XXXX; // await前面 异步呈现阻塞 导致报错 }最好间接用Vue3 script-setup 语法糖去写 Vue3 script-setup语法

October 1, 2021 · 1 min · jiezi

关于vue3:vue3项目asyncLoader报undefined的问题处理

概述最近在开发vue3.x的我的项目中,配置好路由之后点击跳转页面就呈现以下报错: Uncaught (in promise) TypeError: Cannot read property '__asyncLoader' of undefined网上也没有找到问题的解决办法,话不多说,间接上解决办法: 辅助函数defineAsyncComponentVue 3.x 中,对异步组件的应用跟 Vue 2.x 不同了。变动次要有三点: 异步组件申明办法的扭转:Vue 3.x 新增一个辅助函数defineAsyncComponent,用来显示申明异步组件;异步组件高级申明办法中的 component 选项更名为loader;loader绑定的组件加载函数不再接管resolve和reject参数,而且必须返回一个Promise;vue3我的项目中引入组件的写法如下: 留神:defineAsyncComponent只实用于vue3的异步组件,对于路由懒加载是有效的。路由懒加载的办法和vue2.x一样。 心愿能帮到遇到同样问题的你!

September 28, 2021 · 1 min · jiezi

关于vue3:CodePen-Home-elementplus-Date-Picker-日期选择器-defaultvalue设置默认值

聊聊近来学用vue3+element-plus,发现Date Picker 日期选择器 default-value设置默认值不起作用,记录下来 官网文档给出的示例默认值都没显示,有图为证: 解决办法将示例代码改为如下: setup() { const value1 = ref('') const defaultDate = new Date(2010, 9, 1) value1.value = defaultDate const value2 = ref('') const defaultDateRange = [new Date(2010, 9, 1), new Date(2010, 10, 1)] value2.value = defaultDateRange return { value1, value2, defaultDate, defaultDateRange }},成果演示CodePen Home element-plus Date Picker 日期选择器 default-value设置默认值 总结其实也就是说设置default-value基本不起作用,起作用的是通过给Date Picker绑定的value1.value赋一个默认值defaultDate。大家都有什么更好的方法吗?欢送探讨下啊官网组件是不是还有待改良?

September 26, 2021 · 1 min · jiezi

关于vue3:在vue3中使用html2canvas生成海报及问题总结

1. 如何在vue3中应用html2canvasnpm install --save html2canvas生成海报: <template> <div class="poster-box" ref="posterBox"> <div class="thumb"><img src="@assets/goods.jpg" alt=""></div> <div class="goods-info"> <div class="title-box"> <div class="title">情侣装男女红色彩色T恤太空散步宇航员默认发红色须要其余色彩请备注</div> <div class="price">¥99.9</div> </div> <div class="code">二维码</div> </div> </div> <div class="btn" @click="initPoster">生成海报</div> <img v-if="showImg" :src="posterUrl" class="poster" alt=""></template><script>import html2canvas from 'html2canvas'import { ref, unref } from 'vue'export default { setup() { const showImg = ref(false) const posterBox = ref(null) const posterUrl = ref(null) const initPoster = () => { html2canvas(unref(posterBox), { width: unref(posterBox).getBoundingClientRect().width, height: unref(posterBox).getBoundingClientRect().height }).then(canvas => { posterUrl.value = canvas.toDataURL('image/jpeg') showImg.value = true; }); } return { initPoster, showImg, posterBox, posterUrl } }}</script><style lang="scss" scoped>.poster-box { width: 5.5rem; height: 7.4rem; background: #fff; padding: .15rem; .thumb { width: 100%; height: 5.2rem; img { width: 100%; height: 100%; } } .goods-info { margin-top: .2rem; display: flex; justify-content: space-between; .code { width: 1.4rem; height: 1.4rem; line-height: 1.4rem; text-align: center; color: #fff; background: #ddd; margin-left: .1rem; } .title-box { width: 0; flex: 1; } .title { text-align: justify; font-size: .3rem; font-weight: bold; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .price { color: red; font-size: .32rem; font-weight: bold; margin-top: .2rem; } }}.poster { width: 5.5rem;}</style>2. 生成的图片白边问题在某些机型上生成的图片,左边和下边会有白边,如下图:解决办法: ...

September 23, 2021 · 1 min · jiezi

关于vue3:使用vue3封装Switch开关组件

本人写了一个视频播放器组件,为了缩小npm包的体积外面用到的组件都是本人封装的 工作中switch开关组件组件中都有,然而这个组件本人会封装吗?这篇文章教大家使用简略的html元素实现就能实现一个Vue3版本的switch组件。 先看一下图例 开关的状态 vue3实现switch开关组件 为什么说我这个组件简略呢?先上html代码 非常简单 <template> <div class="d-switch" :class="{ 'is-checked': checked }"> <input class="d-switch__input" ref="input" type="checkbox" :checked="checked" @change="handleInput" :true-value="trueValue" :false-value="falseValue" /> <span class="d-switch_action"></span> </div></template>这里解释一下逻辑 1.d-switch元素:最外层就是开关的盒子 用来定义背景色和宽高 通过 classis-checked管制开和关的款式2.d-switch__input元素:认真看一下这个开关组件里我并没有应用@click事件,是因为click事件都是通过这个input元素实现的。input的值也能够通过true-value和false-value 自定义 d-switch_action:这个元素就是开关里的圆色白点。很重要的一点,因为这个组件是通过点击input获取到以后状态,所以这里要把input的 z-index设置为1,笼罩在span标签下面,而后把opacity设置为0.这样你看到的是 span标签的款式,然而你点击的其实是input触发的事件<style lang='less' scoped>.d-switch { position: relative; height: 18px; transition: background 0.2s; width: v-bind(width); background: rgb(117, 117, 117); border-radius: 10px; display: inline-flex; align-items: center; vertical-align: middle; .d-switch__input { position: relative; z-index: 1; margin: 0; width: 100%; height: 100%; opacity: 0; } .d-switch_action { position: absolute; transition: 0.2s; left: 2px; top: 2px; z-index: 0; height: 14px; width: 14px; background: #fff; border-radius: 50%; } &.is-checked { background: v-bind(activeColor); .d-switch_action { left: 100%; background: #fff; margin-left: -18px; } }}</style>最初是增加props属性和事件 ...

September 16, 2021 · 2 min · jiezi

关于vue3:vue3elementplus使用记录

因为elementplus局部只给了Options API的写法,故再此记录应用Composition API写过的组件的办法。 form表单相干当初想要获取ref须要进行一下操作 import { ref } from 'vue'setup () { // 第一步定义ref, 名称与html中的ref="yourRef"统一,并return进来 const yourRef = ref() // 而后就能够和vue2中的ref一样应用了 // 提交表单 const saveOneBlog = () => { console.log('listen formRef', formRef) formRef.value.validate(async (valid) => { if (valid) { const res = await api(params) console.log(res) } }) } // 重置表单 const reset = () => { yourRef.value.resetFields() } return { yourRef }}表单局部代码html局部 <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> <el-form-item label="名称" prop="blogTitle"> <el-input v-model="form.blogTitle" placeholder="请输出博客名称"></el-input> </el-form-item> <el-form-item label="类型" prop="blogTypeId"> <el-select v-model="form.blogTypeId" placeholder="抉择博客类型"> <el-option v-for="item in blogTypeList" :key="item.blogTypeId" :label="item.typeName" :value="item.blogTypeId"> </el-option> </el-select> </el-form-item> <el-form-item label="内容" prop="blogContent"> <v-md-editor v-model="form.blogContent" height="400px" ></v-md-editor> </el-form-item> <el-form-item label="是否可见" prop="isShow"> <el-switch v-model="form.isShow" active-color="#13ce66" inactive-color="#ff4949"> </el-switch> </el-form-item> <el-form-item v-show="isEdit" label="创立工夫" prop="createTime"> {{ form.createTime }} </el-form-item> <el-form-item v-show="isEdit" label="最初批改工夫" prop="lastUpdateTime"> {{ form.lastUpdateTime }} </el-form-item> </el-form> <div class="g-line"></div> <div class="footer-btn"> <el-button type="primary" @click="resetForm">reset</el-button> <el-button type="primary">Save and add aother</el-button> <el-button type="primary" @click="saveOneBlog">Save</el-button> </div>script局部 ...

September 15, 2021 · 2 min · jiezi

关于vue3:vue梳理

Vue解说1.介绍vue的我的项目目录1.1 APP我的项目目录.|-- build // 我的项目构建(webpack)相干代码| |-- build.js // 生产环境构建代码| |-- check-version.js // 查看node、npm等版本| |-- dev-client.js // 热重载相干| |-- dev-server.js // 构建本地服务器| |-- utils.js // 构建工具相干| |-- webpack.base.conf.js // webpack根底配置| |-- webpack.dev.conf.js // webpack开发环境配置| |-- webpack.prod.conf.js // webpack生产环境配置|-- config // 我的项目开发环境配置| |-- dev.env.js // 开发环境变量| |-- index.js // 我的项目一些配置变量| |-- prod.env.js // 生产环境变量|-- dist // 打包后的dist文件| |-- page // 最初打包的文件,间接放到服务器上| |-- web.config // 用于iis重定向|-- node_modules //包文件|-- src // 源码目录| |-- assets // vue公共动态资源| |-- components // vue公共组件| |-- page // vue次要页面| |-- store // vuex的状态治理| |-- App.vue // 页面入口文件| |-- main.js // 程序入口文件,加载各种公共组件|-- static // 动态文件,比方一些图片,js等|-- .babelrc // ES6语法编译配置|-- .editorconfig // 定义代码格局|-- .eslintignore // ES6语法标准监测|-- .eslintrc.js // |-- README.md // 我的项目阐明|-- favicon.ico |-- index.html // 入口页面|-- package.json // 我的项目根本信息. ...

September 13, 2021 · 1 min · jiezi

关于vue3:Vue30-Vite20-Ts40搭建一款简约版本的移动端博客

vue3-vite2-blog-h5一款简洁版本的挪动端博客。前端我的项目次要是采纳Vue3最新语法糖<script setup>和Vant3.0来搭建的;采纳Tsx来渲染公共组件;采纳Vite2.0来构建、打包。后端我的项目次要采纳Node框架Koa2以及MongoDB数据库来设计的。 PC 端博客线上预览地址:http://www.rasblog.comPC 端博客仓库地址:https://github.com/Sujb-sus/vue-node-mongodb-blogH5 端博客仓库地址:https://github.com/Sujb-sus/vue3-vite2-ts-blog-h5我的项目预览 我的项目构造 技术使用一、rem 适配装置插件yarn add amfe-flexible postcss-pxtorem -Samfe-flexible是配置可伸缩布局计划,次要是将 1 rem 设为 viewWidth / 10postcss-pxtorem是 postcss 的插件,用于将像素(px)单元生成 rem 单位在 main.ts 导入amfe-flexibleimport "amfe-flexible";在postcss.config.js配置postcss-pxtoremmodule.exports = { plugins: { "postcss-pxtorem": { rootValue: 37.5, propList: ["*"], }, },};rootValue 依据设计稿宽度除以 10 进行设置,这边假如设计稿为 375,即 rootValue 设为 37.5propList 是设置须要转换的属性,这边*意思就是为所有单位为(px)都进行转换二、增加 css 前缀装置插件yarn add autoprefixer -D在postcss.config.js配置autoprefixermodule.exports = { plugins: { autoprefixer: { overrideBrowserslist: ["Android 4.1", "iOS 7.1"], grid: true, }, },};overrideBrowserslist:浏览器的兼容配置grid: true 为 IE 启用网格布局前缀三、公共组件用 tsx 语法编写// svgIcon.tsximport { defineComponent, computed } from "vue";export default defineComponent({ name: "svgIcon", props: { name: { type: String, required: true, }, }, setup(props) { const iconName = computed(() => `#${props.name}`); return () => ( <> <svg class="icon" aria-hidden="true"> <use xlinkHref={iconName.value}></use> </svg> </> ); },});defineComponent 对 setup 函数进行封装,返回 options 的对象,在 ts 下给予了组件正确的参数类型推断<use xlink:href={iconName.value}>须要改为驼峰模式<use xlinkHref={iconName.value}>,不然会有语法问题四、用<script setup>语法糖1. 父组件传值给子组件<!-- 父组件的html --><List :showTitle="false" :params="params"></List>// 子组件的<script setup>interface Props { showTitle?: boolean; params?: object;}const props = withDefaults(defineProps<Props>(), { showTitle: true, params: undefined,});defineProps定义 props 类型withDefaults提供 props 默认值两者在<script setup>内不须要额定导入即可应用2. 子组件传值给父组件<!-- 父组件的html --><LabelSelect @changeLabel="changeLabel" ref="label"></LabelSelect>// 父组件的<script setup>const changeLabel = (labelName: string) => { params.type = labelName;};// 子组件的<script setup>const emit = defineEmits(["changeLabel"]);emit("changeLabel", labelName);defineEmits定义响应父组件的办法名,须要先定义才可通过 emit()响应emit('changeLabel', data),changeLabel 为响应的办法名,labelName 就是要传给父组件的值3. 逻辑复用用 use...以驼峰的模式结尾定义文件,定义一个 useClickLike 函数且导出;// useClickLikes.tsimport { ref, computed } from "vue";function useClickLike(requestApi: Function) { let currentId = ref(""); // 以后id let isLike = ref(false); // 是否点赞 let likeList = ref<string[]>([]); // 点过赞列表 const handleLikes = (id: string) => { if (likeList.value.includes(id)) { isLike.value = true; likeList.value.splice(likeList.value.indexOf(id), 1); } else { isLike.value = false; likeList.value.push(id); } currentId.value = id; return requestApi({ _id: id, isLike: isLike.value }).catch((err: any) => { console.log(err); }); }; return { handleLikes, };}export default useClickLike;在 vue 文件中援用,先导入进来,再解构出所须要的函数逻辑import useClickLike from "@/useMixin/useClickLike";// 点赞逻辑const { handleLikes } = useClickLike(apiUpdateLikes);handleLikes 就能够在 html 模版间接使用<div class="footer-item" @click.stop="handleLikes(item._id)"></div>4. computed、watch 的应用import { computed, watch } from 'vue'const getLikesNumber = computed( () => (id: string, likes: number) => likeList.value.includes(id) ? likes + 1 : likes );watch(props.params, (newVal,oldVal) => { pageindex.value = 1 hasLoad.value = false loading.value = false finished.value = false list.value = [] getBlogList() })computed 语法跟 vue2 一样,watch 语法有略微不同,props.params 为监听对象,newVal 为监听到的最新值,oldVal 为旧值具体语法可参看官网文档:https://v3.cn.vuejs.org/api/computed-watch-api.html#computed5. vuex 的应用import { useStore } from "vuex";const store = useStore();// 获取label模块actions下的getLabelList办法const getLabelList = () => store.dispatch("label/getLabelList");getLabelList(); // 间接执行办法// 获取label模块getters下的labelList属性const labelList = store.getters["label/labelList"];其余具体用法请参考官网文档:https://next.vuex.vuejs.org/zh/guide/modules.html6. vue-router 的应用配置路由文件,createWebHashHistory制订 hash 模式/:pathMatch(.*)*匹配所有路由做重定向用导入路由文件须要用import.meta.glob,不能用间接用import导入,import在开发时没问题,然而在打包后的文件会辨认不了路由文件import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";import Tabbar from "../components/tabbar";// 先辨认所有的views/文件夹name/*.vue文件// 这里限制性很高,只有门路为/views/文件夹name/*.vue,的文件能力背辨认const modules = import.meta.glob("../views/*/*.vue");const loadComponent = (component: string) => modules[`../views/${component}.vue`];const routes: Array<RouteRecordRaw> = [ { path: "/home", component: loadComponent("home/index"), meta: { title: "首页", }, }, .... { path: "/:pathMatch(.*)*", redirect: "/home", },];const router = createRouter({ history: createWebHashHistory(), routes,});export default router;获取路由携带的 query 参数import { useRouter } from "vue-router";const route = useRouter();const id = route.currentRoute.value.query["id"];后端服务必须得先开启后端服务接口,连贯上MongoDB数据库,不然前端我的项目没法预览。这边的服务接口其实是复用了 PC 端wall-blog我的项目的接口。所以如果想要在治理后盾增加数据的,须要移至该仓库:https://github.com/Sujb-sus/vue-node-mongodb-blog。 ...

September 13, 2021 · 3 min · jiezi

关于vue3:基于vue3xqiankun微前端项目搭建

September 11, 2021 · 0 min · jiezi

关于vue3:基于-VantVue3-倒计时按钮组件的实现

Vant 没有提供倒计时按钮组件,手动实现一下。 // CountDownButton.vue 实现<template> <Button style="min-width: 80px;" size="small" type="primary" :disabled="countDownButtonArgs.timing" @click="emit('click', successCallback)" >{{ loading ? loadingText : countDownButtonArgs.timing ? countDownButtonArgs.count : buttonText }}</Button></template><script setup lang="ts">import { reactive } from 'vue'import { Button } from 'vant'const props = defineProps({ maxSecondNum: { type: Number, default: 60 }, buttonText: { type: String, default: '获取验证码' }, loadingText: { type: String, default: '发送中' }, loading: { type: Boolean, default: false }})type EmitsType = { (e: 'click', successCallback: () => void): void }const emit = defineEmits<EmitsType>()const countDownButtonArgs = reactive<{ timing: boolean; count: number }>({ timing: false, count: 0})const successCallback = () => { countDownButtonArgs.timing = true countDownButtonArgs.count = props.maxSecondNum const timer = setInterval(() => { const { count } = countDownButtonArgs if (count > 0 && count <= props.maxSecondNum) { countDownButtonArgs.count--; } else { countDownButtonArgs.timing = false clearInterval(timer) countDownButtonArgs.count = 0 } }, 1000)}</script><style lang="less"></style>// 应用举例<template> <div> <NavBar title="用户登录"></NavBar> <Form @submit="onLogin"> <CellGroup inset> <Field v-model="phone" name="tel" label="手机号" :rules="[{ required: true, message: '请输出' }]" /> <Field v-model="code" type="password" name="password" label="验证码" :rules="[{ required: true, message: '请输出' }]" > <template #button> <CountDownButton :loading="loading" @click="getCodeFn"></CountDownButton> </template> </Field> </CellGroup> <div style="margin: 16px;"> <Button round block type="primary" native-type="submit">登录</Button> </div> </Form> </div></template><script setup lang="ts">import { ref } from "vue";import { Form, Field, CellGroup, Button, NavBar, Toast } from 'vant'import CountDownButton from '../../../components/CountDownButton.vue'import { sendSmsCode, smsLogin } from './api'import { useRouter } from 'vue-router'const router = useRouter()const phone = ref('');const code = ref('');const onLogin = async () => { const b = await smsLogin(phone.value, code.value) if (b) { Toast('登录胜利') router.push('/tvs/home') }};const loading = ref(false)const getCodeFn = async (successCallback: () => void) => { if (!phone.value) { Toast('请输出手机号'); return; } loading.value = true const b = await sendSmsCode(phone.value) loading.value = false successCallback() if (b) { Toast('验证码发送胜利'); }}</script><style lang="less"></style>成果如下 ...

September 10, 2021 · 2 min · jiezi

关于vue3:Vue3项目中微信授权登录的优雅实现

前言微信受权登录是做微信公众号开发始终绕不开的话题,而且整个受权登录流程的实现,是须要前后端配合一起实现的。在过来前后端还未分离的年代,兴许咱们前端并不需要太过关怀受权的具体实现。然而当初都2021年了,前后端拆散的架构大行其道,如何在前后端拆散的状况下实现微信受权登录就成了明天要探讨的重点问题。 筹备首先,咱们还是须要先梳理下微信受权整个流程是怎么的,这里我就间接将官网文档搬来: 如果用户在微信客户端中拜访第三方网页,公众号能够通过微信网页受权机制,来获取用户根本信息,进而实现业务逻辑。...对于网页受权的两种scope的区别阐明1、以snsapi_base为scope发动的网页受权,是用来获取进入页面的用户的openid的,并且是静默受权并主动跳转到回调页的。用户感知的就是间接进入了回调页(往往是业务页面)2、以snsapi_userinfo为scope发动的网页受权,是用来获取用户的根本信息的。但这种受权须要用户手动批准,并且因为用户批准过,所以毋庸关注,就可在受权后获取该用户的根本信息。...具体而言,网页受权流程分为四步:1、疏导用户进入受权页面批准受权,获取code2、通过code换取网页受权access_token(与根底反对中的access_token不同)3、如果须要,开发者能够刷新网页受权access_token,防止过期4、通过网页受权access_token和openid获取用户根本信息(反对UnionID机制)这里附上微信公众号开发之微信受权的官网文档。 以上是笔者提炼进去的比拟要害的几点信息,当然还有更多的阐明,心愿老手读者们还是先认真看完官网文档。 这里我再补充阐明下,以上流程的4个步骤中,除了第一步以外,另外三步都是须要在服务器端去实现的。前端要做的外围其实是怎么进行用户登录状态的查看判断和登录状态的保护。 实现思路大家都晓得,Vue是前后端拆散技术计划下的产物,它是一个纯前端利用(服务端渲染除外)。通常咱们是须要在用户关上页面,执行到页面的js脚本时,咱们再异步去申请服务端数据,再进行相干逻辑的解决和判断。咱们要实现微信受权登录的前提是,须要先判断用户是否须要登录(cookie或者token)。当用户未登录时,才须要走受权登录流程,当受权登录胜利后,咱们也须要在前端记录好登录状态,以不便在页面切换时,不必再次触发受权登录。再通过剖析可知,前端其实能做的就是获取微信服务器给咱们的code,再将code给咱们的后端,让后端实现后续步骤拿到用户信息后生成用户。那么整个过程我再梳理如下: (前端)检查用户是否登录;(前端)如果未登录,疏导用户进入受权页面批准受权,获取code(前端)将获取到的code提交给后端(后端)通过code换取用户凭证openid(后端)通过openid检查用户是否存在,是否须要注册新用户,并获取用户id(后端)返回用户信息;(前端)记录用户登录状态,跳回登录前页面;这个过程,我画了个图,如下: 上代码依据以上思路,当初开始编码环节。笔者采纳的是Vue3,Vue2的开发者还请依据状况做适当调整。为了不便唤起用户受权登录逻辑,笔者打算将受权登录封住为一个login页面,这样做的益处是咱们在任何判断到须要登录的中央间接通过Vue Router的push办法跳转到登录页面即可。通常状况下,咱们的利用并不是所有页面都须要登录后能力拜访,只有在拜访特定页面时候,才须要用户登录,那么咱们就须要标识哪些页面须要进行登录鉴权。这里咱们能够利用Vue Router的meta属性来进行标识,官网文档对meta解释如下: 有时,你可能心愿将任意信息附加到路由上,如过渡名称、谁能够拜访路由等。这些事件能够通过接管属性对象的meta属性来实现,并且它能够在路由地址和导航守卫上都被拜访到。刚好Vue Router官网就有示例,如下: const routes = [ { path: '/posts', component: PostsLayout, children: [ { path: 'new', component: PostsNew, // 须要登录后能力拜访的页面 meta: { requiresAuth: true } }, { path: ':id', component: PostsDetail, // 任何人都可拜访的页面 meta: { requiresAuth: false } } ] }]接下来咱们就能够在Vue Router的全局守卫beforeEach中获取到这个元信息从而做登录跳转了 router.beforeEach((to, from) => { // 而不是去查看每条路由记录 // to.matched.some(record => record.meta.requiresAuth) if (to.meta.requiresAuth && !userStore.isLogin) { // 此路由须要受权,请查看是否已登录 // 如果没有,则重定向到登录页面 return { path: '/login', // 保留咱们所在的地位,以便当前再来 query: { redirect: to.fullPath }, } }})须要补充阐明的是,userStore.isLogin的实现。这里和咱们理论采纳的登录态保护计划无关,如果是采纳token形式的话,那就是查看token是否曾经存在。笔者采纳了vuex作为来保留token,而后借助插件来将Store中的数据长久化到localStorage。 ...

September 8, 2021 · 2 min · jiezi

关于vue3:VUE3初体验-关于代码管理的我的思考

简图: 解释:1.VUE文件只定义组件,以及模板中所须要的回调办法(例如@click等)。2.useInit.js,只定义监听器、计算属性、生命周期等,相当于VUE2的watch、compute、mounted(等等)等,但用到的办法和依赖的均来源于useTools.js。3.useTools.js,只定义依赖和办法,相当于VUE2的data、props、methods。4.VUE文件从useInit.js中获取模板中用到的依赖。5.useInit.js从useTools.js文件中获取初始化用到的办法和依赖,以及须要传递到VUE文件中的依赖。6.返回办法和依赖。7.返回依赖。 举例:App.vue<template> <div class="test" :style="{ width: state.fatherWidth + 'vw', background: state.fatherBgc, }" > <button @click="changeBgc">变色</button> <child></child> </div></template><script setup>import Child from "./components/child.vue";import { defineComponent } from "vue";import useInit from "./utils/App/useInit";defineComponent({ Child,});let { state } = useInit();function changeBgc() { state.fatherBgc = "lightblue";}</script><style scoped>.test { height: 100vh; overflow: hidden;}</style>child.vue<template> <div class="test"> <button @click="updateWidth">变窄</button> </div></template><script setup>import PubSub from "pubsub-js";function updateWidth() { PubSub.publish("updateWidth")}</script><style scoped></style>useInit.jsimport PubSub from "pubsub-js";import useTools from "./useTools";import { onMounted, onUnmounted, watch } from "vue";export default function useInit() { const { init, pubsubOptions, state, } = useTools(); watch( () => state.fatherWidth, val => { if (val % 2 === 1) { state.fatherBgc = "pink" } } ) onMounted(() => { init(); }); onUnmounted(() => { for (let psevt in pubsubOptions) { PubSub.unsubscribe(psevt); } }); return { state }}useTools.jsimport PubSub from "pubsub-js"import { reactive } from "vue";export default function useTools() { const pubsubOptions = { updateWidth: null, } const state = reactive({ fatherWidth: 100, fatherBgc: 'yellowgreen' }) function updateWidth() { state.fatherWidth -- state.fatherBgc = 'lightblue'; if (state.fatherWidth <= 80) { state.fatherWidth = 100 state.fatherBgc = 'yellowgreen' } } return { init: function() { pubsubOptions.updateWidth = PubSub.subscribe("updateWidth", () => { updateWidth() }) }, pubsubOptions: pubsubOptions, state: state, };}总结:最后我的想法是延长optionAPI的写法,将data、props、components、watch、生命周期钩子等都写到vue组件中,而后将这些依赖以传递的形式传递到useInit等,然而一顿打磨之后发现传递其实能够有起点。比方useTools,把所有的data、methods、都定义到useTools中,而后再返回到内部。其实思路上就是一个正反的区别,然而向外传递的形式能让data和methods的关系更严密,也更直观。然而这两种办法都没有按功能模块进行拆分,简直是把所有的办法都堆到一起。最初再抛出一个问题,有些零碎的原型设计就曾经很大水平的既定了代码的设计,话中有话就是代码的耦合度等和零碎的设计有很大关系。在这种耦合度必然存在的状况下要怎么拆分功能模块,让代码更容易治理和保护。或者是否有更好的代码设计的思路或计划啊,搜索枯肠就是想不出啊~ ...

September 7, 2021 · 1 min · jiezi

关于vue3:vue3-记录

一. watch 深度监听。 import _ from 'lodash'watch( () => _.cloneDeep(xxx), n => {})利用 lodash 办法 深拷贝变量,实现深度监听。Object.create(JSON.parse(JSON.stringify(xxx))).__proto__ 也能实现同样的成果。(Tip:JSON.parse(JSON.stringify(xxx)) 无奈齐全拷贝变量,必须要新对象) 如果是数组对象。 let a = ref([1,2,3]) watch( () => [...a.value], n => {})更新ing。。。

September 6, 2021 · 1 min · jiezi

关于vue3:Vue3基础与入门

字数:7887, 浏览工夫:40分钟,点击浏览原文 从2013年12月8日公布第一个版本至今已,Vue已走过了快八个年头,你理解每个版本名字的意义吗? 版本号名字释义工夫V0.9Animatrix黑客帝国动画版2014.2.25V0.10Blade Runner银翼杀手2014.3.23V0.11Cowboy Bebop星际牛仔2014.11.7V0.12Dragon Ball龙珠2015.6.12V1.0Evangelion新世纪福音战士2015.10.27V2.0Ghost in the Shell攻壳机动队2016.9.30V2.1Hunter X Hunter全职猎人2016.11.22V2.2Initial D头文字D2017.2.26V2.3JoJo's Bizarre AdventureJoJo的微妙冒险2017.4.2V2.4Kill la Kill斩服少女2017.7.13V2.5Level E灵异E接触2017.10.13V2.6Macross超时空要塞2019.2.4V3.0One Piece海贼王2020.9.18V3.1Pluto地上最强机器人2021.6.8V3.2Quintessential Quintuplets五等分的花嫁2021.8.10原来每个版本的名字都是以漫画命名,那么这些动漫,你看过几部呢? 那么接下来咱们就重点聊聊Vue3.0。 缘起一个新工具的呈现,肯定是为了解决已有工具存在的问题。咱们经常据说Vue不适宜开发大型简单的我的项目,一个根本原因是 Vue 现有的 API 迫使咱们通过选项组织代码,然而有的时候通过逻辑关系组织代码更有意义。另一个起因是目前短少一种简洁且低成本的机制来提取和重用多个组件之间的逻辑。 那么接下来咱们就来看看2.0的问题,以及Vue3是如何来解决的。 Option式组织代码的缺点options式组织代码,同一个性能扩散在各个option中,导致在开发时须要在data、methods、computed等option横跳。 Vue3推出了CompositionApi,目标就是为了解决这个问题,它将扩散在各个option中的逻辑组合到一起,上面咱们比照看下: Mixin的问题对于简单的性能,咱们可能会想到应用Mixin来抽离到独自的文件。然而Mixin会有一些应用上的问题,比方命名抵触、属性起源不明确。 Vue3提出了Hooks的形式,能够将每个性能提取到hooks,一个hooks即是一个独立的函数,所以不会再有上述问题。 TypeScript反对的不健全当初大型项目都会标配 TypeScript ,Vue 以后的 API 在集成 TypeScript 时遇到了不小的麻烦,其次要起因是 Vue 依附一个简略的 this 上下文来裸露 property,咱们当初应用 this 的形式是比拟奥妙的。(比方 methods 选项下的函数的 this 是指向组件实例的,而不是这个 methods 对象)。 换句话说,Vue 现有的 API 在设计之初没有关照到类型推导,这使适配 TypeScript 变得复杂。 以后,大部分应用 TypeScript 的 Vue 开发者都在通过 vue-class-component 这个库将组件撰写为 TypeScript class (借助 decorator)。它必须依赖 decorator——一个在实现细节上存在许多未知数的十分不稳固的 stage 2 提案。基于它是有极大危险的。 ...

September 3, 2021 · 11 min · jiezi

关于vue3:vue3播放器插件vue3videoplay支持m3u8hls视频

插件Github地址 vue3-video-play vue3-video-playhls.js player component for Vue3. 实用于 Vue3 的 hls.js 播放器组件。 先看一下这个播放器(vue3-video-play)的界面吧 vue3-video-play视频播放插件基于原生的HTML5的 <video> 标签 开发,所以反对的视频格式和 <video> 统一,并且反对<video>标签的所有原生属性和办法 <span style="color:#cb3837"> 必须应用 vue@3.2.4及以上版本</span> 性能一览反对快捷键操作反对倍速播放设置反对镜像画面设置反对关灯模式设置反对画中画模式播放反对全屏/网页全屏播放反对从固定工夫开始播放反对挪动端,挪动端会主动调用自带视频播放器反对hls视频流播放,反对直播hls播放反对清晰度切换 主页示例https://xdlumia.github.io rc版本 v1.3.0-rc.3 新增: 反对hls视频流播放新增: 新增画质切换,需视频流反对新增: 新增画音视切换,需视频流反对新增: props参数减少currentTime属性,可跳转到固定工夫播放新增: props参数减少type属性,视频格式 近期更新 v1.2.52 新增: 右键菜单性能,右键菜单包涵,视频滤镜调节、快捷键阐明、复制以后视频网址新增: mirrorChange loopChange lightOffChange 事件新增: 减少空格快捷键 播放/暂停 的操作优化: 如果音量为 0 敞开静音按钮 音量设置为 5 使用指南装置npm装置: npm i vue3-video-play --saveyarn装置: yarn add vue3-video-play --save开始应用全局应用import { createApp } from 'vue'import App from './App.vue'let app = createApp(App)import vue3videoPlay from 'vue3-video-play' // 引入组件import 'vue3-video-play/dist/style.css' // 引入cssapp.use(vue3videoPlay)app.mount('#app')组件内应用// require styleimport 'vue3-video-play/dist/style.css'import { videoPlay } from 'vue-video-play'export default { components: { videoPlay }}根本示例提供了丰盛了配置性能:::demo 自定义配置 比方自定义poster。 ...

August 31, 2021 · 2 min · jiezi

关于vue3:elementui-plus怎么在级联选中后关闭弹层

<el-cascader v-model="form.productCategoryId" @change="classifyChange" :options="classify" :props="{ checkStrictly: true, value: 'categoryId', label: 'categoryName', expandTrigger: 'hover', emitPath: false, }" clearable :show-all-levels='false' ref='classifyRef'></el-cascader>定义一个refconst classifyRef = ref() setup外面 const classifyChange = () => { console.log(classifyRef.value) // 调用实例的办法手动敞开 classifyRef.value.togglePopperVisible()}

August 23, 2021 · 1 min · jiezi

关于vue3:用原生写一个简易双向绑定的例子

var obj = {};Object.defineProperty(obj,'hello',{ get:function(){ //咱们在这里拦挡到了数据 console.log("get办法被调用"); }, set:function(newValue){ //扭转数据的值,拦挡下来额 console.log("set办法被调用"); document.getElementById('test').value = newValue; document.getElementById('test1').innerHTML = newValue; }});//obj.hello;//obj.hello = '123';document.getElementById('test').addEventListener('input',function(e){ obj.hello = e.target.value;//触发它的set办法})html <div id="mvvm"> <input v-model="text" id="test"></input> <div id="test1"></div> </div>

August 9, 2021 · 1 min · jiezi

关于vue3:为什么我推荐vuers都来写compositionapi

一、罕用语法上的不同1.data 2.所有的内容包在setup外面,在template应用的数据和办法须要return 二、应用组合式api的益处1.按性能划分,便于保护依照原来的写法,实现一个性能,我要写在不同的生命周期外面,不聚合~ Options API Composition API 我的项目上的例子 2.逻辑复用 三、如何封装一个逻辑函数其实逻辑复用函数简略了解就是 有状态的函数 比函数多了状态,比组件少了视图。 getCertificateList useSearch useBoolean useAsync 库函数1.https://github.com/vueuse/vueuse 2.https://github.com/pikax/vue-composable 3.https://github.com/dewfall123/ahooks-vue 友情链接:1.react hooks助力拥抱react hooks:https://zhuanlan.zhihu.com/p/103150605?utm_source=wechat_session react hooks函数库:https://github.com/alibaba/hooks 2.composition-api作者分享:https://github.com/Bin-FE/binfe-salon-ppt github:https://github.com/vuejs/composition-api 官网文档:https://v3.cn.vuejs.org/guide/composition-api-introduction.html 疾速上手文档:https://mp.weixin.qq.com/s/GaII_4o69SGpI7IPeIMZSw

August 4, 2021 · 1 min · jiezi