>웹 프론트엔드 >View.js >Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.

Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.

青灯夜游
青灯夜游앞으로
2022-07-26 19:57:092794검색

Vue3를 빠르게 시작하는 방법은 무엇입니까? 다음 기사에서는 Vue2와 Vue3를 비교하고 Vue2 개발자가 Vue3을 빠르게 시작할 수 있는 방법을 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.

Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.

저자는 이전에 Vue2+React 개발자였습니다. 프로젝트는 Vue3에서 직접 시작해야 하므로 빠르게 배우고 React와 관련된 몇 가지 차이점을 비교해 보겠습니다. 읽기 전제 조건: 이미 Vue2 개발을 시작했습니다. 이 문서에서 논의된 주요 문제: 已经上手了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
      Vue3의 새로운 기능
    • Vue2 Vue3과의 몇 가지 차이점

    Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.Vue2 개발자가 Vue3을 빠르게 시작하는 방법

    Vue3과 React의 간단한 비교

    Vue3을 사용하여 구성 요소 라이브러리 작성


    (동영상 공유 학습: vue 비디오 튜토리얼)

    Vue2 대 Vue3🎜🎜🎜

    1. 간단히 말해서🎜

      🎜Vue2는 단일 노드만 지원합니다. , Vue3 템플릿은 반응 조각과 유사한 Multiple node를 지원합니다🎜🎜Changes는 기본적으로 스크립트에 있습니다(Option api -> Composition api). 화면! ! ! 🎜🎜style은 DefineProperty
        대신 v-bind🎜🎜Proxy를 지원합니다.🎜defineProperty는 배열 객체에 대한 심층 모니터링을 구현할 수 없습니다. Proxy는 더욱 강력한 기능을 갖춘 최신 브라우저 API입니다. . 🎜🎜더 이상 IE를 지원하지 않습니다. Vue2가 Vue3의 일부 업데이트를 즐기고 싶다면 Vue2.7 버전으로 업그레이드하는 것이 좋습니다.🎜🎜🎜🎜TypeScript 지원
          🎜Vue2는 Facebook을 사용합니다. Flow, TypeScript를 완벽하게 지원할 수 없음(따라서 프로젝트 초기 단계의 기술 선택이 매우 중요함) 🎜🎜Vue3 TypeScript 완전히 다시 작성, 제공 React 지원과 동일한 TS 🎜🎜🎜🎜새로운 생태학
            🎜기본적으로 Vue3 업그레이드와 함께 제공되는 동일한 vue 주변 장치 세트이지만 상태 관리에서는 원래 Vuex에서 Pina🎜🎜로 변경할 것을 권장합니다. vitest 등을 포함한 새로운 vite 지원으로 공식은 더 많은 주변 도구를 제공합니다 🎜🎜🎜🎜기타 최적화
              🎜더 나은 성능, 더 작은 크기 말할 필요도 없이 🎜🎜<code>이벤트 수신 캐시는 @click에 바인딩된 함수와 유사하며 여러 번 생성할 필요가 없으며 캐시 핸들러 캐시🎜🎜SSR에 배치됩니다. : Vue 3.0은 정적 태그를 사용하여 텍스트로 직접 변환합니다. 먼저 JSX를 가상 DOM으로 변환한 다음 가상 DOM을 HTML로 변환하는 React와 비교할 때 Vue3은 🎜🎜후크 사용)이 훨씬 빠릅니다. > 기존 믹스인을 포기하고 Hooks를 사용하세요. 기존 믹스인의 몇 가지 단점을 해결하세요🎜🎜🎜🎜

              🎜2 소스코드🎜

              🎜모르겠습니다. 자세한 내용은 나중에 추가하겠습니다🎜

              🎜diff 알고리즘 최적화🎜

                🎜는 더 이상 vue2와 동일하지 않습니다. 두 개의 가상 DOM 트리. Vue3은 동적 및 정적 조합 방법을 채택하여 diff 성능을 최적화합니다. 🎜🎜 컴파일 단계를 통해 정적 템플릿을 분석하고 블록 트리를 컴파일 및 생성합니다. 업데이트 성능은 템플릿의 전체 크기 => 및 동적 콘텐츠의 양과 관련이 있습니다. 이는 매우 큰 성능 혁신입니다. 렌더링 함수 외부에서 코드를 해제하면 모든 렌더링에서 이러한 객체가 다시 생성되는 것을 방지하여 메모리 사용량을 크게 향상시키고 가비지 수집 빈도를 줄입니다. 🎜🎜

                🎜소스 코드 관리🎜

                  🎜vue2 poly-repo
                    🎜vue2.x 소스 코드는 다음에서 호스팅됩니다. src 디렉토리를 생성한 후 기능에 따라 컴파일러(템플릿 컴파일과 관련된 코드), 코어(플랫폼과 독립적인 일반 런타임 코드), 플랫폼(플랫폼별 코드), 서버(서버 측 렌더링과 관련된 코드)로 분할합니다. sfc( .vue 단일 파일 구문 분석 관련 코드), 공유(공유 도구 코드) 및 기타 디렉터리🎜🎜🎜🎜vue3 mono-repo
                      🎜패키지는 독립적일 수 있습니다. vue.js 예를 들어 사용자가 vue3.0의 반응형 스타일을 사용하려는 경우 vue.js 전체에 의존하는 대신 반응형에만 의존하면 됩니다. 참조 패키지의 크기이지만 vue2.x는 현재 이를 수행할 수 없습니다. 🎜🎜🎜🎜🎜소스 코드 구조 비교🎜🎜🎜🎜🎜🎜🎜🎜새로운 API🎜🎜🎜🎜🎜🎜🎜🎜🎜결합 API란 무엇인가요? - Vue 공식🎜🎜🎜
                      • 과거 컴포넌트가 너무 길었을 때 optionsApi로 인해 발생했던 유지 관리가 어려웠던 문제를 해결했습니다.
                      • 로직을 전체 블록에서 재사용할 수 있습니다.
                      • 모든 API를 import로 도입하고, Tree-shaking에 매우 친화적이며, 기능을 사용하지 않습니다. 정리되고 패키지 크기가 줄어듭니다

                      1. setup

                      • 컴포넌트가 생성되기 전에 새로운 setup 옵션이 실행됩니다setup 选项在组件被创建之前执行,一旦 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
              는 일단 구문 분석되면 복합 API의 진입점으로 사용됩니다.
            Vue2의 beforeCreate 및 create 라이프 사이클로 사용할 수 있습니다.

            await 구문을 직접 작성할 수 있습니다.

            SFC 단일 파일 구성 요소 <script lang="ts" setup>에서 직접 사용 가능 </ code> 또는 <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;Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.&quot;/&gt;🎜🎜ref를 &lt;code&gt;내보내기 기본값&lt;/script&gt;&lt;/code&gt;과 함께 사용하여 &lt;code&gt; 기초 &lt;/code&gt; 🎜🎜템플릿 유형의 반응형 데이터는 기본적으로 데이터를 표시하기 위해 값을 호출합니다. 스크립트에서 React ref와 유사한 🎜🎜를 호출하려면 &lt;code&gt;.value&lt;/code&gt;를 사용해야 합니다. .current를 사용하여 값을 가져오고 vue3은 값을 가져옵니다. 🎜🎜Ref의 본질은 Reactive를 통해 만들어집니다. Ref(10)=&gt;Reactive({value:10})🎜🎜&lt;blockquote&gt;🎜직접 지원하지 않는다는 정신적 부담도 있음을 분명히 했습니다. 스크립트 액세스. 그 이유는 기본 유형이 변경 사항을 가로챌 수 없기 때문입니다. 물론 일부 사람들은 기본 유형을 래핑하기 위해 new String('foo') 과 유사한 구문을 사용하도록 제안했습니다. 개인적으로 지원되는 리액티브를 직접 사용하면 좋을 것 같아요🎜&lt;/blockquote&gt; &lt;h4 data-id=&quot;heading-9&quot;&gt;🎜관련 api🎜&lt;/h4&gt;🎜🎜&lt;code&gt;Ref&lt;/code&gt; ts 정의import { type Ref } from 'vue';🎜🎜&lt;code&gt;isRef&lt;/code&gt; ref 객체인지 확인합니다. 일반적으로 ref, toRef, toRefs🎜🎜&lt;code&gt;toRefs&lt;/code&gt;에 의해 생성된 변수는 &lt;code&gt;반응형 객체&lt;/code&gt;를 단일 반응형 객체🎜🎜&lt;code&gt;shallowRef&lt;/code&gt;로 분해하여 추적 자체를 생성합니다. .value는 참조를 변경하지만 해당 값을 반응형으로 만들지는 않습니다. 이는 페이지 DOM을 강제로 업데이트하기 위해 ref🎜🎜&lt;code&gt;triggerRef&lt;/code&gt;와 동일한 구조로 비반응형 변수를 생성하는 것으로 간단히 이해됩니다. 생성된 참조가 변경되지 않았더라도 DOM을 업데이트하려면 🎜🎜&lt;code&gt;customRef&lt;/code&gt;를 사용하여 계산된 것과 유사한 get 및 set을 제공하고 참조 동작을 사용자 정의할 수 있습니다🎜🎜&lt;h3 data-id=&quot;heading-10&quot;&gt; 🎜3.reactive🎜🎜🎜🎜reactive는 &lt;code&gt;참조 유형&lt;/code&gt;의 반응형 데이터를 생성하는 데 사용됩니다.🎜🎜Reactive의 본질은 데이터의 각 레이어를 &lt;code&gt; code&gt;프록시 객체&lt;/code&gt;🎜 🎜Reactive의 반응성은 기본적으로 &lt;code&gt;재귀적&lt;/code&gt;입니다. 특정 레이어의 값을 변경하면 DOM을 다시 렌더링하기 위해 재귀적으로 호출됩니다. 🎜🎜&lt;code&gt;직접 해체&lt;/code&gt;하면 응답성이 손실되므로 &lt;code&gt;toRefs&lt;/code&gt;로 래핑해야 합니다. 참조 유형의 참조 주소를 직접 변경하면 응답성이 저하될 수도 있습니다🎜🎜&lt;h4 data-id=&quot;heading-11&quot;&gt;🎜관련 api🎜&lt;/h4&gt;🎜🎜&lt;code&gt;읽기 전용&lt;/code&gt; Read-only🎜🎜&lt;code&gt;shallowReactive&lt;/code&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. 🎜🎜셋업은 생성된 그대로 사용하고, 다른 이름은 변경해서 사용하는데 큰 차이는 없습니다🎜<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做代码高亮。
    • 或者通过项目配置,指定相关插件配置

    Vue2 개발자가 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

    Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.

    结语


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

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

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

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

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

    Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.

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

    위 내용은 Vue2 개발자가 Vue3을 빠르게 시작하는 방법에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제