Vue PDF 预览与标注实现解析
最近在做一个文件预览功能,需要在浏览器里展示 PDF 并支持位置标记和缩放。折腾了一段时间,把实现思路整理一下。 PDF 渲染 PDF 在浏览器里渲染,直接用 @tato30/vue-pdf 这个库。它基于 pdf.js,用起来还算顺手。 ...
最近在做一个文件预览功能,需要在浏览器里展示 PDF 并支持位置标记和缩放。折腾了一段时间,把实现思路整理一下。 PDF 渲染 PDF 在浏览器里渲染,直接用 @tato30/vue-pdf 这个库。它基于 pdf.js,用起来还算顺手。 ...
后端请求 后端封装 from abc import ABC, abstractmethod from openai import OpenAI import config class BaseAIService(ABC): """AI服务的抽象基类""" @abstractmethod def get_stream_completion(self, messages): """获取流式响应""" pass @abstractmethod async def process_stream_response(self, response): """处理流式响应""" pass class HuoShanAIService(BaseAIService): """火山引擎 AI 服务实现""" def __init__(self): self.config = config.HUO_SHAN_COMPLETION_CONFIG self.client = OpenAI( api_key=self.config["api_key"], base_url=self.config["base_url"] ) def get_stream_completion(self, messages): """获取流式响应""" return self.client.chat.completions.create( model=self.config["fast_llm"], messages=messages, temperature=0.3, top_p=1, max_tokens=8192, stream=True ) async def process_stream_response(self, response): """处理流式响应""" reasoning_content = "" answer_content = "" is_answering = False try: for chunk in response: try: if not chunk.choices or not chunk.choices[0].delta: continue delta = chunk.choices[0].delta # 处理思考过程 if hasattr(delta, 'reasoning_content') and delta.reasoning_content: reasoning_text = delta.reasoning_content print(reasoning_text, end='', flush=True) reasoning_content += reasoning_text yield f"__r__{reasoning_text}".encode('utf-8', errors='ignore') # 处理回复内容 elif hasattr(delta, 'content') and delta.content: if not is_answering: print("\n" + "=" * 20 + "完整回复" + "=" * 20 + "\n") is_answering = True content_text = delta.content print(content_text, end='', flush=True) answer_content += content_text yield f"__a__{content_text}".encode('utf-8', errors='ignore') except UnicodeEncodeError as e: print(f"Encoding error: {e}") continue except Exception as e: print(f"Error processing chunk: {e}") yield f"__a__处理响应时发生错误: {str(e)}".encode('utf-8', errors='ignore') except Exception as e: print(f"Stream processing error: {e}") yield f"__a__处理流式响应时发生错误: {str(e)}".encode('utf-8', errors='ignore') def get_ai_service(provider="huoshan"): """工厂函数,根据提供商返回对应的 AI 服务实例""" providers = { "huoshan": HuoShanAIService, # 未来可以添加其他提供商 # "openai": OpenAIService, # "azure": AzureAIService, } service_class = providers.get(provider) if not service_class: raise ValueError(f"不支持的 AI 提供商: {provider}") return service_class() 调用并且返回值 ...
在开发过程中,我们经常需要实现日期选择功能,而有时用户可能希望使用农历日期进行选择。本文将介绍如何使用 Vue 实现一个支持公历和农历选择的日期选择器。 ...
为什么使用 Pinia? https://pinia.vuejs.org/zh/ Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 export const state = reactive({}) 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞。 而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能: ...
Vue2-VueX 1.vuex介绍 目标 什么是vuex 为什么学习vuex 通信方案 组件关系 数据通信 父子关系 父传子:props ; 子传父:$emit 非父子关系 vuex (一种组件通信方案) vuex是什么 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理数据,以相应的规则保证状态以一种可预测的方式发生变化 ...
VueCLI https://cli.vuejs.org/zh/ 什么是Vue脚手架? 我们前面学习了如何通过webpack配置Vue的开发环境,但是在真实开发中我们不可能每一个项目从头来完成 所有的webpack配置,这样显示开发的效率会大大的降低; 所以在真实开发中,我们通常会使用脚手架来创建一个项目,Vue的项目我们使用的就是Vue的脚手架; 脚手架其实是建筑工程中的一个概念,在我们软件工程中也会将一些帮助我们搭建项目的工具称之为脚手架; 我们可以通过CLI选择项目的配置和创建出我们的项目; Vue CLI已经内置了webpack相关的配置,我们不需要从零来配置; Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供: ...
Vue 过渡与动画初体验 认识动画 在开发中,我们想要给一个组件的显示和消失添加某种过渡动画,可以很好的增加用户体验: React框架本身并没有提供任何动画相关的API,所以在React中使用过渡动画我们需要使用一个第三方库 react-transition-group; Vue中为我们提供一些内置组件和对应的API来完成动画,利用它们我们可以方便的实现过渡动画效果; 我们来看一个案例: Hello World的显示和隐藏; 通过下面的代码实现,是不会有任何动画效果的; <template> <div> <button @click="toggle">显示/隐藏</button> <h2 v-if="show">App组件</h2> </div> </template> <script> export default { data() { return { show: true } }, methods: { toggle() { this.show = !this.show; } } } </script> 没有动画的情况下,整个内容的显示和隐藏会非常的生硬: 如果我们希望给单元素或者组件实现过渡动画,可以使用 transition内置组件来完成动画; Vue的 transition 动画 https://cn.vuejs.org/guide/built-ins/transition.html#transition ...
认识组件化开发 认识组件化开发 人面对复杂问题的处理方式: 任何一个人处理信息的逻辑能力都是有限的 所以,当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆的内容。 但是,我们人有一种天生的能力,就是将问题进行拆解。 如果将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在整体当中,你会发现大的问题也会迎刃而解。 组件化也是类似的思想: 如果我们将一个页面中所有的处理逻辑 全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展; 但如果,我们讲一个页面拆分成一个个 小的功能块,每个功能块完成属于自己 这部分独立的功能,那么之后整个页面 的管理和维护就变得非常容易了; 如果我们将一个个功能块拆分后,就可 以像搭建积木一下来搭建我们的项目; 现在可以说整个的大前端开发都是组件化的天下,无论从三大框架(Vue、React、Angular),还是跨平台方案 的Flutter,甚至是移动端都在转向组件化开发,包括小程序的开发也是采用组件化开发的思想 所以,学习组件化最重要的是它的思想,每个框架或者平台可能实现方法不同,但是思想都是一样的。 我们需要通过组件化的思想来思考整个应用程序: 我们将一个完整的页面分成很多个组件; 每个组件都用于实现页面的一个功能块; 而每一个组件又可以进行细分; 而组件本身又可以在多个地方进行复用; Vue的组件化 vue 项目起始文件 createApp 函数传入了一个对象App,这个对象其实本质上就是一个组件,也是我们应用程序的根 组件; 组件化提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用; 任何的应用都会被抽象成一颗组件树; ...