中小型企業適合用Vuecss
大型公司通常用reacthtml
vue
舉例:jQuery好處:抹平了各個瀏覽器之間的差別 鏈式操做domreact
相似於一個套餐git
框架:是一個總體 相似於全家桶 性能的優化,方法的實現 es6
UI框架:bootstrap面試
Vue是MVVM框架ajax
是漸進式的JavaScript框架正則表達式
漸進式:只包含核心語法,若是須要其餘功能須要單獨安裝例如 路由vuex 先後端數據交互的方式vue-router
好處:便捷不繁重(有須要纔去安裝)
什麼是mvvm
mvc:model view controller
mvvm:
M層:model層 數據層 數據的增刪改查
V: view層 視圖層 類十餘html同樣的模板 主要用來做展現
VM: viewModel層 model層與view層之間的一個映射 聯繫model層和view層
例如:數據層發生改變 視圖層也會跟着發生改變
數據驅動視圖
vue不支持IE8及如下的版本
cdn引入
npm install vue下載
<div id="app"> <h2> {{message}} </h2> </div> <script src="./vue.js"></script> <script> let vm = new Vue({ //做用:vue起做用的範圍 el:"#app",//document.querySelector // 當前組件所須要的狀態(vue所須要的屬性) data:{ message:「xa-1901」 } }) </script>
底層原理:innertext 做用:渲染數據 v-text的值:任何js表達式
<div id="app"> <h2 v-text="message"></h2> <h2 v-text="arr[0]"></h2> //當vue沒有引入時就是標籤添加一個屬性 //簡寫 //當vue沒有引入時就是不能識別{{}},頁面會顯示{{}} <h2 >{{message}}</h2> <h2>{{ arr[0]}}</h2> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ message:"xz1901", arr:[10,20] } }) </script>
v-html:html
做用:渲染數據
底層原理 innerHTML
v-html的值:任何js表達式
能不用最好不用, 不安全
<div id="app"> <h2 v-html="message"></h2> <h2 v-html="arr[0]"></h2> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ message:"<h4>xz1901</h4>", arr:[10,20] } }) </script>
v-if:顯示隱藏 值:布爾值 true:顯示 false:隱藏 原理:操做dom節點
v-show:顯示隱藏 值:布爾值 true:顯示 false:隱藏 原理:display屬性
限制:v-else v-else-if前面必須有v-if 做用:鏈式調用
<div id="app"> <h2 v-html="message"></h2> <h2 v-html="arr[0]"></h2> <hr> <h2 v-show="flag">{{message}}</h2> <h2 v-if="flag">{{message}}</h2> <hr> <h2 v-if="cases == 1">週一</h2> <h2 v-else-if="cases == 2">週二</h2> <h2 v-else-if="cases ==3">週三</h2> <h2 v-else-if="cases == 4">週四</h2> <h2 v-else="cases == 4">週四</h2> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ message:"xz1901", arr:[10,20], flag:false } }) </script>
語法:v-for="(數組中的值,數組中的下標) in 須要遍歷的數據"
<div id="app"> <p v-for="(item,index) in data.arr">{{item}}----{{index}}</p> <p v-for="(item,key) in obj">{{item}}----{{key}}</p> <div id="box"> <div v-for="(item,index) in res"> <p>{{item.name}}</p> <p>{{item.age}}</p> </div> </div> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ arr:[10,20] } obj:{ name:「張三」, age:19, sex:「nv」 }, res:[ {name:"lisi", age:20, sex:"nv", }, {name:"wangwu", age:19, sex:"nv",} ] }) </script>
v-bind:綁定屬性 id class style src title href 簡寫 :簡寫名稱
<div id="app"> <div v-bind:id="id"> </div> <div :class="myclass"> </div> <div :class="myclassArr"> </div> <div :class="myclassObj"> </div> <div :style="mystyle"> </div> <img :src="path" :title="title"> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ id:"box", myclass:"box1 box2", myclassArr:["box1","box2"], myclassObj:{ "content1":true, "content2":false, }, myStyle:{ color:"red", }, path:"baidu.com", title:"一張圖片" } }) </script>
v-on:事件綁定 v-on:click v-on:dblclick v-on:mouseover 簡寫方式 v-on ---->@ 用法: v-on:事件mingc.修飾符.修飾符 一個事件能夠有多個修飾符
修飾符:
stop 阻止冒泡 prevent 阻止瀏覽器默認行爲 once 只會觸發一次 keydown 按下某個鍵出發 keydown.enter keydown.enter 按下enter鍵
若是在時間中用到事件對象,須要在事件中傳入$event
<div id="app"> <div id="box" v-on:click="handle(abc)"><div> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ }, //當前vue所需的一些事件函數必須放在methods methods:{ handle(ddd){ console.log(1234567) } }) </script>
實現雙數據綁定 使用的元素:form表單的元素可使用v-model vue3.0中廢除了 object.defineProperty() 換成es6的Proxy
<!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> <style> </style> </head> <body> <div id="app"> <form action="" > <label for="">男:<input type="radio" v-model="radioVal" value="男"></label> <label for="">女:<input type="radio" v-model="radioVal" value="女"></label> </form> <div>您的性別是:{{radioVal}}</div> <hr> <form action=""> <label for="">籃球 <input type="checkbox" value="籃球" v-model="checkVal"></label> <label for="">足球 <input type="checkbox" value="足球"v-model="checkVal"></label> <label for="">排球 <input type="checkbox" value="拍球" v-model="checkVal"></label> <label for="">乒乓球 <input type="checkbox" value="乒乓球" v-model="checkVal"></label> <h3>您選的愛好是:</h3> <div v-for="item in checkVal">{{item}}</div> </form> </div> </body> </html> <script src="vue.js"></script> <script> var vm = new Vue({ el : "#app", data : { radioVal:"男", checkVal:[], }, methods:{ }, }) </script>
v-pre:不解析{{}}中的數據包括{{}}
只會渲染一次數據
當數據發生改變的時候加v-once指令的標籤數據不會發生改變
防止第一次渲染的時候{{}}的出現
<html> <body> <div id="app"> <div>{{box}}</div> <!-- 只改變一次 --> <div v-once>{{box}}</div> <!-- 原樣輸出 --> <div v-pre>{{box}}</div> <button @click=handle1>按鈕</button> </div> </body> </html> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ box:"1901", }, methods:{ handle1(){ this.box="1902"; }, } }); </script>
一、全局自定義指令 directive
二、局部自定義指令 directives
做用範圍不一樣 寫的位置不一樣
全局指令:
Vue.directive(參數1,參數2)
參數1,指令的名稱
參數二、指令實現的方法
參數1:當前元素做用在哪一個元素上
參數2:是一個對象
modifiers:修飾符
value:指令的表達式
expression:表達式
Vue.directive必須寫在實例化以前
會有生命週期
Vue.directive('ccc',(el,{modifiers,value}))=>{
console.log("我是自定義制定")
}
<style> #box{ width:200px; height:200px; background:red; position:absolute; } </style> <div id="app"> <div id="box" v-drag></div> </div> <script src="vue.js"></script> <script> Vue.directive("drag",(el,{modifiers,value})=>{ // console.log(rest) var ofX,ofY el.addEventListener("mousedown",downCallback); function downCallback(e){ //鼠標在當前元素內部的位置 ofX = e.offsetX; ofY = e.offsetY; document.addEventListener("mousemove",moveCallback); document.addEventListener("mouseup",upCallback); }; function moveCallback(e){ var x=e.clientX-ofX; var y=e.clientY-ofY; el.style.left=x+"px"; el.style.top=y+"px"; }; function upCallback(){ document.removeEventListener("mousemove",moveCallback); document.removeEventListener("mouseup",upCallback) } }) var vm = new Vue({ el:"#app", data:{}, methods:{}, computed:{} }) </script>
computed 計算屬性 經過計算得來的屬性
一、computed 裏面的函數建議有返回值,不建議改變data中的屬性
二、調用computed中的方法時,不須要加括號
三、基於vue依賴,當出發屬性時會觸發相對應的方法
四、當computed中函數執行完畢後,會執行緩存,當下次所依賴的函數沒有發生改變時,會從緩存中讀取數據
一個屬性受多個屬性影響
本身觸發不須要調用 緩存存數據
computed是屬性調用,調用不須要加括號,當下次所依賴的函數沒有發生改變時,再次調用時,會從緩存中讀取數據
methods是函數調用, 沒有緩存存數據,每次調用每次執行
使用場景:一個屬性受多個屬性影響時會使用computed例如購物車的結算
<div id="app"> <input type="text"v-model.number="a"> <input type="text"v-model.number="b"> <p v-cloak>結果:{{handle()}}</p> <p v-cloak>結果:{{handleCom}}</p> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ a:"", b:"", sum:"", }, methods:{ handle(){ console.log("handle()被調用了") return this.a+this.b; } }, computed:{ handleCom(){ console.log("handleCom被調用了") return this.a+this.b; } } }) </script>
過濾器:用來過濾數據的一個接口
全局: Vue.filter("name",(val,n,sign)=>{
執行的操做
return 值
})
參數1:過濾器名稱
參數2:過濾器實現的方法
參數2:有三個參數:
一、val 內容
二、n 長度
三、sign 後綴
如何使用過濾器
經過管道符 | 管道符左邊是渲染的數據,右邊是過濾器的名稱
局部: filters:{}
<div id="app"> <h2>{{message | reverse(3,'')}}</h2> </div> <script src="vue.js"></script> <script> Vue.filter("reverse",(val,n,sign)=>{ return "$"+val.substring(0,n).split("").reverse().join(sign) }); var vm = new Vue({ el:"#app", data:{ message:"xa1901" } }) </script
>
$on 綁定事件
參數1:事件名稱
canshu2:綁定的事件函數
$emit 觸發事件
參數1:名稱
參數2:須要傳遞給事件函數的參數
$off:解綁事件
參數1:事件名稱 若是隻寫一個參數的話會解綁全部的事件
參數2:須要解綁的事件函數
$once: 綁定一次事件
參數和on同樣
<script> var vm = new Vue({ el:"#app", data:{ }, methods:{ } }); vm.$on("test",func1) //綁定 vm.$emit("test","345")//觸發 vm.$off("test",func1)//解綁 function func1(val){ console.log(111,val) } function func1(val){ console.log(111,val) } vm.$once("test",func2)//綁定一次 vm.$emit("test","444")//觸發 function func2(val){ console.log(222,val) } vm.$emit("test","666")//再次觸發,不會執行 function func2(val){ console.log(222,val) } </script>
$mount() 掛載 外部掛載
vm.$mount("#app")//和el同樣
$destroy() 卸載 外部卸載
vm.$destroy("#app")
$forceUpdate 強制更新
迫使 Vue 實例從新渲染。
methods:{
changeA(){
this.obj.age = 19;
this.$forceUpdate();//強制更新
}
}
//將非響應式屬性變爲響應式屬性
在實例外部去訪問data中的屬性
vm
vm.message
vm.$data.message
watch:作屬性的監聽
一、watch中的函數的名稱必須是data中的屬性
二、watch中參數會接受兩個值,一個是新值,一個是舊值
三、watch中的函數時不須要調用的,但凡所依賴的屬性發生了改變,那麼就會調用相關的函數
四、在watch的屬性監聽當中儘可能不要去修改data中的屬性
五、 watch監聽屬性的時候,只能監聽對象的引用是否發生改變,而具體的屬性值發生改變是不會監聽的
有兩種方式能夠監聽到值
a、對象.屬性
b、深度監聽 handler(newVal,oldVal){} , deep:true
六、 watch作屬性監聽的時候,若是屬性是一個對象,那麼須要作深度監聽,利用handler和deep
七、 watch初始化的時候是不會執行的 immediate:true
解決方法:添加immediate:true屬性
八、watch不會對數組的修改(特殊狀況:this.arr[0]=100)進行監聽
解決方法:
一、用$set
二、數組的方法splice
一個屬性影響多個屬性
模糊查詢
網頁自適應
發起後端請求
監聽窗口的變化
computed場景:
商品總價結算
商品的篩選
$set:
給一個響應式對象添加一個屬性,而且這個屬性也是響應式的
對象的用法:
this.set(target,key,value);
Shuzu:
this.set((target,index,value);)
<body> <div id="app"> <input type="text"v-model="name"> <h2>{{name}}</h2> <input type="text"v-model="obj.name"> <h2>{{obj.name}}</h2> <p v-for="item in arr">{{item}}</p> <button @click="haldleChange">按鈕</button> </div> </body> <script src="vue.js"></script> <script> var vm = new Vue({ el:"#app", data:{ name:"zhangsan", obj:{ name:"moria", }, arr:[1,2,3,4,5] }, methods:{ haldleChange(){ this.arr[0]=100;//不能經過索引的方式直接操做數組 // this.arr.splice(0,1,199); // this.$set(this.arr,0,100); } }, watch:{ name(newVal,oldVal){ console.log(newVal+"+"+oldVal) }, // obj:{ // handler(newVal,oldVal){ // console.log("我變了") // }, // deep:true, // immediate:true //} "obj.name":{//對象打點要加引號 handler(newVal,oldVal){ console.log("我變成"+newVal) }, deep:true, immediate:true }, arr(newVal){ console.log("數組變了"); } } })
由HTML css js 等 封裝好的一個功能,便於二次維護和複用
複用性
頁面上任何一個部分都是組件
模塊:
一個大的功能,每個模塊可分爲多個組件 首頁模塊分爲頭部組件,banner組件
能夠理解爲模塊包含組件
全局組件
Vue.component()
參數1:組件名稱 最好用大寫用於區分組件名稱和HTML標籤
參數2:組件的配置項 -》對象
組件配置項與vm中的配置項如出一轍
有兩點不同
一、多一個template
二、data不是屬性,是一個函數
局部組件
components:{}
腳手架:幫助快速搭建一個項目的骨架
a、全局安裝腳手架 cnpm install -g @vue/cli
b、當前項目下構建項目 vue create 項目名稱
c、選擇你須要的類目
src:開發環境目錄 開發所需文件
assets 靜態資源文件 可放置css,js文件
components 公共組件編寫的地方
static:靜態資源文件 圖片 json數據等
test:單元測試、代碼測試
.gitignore: git上傳須要忽略的文件格式
package.json 項目的基本信息(項目的名稱、項目所需模塊、版本等)
bable:用來作代碼轉義
.vue文件:template寫結構
script寫徐建邏輯
style寫組件樣式
一個。vue文件至關於一個組件
render是一個配置項
是一個函數
用來渲染虛擬dom 渲染組件
一個組件從建立到銷燬的過程
建立 掛載 更新 銷燬
當組件實例化的時候,作的一個初始化操做,注意當前生命週期是組件尚未實例化完畢,
所以,你是訪問不到當前組件的data或者methods的屬性和方法及其餘生命週期函數(this能夠訪問到)
場景:初始化的loading
一、Created執行完畢以後,會將data以及methods身上的全部屬性和方法都添加到vm的實例身上
內部操做:遍歷 掛載 因此能夠直接使用data和methods中的屬性和方法
二、Created生命週期函數會將data身上全部的屬性都添加上一個getter和setter方法,使得data的屬性具備響應式特徵
應用場景:ajax請求
一、數據和模板還未進行結合,還能夠對數據進行最後的一次處理
二、在這個生命週期函數中,是訪問不到真實的DOM結構
一、數據與模板進行相結合生成真是的dom
二、在這個生命週期函數中咱們能夠經過this.$refs.屬性名稱,獲取真實的dom結構,並對dom進行處理
三、通常狀況下咱們都會在當前生命週期函數中作方法的實例化
一、更新的數據和模板還未進行結合,更新的最後一次修改
二、在這個生命週期函數中也能夠獲取到真實的dom結構
一、更新的數據和模板進行相結合,在這個生命週期函數中咱們能夠獲取到數據更新後的dom結構,以及對數據的作一個監聽
相似於watch
一、在當前生命週期函數中仍然能訪問到dom結構
使用場景:作一些事件監聽的解綁 事件的移除
一、在這個生命週期函數中訪問不到真實的dom結構了
二、在這個生命週期中會將vm與dom之間的關聯所有都斷開
組件之間的通信
傳遞:當父組件給子組件進行傳值的時候,給子組件的標籤上加一個自定義屬性 值爲須要傳遞的數據
接收:在子組件內部經過props進行接受,props進行接收的方式有2種 一種是數組 一種是對象
數組接收: props:[自定義屬性] 對象接收: props:{ 自定義屬性:{ type:類型 default:"默認值", required:必須傳遞 } }
接收:當子組件給父組件進行傳值的時候,首先給子組件標籤綁定一個自定義方法,值爲一個函數,
注意 這個函數不須要加() 傳遞過來的值經過這個函數就能夠接收到
傳遞:在子組件內部經過 this.$emit("自定義方法名稱",須要傳遞的參數) 來進行傳遞數據
一、首先須要讓全部的子組件都擁有共同的一個事件訂閱的方法
Vue.prototype.Observer = new Vue();
二、給須要傳值的組件調用this.Observer.$emit("事件名稱",傳遞的值)
三、給須要接受的組件調用this.Observer.$on("事件名稱",回調函數)
一、首先須要讓全部的子組件都擁有共同的一個事件訂閱的方法
手動封裝的Observer import Observer from "./Observer"; Vue.prototype.Observer = Observer;
二、給須要傳值的組件調用this.Observer.$emit("事件名稱",傳遞的值)
三、給須要接受的組件調用this.Observer.$on("事件名稱",回調函數)
// 手動封裝$on $emit $off 事件訂閱
let evenList={
};
const $on = (evenName,callback)=>{
if(!evenList[evenName]){
evenList[evenName]=[]
};
evenList[evenName].push(callback)
};
const $emit = (evenName,params)=>{
if(evenList[evenName]){
evenList[evenName].forEach((cb)=>{
cb(params)
})
}
}
const $off = (eventName,callback)=>{
if(EventList[eventName]){
if(callback){
var index = EventList[eventName].indexOf(callback);
EventList[eventName].splice(index,1);
}else{
EventList[eventName].length = 0;
}
}
}
export default {
$on,
$emit,
$off,
}
談談你對單項數據流的理解
當父組件給子組件傳遞數據時,子組件只能接受不能修改,由於數據是單項流動的
若是自組件修改父組件的信息後,有可能會致使其餘組件數據也會發生錯誤,錯誤沒法捕獲
爲何組件中的data是一個函數,而不是對象?
data是當前組件所須要的狀態,模塊中不少個組件
每個組件都會返回獨立的對象,若是data是對象的狀況下,可能進行復用,由於對象是引用數據類型;可是若是是一個函數的狀況下,那麼就會每次返回一個新的對象,保證每一個組件都有一個獨立的對象(狀態 )
多個組件經過同一個掛載點進行切換展現,經過is屬性動態來改變組件
經過一個內置組件<component></component> 以及這個組件的屬性is來進行切換的
keep-alive:用來去包裹動態切換的頁面或者組件 (內置組件)
做用:凡是用keep-alive包裹的組件,不會被二次建立和銷燬,而是進行了一個緩存
keep-alive組件身上會有如下這幾個經常使用的屬性
include:
值:字符串 正則表達式
做用:指定哪些組件被緩存
exclude:
值:字符串 正則表達式
做用:排除哪些組件被緩存
max:數字
做用:最大能夠緩存多少個組件
凡是使用了keep-alive包裹的組件都會多2個生命週期函數
deactivated:當組件被切換隱藏的時候會進行緩存狀態的生命週期
activated:當組件被切換顯示的時候會進行進入活躍狀態的生命週期
正常狀況下組件當作標籤使用的時候,組件標籤內部嵌套的元素是不會顯示的 若是須要進行顯示,則須要用到插槽
一、在組件標籤內部書寫一個template標籤 標籤添加一個指令 v-slot
二、將須要作嵌套的內部放在template標籤內部
三、在組件內部經過<slot></slot>進行接受
有名字的插槽
一、在組件標籤內部書寫一個template標籤 標籤添加一個指令 v-slot:插槽的名稱
二、將須要作嵌套的內部放在template標籤內部
三、在組件內部經過<slot name='插槽的名稱'></slot>進行接受
帶參數的插槽 ------數據的子傳父
一、在組件內部經過<slot name='插槽的名稱' :自定義屬性="須要傳遞的值"></slot>綁定一個自定義屬性 值爲須要傳遞的數據
二、在組件標籤內部書寫一個template標籤 標籤添加一個指令 v-slot:插槽的名稱="須要接收的這個對象"
二、在template內部的標籤上進行數據的渲染 {{須要接收的這個對象.自定義屬性}}
在vue中使用插件的步驟
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
mode:"hash",
//每個路由頁面的配置項
routes: [
{
path: '/movie',
name: 'movie',
component: Movie
}
]
})
當路由配置成功之後Vue中就會多了兩個內置組件
<router-view></router-view> //當路徑匹配成功之後 router-view用來顯示相對應的組件
<router-link></router-link>
一、作路由的跳轉 必需要添加一個屬性 to:跳轉的路徑
二、除此以外 router-link 身上還會有一個tag屬性 指定router-link 渲染成指定的標籤
mode:路由的形式 hash路由 history路由
routes:[] 每個路由頁面的配置項
routes中的配置項
path:"路徑匹配的路徑"
component:當路徑匹配成功須要渲染的組件
redirect:重定向
流程
一、在定義路由的時候設置傳遞數據的key值 path:"/路由地址/:key1/:key2" key1 key2表明的數據的鍵值
二、在作路由跳轉的時候定義傳遞的數據 to="/路由地址/參數1/參數2"
三、在須要接受信息的組件內部經過this.$route.params進行接收
流程:
一、經過query的方式進行數據的傳參 key=val&key=val
所謂的query傳值其實就是咱們常說的get傳值的方式 經過?後面進行拼接
二、接收的時候經過this.$route.query進行接收
一、在定義路由的時候添加一個屬性props:true
二、接收的時候只須要經過props進行接收便可
query傳值 和 params 傳值的區別?
前者的參數可傳可不傳
後者的參數是必需要傳遞的
路由跳轉的方式
一、a標籤跳轉 影院
二、組件 router-link
三、編程式導航 經過js進行路由的跳轉
this.$router.push 跳轉
this.$router.back 後退
this.$router.forward 前進
this.$router.replace 替換 children:路由嵌套的配置項 這個屬性和routes同樣
路由嵌套中path只須要寫路徑的名稱便可
一、npm install vuex - S
二、Vue.use(Vuex)
三、 建立store模塊,定義狀態管理的規則
state :共享的狀態
mutations :更改狀態
actions:接受組件的事件(dispath),經過異步獲取數據提交mutations(commit)
getters:獲取最新狀態,響應式的
moudle:分模塊進行狀態的管理
四、把store模塊註冊到viewmodel
五、this.$store 來訪問這個store
mapGetters 把store中的getters方法的結果映射到組件中的computed屬性
會主動訂閱倉庫中的狀態變化,響應式的
mapMutations
mapState
dispatch("事件名")
定義一個vue插件
//插件中 export default { install(Vue,options){ Vue.prototype.$show = function(){ alert(1) } } } main.js中 import MyPlugin from '' Vue.use(MyPlugin)