一 .v-if和v-show的區別
v-if
和 v-show
是 Vue.js 中兩個常用的條件渲染指令,它們都可以根據條件決定是否渲染某個元素。但是它們之間存在一些區別。
- 語法:
v-if
和v-show
的語法相同,都接收一個布爾值作為參數。
<div v-if="show">Hello, World!</div>
<div v-show="show">Hello, World!</div>
- 條件渲染:
v-if
會根據條件決定是否渲染整個元素,如果條件為false
,則元素不會被渲染;v-show
會根據條件決定是否顯示元素,如果條件為false
,則元素會隱藏,但仍然存在于 DOM 中。
<div v-if="show">Hello, World!</div>
<div v-show="show">Hello, World!</div>
- 性能:
v-if
會根據條件決定是否渲染整個元素,如果條件為false
,則元素不會被渲染,這種情況下,Vue.js 會銷毀和重建元素,性能較差;v-show
會根據條件決定是否顯示元素,如果條件為false
,則元素會隱藏,但仍然存在于 DOM 中,這種情況下,Vue.js 不會銷毀和重建元素,性能較好。
總結:v-if
和 v-show
都可以根據條件決定是否渲染某個元素,但它們之間存在一些區別。v-if
會根據條件決定是否渲染整個元素,如果條件為 false
,則元素不會被渲染,這種情況下,Vue.js 會銷毀和重建元素,性能較差;v-show
會根據條件決定是否顯示元素,如果條件為 false
,則元素會隱藏,但仍然存在于 DOM 中,這種情況下,Vue.js 不會銷毀和重建元素,性能較好。在實際使用中,可以根據具體需求選擇合適的指令。
二.如何理解mvvm
MVVM(Model-View-ViewModel)是一種前端開發模式,它將數據與視圖分離,從而提高代碼的可維護性和可擴展性。
在 MVVM 模式中,Model 表示數據模型,View 表示視圖,ViewModel 表示視圖模型。數據模型負責存儲數據,視圖負責展示數據,視圖模型負責將數據與視圖進行綁定。
在 MVVM 模式中,視圖模型負責將數據與視圖進行綁定。當數據模型中的數據發生變化時,視圖模型會自動更新視圖,從而實現數據與視圖的雙向綁定。
以下是一個簡單的 MVVM 示例:
<template><div><input v-model="searchText" placeholder="Search" /><p>Search text: {{ searchText }}</p></div>
</template><script>
export default {data() {return {searchText: ''};}
};
</script>
在這個示例中,searchText
是數據模型,<input>
和 <p>
是視圖,v-model
是視圖模型。當用戶在輸入框中輸入內容時,searchText
會自動更新,視圖中的內容也會自動更新。
總結:MVVM 是一種前端開發模式,它將數據與視圖分離,從而提高代碼的可維護性和可擴展性。在 MVVM 模式中,視圖模型負責將數據與視圖進行綁定,實現數據與視圖的雙向綁定。
model-view-viewmodel的縮寫,是一種設計思想。
model就是數據模型,用于定義數據修改和操作。
view是視圖。
viewmodel是連接view和model的橋梁。
當數據改變時,viewmodel通過監聽到數據變化,自動更新視圖,當用戶操作視圖時,viewmodel可以監聽視圖變化,通知數據進行改動。
viewmodel通過雙向綁定把view和model連接起來,他們之間的同步是自動的。
三.組件生命周期
Vue 組件的生命周期指的是組件從創建到銷毀的一系列過程,可以分為創建、掛載、更新、銷毀四個階段。
-
創建階段:在創建階段,Vue 會進行一些初始化工作,如初始化數據、事件、計算屬性等。
-
掛載階段:在掛載階段,Vue 會根據模板編譯生成 DOM,并將數據與 DOM 進行綁定。
-
更新階段:在更新階段,Vue 會根據數據的變化,更新 DOM。
-
銷毀階段:在銷毀階段,Vue 會進行一些清理工作,如解綁事件、計算屬性等。
以下是 Vue 組件的生命周期鉤子函數:
-
beforeCreate:在創建階段之前調用,此時 Vue 實例尚未被創建。
-
created:在創建階段之后調用,此時 Vue 實例已經被創建,但 DOM 尚未被編譯。
-
beforeMount:在掛載階段之前調用,此時 DOM 尚未被編譯。
-
mounted:在掛載階段之后調用,此時 DOM 已經被編譯,但尚未被渲染。
-
beforeUpdate:在更新階段之前調用,此時 DOM 已經被渲染,但數據尚未被更新。
-
updated:在更新階段之后調用,此時 DOM 已經被更新,但尚未被渲染。
-
beforeUnmount:在銷毀階段之前調用,此時 DOM 已經被渲染,但尚未被解綁。
-
unmounted:在銷毀階段之后調用,此時 DOM 已經被解綁,Vue 實例已被銷毀。
總結:Vue 組件的生命周期指的是組件從創建到銷毀的一系列過程,可以分為創建、掛載、更新、銷毀四個階段。在不同的生命周期階段,Vue 會調用不同的生命周期鉤子函數,我們可以通過這些鉤子函數來執行一些特定的操作。
簡言之:
- 創建
beforeCreate:屬性和方法都不能使用
created:實例創建完成之后,可以使用和修改數據,但頁面沒有被渲染
- 掛載
beforemount:虛擬dom創建完成,即將渲染
mounted:把編譯好的模板掛載到頁面
- 更新
beforeUpdate:組件更新之前使用,數據是新的,頁面上的數據是舊的,組件即將更新
updated:render重新渲染,數據和頁面都是新的
- 銷毀
beforeDestory:清除定時器等操作
destroyed:組件被銷毀
使用keep-alive時多出兩個
activited:組件激活時
deactivited:組件銷毀時
四.在created和mounted去請求數據,有什么區別
在 Vue.js 中,created
和 mounted
是兩個常用的生命周期鉤子函數,都可以用來請求數據。但是它們之間存在一些區別。
-
調用時間:
created
鉤子函數在 Vue 實例被創建后立即調用,此時 Vue 實例的data
和methods
屬性已經初始化,但 DOM 尚未被編譯;mounted
鉤子函數在 DOM 被編譯后調用,此時 Vue 實例的data
和methods
屬性已經初始化,DOM 已經渲染。 -
請求數據:在
created
鉤子函數中請求數據,如果請求失敗,可能會導致 Vue 實例無法被創建;在mounted
鉤子函數中請求數據,即使請求失敗,也不會影響 Vue 實例的創建和渲染。 -
頁面加載速度:在
created
鉤子函數中請求數據,可能會導致頁面加載速度變慢,因為請求數據需要時間;在mounted
鉤子函數中請求數據,可以確保在頁面加載完成后立即請求數據,從而提高頁面加載速度。
總結:created
和 mounted
都可以用來請求數據,但它們之間存在一些區別。created
鉤子函數在 Vue 實例被創建后立即調用,此時 Vue 實例的 data
和 methods
屬性已經初始化,但 DOM 尚未被編譯;mounted
鉤子函數在 DOM 被編譯后調用,此時 Vue 實例的 data
和 methods
屬性已經初始化,DOM 已經渲染。在實際使用中,可以根據具體需求選擇合適的鉤子函數來請求數據。
created:渲染前調用,先初始化數據。
mounted:渲染后調用,請求數據可能會出現閃屏,created不會。
請求的數據對dom有影響,使用created,與dom無關,可以放在mounted。
五.vue組件通信
Vue 組件通信主要有以下幾種方式:
- props 和 $emit:通過 props,父組件可以將數據傳遞給子組件;通過 $emit,子組件可以將數據傳遞給父組件。
<!-- 父組件 -->
<template><div><child-component :message="parentMessage"></child-component></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentMessage: 'Hello from parent'};}
};
</script>
<!-- 子組件 -->
<template><div>{{ message }}<button @click="sendMessage">Send message to parent</button></div>
</template><script>
export default {props: ['message'],methods: {sendMessage() {this.$emit('message-sent', 'Hello from child');}}
};
</script>
.sync
修飾符:在 Vue 2.3.0 版本中,引入了.sync
修飾符,可以簡化子組件修改父組件數據的操作。
<!-- 父組件 -->
<template><div><child-component :message.sync="parentMessage"></child-component></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentMessage: 'Hello from parent'};}
};
</script>
<!-- 子組件 -->
<template><div>{{ message }}<button @click="sendMessage">Send message to parent</button></div>
</template><script>
export default {props: ['message'],methods: {sendMessage() {this.message = 'Hello from child';this.$emit('update:message', 'Hello from child');}}
};
</script>
- Vuex:Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式與庫。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。
// store.js
import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({state: {count: 0},mutations: {increment(state) {state.count++;}},actions: {increment(context) {context.commit('increment');}},modules: {count: {state: {count: 0},mutations: {increment(state) {state.count++;}},actions: {increment(context) {context.commit('increment');}}}}
});
- $root 和 $parent:通過 $root 和 $parent,可以訪問到 Vue 實例的根節點和父節點。
<!-- 子組件 -->
<template><div>{{ rootMessage }}{{ parentMessage }}</div>
</template><script>
export default {inject: ['rootMessage', 'parentMessage'],created() {console.log(this.$root); // 訪問根節點console.log(this.$parent); // 訪問父節點}
};
</script>
總結:Vue 組件通信主要有 props
和 $emit
、.sync
修飾符、Vuex、$root 和 $parent 等方式。在實際項目中,可以根據具體需求選擇合適的通信方式。
簡言之:
父傳子:
props
,$ref
--引用信息對象會注冊在父組件$refs
對象上子傳父:
$emit
—子組件綁定自定義事件,子組件綁定接收兄弟傳:全局事件總線
$bus
用on和emit
來進行數據傳輸
六.keep-alive
keep-alive
是 Vue.js 提供的一個生命周期鉤子函數,它會在組件被銷毀后,將其緩存到內存中,當再次訪問時,會從緩存中取出組件實例,而不是重新創建一個新的實例。這樣可以減少內存的消耗,提高頁面的加載速度。
keep-alive
主要用于需要頻繁切換的頁面,如首頁、列表頁等。當用戶在兩個頁面之間頻繁切換時,使用 keep-alive
可以避免頻繁地創建和銷毀組件實例,從而提高頁面的加載速度。
要使用 keep-alive
,需要遵循以下步驟:
- 在需要緩存的組件上添加
keep-alive
屬性。
<template><div><!-- 頁面內容 --></div>
</template><script>
export default {name: 'MyComponent',keepAlive: true
};
</script>
- 在
keep-alive
生命周期鉤子函數中,可以進行一些緩存數據的處理。
export default {name: 'MyComponent',keepAlive: true,mounted() {console.log('Component mounted');},destroyed() {console.log('Component destroyed');}
};
注意:keep-alive
主要用于需要頻繁切換的頁面,對于一些需要根據用戶操作進行緩存的數據,可以使用 Vuex 等狀態管理庫進行管理。
是vue的內置組件,包裹組件時,會緩存不活躍的組件實例。
防止重復渲染、減少加載時間和性能消耗。
七. axios如何封裝
Axios 是一個基于 Promise 的 HTTP 客戶端,用于在瀏覽器和 Node.js 中發起 HTTP 請求。 Axios 具有以下特點:
- 支持 Promise API
- 支持攔截器
- 支持請求和響應的數據處理
- 支持取消請求
- 支持自動轉換 JSON
下面是一個簡單的 Axios 封裝示例:
- 安裝 Axios:
npm install axios
- 創建
axios.js
文件,封裝 Axios:
import axios from 'axios';const instance = axios.create({// 基本 URLbaseURL: 'https://api.example.com',timeout: 5000,
});// 請求攔截器
instance.interceptors.request.use(function (config) {// 在發送請求之前做些什么return config;},function (error) {// 對請求錯誤做些什么return Promise.reject(error);}
);// 響應攔截器
instance.interceptors.response.use(function (response) {// 對響應數據做點什么return response;},function (error) {// 對響應錯誤做點什么return Promise.reject(error);}
);export default instance;
- 在需要使用 Axios 的地方引入封裝好的 Axios:
import axios from './axios';axios.get('/users').then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});
在這個示例中,我們創建了一個名為 instance
的 Axios 實例,并設置了請求攔截器和響應攔截器。然后,我們將封裝好的 Axios 實例導出,以便在其他地方使用。
注意:這個示例僅作為參考,實際項目中可能需要根據具體需求進行調整。
下載axios----創建實例----封裝請求和響應攔截器----封裝接口-----使用
八.vue路由傳參
Vue.js 中的路由傳參主要有以下幾種方式:
- 使用 query 參數:在路由的路徑中添加 query 參數,如
/search?keyword=xxx
。在組件中,可以通過this.$route.query
獲取 query 參數。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search',name: 'Search',component: Search,props: true}
];const router = new VueRouter({routes
});export default router;
<!-- Search.vue -->
<template><div><h2>Search</h2><p>Keyword: {{ keyword }}</p></div>
</template><script>
export default {props: ['keyword']
};
</script>
- 使用 props:在路由的
props
屬性中定義需要傳遞的參數,如{ keyword: String }
。在組件中,可以通過this.$route.params
獲取 params 參數。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search/:keyword',name: 'Search',component: Search,props: {keyword: String}}
];const router = new VueRouter({routes
});export default router;
<!-- Search.vue -->
<template><div><h2>Search</h2><p>Keyword: {{ keyword }}</p></div>
</template><script>
export default {props: ['keyword']
};
</script>
- 使用
to
屬性:在路由的to
屬性中,可以使用{ propName: propValue }
的形式傳遞參數。在組件中,可以通過this.$route.params
獲取 params 參數。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search',name: 'Search',component: Search,to: {name: 'Search',params: {keyword: 'xxx'}}}
];const router = new VueRouter({routes
});export default router;
<!-- Search.vue -->
<template><div><h2>Search</h2><p>Keyword: {{ keyword }}</p></div>
</template><script>
export default {props: ['keyword']
};
</script>
總結:Vue.js 中的路由傳參主要有使用 query 參數、使用 props 和使用 to
屬性三種方式。在實際項目中,可以根據具體需求選擇合適的傳參方式。
params傳參:
this.$router.push({name:'',params:{}})
this.$route.params.id
路由屬性傳參
this.$router.push({name:'/${item.id}'})
路由配置
{path:'/index:id'}
query傳參
this.$router.push({name:'index',query:{}})
九.路由hash模式和history有啥區別
路由的 hash 模式和 history 模式的主要區別在于 URL 的表現形式和瀏覽器的歷史記錄。
- URL 表現形式:
- hash 模式:URL 中會帶有
#
符號,如http://example.com/#/search
。 - history 模式:URL 中不會帶有
#
符號,如http://example.com/search
。
- 瀏覽器歷史記錄:
- hash 模式:在瀏覽器中,點擊回退按鈕會返回到上一個頁面,而不是跳轉到上一個 URL。
- history 模式:在瀏覽器中,點擊回退按鈕會跳轉到上一個 URL,而不是返回到上一個頁面。
總結:hash 模式和 history 模式的主要區別在于 URL 的表現形式和瀏覽器的歷史記錄。在實際項目中,可以根據具體需求選擇合適的路由模式。
hash地址上有#,history沒有
地址欄回車刷新時,hash會加載相應頁面,history會報404
hash支持低版本瀏覽器,因為H5新增的API
hash不會重新加載頁面
history有歷史記錄,可以通過pushState和replaceState(0)去修改歷史記錄,并不立刻發送請求
history需要后臺配置
十.路由攔截
Vue.js 中的路由攔截主要通過導航守衛來實現。導航守衛是 Vue Router 提供的全局導航守衛,可以在路由導航過程中執行一些操作,如攔截導航、改變導航參數等。
Vue Router 提供了以下幾種導航守衛:
- beforeEach:在導航守衛中,可以在導航到新路由之前執行一些操作。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search',name: 'Search',component: Search,beforeEach: (to, from, next) => {// 在這里可以執行一些操作,如驗證用戶是否登錄if (!userLoggedIn) {next({ name: 'Login' });} else {next();}}}
];const router = new VueRouter({routes
});export default router;
- beforeEnter:在導航守衛中,可以在導航到新路由之前執行一些操作。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search',name: 'Search',component: Search,beforeEnter: (to, from, next) => {// 在這里可以執行一些操作,如驗證用戶是否登錄if (!userLoggedIn) {next({ name: 'Login' });} else {next();}}}
];const router = new VueRouter({routes
});export default router;
- beforeRouteEnter:在導航守衛中,可以在導航到新路由之前執行一些操作。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search',name: 'Search',component: Search,beforeRouteEnter: (to, from, next) => {// 在這里可以執行一些操作,如驗證用戶是否登錄if (!userLoggedIn) {next({ name: 'Login' });} else {next();}}}
];const router = new VueRouter({routes
});export default router;
- beforeRouteUpdate:在導航守衛中,可以在導航到新路由之前執行一些操作。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search',name: 'Search',component: Search,beforeRouteUpdate: (to, from, next) => {// 在這里可以執行一些操作,如驗證用戶是否登錄if (!userLoggedIn) {next({ name: 'Login' });} else {next();}}}
];const router = new VueRouter({routes
});export default router;
- beforeRouteLeave:在導航守衛中,可以在導航離開當前路由之前執行一些操作。
// router.js
import VueRouter from 'vue-router';
import Search from './components/Search.vue';const routes = [{path: '/search',name: 'Search',component: Search,beforeRouteLeave: (to, from, next) => {// 在這里可以執行一些操作,如保存當前路由信息saveCurrentRouteInfo();next();}}
];const router = new VueRouter({routes
});export default router;
總結:Vue.js 中的路由攔截主要通過導航守衛來實現。導航守衛是 Vue Router 提供的全局導航守衛,可以在路由導航過程中執行一些操作,如攔截導航、改變導航參數等。在實際項目中,可以根據具體需求使用導航守衛來實現
router.before e ach((to,from,next)=>{})
十一.vue的動態路由
在路由配置里設置meta屬性,擴展權限相關字段,在路由導航守衛里判斷這個權限標識實現動態的增加和跳轉路由
十二…如何解決刷新后二次加載路由
window.location.reload()matchercosnt router=createRouter()export function resetRouter(){const newRouter=creatRouter()router.matcher=newRouter.matcher}
十三.vuex刷新頁面數據丟失
vuex會重新獲取數據
把數據保存在瀏覽器緩存里cookie、localstorage、session
頁面刷新時,再次請求數據,動態更新vuex里面的數據
十四.computed和watch區別
computed
和 watch
是 Vue.js 中兩個重要的屬性,它們都可以實現數據的雙向綁定,但它們之間存在一些區別。
-
定義方式:
computed
是通過Object.defineProperty()
方法來定義的,而watch
是通過Vue.prototype.watch
方法來定義的。 -
依賴收集:
computed
屬性會進行依賴收集,當依賴的數據發生變化時,會自動更新視圖;而watch
屬性不會進行依賴收集,需要手動觸發視圖更新。 -
緩存:
computed
屬性會緩存計算結果,當依賴數據發生變化時,會重新計算;而watch
屬性不會緩存計算結果,每次都會重新計算。 -
性能:
computed
屬性性能比watch
屬性高,因為它進行了依賴收集,而watch
屬性需要手動觸發視圖更新。
總結:computed
和 watch
都可以實現數據的雙向綁定,但它們之間存在一些區別。computed
屬性會進行依賴收集,當依賴的數據發生變化時,會自動更新視圖;而 watch
屬性不會進行依賴收集,需要手動觸發視圖更新。computed
屬性會緩存計算結果,當依賴數據發生變化時,會重新計算;而 watch
屬性不會緩存計算結果,每次都會重新計算。computed
屬性性能比 watch
屬性高,因為它進行了依賴收集。
computed:計算屬性,支持緩存,以來的屬性值發生變化,計算屬性會重新計算,否則用緩存,不支持異步,第一次加載就監聽,函數中必須有return
watch:監聽屬性,監聽data中數據的變化,不支持緩存,支持異步,第一次加載不監聽,可以不用有return
十五.vuex使用場景和屬性
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式和庫。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 適用于需要共享狀態的應用程序。
Vuex 具有以下屬性:
-
狀態(state):Vuex 通過
state
屬性來定義應用程序的狀態。狀態可以是嵌套的對象,也可以是基本的數據類型。 -
突變(mutations):Vuex 通過
mutations
屬性來定義狀態的突變。突變是同步的,并且只能通過commit
方法來觸發。 -
操作(actions):Vuex 通過
actions
屬性來定義異步操作。操作可以觸發突變,也可以執行其他異步操作。 -
模塊(modules):Vuex 通過
modules
屬性來定義模塊。模塊可以包含自己的狀態、突變、操作和模塊。
Vuex 適用于以下場景:
-
單頁面應用程序:Vuex 適用于需要共享狀態的單頁面應用程序。
-
多組件應用程序:Vuex 適用于需要共享狀態的多組件應用程序。
-
需要狀態持久化的應用程序:Vuex 適用于需要狀態持久化的應用程序。
-
需要權限控制的應用程序:Vuex 適用于需要權限控制的應用程序。
使用 Vuex 的步驟:
-
安裝 Vuex:
使用 npm 或 yarn 安裝 Vuex:
npm install vuex --save
或
yarn add vuex
-
創建 Vuex store:
在項目中創建一個名為
store.js
的文件,并在其中創建一個 Vuex store:import Vue from 'vue'; import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({state: {},mutations: {},actions: {},modules: {} });
-
定義狀態、突變、操作和模塊:
在
store.js
文件中,可以定義狀態、突變、操作和模塊。例如:state: {count: 0 }, mutations: {increment(state) {state.count++;} }, actions: {increment(context) {context.commit('increment');} }, modules: {count: {state: {count: 0},mutations: {increment(state) {state.count++;}},actions: {increment(context) {context.commit('increment');}}} }
-
引入 store 到 main.js:
在
main.js
文件中,引入store.js
并將其添加到 Vue 實例中:import Vue from 'vue'; import App from './App.vue'; import store from './store';new Vue({store,render: h => h(App) }).$mount('#app');
-
使用 mapState、mapGetters、mapMutations 和 mapActions:
在 Vue 組件中,可以使用
mapState
、mapGetters
、mapMutations
和mapActions
輔助函數來簡化代碼。例如:import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';export default {computed: {...mapState(['count'])},methods: {...mapMutations(['increment']),...mapActions(['increment'])} };
總結:Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式和庫,它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 適用于需要共享狀態的應用程序,如單頁面應用程序、多組件應用程序
state:存儲變量
getters:state的計算屬性
mutations:提交更新數據的方法,同步
actions:異步操作
modules:模塊化vuex
用戶個人信息、購物車等
十六.vue雙向綁定的原理
Vue.js 中的雙向綁定是通過 Object.defineProperty() 方法實現的。這個方法可以讓我們在訪問或修改一個屬性時執行一些自定義操作。Vue.js 利用這個方法實現了數據的雙向綁定。
具體來說,Vue.js 會將數據對象中的每個屬性轉換為 getter 和 setter,從而實現數據的雙向綁定。當數據對象中的屬性被訪問或修改時,getter 和 setter 會被觸發,從而更新視圖。
以下是一個簡單的示例:
class Vue {constructor(data) {this.data = data;for (const key in data) {Object.defineProperty(this, key, {get() {return this.data[key];},set(value) {this.data[key] = value;}});}}
}const vm = new Vue({data: {count: 0}
});console.log(vm.count); // 輸出 0
vm.count = 1;
console.log(vm.count); // 輸出 1
在這個示例中,我們創建了一個簡單的 Vue 類,它將數據對象中的每個屬性轉換為 getter 和 setter。當我們訪問或修改 vm.count
時,getter 和 setter 會被觸發,從而更新視圖。
Vue.js 利用這個原理實現了數據的雙向綁定,從而實現數據和視圖的同步。
通過數據劫持結合發布者訂閱者模式,利用object.defineProperty()劫持各個屬性的setter和getter,在數據發生變化時發布消息給訂閱者,觸發相應的監聽回調渲染視圖。
十七.diff和虛擬dom
diff
和虛擬 DOM 是前端性能優化的重要技術。diff
算法用于計算新舊 DOM 之間的差異,從而實現最小化頁面重排和重繪。虛擬 DOM 是一種模擬 DOM 的技術,它將實際 DOM 轉換為虛擬 DOM,然后在虛擬 DOM 上進行操作,最后將虛擬 DOM 轉換回實際 DOM。
diff
算法的核心思想是將新舊 DOM 進行比較,找出它們之間的差異,然后將差異應用到實際 DOM 上。diff
算法的實現方式有很多,如深度優先搜索(DFS)、廣度優先搜索(BFS)等。
虛擬 DOM 的實現方式是將實際 DOM 轉換為虛擬 DOM,然后將虛擬 DOM 存儲在內存中。當需要更新 DOM 時,先將新的虛擬 DOM 轉換回實際 DOM,然后將新 DOM 與舊 DOM 進行比較,找出差異,最后將差異應用到實際 DOM 上。
以下是一個簡單的示例:
// 假設這是實際 DOM
const oldDom = document.createElement('div');
oldDom.innerHTML = '<p>Hello, World!</p>';// 創建虛擬 DOM
const vdom = {type: 'div',props: {},children: [{type: 'p',props: {},children: ['Hello, World!']}]
};// 將虛擬 DOM 轉換回實際 DOM
const newDom = createElement(vdom);// 比較新舊 DOM,找出差異
const patches = diff(oldDom, newDom);// 將差異應用到實際 DOM 上
applyPatches(oldDom, patches);
在這個示例中,我們首先創建了一個實際 DOM 和一個虛擬 DOM。然后,我們將虛擬 DOM 轉換回實際 DOM,并比較新舊 DOM,找出差異。最后,我們將差異應用到實際 DOM 上。
通過使用 diff
和虛擬 DOM,我們可以實現前端性能優化,減少頁面重排和重繪。
虛擬dom,描述元素與元素之間的關系,創建的一個js對象。
如果組件內有響應的數據,數據發生改變時,render函數會生成一個新的虛擬dom,新的虛擬dom會和舊的虛擬dom進行比對,找到需要修改的虛擬dom內容,然后去對應的真實dom中修改。
diff是虛擬dom對比時用的,返回一個patch對象來存儲兩個節點不同的地方,最后用patch里的記錄信息更新真實dom。
十八.vue和jquery的區別
Vue.js 和 jQuery 都是前端流行的 JavaScript 庫,但它們之間存在一些關鍵區別。
-
核心思想:Vue.js 的核心思想是數據綁定和視圖渲染,而 jQuery 的核心思想是選擇器、操作 DOM 和事件處理。
-
語法:Vue.js 使用基于 HTML 的模板語法,而 jQuery 使用基于 CSS 的選擇器語法。
-
數據綁定:Vue.js 支持數據雙向綁定,而 jQuery 不支持。
-
視圖渲染:Vue.js 支持組件化和響應式視圖,而 jQuery 不支持。
-
性能:Vue.js 的性能通常比 jQuery 更高,因為它使用了虛擬 DOM 和優化了 DOM 操作。
-
社區支持:Vue.js 擁有龐大的社區支持,而 jQuery 的社區支持正在逐漸減少。
-
兼容性:Vue.js 支持現代瀏覽器,而 jQuery 支持舊版瀏覽器。
總結:Vue.js 和 jQuery 都是前端流行的 JavaScript 庫,但它們之間存在一些關鍵區別。Vue.js 更注重數據綁定和視圖渲染,而 jQuery 更注重選擇器、操作 DOM 和事件處理。在性能、社區支持和兼容性等方面,Vue.js 通常比 jQuery 更具優勢。
原理不同:vue就是數據綁定,jq時先獲取dom在處理。
著重點不同:vue是數據驅動,jq著重于頁面。
操作不同
十九.vuex的響應式處理
觸發事件的時候會通過dispatch來訪問action中的方法,actions中的commit會觸發mutations中的方法從而修改state里的值,通過getter把數據更新到視圖