計算屬性如何使用
一般我們在寫vue的時候,在模板內寫的表達式非常便利,它運用于簡單的運算,但是他也有一些復雜的邏輯,包括運算、函數調用等,那么就用到了計算屬性,他依賴于data中數據變化的? data 中數據變化的時候? ? 計算屬性就會重新執行,視圖也會更新。
計算屬性的 set? get 如何使用
每一個計算屬性都包含一個getter 和一個setter?;
絕大多數情況下,我們只會用默認的getter 方法來讀取一個計算屬性,在業務中很少用到setter,所以在聲明一個計算屬性時,可以直接使用默認的寫法,不必將getter 和setter 都聲明。
但在你需要時,也可以提供一個setter 函數, 當手動修改計算屬性的值就像修改一個普通數據那樣時,就會觸發setter 函數,
watch 如何使用
之前做一個H5的項目。需求是當用戶在輸入完了手機號和驗證碼之后,登錄按鈕才可以點擊。?
在沒有使用vue之前,我們可能是通過input的change事件來判斷,用戶是否輸入了內容,然后修改按鈕的狀態。現在有了vue,就省事了很多,我們只需要在watch中,監聽數據模型的值改變即可。
在input 上綁定一個v-mode="pass"綁定一個數據名, 在data里寫入綁定的事件名,通過watch來監聽輸入內容的改變,但是如果,監聽的是一個對象?里面有一個deep屬性可以在選項參數中指定deep:true.也叫深度監聽??
<input v-model="passw2" placeholder="請再次輸入密碼" />
計算屬性和watch的區別
在我們運用vue的時候一定少不了用計算屬性computed和watch?
computed計算屬性是用來聲明式的描述一個值依賴了其它的值。當你在模板里把數據綁定到一個計算屬性上時,Vue 會在其依賴的任何值導致該計算屬性改變時更新 DOM。這個功能非常強大,它可以讓你的代碼更加聲明式、數據驅動并且易于維護。?
watch監聽的是你定義的變量,當你定義的變量的值發生變化時,調用對應的方法。
就好在div寫一個表達式name,data里寫入num和lastname,firstname,在watch里當num的值發生變化時,就會調用num的方法,方法里面的形參對應的是num的新值和舊值,
而計算屬性computed,計算的是Name依賴的值,它不能計算在data中已經定義過的變量。
prop 驗證,和默認值
我們在父組件給子組件傳值得時候,為了避免不必要的錯誤,可以給prop的值進行類型設定,讓父組件給子組件傳值得時候,更加準確,prop可以傳一個數字,一個布爾值,一個數組,一個對象,以及一個對象的所有屬性。
組件可以為 props 指定驗證要求。如果未指定驗證要求,Vue 會發出警告
比如傳一個number類型的數據,用defalt設置它的默認值,如果驗證失敗的話就會發出警告。
prop 如何傳一個對象的所有屬性
方法一:使用不帶參數的v-bind寫法
v-bind中沒有參數,而組件中的props需要聲明對象的每個屬性
方法二:使用帶參數的v-bind寫法
v-bind后跟隨參數todo,組件中的props需要聲明該參數,也就是v-bind后跟隨參數todo,
組件就可以通過todo來訪問對象的屬性
插槽,具名插槽,插槽默認內容
單個插槽;在父組件寫一個標簽,在子組件通過slot來接受標簽里的內容,他只能用一個slot。單個插槽可以放置在組件的任意位置,但是就像它的名字一樣,一個組件中只能有一個該類插槽。
具名插槽:在父組件標簽寫入slot,子組件里面寫name名字,他們兩個名字要相對應,才能通過名字在找到對應的位置。相對應的,具名插槽就可以有很多個,只要名字(name屬性)不同就可以了。
作用域插槽
舉個例子,比如我寫了一個可以實現條紋相間的列表組件,發布后,使用者可以自定義每一行的內容或樣式(普通的slot就可以完成這個工作)。而作用域插槽的關鍵之處就在于,父組件能接收來自子組件的slot傳遞過來的參數,子組件與父組件的數據動態交互的一種常見案例
父組件中必須要有template元素,且必須有scope特性,scope特性中是臨時變量名,
接收從子組件中傳遞上來的屬性,屬性可以是任意定義的。
動態組件
在我們平時使用vue中的模板的時候,許多時候都是直接定義成一個固定的模板,但是,vue中提供了一個動態模板,可以在任意模板中切換,就是用vue中<component>用:is來掛載不同的組件。
我們在components中注冊了三個模板,當我們點擊當前按鈕的時候,就會將模板切換模板,可以說是非常方便了。如果要把組件切換過程中的將狀態保留在內存中,可以添加一個 keep-? alive 指令參數,防止重復渲染DOM。
動態組件上使用keep-alive
<keep-alive>是Vue的內置組件,能在組件切換過程中將狀態保留在內存中,防止重復渲染DOM。
11子組件訪問父組件實例子 $parent
this.$parent
在子組件中判斷this.$parent獲取的實例是不是父組件的實例
在子組件中console.log(this.$parent) ?打印出this.$parent
在父組件中console.log(this)? 打印出this
看看打印出來的兩個實例是不是同一個
如果是同一個 ?就可以在子組件中通過this.$parent.屬性名和方法名,來調用父組件中的數據或者方法
12 父組件訪問子組件變量? this.$refs.usernameInput
給子組件添加ref屬性然后,通過vm.$refs來調用子組件的methods中的方法或者獲得data
父組件: 在子組件中加上ref即可通過this.$refs.ref.method調用
13 vue雙向數據綁定原理
view更新data其實可以通過事件監聽即可,比如input標簽監聽 'input' 事件就可以實現了。所以我們著重來分析下,當數據改變,如何更新視圖的。
數據更新視圖的重點是如何知道數據變了,只要知道數據變了,那么接下去的事都好處理。如何知道數據變了,就是通過Object.defineProperty( )對屬性設置一個set函數,當數據改變了就會來觸發這個函數,所以我們只要將一些需要更新的方法放在這里面就可以實現data更新view了。
視圖view到data? :可以通過事件監聽即可,比如input標簽監聽 'onchange' 事件就可以實現了
data到view:通過Object.defineProperty( )對屬性設置一個set函數,當數據改變了就會來觸發這個函數,所以我們只要將一些需要更新的方法放在這個set函數里面就可以實現data更新view了。
14 vue 組件通信
1) 父傳遞子
父:自定義屬性名 + 數據(要傳遞)=> :value="數據"
子:props ["父組件上的自定義屬性名“] =>進行數據接收
1) 子傳遞父
? 子:this.$emit('自定義事件名稱', 數據)? 子組件標簽上綁定@自定義事件名稱='回調函數'
? ? 父:methods: {? ? 回調函數() {? ? ? //邏輯處理? }? }
1) 兄弟組件
? 通過中央通信 let? bus? =? new? Vue()
? ? ? ? ? A:methods :{ 函數{bus.$emit(‘自定義事件名’,數據)}? 發送
? ? ? ? ? B:created (){bus.$on(‘A發送過來的自定義事件名’,函數)}? 進行數據接受
15 vue 生命周期
vue實例從被創建到銷毀的一系列過程就叫vue生命周期.也就是從開始創建、初始化數據、編譯模版、掛載DOM→渲染、更新、渲染、卸載等一系列過程。
BeforeCreate? 實例創建之前調用
Created? ? ? 實例創建成功,此時data中的數據已經初始化
beforeMount? 掛載之前的狀態
Mounted? ? ? 已經掛載的狀態
BeforeUpdate? 數據更新前的狀態
Updated? ? ? 數據更 新完成時的狀態
beforeDestory? 在vue實例銷毀之前調用,
Destoryed? ? 在vue實例銷毀之后調用,vue實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀。
16 ?vue webpack打包項目修改哪些配置
Config文件夾下面的index.js 設置里面的assetsPublicpath屬性值為./?
如果圖片太大的話,可以設置bulid文件夾下面的webpack.base.conf.js,設置圖片的limit將它的值設大點,
Utils.js添加publicpath為../../
17 ?vue路由傳參數
使用query方法傳入的參數使用this.$router.query接受
使用params方式傳入的參數使用this.$router.params接受
一、用name傳遞參數
在路由文件src/router/index.js里配置name屬性。
routes:?[
????{
??????path:?'/',
??????name:?'Hello',
??????component:?Hello
????}
]
模板里(src/App.vue)用$router.name的形勢接收,比如直接在模板中顯示:
<p>{{ $route.name}}</p>
二、通過<router-link> 標簽中的to傳參
<router-link>標簽中的to屬性進行傳參,需要注意的是這里的to要進行一個綁定,寫成:to。
<router-link?:to="{name:xxx,params:{key:value}}">valueString</router-link>
18 ? 路由導航守衛
全局鉤子函數? : beforeEach()? 每次每一個路由改變的時候都得執行一遍
組件內的鉤子函數? :
to: (Route路由對象) ?即將要進入的目標?路由對象? ???
from: (Route路由對象)??當前導航正要離開的路由
next: (Function函數) ??一定要調用該方法來?resolve?這個鉤子
beforeRouteEnter 路由之前調用
beforeRouteUpdate 復用時調用
beforeRouteLeave? 離開路由時調用
19 什么是vuex,使用vuex的好處
Vuex是一個專為 Vue.js 應用程序開發的狀態管理模式。
好處:
? ? 可以做狀態管理? 采用localstorage保存信息,數據便一直存儲在用戶的客戶端中
? ? 使用場景:適合在巨大后復雜的項目中使用,
20 state,getter,mutation,action,module,plugins? 各自的用途,和用法
State:{? count: 0? }? 保存著所有的全局變量
Getter: 對state中的數據派生出一些狀態,例如對數據進行過濾。(可以認為是store中的計算屬性),會對state中的變量進行過濾再保存,只要state中的變量發生了改變,它也會發生變化,不變化的時候,讀的緩存。
Mutation:更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。
一條重要的原則就是要記住 mutation 必須是同步函數。
Action: Action 類似于 mutation, 不同點在于,Action 提交的是 mutation,而不是直接變更狀態。Action 可以包含任意異步操作,mutation只能是同步。
有點不同的是Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters。
Module: //模塊,可以寫很多模塊,最后都引入到一個文件。分散管理。
生成實例的時候 都放在Store的modules中
plugins:插件(Plugins)是用來拓展webpack功能的,它們會在整個構建過程中生效,執行相關的任務。
21 vuex中使用persistedstate 插件進行長久儲存 (需要自己寫代碼測試)
安裝? npm?install?vuex-persistedstate?--save
store.js引入
import VuexPersistence from "vuex-persist";
創建一個對象:
const vuexLocal = new VuexPersistence({
? ? storage:window.localStorage
})
安裝進vuex插件:
export default new Vuex.Store({
? ? state:{
? ? ? ? info:{}
? ? },
? ? mutations:{
? ? ? ? setInfo(state,info){
? ? ? ? ? ? state.info=info;
? ? ? ? }
? ? },
? ? plugins:[VuexPersistence()]
})
默認存儲到localStorage
想要存儲到sessionStorage,配置如下
import createPersistedState from "vuex-persistedstate"const store = new Vuex.Store({
? plugins: [createPersistedState({
? ? ? storage: window.sessionStorage
? })]
})
22 vue開發中遇到的問題
1、setInterval路由跳轉繼續運行并沒有及時進行銷毀
比如一些彈幕,走馬燈文字,這類需要定時調用的,路由跳轉之后,因為組件已經銷毀了,但是setInterval還沒有銷毀,還在繼續后臺調用,控制臺會不斷報錯,如果運算量大的話,無法及時清除,會導致嚴重的頁面卡頓。
解決方案:在組件生命周期beforeDestroy停止setInterval
beforeDestory() {
? ? clearInterval(this.timer);
? ? MessageBox.close()? ? ? ? ? ? ? ?
}
2、vuejs循環插入圖片?
在寫循環的時候,寫入如下代碼:
<div class="bio-slide" v-for="item in items">?
? ? <img src="{{item.image}}"></div>
此時在控制臺會出現警告?
[Vue Warn]: src=”{{item.image}}”: interpolation in “src” attribute will cause a 404 request. Use v-bind:src instead.這里意思是在“src”屬性插值將導致404請求。使用v-bind:src代替。?
所以替換成如下:
<div class="bio-slide" v-for="item in items">?
? ? <img v-bind:src="item.image">
</div>
這里需要主要,v-bind在寫的時候不能再用{{}},
3、組件的異步加載(按需加載組件)
在平時的demo中,你可能不會遇見這個需求,當頁面很多,組件很多的時候,你會發現你的頁面在首次加載的時候,異常的慢,這個是因為vue首次加載的時候把可能一開始看不見的組件也一次加載了,這個時候就需要對頁面優化了,就需要異步組件了。如何去寫異步組件呢,實際上很簡單,只需要在你的路由index,js里加上require就可以了,像下面這樣,這也是所謂的按需加載組件的實現原理。
4、vuex組件中訪問state報錯
TypeError: Cannot read property ‘state’ of undefined”
在組件中使用this.$store.state.test訪問state的屬性報錯,是因為store的實例并未注入到所有的子組件,需修改main.js
new Vue({
el: '#app',
store, //將store注入到子組件
router,
components: { App },
template: '<App/>'
})