如何快速上手Vue3?以下這篇文章給大家比較一下Vue2和Vue3,並介紹一下Vue2開發者如何快速上手Vue3,希望對大家有幫助!
筆者之前是Vue2 React開發者,因專案需要直接上手Vue3,所以快速學習一下,中間會對比一些和React相關的差異。閱讀前提:已經上手了Vue2的開發
,本文主要聊的問題:
Vue3的全新特性
Vue2和Vue3的一些差異
Vue2開發者如何快速上手Vue3
Vue3和React的簡單比對
使用Vue3編寫元件庫
(學習影片分享:vue影片教學)
單節點
,Vue3 template支援多節點
,類似react fragments變化
基本上都在script中(Option api -> Composition api)不會再看滿螢幕的this了! ! ! v-bind
Proxy
是瀏覽器最新api,功能更加強大。 Vue2.7
版本Flow
,無法完美支援TypeScript
(所以專案初期技術選型很重要)完全重寫
,提供和React一樣的TS支援Pina
vite
支持,包括vitest
等,官方提供週邊工具更多了效能更好,體積更小
就不用說了事件監聽快取
,類似@click綁定的函數,無需多次創建,放在了cacheHandler緩存中#SSR
:Vue 3.0 會將靜態標籤直接轉化為文本,相比React 先將JSX 轉換成虛擬DOM,再將虛擬DOM 轉換為HTML,這一點Vue3的速度要快很多Use Hooks
放棄過去的mixins,使用Hooks解決過去mixins的一些缺點#了解的不多,後續再補充
動靜結合
的方法,最佳化diff效能模版整體大小相關
=》與動態內容的數量相關
,這是一個非常大的效能突破。將程式碼提升到渲染函數之外,這可以避免在每次渲染時重新建立這些對象,從而大大提高記憶體使用率並減少垃圾回收的頻率。 poly-repo
mono-repo
獨立於
vue.js去使用,這樣例如使用者想要使用vue3.0的響應式,可以單獨依賴reactive
,而不必依賴整個vue.js,減少引用包的體積,而vue2.x卻做不到這一點。 原始碼結構比較
setup
選項在元件被建立之前執行,一旦 props
被解析完成,它就會被當作組合式API 的入口。 await語法
< ;script lang="ts" setup>
即可,或者也可以結合export default
使用<script> const result = await Http.get('/getUserInfo') </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) } }
#ref 用來建立
template中預設呼叫value顯示數據,script需要使用
跟react ref差不多,react是.current取得值,vue3是.value。
相關api
import { type Ref } from 'vue';
isRef
# 判斷是否為ref物件。一般是ref,toRef,toRefs創建的變數
triggerRef
customRefreactive 用來建立引用型別
的響應式資料#######reactive的本質是將每一層的資料都解析成###proxy物件#########reactive 的響應式預設都是###遞迴的###,改變某一層的值都會遞歸的呼叫一遍,重新渲染dom。 #########直接解構###,響應性會遺失,需要用###toRefs###包。引用類型直接改變引用位址也會導致響應式遺失#############相關api################readonly### 將reactive的值更改為唯讀#########shallowReactive### 只能回應淺層的資料如果是深層的資料只會改變值不會改變檢視######import { reactive, toRefs } from 'vue' const book = reactive({ author: 'Vue Team', year: '2020', title: 'Vue 3 Guide', description: 'You are reading this book right now ;)', price: 'free' }) let { author, title } = toRefs(book) title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref console.log(book.title) // 'Vue 3 Detailed Guide'####### 4.生命週期#########區別不大,把setup當created用,其它就當改了個名###
<script> import { onMounted } from 'vue'; const getUserInfo = () => { console.log('获取用户信息'); }; onMounted(getUserInfo); </script>#########
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
是拿不到的。显式
指定依赖源,watchEffect - 自动
收集依赖源可以理解为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("开发调试"); }, } );
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
// template <suspense> <template> <asynccomponent></asynccomponent> </template> <template> <div>loading...</div> </template> </suspense> // script const AsyncComponent = defineAsyncComponent(() => import('./asyncComponent.vue'))
Teleport 是一种能够将我们的模板渲染至指定DOM节点,不受父级style、v-show等属性影响,但data、prop数据依旧能够共用的技术;类似于 React 的 Portal
。之前写react是不怎么用这个属性,vue3这个估计也没多大用。
主要解决的问题 因为Teleport节点挂载在其他指定的DOM节点下,完全不受父级style样式影响
to 属性 插入指定元素位置,body,html,自定义className等等
<teleport> <loading></loading> </teleport>
defineXxxx 无需import即可直接使用
和vue2一致
两者用法,除了pina没有Mutations,差别不大。但是官方推荐的东西,自然有它的各种优点
react中 {{}} => {}
import { ref } from 'vue' let v = ref<string>('') const renderDom = () => { return ( <input> <div> {v.value} </div> > ) } export default renderDom</string>
无需导入xxx,import { reactive,ref } from "vue";
,只需要用即可
自定义组件名称,需要引入插件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: 'TButton', }); </script>
或者通过项目配置,指定相关插件配置
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); }, };
用了react hook的人都知道很香,vue3支持这个相当不错,能解决很多业务场景的封装
可以当做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;
Vue3 的依赖追踪是全自动的,不需要担心传了错误的依赖数组给 useEffect/useMemo/useCallback 从而导致回调中- 使用了过期的值
Vue3 Hook也没React Hook那么多限制,后续用用看怎么样
笔者vue3也刚用不久,如有错误,还请兄弟们指出
本文所有demo都在该仓库中JJ-UI 一款Vue3组件库,参考大佬文章刚刚搭建好,后续会基于这个架子开发自己的vue3组件库
以上是聊聊Vue2開發者如何快速上手Vue3的詳細內容。更多資訊請關注PHP中文網其他相關文章!