日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

在新项目中使用 Vue3 使用总结

發布時間:2024/9/27 vue 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在新项目中使用 Vue3 使用总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、使用背景

最近公司需要搭建一個新項目,用于做官網。因為作為官網,首先項目不算大,一共只有十來個頁面,并且想要用戶體驗感很好,所以最終選定以 Vue 作為技術棧。

雖然 Vue3 (中文官網)剛問世不久,但是如果采用VUE2 搭建項目,以后可能會面臨 Vue 版本升級問題,從 Vue2 跨度到 Vue3 有很多不兼容的變更,并且時代在發展,使用新技術會更加具有 可維護可擴展性。

二、項目搭建

這里我使用的是 vue cli4 進行項目搭建

三、devtools

Vue.js devtools 沒辦法調試vue3的項目,官方也提供了升級版的devtools:vue devtools beta

四、安裝依賴

安裝一些常用依賴,值得注意的是Vue3的某些插件與Vue2并不相同。

特別說明:

1、element-plus

這是基于 Vue 3.0 的桌面端組件庫。

如何全局使用element-plus:

// plugins/element.js import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import 'dayjs/locale/zh-cn' import locale from 'element-plus/lib/locale/lang/zh-cn'export default (app) => {app.use(ElementPlus, { locale }) }// main.js import installElementPlus from './plugins/element'const app = createApp(App) installElementPlus(app)// 使用 <template><el-button>按鈕</el-button> </template>

2、 axios

值得注意的是,在Vue2中通過 new Vue()創建Vue實例,并沒有app的概念,但是在Vue3中,引入了createApp。所以axios的y引用方式有所差異。具體內容參照:Vue3 安裝axios使用報錯:Uncaught TypeError: Cannot read property ‘use‘ of undefined。

如何使用axios:

// 方式一:全局掛載 此方式不合適于 將項目里的不同模塊的請求都放在相應文件里, // 因為我們在發請求時可能無法獲取到當前實例this // plugins/axios.js export const plugin = {install: function (app, options) {console.log(options)// 添加全局的方法app.config.globalProperties.axios = _axios;} }// main.js import { plugin as axios } from './plugins/axios' const app = createApp(App) app.use(axios)//使用: this.$axios.post('api/Login',{card:111}).then(res => console.log(res))//方式二:直接使用 // plugins/axios.js const _axios = axios.create(config) export default _axios// 使用: import axios from '@/plugins/axios'// 獲取崗位類別 export function getJobCategories() {return axios.post('api/Login',{card:111}) }

3、Vue Router

Vue router4 也提供了hook鉤子函數供使用。

在 setup里使用 router

import { useRouter } from "vue-router" const router = useRouter() router.push('/')

五、Vue3新特性

1、組合式API

什么是組合式API?

簡單來說就是 將之前散布在vue文件里 的各個功能函數 組合 在一個函數里

這樣會使我們的代碼更加類聚,如果使用過react 函數式組件的同學應該會發現,他們及其類似。

(1)Setup

setup作為組合式api的入口點,所有的函數都可以被放置在setup里進行書寫,需要被setup外部使用的參數,通過 return 暴露出去

setup接收兩個參數:props、context

props接受父組件傳遞而來的參數,當然,這些參數也是響應式的。值得注意的是,在setup里使用 props時,必須在props里定義的變量 才可被setup的props所接收到,在setup里獲取props的變量時,不可使用es6的解構方法,因為它會消除 prop 的響應性,如果需要解構 prop并保留響應式,可以使用 setup 函數中的 toRefs 函數。


context 暴露三個組件的 property: attrs(Attribute)、slots(卡槽)、emit(觸發事件),context是一個普通的 JavaScript 對象,不具有響應式,可以使用es6解構語法。

注意??

setup是在解析其它組件選項之前被調用的,所以在setup里無法準確的訪問到當前組件實例:this。

想要在setup里獲取當前組件實例,官方提供了一個函數:getCurrentInstance,但是getCurrentInstance只能在setup和生命鉤子函數里使用

// getCurrentInstance代表全局上下文,ctx相當于Vue2的this, // 但是特別注意ctx代替this只適用于開發階段,等你放到服務器上運行就會出錯, // 后來查閱資料說的得用proxy替代ctx,才能在你項目正式上線版本正常運行const { ctx, proxy } = getCurrentInstance()

(2)生命周期鉤子

(3)Provide / Inject:父子組件跨層級傳輸數據

