Maison >interface Web >Voir.js >Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3

Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3

青灯夜游
青灯夜游avant
2022-07-26 19:57:092790parcourir

Comment démarrer rapidement avec Vue3 ? L'article suivant comparera Vue2 et Vue3 et présentera comment les développeurs Vue2 peuvent démarrer rapidement avec Vue3. J'espère que cela sera utile à tout le monde !

Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3

L'auteur était auparavant un développeur Vue2+React. Puisque le projet doit être démarré directement avec Vue3, je vais l'apprendre rapidement et comparer quelques différences liées à React. Prérequis à la lecture : Avoir déjà commencé à développer Vue2 Les principales problématiques abordées dans cet article : 已经上手了Vue2的开发,本文主要聊的问题:

  • Vue3的全新特性

  • Vue2和Vue3的一些区别

  • Vue2开发者如何快速上手Vue3

  • Vue3和React的简单比对

  • 使用Vue3编写组件库

(学习视频分享:vue视频教程

Vue2 vs Vue3


1、简单点说

  • Vue2只支持单节点,Vue3 template支持多节点,类似react fragments
  • 变化基本都在script中(Option api -> Composition api)不会再看见满屏的this了!!!
  • style支持v-bind
  • Proxy代替defineProperty
    • defineProperty无法实现对数组对象的深层监听,Proxy是浏览器最新api,功能更加强大。
    • 不再支持IE,Vue2想享受Vue3带来的部分更新,可考虑升级Vue2.7版本
  • TypeScript的支持
    • Vue2采用的是Facebook的Flow,没法完美支持TypeScript(所以项目初期技术选型很重要)
    • Vue3 TypeScript完全重写,提供和React一样的TS支持
  • 全新生态
    • 基本还是vue周边伴随Vue3升级那一套,但是状态管理推荐,由原来的Vuex变为Pina
    • 全新的vite支持,包括vitest等,官方提供周边工具更多了
  • 其它优化
    • 性能更好,体积更小就不用说了
    • 事件监听缓存,类似@click绑定的函数,无需多次创建,放在了cacheHandler缓存中
    • SSR:Vue 3.0 会将静态标签直接转化为文本,相比 React 先将 JSX 转化为虚拟 DOM,再将虚拟 DOM 转化为 HTML,这一点Vue3的速度要快很多
    • Use Hooks 放弃过去的mixins,使用Hooks解决过去mixins的一些缺点

2、源码

了解的不多,后续再补充

diff算法的优化

  • 不再和vue2一样,完全对比两棵虚拟DOM树,Vue3采用动静结合的方法,优化diff性能
  • 通过编译阶段对静态模板进行分析,编译生成 Block tree。更新性能由 模版整体大小相关 =》与动态内容的数量相关,这是一个非常大的性能突破。将代码提升到渲染函数之外,这样可以避免在每次渲染时重新创建这些对象,从而大大提高内存使用率并减少垃圾回收的频率。

源码管理

  • vue2 poly-repo
    • vue2.x的源码托管在src目录中,然后依据功能拆分出了complier(模板编译的相关代码),core(与平台无关的通用运行时代码),platforms(平台专有代码),server(服务端渲染的相关代码)、sfc(.vue 单文件解析相关代码)、shared(共享工具代码) 等目录
  • vue3 mono-repo
    • package可以独立于vue.js去使用,这样例如用户想要使用vue3.0的响应式,可以单独依赖reactive
      Les nouvelles fonctionnalités de Vue3
    • .

      Vue2 Quelques différences avec Vue3

    Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3Comment les développeurs Vue2 peuvent démarrer rapidement avec Vue3

    Une comparaison simple entre Vue3 et React

    Utiliser Vue3 pour écrire des bibliothèques de composants


    (Partage de vidéos d'apprentissage : vue vidéo tutoriel)

    Vue2 vs Vue3🎜🎜🎜

    1. Pour faire simple🎜

      🎜Vue2 ne prend en charge que un seul nœud , le modèle Vue3 prend en charge Plusieurs nœuds, similaires aux fragments de réaction🎜🎜Les Modifications sont essentiellement dans le script (Option api -> Composition api). l'écran ! ! ! 🎜🎜style prend en charge v-bind🎜🎜Proxy au lieu de définirProperty
        🎜defineProperty ne peut pas implémenter une surveillance approfondie des objets du tableau Proxy est la dernière API du navigateur et est plus puissante. fonctions. 🎜🎜Ne prend plus en charge IE. Si Vue2 souhaite profiter de certaines des mises à jour apportées par Vue3, vous pouvez envisager de passer à la version Vue2.7🎜🎜🎜🎜Support TypeScript
          🎜Vue2 utilise celui de Facebook. Flow, ne peut pas parfaitement prendre en charge TypeScript (la sélection de la technologie au début du projet est donc très importante) 🎜🎜Vue3 TypeScript entièrement réécrit, fournissant le même TS que React Support 🎜🎜🎜🎜Nouvelle écologie
            🎜Fondamentalement, toujours le même ensemble de périphériques vue qui accompagnent la mise à niveau de Vue3, mais la gestion du statut recommande de passer de la Vuex d'origine à Pina🎜🎜 le nouveau support vite, y compris <code>vitest, etc., le officiel fournit plus d'outils périphériques 🎜🎜🎜🎜Autres optimisations
              🎜Meilleures performances, taille plus petite Inutile de dire que 🎜🎜<code>Cache d'écoute d'événements, similaire à la fonction liée par @click, n'a pas besoin d'être créé plusieurs fois et est placé dans le cache cacheHandler🎜🎜SSR  : Vue 3.0 utilisera des balises statiques pour convertir directement en texte. Par rapport à React, qui convertit d'abord JSX en DOM virtuel puis convertit le DOM virtuel en HTML, Vue3 est beaucoup plus rapide 🎜🎜Utiliser des Hooks Abandonnez les mixins passés et utilisez Hooks. Résolvez certaines lacunes des mixins passés🎜🎜🎜🎜<h3 data-id="heading-3">🎜2 Code source🎜</h3> <blockquote>🎜Je ne sais pas. beaucoup à ce sujet, j'en ajouterai plus plus tard🎜</blockquote> <h4 data-id="heading-4">🎜Optimisation de l'algorithme Diff🎜</h4> <ul>🎜 n'est plus la même chose que vue2. deux arbres DOM virtuels. Vue3 adopte la méthode <code>combinaison de dynamique et statique, optimise les performances des différences 🎜🎜 Analysez le modèle statique tout au long de l'étape de compilation, compilez et générez l'arborescence de blocs. Les performances de mise à jour sont liées à la taille globale du modèle => et à la quantité de contenu dynamique. Il s'agit d'une très grande avancée en termes de performances. Retirer le code en dehors de la fonction de rendu évite de recréer ces objets à chaque rendu, ce qui améliore considérablement l'utilisation de la mémoire et réduit la fréquence du garbage collection. 🎜🎜

              🎜Gestion du code source🎜

                🎜vue2 poly-repo
                  🎜Le code source vue2.x est hébergé dans le répertoire src, puis divisé selon les fonctions en compilateur (code lié à la compilation du modèle), core (code d'exécution général indépendant de la plateforme), plateformes (code spécifique à la plateforme), serveur (code lié au rendu côté serveur), sfc (code associé à l'analyse de fichier unique .vue), partagé (code de l'outil partagé) et autres répertoires🎜🎜🎜🎜vue3 mono-repo
                    🎜le package peut être indépendant vue.js Pour l'utiliser, par exemple, si l'utilisateur souhaite utiliser le style réactif de vue3.0, il peut dépendre du réactif seul au lieu de s'appuyer sur l'intégralité de vue.js, ce qui réduit le taille du package de référence, mais vue2.x ne peut pas le faire à ce stade. 🎜🎜🎜🎜🎜Comparaison de la structure du code source🎜🎜🎜🎜🎜🎜🎜🎜Nouvelle API🎜🎜🎜🎜🎜🎜🎜🎜🎜Qu'est-ce qu'une API combinée ? -Vue officielle🎜🎜🎜
                    • Résolu le problème de difficulté de maintenance causé par les optionsApi lorsque les composants étaient trop longs dans le passé
                    • La logique peut être réutilisée dans son ensemble
                    • Toutes les API sont introduites par importation, très conviviales pour le Tree-shaking, aucune fonction n'est utilisé, et ils sont empaquetés. Il sera nettoyé et la taille du package sera réduite

                    1 setup

                    • La nouvelle option setup est exécutée avant la création du composantsetup 选项在组件被创建之前执行,一旦 props 被解析完成,它就将被作为组合式 API 的入口。
                    • 可以当做Vue2的beforeCreate和create生命周期用
                    • 可直接写await语法
                    • SFC单文件组件中直接使用<script lang="ts" setup></script>即可,或者也可以结合export default使用
            <script>
            const result = await Http.get(&#39;/getUserInfo&#39;)
            </script>
            // or 
            export default {
              setup(props, context) {
                // Attribute (非响应式对象,等同于 $attrs)
                console.log(context.attrs)
                // 插槽 (非响应式对象,等同于 $slots)
                console.log(context.slots)
                // 触发事件 (方法,等同于 $emit)
                console.log(context.emit)
                // 暴露公共 property (函数)
                console.log(context.expose)
              }
            }

            2、ref

            • ref 用来创建基础类型的响应式数据
            • template中默认调用value显示数据,script中需要使用.value 调用
            • 和react ref差不多,react是.current获取值,vue3是.value。
            • Ref的本质是通过Reactive创建的,Ref(10)=>Reactive({value:10})

            有一定的心智负担,尤大也明确说了不会支持script中直接访问。究其原因,还是基础类型无法拦截它的变化,当然也有大哥提出用new String('foo')类似的语法对基础类型进行包装。个人感觉直接拿已支持的reactive来搞也不错

            相关api

            • Ref ts定义 import { type Ref } from 'vue';
            • isRef  判断是否为ref对象。一般是ref,toRef,toRefs创建的变量
            • toRefsreactive对象解构为单个响应式对象
            • shallowRef 创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的,简单理解为创建一个和ref相同结构的非响应式变量
            • triggerRef 强制更新页面DOM。即使创建的ref没有变,想更新dom可以用
            • customRef 提供类似于computed的get和set,可自定义ref行为

            3、reactive

            • reactive 用来创建引用类型的响应式数据
            • reactive的本质是将每一层的数据都解析成proxy对象
            • reactive 的响应式默认都是递归的,改变某一层的值都会递归的调用一遍,重新渲染dom。
            • 直接解构,响应性会丢失,需要用toRefs包裹。引用类型直接改变引用地址也会导致响应式丢失

            相关api

            • readonly 将reactive的值更改为只读
            • shallowReactive. props est une fois analysé, il sera utilisé comme point d'entrée à l'API composite.
            Peut être utilisé comme cycle de vie de création et de création de Vue2

            Peut écrire directement la syntaxe d'attente

            Utiliser directement dans le composant de fichier unique SFC <script lang="ts" setup> </ code>, ou vous pouvez utiliser <p><pre class="brush:php;toolbar:false">import { reactive, toRefs } from &amp;#39;vue&amp;#39; const book = reactive({ author: &amp;#39;Vue Team&amp;#39;, year: &amp;#39;2020&amp;#39;, title: &amp;#39;Vue 3 Guide&amp;#39;, description: &amp;#39;You are reading this book right now ;)&amp;#39;, price: &amp;#39;free&amp;#39; }) let { author, title } = toRefs(book) title.value = &amp;#39;Vue 3 Detailed Guide&amp;#39; // 我们需要使用 .value 作为标题,现在是 ref console.log(book.title) // &amp;#39;Vue 3 Detailed Guide&amp;#39;&lt;h3 data-id=&quot;heading-8&quot;&gt;&lt;p&gt;2, ref&lt;img src=&quot;https://img.php.cn/upload/image/658/946/527/1658836117320807.png&quot; title=&quot;1658836117320807.png&quot; alt=&quot;Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3&quot;/&gt;🎜🎜ref en combinaison avec &lt;code&gt;export default&lt;/script&gt;&lt;/code&gt; pour créer le &lt;code&gt; base Données réactives de type &lt;/code&gt; 🎜🎜template appelle la valeur pour afficher les données par défaut, vous devez utiliser &lt;code&gt;.value&lt;/code&gt; pour appeler 🎜🎜 ce qui est similaire à React utilise la réf. .current pour obtenir la valeur, et vue3 le fait. 🎜🎜L'essence de Ref est créée via Reactive. Ref(10)=&gt;Reactive({value:10})🎜🎜&lt;blockquote&gt;🎜Youda a également clairement indiqué qu'il ne prendrait pas en charge directement. accès dans les scripts. La raison est que le type de base ne peut pas intercepter ses modifications. Bien sûr, certaines personnes ont proposé d'utiliser une syntaxe similaire à new String('foo') pour envelopper le type de base. Personnellement, je pense qu'il serait bien d'utiliser directement le réactif pris en charge🎜&lt;/blockquote&gt; &lt;h4 data-id=&quot;heading-9&quot;&gt;🎜API associées🎜&lt;/h4&gt;🎜🎜&lt;code&gt;Ref&lt;/code&gt; ts definitionimport { type Ref } from 'vue';&lt;/code&gt;🎜🎜&lt;code&gt;isRef&lt;/code&gt; Détermine s'il s'agit d'un objet ref. Généralement, les variables créées par ref, toRef, toRefs🎜🎜&lt;code&gt;toRefs&lt;/code&gt; Déconstruisent l'&lt;code&gt;objet réactif&lt;/code&gt; en un seul objet réactif🎜🎜&lt;code&gt;shallowRef&lt;/code&gt; Créer lui-même un suivi .value modifie la référence, mais ne rend pas sa valeur réactive. Cela s'entend simplement comme la création d'une variable non réactive avec la même structure que ref🎜🎜&lt;code&gt;triggerRef&lt;/code&gt; pour forcer la mise à jour du DOM de la page. Même si la référence créée n'a pas changé, si vous souhaitez mettre à jour le dom, vous pouvez utiliser 🎜🎜&lt;code&gt;customRef&lt;/code&gt; pour fournir un get et un set similaire à calculé, et vous pouvez personnaliser le comportement de la référence🎜🎜&lt;h3 data-id=&quot;heading-10&quot;&gt; 🎜3. reactive🎜🎜🎜🎜reactive est utilisé pour créer des données réactives de &lt;code&gt;type de référence&lt;/code&gt;🎜🎜L'essence de la réactivité est d'analyser chaque couche de données en objets proxy&lt;/h3&gt;&lt;/code&gt;🎜 🎜La réactivité de Reactive est &lt;code&gt;récursive&lt;/code&gt; par défaut. La modification de la valeur d'un certain calque sera appelée de manière récursive pour restituer le DOM. 🎜🎜&lt;code&gt;Déconstruction directe&lt;/code&gt;, la réactivité sera perdue et devra être enveloppée avec &lt;code&gt;toRefs&lt;/code&gt;. Changer directement l'adresse de référence du type de référence entraînera également une perte de réactivité🎜🎜&lt;h4 data-id=&quot;heading-11&quot;&gt;🎜API associée🎜&lt;/h4&gt;🎜🎜&lt;code&gt;readonly&lt;/code&gt; Changez le la valeur de réactif en lecture seule🎜🎜&lt;code&gt;shallowReactive&lt;/code&gt; ne peut répondre qu'à des données superficielles. S'il s'agit de données profondes, cela ne changera que la valeur mais pas la vue🎜🎜&lt;/ul&gt; &lt;pre class=&quot;brush:php;toolbar:false&quot;&gt;&lt;script&gt; import { onMounted } from &amp;#39;vue&amp;#39;; const getUserInfo = () =&gt; { console.log(&amp;#39;获取用户信息&amp;#39;); }; onMounted(getUserInfo); &lt;/script&gt;</pre>🎜🎜4. 🎜🎜Il n'y a pas beaucoup de différence. La configuration est utilisée telle qu'elle a été créée et les autres noms sont modifiés🎜<pre class="brush:php;toolbar:false">import { ref, reactive, watch } from 'vue' const counter1 = ref(0) const counter2 = ref(0) // 监听多个 watch([counter1, counter2], (newValue, oldValue) =&gt; {   console.log('The new counter1 value is: ' + counter1.value)   console.log('The new counter2 value is: ' + counter2.value) }) const obj = reactive({   name: 'JJ',   age: 18 }) // 深度监听对象 watch(obj, (newValue, oldValue) =&gt; {   console.log('The new obj value is: ' + obj.value) }, {    deep: true,    immediate: true }) // watch监听单个属性 watch(() =&gt; obj.name, (newValue, oldValue) =&gt; {   console.log('The new obj value is: ' + obj.value) }, {    deep: true,    immediate: true })</pre>🎜🎜🎜<h3 data-id="heading-13"><strong>5、watch & watchEffect</strong></h3> <h4 data-id="heading-14"><strong>watch</strong></h4> <ul> <li>功能和vue2一致</li> <li>watch(监听参数,变化回调,配置参数)</li> <li>注意监听对象的单个属性:<code>watch(() => articleInfo.author, (newVal) => {}),第一个参数为箭头函数返回要监听的目标属性
          import { ref, reactive, watch } from 'vue'
          
          const counter1 = ref(0)
          const counter2 = ref(0)
          // 监听多个
          watch([counter1, counter2], (newValue, oldValue) => {
            console.log('The new counter1 value is: ' + counter1.value)
            console.log('The new counter2 value is: ' + counter2.value)
          })
          
          const obj = reactive({
            name: 'JJ',
            age: 18
          })
          // 深度监听对象
          watch(obj, (newValue, oldValue) => {
            console.log('The new obj value is: ' + obj.value)
          }, {
             deep: true,
             immediate: true
          })
          // watch监听单个属性
          watch(() => obj.name, (newValue, oldValue) => {
            console.log('The new obj value is: ' + obj.value)
          }, {
             deep: true,
             immediate: true
          })

          watchEffect

          • 类似React useEffect,但是不需要写依赖项,只要我们回调中引用了 响应式的属性
          • 和watch的区别:
            • 同一个功能的两种不同形态,底层的实现是一样的
            • watch 可以获取到新值与旧值(更新前的值),而 watchEffect 是拿不到的。
            • watch - 显式指定依赖源,watchEffect - 自动收集依赖源
            • watchEffect 在组件初始化的时候就会执行一次用以收集依赖,watch指定了依赖,所以不需要。
            • 可以理解为watchEffect 就是配置了{ immediate: true } 的watch
          • 使用场景:antfu小哥:推荐在大部分时候用 watch 显式的指定依赖以避免不必要的重复触发,也避免在后续代码修改或重构时不小心引入新的依赖。watchEffect 适用于一些逻辑相对简单,依赖源和逻辑强相关的场景(或者懒惰的场景 )。
          const stopWatch = watchEffect(
            (oninvalidate): void => {
              oninvalidate(() => {
                console.log("前置校验函数");
              });
              // 引用了响应式的属性 count
              console.log("watchEffect count变化", count.value);
            },
            {
              // 副作用刷新时机 flush 一般使用post
              // 可选:pre(组件更新前执行)/sync(强制效果始终同步触发)/post(组件更新后执行)
              flush: "post",
              // 开发调试
              onTrigger() {
                console.log("开发调试");
              },
            }
          );

          6、computed

          • 更加灵活,可以在定义响应式变量时声明
          • 作用和vue2无差异
          import { ref, computed } from 'vue'
          
          const counter = ref(0)
          const twiceTheCounter = computed(() => counter.value * 2)
          // get set写法
          const plusOne = computed({
            get: () => counter.value + 1,
            set: (val) => {
              counter.value = val - 1
            },
          })
          
          plusOne.value = 1
          console.log(counter.value) // 0
          
          counter.value++
          console.log(counter.value) // 1
          console.log(twiceTheCounter.value) // 2

          组件


          1、异步组件

          • 通过进行引入defineAsyncComponent
          • 可配合Suspense 进行更多操作,可用于loading和骨架屏相关,和react Suspense基本一致。不过react Suspense基本一致这个属性都不太好用,vue的不清楚实际场景咋样
          // template
          <suspense>
            <template>
              <asynccomponent></asynccomponent>
            </template>
          
            <template>
              <div>loading...</div>
            </template>
          </suspense>
          
          // script
          const AsyncComponent = defineAsyncComponent(() => import('./asyncComponent.vue'))

          2、Teleport传送组件

          Teleport 是一种能够将我们的模板渲染至指定DOM节点,不受父级style、v-show等属性影响,但data、prop数据依旧能够共用的技术;类似于 React 的 Portal。之前写react是不怎么用这个属性,vue3这个估计也没多大用。

          主要解决的问题 因为Teleport节点挂载在其他指定的DOM节点下,完全不受父级style样式影响

          to 属性 插入指定元素位置,body,html,自定义className等等

          <teleport>
              <loading></loading>
          </teleport>

          3、keep-alive缓存组件

          • 作用和vue2还是一样的,生命周期名称变了
          • 初次进入时:onMounted> onActivated
          • 退出后触发 deactivated
          • 再次进入:只会触发 onActivated

          4、组件通信

          defineXxxx

          defineXxxx 无需import即可直接使用

          • defineProps 代替过去的props
          • defineEmits 代替过去的$emit
          • defineOptions 自定义一些组件属性,比如组件名称(需要插件支持)
          • defineComponent 用于render函数、TSX、IDE提醒等
          • defineExpose 子组件声明的数据,暴露给父组件直接用

          provide/inject

          和vue2一致

          vuex & pina

          两者用法,除了pina没有Mutations,差别不大。但是官方推荐的东西,自然有它的各种优点

          • Vuex: State、Gettes、Mutations(同步)、Actions(异步)
          • Pinia: State、Gettes、Actions(同步异步都支持)
          • Vuex4 用于 Vue3 ,Vuex3 用于 Vue2
          • Pinia2.x 即支持 Vue2 也支持 Vue3

          TS支持


          • 可以让写react的兄弟,快速上手写vue3
          • react中 {{}} => {}

          • 兼容的指令:v-model,v-if,v-show
          import { ref } from 'vue'
          let v = ref<string>('')
          const renderDom = () => {
              return (
                  
                     <input>
                     <div>
                         {v.value}
                     </div>
                  >
              )
          }
          export default renderDom</string>

          插件


          1、开源插件

          unplugin-auto-import/vite

          无需导入xxx,import { reactive,ref } from "vue";,只需要用即可

          unplugin-vue-define-options

          自定义组件名称,需要引入插件unplugin-vue-define-options,并在vite中配置

          import { defineConfig } from 'vite';
          import vue from '@vitejs/plugin-vue';
          import DefineOptions from 'unplugin-vue-define-options/vite';
          
          export default defineConfig({
            plugins: [vue(), DefineOptions()],
          });

          不使用插件,也可以通过多写一个script标签来单独写options

          <script>
              export default {
                  name: "TButton",
              };
          </script>
          <script>
            defineOptions({
              name: &#39;TButton&#39;,
            });
          </script>

          2、vscode插件

          volar vscode

          • vetur只支持vue2,volar只支持vue3,两者冲突。
          • 建议禁用vetur,格式化代码使用prettier,本地使用volar做代码高亮。
          • 或者通过项目配置,指定相关插件配置

          Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3

          指令


          1、v-model

          • 底层语法糖时间改变,之前vue2是update:input,vue3 是update:modelValue
          • 支持多个v-model
          • 支持自定义修饰符
          • 弃用.sync等

          2、自定义指令

          生命周期(和vue3一致)

          • created 元素初始化的时候
          • beforeMount 指令绑定到元素后调用 只调用一次
          • mounted 元素插入父级dom调用
          • beforeUpdate 元素被更新之前调用
          • update 这个周期方法被移除 改用updated
          • beforeUnmount 在元素被移除前调用
          • unmounted 指令被移除后调用 只调用一次

          自定义拖拽指令v-move

          • 比如这个v-move 封装自定义拖拽指令
          import { Directive } from "vue";
          const vMove: Directive = {
            mounted(el: HTMLElement) {
              let moveEl = el.firstElementChild as HTMLElement;
              const mouseDown = (e: MouseEvent) => {
                //鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离
                console.log(e.clientX, e.clientY, "-----起始", el.offsetLeft);
                let X = e.clientX - el.offsetLeft;
                let Y = e.clientY - el.offsetTop;
                const move = (e: MouseEvent) => {
                  el.style.left = e.clientX - X + "px";
                  el.style.top = e.clientY - Y + "px";
                  console.log(e.clientX, e.clientY, "---改变");
                };
                document.addEventListener("mousemove", move);
                document.addEventListener("mouseup", () => {
                  document.removeEventListener("mousemove", move);
                });
              };
              moveEl.addEventListener("mousedown", mouseDown);
            },
          };

          Hook


          用了react hook的人都知道很香,vue3支持这个相当不错,能解决很多业务场景的封装

          1、自定义Hook

          可以当做mixins写

          // useWindowResize
          import { onMounted, onUnmounted, ref } from "vue";
          
          function useWindowResize() {
            const width = ref(0);
            const height = ref(0);
            function onResize() {
              width.value = window.innerWidth;
              height.value = window.innerHeight;
            }
            onMounted(() => {
              window.addEventListener("resize", onResize);
              onResize();
            });
            onUnmounted(() => {
              window.removeEventListener("resize", onResize);
            });
            
            return {
              width,
              height
            };
          }
          
          export default useWindowResize;

          2、hook库

          3、react vs vue3

          Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3

          结语


          • Vue3 的依赖追踪是全自动的,不需要担心传了错误的依赖数组给 useEffect/useMemo/useCallback 从而导致回调中- 使用了过期的值

          • Vue3 Hook也没React Hook那么多限制,后续用用看怎么样

          • 个人比较喜欢SFC语法,html、js、css分离开

          笔者vue3也刚用不久,如有错误,还请兄弟们指出

          本文所有demo都在该仓库中JJ-UI 一款Vue3组件库,参考大佬文章刚刚搭建好,后续会基于这个架子开发自己的vue3组件库

          Parlons de la façon dont les développeurs Vue2 peuvent démarrer rapidement avec Vue3

          【相关视频教程推荐:vuejs入门教程web前端入门

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer