首页 > 其他分享 >记录--Vue使用CDN引入,响应式失效?

记录--Vue使用CDN引入,响应式失效?

时间:2023-12-05 18:23:42浏览次数:39  
标签:Vue plugin -- CDN vue2 import vitejs

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

背景

最近心血来潮,想要在本地开发时,也用CDN的方式引入 Vue,想着既然通过CDN引入了,那么在项目中就没必要再 import Vue,然后把项目中引入 Vue 的地方都删掉,结果改完后,界面看似正常运行,但数据变更后,界面没有重新渲染。经过一番折腾,终于定位到问题。

vue版本:Vue2.7+;打包工具:Vite;核心插件:@vitejs/plugin-vue2;

在解决这个问题之前,我们需要先搞清楚两个事情:1)@vitejs/plugin-vue2的作用;2)@vitejs/plugin-vue2的工作原理。

@vitejs/plugin-vue2的作用

vite不做赘述,具体内容看官网

在聊@vitejs/plugin-vue2的作用之前,我们必须搞清楚什么是单文件组件

Vue 的单文件组件 (即 *.vue 文件,英文 Single-File Component,简称 SFC) 是一种特殊的文件格式,使我们能够将一个 Vue 组件的模板、逻辑与样式封装在单个文件中。

很明显,这是 Vue 自己定义并实现的组件模板,不能直接在浏览器中运行,在实际项目中,我们一般会使用集成了 SFC 编译器的构建工具,比如 Vite 或者 Vue CLI (基于 webpack)。本文只讨论使用 Vite 的情况。

@vitejs/plugin-vue2 就是提供对 Vue 2.7 的单文件组件支持。如果大家的Vue项目是使用 Vite ,下面这段代码应该不陌生:

// vite.config.js
import vue from '@vitejs/plugin-vue2'

export default {
  plugins: [vue()]
}

想要*.vue 文件能正常在浏览器中运行,我们就需要做以上配置。

@vitejs/plugin-vue2的工作原理

扒了一下这个插件的源码,发现一行至关重要的代码,如下图:

这个插件在工作时,要依赖 Vue,上面红色框标注的部分,就是它如何去查找 Vue 的逻辑。如果我们在配置文件中,配置了 Vue alias,则会使用配置的alias,否则默认使用本地安装的 Vue。如何使用alias,参加vite文档alias

这里可以先记住这个逻辑,后面有用。

问题分析

我们先看看复现问题的路径:1. 在 index.html 直接引入 Vue CDN;2. 删除项目中import Vue 的代码。

然后本地Run起来,界面看起来很正常,但是,修改数据后,发现界面没有重新渲染。为什么呢?

我们先看经过 @vitejs/plugin-vue2 处理之后生成的代码是什么样的,如下图:

因为我在项目中,没有为 Vue 配置 alias,所以**@vitejs/plugin-vue2直接使用了我本地安装的 Vue**。原因见@vitejs/plugin-vue2的工作原理

但问题是,我在项目中删除了 import Vue 的代码,这个时候界面之所以能正常运行,是因为我在index.html引入的 Vue 有正常初始化,这里就产生了一个冲突:

最后@vitejs/plugin-vue2处理的产物中,是使用本地 Vue 导出的 Ref 来处理响应式变量,但真正执行 Vue 初始化动作依赖的却是 CDN。这会带来什么问题?

也就是说,数据变化后,能正常执行响应式逻辑,但是 notify 的时候,却找不到可通知对象(此时,是触发了 本地安装 Vue 的代码逻辑),因为初始化的时候,收集依赖关系时,执行的是 CDN 导入的 Vue 代码逻辑,这两者之间没有正确建立联系,导致数据变了,但是界面没有重新渲染。

如果看不懂,可能需要了解一下 Vue 初始化时 干了啥,主要是要知道如何收集依赖,并触发DOM更新,要理解Watcher是如何工作的。

如何解决

很简单,我们只要保证初始化 和 最后数据变化执行 的代码逻辑 来自同一个源就可以,而不是一个来自 本地安装的 Vue,一个来自CDN。

最简单的方法,就是在项目中手动import Vue,这个时候,初始化的时候,就会走 本地安装的 Vue 的代码逻辑。