// 父組件 setup () {// readonly包裹后可以在組件內引用時不被改變值。// 否則在組件內可以直接通過applyPositionId.value=***將值改變provide('applyPositionId', readonly(applyPositionId))// 函數也可傳遞provide('hideApplyModal', hideApplyModal) }//子組件接收 setup() {const applyPositionId = inject('applyPositionId')const hideApplyModal = inject('hideApplyModal')// 函數調用hideApplyModal() }

2、響應性 API

在Vue2里,我們定義在data里的數據,會被 Object.defineProperty() 數據劫持,通過觀察者模式 最終成為響應式數據。
在Vue3里,實現響應式的 方式改為了 es6 新增的語法 proxy,通過對象攔截方式實現響應式,解決了vue2中的一些漏區。
關于這兩點的相關知識有很多,我會新寫一篇文章做相應的說明。這里主要介紹Vue3的一些新特性的使用。

(1)reactive

reactive用于為對象創建響應式狀態,其作用相當于Vue 2.x 中的 Vue.observable()。為對象創建響應式狀態后,就不會存在 Vue2中 修改 某個對象在data定義時沒有被定義到的屬性,不會存在響應式狀態 的問題。

setup() {const obj = { count: 0}const state = reactive(obj)console.log(state.count) // 0 }

官網有一句話:

響應式轉換是“深層”的——它影響所有嵌套 property。這是什么意思呢?

當我們使用 proxy (不了解 proxy 的可以閱讀:阮一峰 es6入門)做 對象攔截 時,他會劫持此對象的所有property 屬性。

vue2使用 Vue.observable() 使一個對象可響應,被傳入的對象會直接被 Vue.observable 變更為響應式。而 reactive 是為傳入對象創建一個響應式的副本,不改變原始對象,當我們直接改變原始對象時,原始對象不會是響應式的。

(2)readonly

readonly獲取一個對象 (響應式或純對象) 或 ref 并返回原始代理的只讀代理const state = reactive({ count: 0 }) const copy = readonly(state)// error copy.count++

(3)ref

此ref非彼ref,在Vue和react里,都有ref的概念。當其作用域HTML文件時,ref是React/Vue提供的用來操縱React/Vue組件實例或者DOM元素的接口。

而 響應性 API 里 ref 是 用來創建一個具有響應式且可變的 ref 對象,ref 對象具有指向 其所創建變量的.value屬性。在setup里被return 出去時,會自動綁定其value值。

setup() {const count = ref(0)console.log(count.value) // 0return {count} }mounted() {console.log(count) // 0 }

官網有這么一句話:

看了半天我也不是特別明白它是什么意思。將 ref 與 reactive 使用下來,發現他們兩除了在使用方式上有所不同以外,沒有什么太大的區別。高度響應式 的感念還是沒有體會到。通過源碼我可以看見,在使用ref為 對象創建 響應式數據時,其內部調用的也是 reactive 方法。


如果大家有什么理解,可以評論告訴我。🙏🙏

(4)computed

computed的使用很簡單,本質上和vue2沒有什么太大的區別

(5)watch

等同于vue2的this.$watch,可監聽一個或多個源。當 被依賴的值 發生改變時,執行。

// 偵聽一個getter const state = reactive({ count: 0 }) watch(() => state.count,(newcount, prevCount) => {console.log('新值:', newcount)console.log('舊值:', prevCount)} )// 直接偵聽一個ref const count = ref(0) watch(count, (newcount, prevCount) => {console.log('新值:', newcount)console.log('舊值:', prevCount) })// 監聽多個源,使用數組形式 const fooRef = ref(0) const barRef = ref(1) watch([fooRef, barRef], ([newFoo, newBar], [prevFoo, prevBar]) => {console.log('新Foo值:', newFoo)console.log('舊Foo值:', prevFoo)console.log('新Bar值:', newBar)console.log('舊Bar值:', prevBar)})

(6)watchEffect

watchEffect響應式地跟蹤其依賴項時立即運行一個函數,并在更改依賴項時重新運行它:意思就是頁面初始化時會被立即執行一次,并在依賴項發生改變時,再次執行。熟悉React Hook 的同學會非常熟悉,他與useEffect 所實現的功能是一樣的,唯一不同的是,useEffect需要我們手動傳入依賴,而 watchEffect 會自動收集依賴。

const count = ref(0)watchEffect(() => console.log('value:', count.value)) // value:0setTimeout(() => {count.value++// value:1 }, 100)

六、非兼容變更

Vue3 在 Vue2上,有許多的非兼容變更,這里列舉一些比較常用的屬性。

1、v-model

在Vue2中的 v-model 等同于:value + input 的語法糖。
在Vue3中的 v-model 等同于:modelValue + update:modelValue。

// Vue2 <ChildComponent v-model="pageTitle" /><!-- 等同于: --> <ChildComponent :value="pageTitle" @input="pageTitle = $event" />// Vue3 <ChildComponent v-model="pageTitle" /><!-- 等同于: --> <ChildComponent :modelValue="pageTitle" @update:modelValue="pageTitle = $event" />

在Vue2中,我們想要改變v-model傳下來的值,需要model選項去改變。

// parentComponent <ChildComponent v-model="pageTitle" />// ChildComponent export default {model: {prop: 'title',event: 'change'},props: {// 這將允許 `value` 屬性用于其他用途value: String,// 使用 `title` 代替 `value` 作為 model 的 proptitle: {type: String,default: 'Default title'}} }// 或者 <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" /> // 或者 <ChildComponent :title.sync="pageTitle" />// 子組件 this.$emit('update:title', '新title')

在Vue3中,移除了v-bind .sync 修飾符,以上功能簡寫為:

<ChildComponent v-model:title="pageTitle" /> // 等同于 <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />// 子組件: setup(props, context) {const { emit } = context || {}const onClose =() => {emit('update:pageTitle', '新title')}return {onClose,} }

2、v-if 與 v-for

在Vue2中,v-if 與 v-for 同時作用于同一個DOM節點時,v-for 的優先級 高于 v-if 。
在Vue3中,v-if 與 v-for 同時作用于同一個DOM節點時,v-if 的優先級 高于 v-for 。
且 v-if/v-else/v-else-if 的分支中繼續使用 key attribute,因為沒有為條件分支提供 key 時,也會自動生成唯一的 key。

3、filters

Vue3中filters已被徹底移除,建議使用computed代替。

4、template

在Vue2中,template 里只支持一個根結點,否則會報錯。
在Vue3中,template 里只支持多個根結點。

5、prop

在Vue2中,我們需要在 prop 里訪問data里的字段,可以使用 this 。
在Vue3中,prop 里不再支持this。

七、自定義Hook

1、useFetch

import { reactive, toRefs } from 'vue'export default function useFetch(api, params, transformer) {if (typeof api !== 'function') {throw new TypeError('api should be type of fuction')}// 定義初始狀態const state = reactive({data: null,loading: false,})// 定義查詢函數const doFetch = (otherParams) => {const finalParams = {...(params || {}),...(otherParams || {})}state.loading = truereturn api(finalParams).then((data) => {state.data = typeof transformer === 'function' ? transformer(data) : datastate.loading = falsereturn data}).catch((err) => {console.log(err && err.message)state.loading = false})}// 返回狀態refs和查詢函數return [toRefs(state), doFetch] }// 使用 import useListFetch from '@/hooks/useListFetch'setup() {const getdataFunc = (params) => {const { id } = params || {}return axios.get(`/xxx?id=${id}`)}const [{ data, loading: isLoading},getData,] = useListFetch(getdataFunc, {id: 10,})getData() }

2、useListFetch

import { reactive, toRefs } from 'vue'export default function useListFetch(api, params, transformer) {if (typeof api !== 'function') {throw new TypeError('api should be type of fuction')}// 定義list初始狀態const state = reactive({items: [],loading: false,isLastPage: false,})const { pageSize = 10, ...otherParams } = params || {}// 定義查詢函數const doFetch = () => {const preSize = state.items.lengthconst finalParams = {...otherParams,offset: preSize,limit: pageSize,}state.loading = truereturn api(finalParams).then((data) => {if (data && Array.isArray(data)) {const newData = typeof transformer === 'function' ? transformer(data) : dataconst newItems = [...state.items, ...newData]state.items = newItemsif (newItems.length !== preSize + pageSize) {state.isLastPage = true}}state.loading = falsereturn data}).catch((err) => {console.log(err && err.message)state.loading = false})}// 返回狀態refs和查詢函數return [toRefs(state), doFetch] }// 使用 import useListFetch from '@/hooks/useListFetch'setup() {const getListFunc = (params) => {const { offset = 0, limit = 10 } = params || {}return axios.get(`/xxx?offset=${offset}&limit=${limit}`)}const [{ items: videoList, loading: isLoading, isLastPage: isLastPage },getList,] = useListFetch(getListFunc, {pageSize: 10,})getList() }

八、項目打包

參考文檔:https://cli.vuejs.org/zh/guide/

以上就是本人在使用Vue3時一些相對變化比較重要的地方。

總結

以上是生活随笔為你收集整理的在新项目中使用 Vue3 使用总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。