相信進來的小夥伴都對vue有必定的瞭解或者使用,畢竟如今前端最火的框架之一,vue是最好學的和入門相對簡單,畢竟是中文吧,親切感倍增,鄙人呢,如今的工做用的主要框架也是vue,平時喜歡追根溯源,最近身邊不少小夥伴去面試或者作面試官,反饋的某某大佬,寫代碼棒棒的,但在原理和使用場景方面不夠透徹,因此在這裏就總結一些你們平時不留意的點,從vue入門到源碼小實現,寫來旨在和你們一塊兒交流。html
vue(讀音/u:/,相似於vew)是一套用於構建用戶界面的漸進式框架。 特色:易用,靈活,高效 漸進式框架; 逐一遞增vue+ components+vue-router+vuex+vue-cli前端
庫是將代碼集合成一個產品庫是咱們調用庫中的方法實現本身的功能。(好比你們熟悉的jquery,就是庫。) 框架則是爲解決一類問題而開發的產品框架是咱們在指定的位置編寫好代碼,框架幫咱們調用。(vue、react、ng) 總而言之,框架是庫的升級版 plus。vue
//...引入庫等
let vm = new Vue({
el:'#app',
//template: '<h1>hello world</h1>',
data:{ // 存放數據
msg:'hello',
info:{xxx:'xxx'},
arr:[1,2,3,4]
}
});
vm.$nextTick(()=>{
console.log(vm.$el.innerHTML);
console.log(vm.$options);
});
vm.$watch('info.xxx',function(newValue,oldValue){
console.log(newValue,oldValue);
})
複製代碼
vue實例上的方法 vm.options nextTick 等等node
固然你能夠在控制檯上面打印react
在傳統的mvc中除了mode和vew之外的邏輯都放在了 controller中,致使 controller邏輯複雜難以維護,在mwm中vew和 mode沒有直接的關係,所有經過 vIewMode進行交互jquery
方便你們加深印象百度一張圖片: 面試
容許開發者聲明式地將DOM綁定至底層vue實例的數據。在使用數據前須要先聲明 編寫三元表達式 JavaScript表達式算法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 取值表達式 能夠 運算 , 取值 , 作三元 -->
{{1+1}}
{{msg}}
{{flag?'ok':'no'}}
{{ {name:1} }}
{{ 'msg' + 'hello'}}
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data:{
msg:'hello',
flag:true
}
});
</script>
</body>
</html>
複製代碼
vue 數據劫持,必需要知道Object.defineProperty,如下是代碼簡單實現vue-router
// 數據源
let obj = {
name:'jw',
age: {
age:18
}
}
function observer(obj){
if(typeof obj == 'object'){
for(let key in obj){
defineReactive(obj,key,obj[key]);
}
}
}
function defineReactive(obj,key,value){
observer(value); // 判斷value是否是一個對象 若是是對象 會繼續監控
Object.defineProperty(obj,key,{
get(){
return value
},
set(val){
observer(val); // 若是設置的值是對象 須要在進行這個對象的監控
console.log('數據更新了')
value = val;
}
})
}
observer(obj);
obj.age = {name:1};
複製代碼
Object.defienProperty 不支持數組的,固然有童鞋就會問,那若是是數組呢,vuex
// vue 把 這個數組上的全部方法 都重寫了
let arr = ['push','slice','shifit','unshift']
arr.forEach(method=>{
let oldPush = Array.prototype[method];
Array.prototype[method] = function(value){
console.log('數據更新了')
oldPush.call(this,value);
}
})
obj.age.push(5);
obj.age.length--;
複製代碼
若是屬性不存在 默認後增長的內容 並不會刷新視圖
數組調用push 是無效的
在vue中 Directives)是帶有v-前綴的特殊特性,主要的功能就是操做DOM, 多的不說,上代碼說明
<div id="app">
<!-- 內部會進行緩存 之後使用的都是緩存裏的結果 -->
<div v-once>{{msg}}</div>
<!-- v-html innerHTML XSS攻擊 不能將用戶輸入的內容展示出來 內容必須是可信任的-->
<div v-html="d"></div>
<!-- v-if 若是不成裏 dom就會消失 -->
<!-- v-if 控制的是 dom 有沒有 v-show控制的是樣式 -->
<!-- v-show不支持template -->
<template v-show="flag">
<div>hello</div>
<div >123</div>
</template>
<div>312</div>
</div>
複製代碼
v-for 記得寫key,提升渲染效率,後面說的diff算法的時候會詳細說,key能夠用來區分元素,儘可能不要使用index作爲key 若是有惟一標示 儘可能使用 惟一標示哦,有點須要注意的,就是template循環的時候key放在子元素上面,vue 2.5 以上要求 必須在循環時 使用key屬性 。
<template v-for="i in 3" >
<div :key="i+'_1'" :a="i+'_1'">{{i}}</div>
<div :key="`${i}_2`" :a="`${i}_2`" a="{{i}}">{{i}}</div>
</template>
複製代碼
v-model 實現一個輸入框雙向綁定只須要
<input type="text" v-model="msg">
複製代碼
其實v-model 是 @input + :value 的一個語法糖
<input type="text" :value="msg" @input="e=>msg=e.target.value">
複製代碼
小面試題:
computed 和 method的區別
computed 和 watch 區別
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
{{ fullName }}
{{msg}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data:{
firstName:'大',
lastName:'飛',
msg:'hello',
fullName:''
},
// mounted(){ // 順便說下,在不一樣的階段會被調用 是鉤子函數
// this.getFullName();
// },
methods:{
getFullName(){
this.fullName = this.firstName + this.lastName
}
},
watch:{ // vm.$watch('firstname',()=>{})
firstName:{
handler(newValue){
setTimeout(()=>{
this.getFullName();
},1000)
},
immediate:true // deep:true
},
lastName(){
this.getFullName();
}
},
computed:{ // Object.defineProperty來實現
fullName(){ // get方法,有緩存 若是值沒有更改會從緩存中取值
return this.firstName + this.lastName
}
},
// methods:{
// getFullName(){
// console.log('哈哈')
// return this.firstName + this.lastName
// }
// }
})
</script>
</body>
</html>
複製代碼
computed用法深刻一點點,相信你們平時都會有作多選框,你們的方法估計是都是用methods來實現,能夠嘗試用computed,代碼更少更優雅。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
全選 <input type="checkbox" v-model="checkAll">
<input type="checkbox" v-for="(item,key) in checks" v-model="item.value" :key="key">
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data:{
checks:[{value:true},{value:false},{value:true}],
},
computed:{
checkAll:{
get(){
return this.checks.every(check=>check.value)
},
set(value){ // 雙向綁定數據
this.checks.forEach(check =>check.value = value);
}
}
}
})
</script>
</body>
</html>
複製代碼
今晚先寫到這裏,有空再繼續更新自定義指令,生命週期,router、vuex,基本的坑點講完後,咱們再看看她們簡單實現的小原理。感謝你,可以看到這裏。 See you !