不过这样的话,还是会加载两次 Vue,不是特别优雅。也可以使用 CDN 加载的 Vue,也得在项目中 import Vue,只不过引入的 路径要变化。

import Vue from '具体的 Vue 路径'

可以通过配置 alias,简化 from 后面的路径,变成 import Vue from 'Vue'。

本文转载于:

https://juejin.cn/post/7295694519185440777

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

标签:Vue,plugin,--,CDN,vue2,import,vitejs
From: https://www.cnblogs.com/smileZAZ/p/17877862.html

相关文章

  • iwtgm-33
    CodeforcesRound912(Div.2)A.只要k大等于2,那么每个数的位置就可以任意放置(两两交换可以到达任何位置),一定可以符合条件特判序列本来就升序,那么k的值无关紧要intn,k;inta[110];voidsolve(){cin>>n>>k;boolflag=true;for(inti=1;i<=n;i++){c......
  • Optional常用方法实例, 源码挺简单的,重要的是option 与 stream 以及lambda 的连贯使用
    Optionalstaticmethods: Optional.ofNullable();Optional.empty();Optional.of(); ​ empty():publicstatic<T>Optional<T>empty(){@SuppressWarnings("unchecked")Optional<T>t=(Optional<......
  • 鲜花
    济南打完了,感觉自己的算法竞赛生涯也结束的差不多了(?),完结撒鲜花来了。高中前没啥好说的,虽然接触了oi,但很摆。高中两年oi,我学到了啥呢?各种算法,各种人类智慧,特别是EI的多项式科技。是学到不少,但学到了这些在算法竞赛之外有啥用,没啊。高中打oi又对我有啥实际收益呢?noiday2......
  • Border 基本使用
    Border基本使用1单线效果  代码:<BorderGrid.Row="0"BorderThickness="0,0,0,1"BorderBrush="Red"/>说明:BorderThickness="0,0,0,1"可以分别设置四条边,顺序是:左上右下2虚线效果  代码:<BorderGrid.Row="0"BorderThick......
  • vue3使用虚拟化表格自定义表格并动态生成表头
    elementPlus的虚拟化表格用的是lang=tsx,先安装cnpmi@vitejs/plugin-vue-jsx然后去vite.config.ts里加配置importvueJsxfrom'@vitejs/plugin-vue-jsx'plugins:[vue(),vueJsx(),]再去tsconfig.json中加东西//不要把compilerOptio......
  • vue项目:如何在编辑用户信息后,能够及时更新layout下的navar组件中的用户名,而不是手动刷
    问题描述:layout下的navar组件中展示用户名,初始化时进入layout层会进入mouted中请求接口数据展示名称,但是在编辑弹框中编辑成功后,关闭弹框,此时不会走layout的mouted,因为layout组件的mouted已经加载过一次了,不手动刷新浏览器是不会走mouted生命周期的。那怎么解决这个不能及时更新数......
  • Linux-01常用文件管理命令
    文件系统文件系统结构tip:[start]仅举例常见内容tip:[end]/根目录bin可执行文件命令(ls,...)etc配置文件(nginx代理服务器配置文件,...)var日志log文件lib存头文件/安装包home用户的家目录(/home/acs,...)proc进程信息文件(cpuinfo系统资源,...)路径......
  • Android OpenGL ES入门
    1.OpenGL和OpenGLESOpenGL(OpenGraphicsLibrary)是一种用于渲染2D和3D图形的跨平台编程接口。OpenGL提供了一套标准的函数和接口,使开发人员能够在各种操作系统上创建高性能的图形应用程序,这些操作系统包括Windows、Linux、macOS和一些嵌入式系统。OpenGLES(OpenGLforEm......
  • HTML学习笔记四:html-body-行内元素
    HTML学习笔记四:body元素行内元素MDN元素查询地址所有的html的元素我们都可以通过以下地址进行相关的查询和理解。https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/metabody中元素分类块级元素行内元素行内元素行内元素区别于块级元素,不会独占一行,一个行内元......
  • How to use Python Decorators_2
    类也可以用来构建装饰器;现在以一个类而不是一个函数的方式,来重新构建logit;fromfunctoolsimportwrapsclasslogit(object):def__init__(self,logfile='out.log'):self.logfile=logfiledef__call__(self,func):@wraps(func)de......