Vue 基礎篇 一、框架與庫的區別 JQ庫 DOM(DOM操作) + Ajax請求 art template庫 模板引擎 框架 全方位、功能齊全 簡易的DOM體驗 + 發請求 + 模板引擎 + 路由功能 + ... 代碼上的不同: 一般使用庫:調用某個函數,自己可以把控庫的代碼 一般使用框架:其框架 ...
Vue 基礎篇
一、框架與庫的區別
- JQ庫->DOM(DOM操作) + Ajax請求
- art-template庫->模板引擎
- 框架 -> 全方位、功能齊全
- 簡易的DOM體驗 + 發請求 + 模板引擎 + 路由功能 + ...
- 代碼上的不同:
- 一般使用庫:調用某個函數,自己可以把控庫的代碼
- 一般使用框架:其框架在幫我們運行已編寫好的代碼
- 框架:初始化自身的一些行為
- 執行你所編寫的代碼
- 施放一些資源
庫:小而精
框架:大而全 ( 框架包含了各種庫 )
二、起步
- 引包
- 直接用
<script>
引入 - CDN
- NPM
- 直接用
npm install --yes
npm install vue --save ( npm install vue -S )
- 創建實例化對象 new Vue( options 對象 )
- options
- el : 目的地( 選擇器 )
- data : 數據屬性 ( 既可以是一個對象,也可以是一個函數 )
- 數據驅動試圖:數據發生改變時,視圖 發生改變。
- 除了數據屬性,vue 實例還暴露了一些有用的實例屬性和方法。他們都有首碼 $,如: $el,$data 。
- template : 模板內容
- 優先順序:如果 template 中定義了內容,那麼有限載入 template;反之,載入 el 掛載的模板
- options
- vue的模板語法:
- {{}} 雙大括弧插值 同 react 中的 {}
- {{ 表達式 }}
- 對象 ( 不要連續三個大括弧 {{ { key : value } }} )
- 字元串 {{ ’XXX‘ }}
- 判斷後的布爾值 {{ true }}
- 三元表達式 {{ true ? '正確' : '錯誤' }}
- 可以用於頁面中簡單粗暴的調試
- 註意:必須在 data 這個函數中返回的對象中聲明
- 設計模式:MVC 與 MVVM
- MVC:Model( 數據模型 )、View( 視圖 )、Controller( 控制器 )
- 數據不是主動展示到 視圖 上的,它是靠 控制器 取到 model 然後展示到 view。
- MVVM:Model、View、ViewModel
- vue的設計模式為MVVM, 只關註的是視圖層
- MVC:Model( 數據模型 )、View( 視圖 )、Controller( 控制器 )
三、指令 ( v-xxx )
- 在vue中提供了一些對於頁面+數據的更為方便的輸出,這些操作就叫做指令
- 比如html頁面中的屬性
<div v-xxx></div>
- 指令中封裝了一些DOM行為,結合屬性作為一個暗號,暗號有對應的值,根據不同的值,框架會進行相關的DOM操作的綁定。
- 比如html頁面中的屬性
- 常用指令
- v-text:元素的InnerText屬性,其實就是給元素的innerText賦值,必須是雙標簽,跟{{}}效果是一樣的,使用較少。
- v-html:元素的InnerHtml,其實就是給元素的innerHtml賦值。
- v-if:判斷是否插入這個元素,相當於對元素的銷毀和創建。appendChild()、removeChild()
- v-else-if
- v-else
- v-show:隱藏元素,如果確定要隱藏,會給元素的style加上
display:none;
,是基於css樣式的切換。
- v-if 與 v-show 的區別 ( 官網解釋 )
v-if
是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當的被銷毀和重建。v-if
也是惰性的:如果在初始渲染時條件為假,則什麼也不做——直到條件第一次變為真時,才會開始渲染條件塊。- 相比之下,
v-show
就簡單的多——不管初始條件是什麼,元素總會被渲染。並且只是簡單的基於css進行 顯/隱 切換。 - 一般來說,
v-if
有更高的切換開銷,而v-show
有更高的初始渲染開銷。因此,如果需要非常頻繁的切換,則使用v-show
較好;如果在運行時條件很少改變,則使用v-if
較好。
- v-bind:綁定標簽上的屬性( 內置的屬性和自定義的屬性 ),
v-bind:class="box"
,簡寫:
。
<div class="container" :class="{active: true}"></div>
// 渲染為 DOM
<div class="container active"></div>
- v-on:
v-on:原生事件名 = '函數名'
,簡寫@
// html
<div class="container" @click="clickHandler"></div>
// js
methods:{
clickHandler(e){
console.log(this);
}
}
- v-for:
v-for="item,index in arr"
<ul>
<li v-for="item,index in list">
{{index}}--{{item}}
</li>
</ul>
- v-model:數據雙向綁定
- 只會體現在UI空間中,只能應用在有value屬性的元素。
<input v-model="msg">
// 等同於
<input :value="msg" @input="msg = $event.target.value" />
那麼
v-model
其實就是v-bind
和v-on
的語法糖。
四、組件
1.局部組件
局部組件使用打油詩:聲子掛子用子
聲明子組件;父組件掛載子組件;父組件使用子組件。
// 局部組件的聲明
var App = {
data(){
return{
}
},
template:`
<div>我是入口組件</div>
`
}
// vue實例
new Vue({
el:"",
data(){
},
// 掛載子組件
components:{
App
},
// 父組件直接可以使用
template:`<App />`
})
組件命名:
1.短橫線分隔 命名:當引用組件時,也要使用 短橫線分隔 形式。( 如:
2.駝峰式命名:當引用組件時,可以使用 短橫線分隔 形式或者 駝峰 形式。( 如:
[註]:直接在DOM( 即非字元串的模板 )中使用時只有 短橫線分隔 形式是有效的。
[建議]:命名時用 駝峰 形式,使用時用 短橫線分隔 形式。
2.全局組件
Vue.component("組件名", options)
// 全局組件聲明
// 第一個參數是組件的名字,第二個參數是options配置項
Vue.component("Vbtn", {
template:`
<button>按鈕</button>
`
})
// 全局組件使用
var App = {
template:`
<div>
...
<Vbtn />
</div>
`
}
五、組件通信
1.通過 prop 往子組件通信
- 1.Parent 2.Child
- 先給父組件中綁定自定義的屬性
Vue.component("Parent", {
data(){
return{
msg:"我是父組件的數據"
}
},
template:`
<div>
<p>我是父組件</p>
<Child :childData="msg" />
</div>
`
})
在子組件中使用 props 接收父組件傳遞的數據
在子組件中任意使用
Vue.component("Child", {
template:`
<div>
<p>我是子組件</p>
<input type="text" v-model="childData" />
</div>
`,
props:["childData"]
})
2.通過 事件 向父組件發送消息
- 在父組件綁定自定義的事件
- 在子組件中 觸發原生的事件,在函數中使用
$emit
觸發其父組件中自定義的事件$emit("自定義的事件名", "消息")
// Child
Vue.component("Child", {
template:`
<div>
<p>我是子組件</p>
<input type="text" v-model="childData" @input="changeValue(childData)" />
</div>
`,
props:["childData"],
methods:{
changeValue(val){
// 自定義的事件一定要通過 this.$emit() 去觸發
// $emit("自定義的事件名", "消息")
this.$emit(childHandler, val)
}
}
})
// Parent
Vue.component("Parent", {
data(){
return{
msg:"我是父組件的數據"
}
},
template:`
<div>
<p>我是父組件</p>
<Child :childData="msg" @childHandler="childHandlerFn" />
</div>
`,
methods:{
childHandlerFn(val){
console.log(val);
}
}
})
六、插槽 slot
插槽:內置組件 slot,作為承載分發內容的出口
/* 模擬 elementUI 按鈕組件的實現 */
// 子組件
Vue.component("Vbtn", {
template:`
<button class="default" :class="type">
<slot>按鈕</slot>
</button>
`,
props:["type"]
})
// 父組件
var App = {
template:`
<div>
...
<Vbtn type="primary">登陸</Vbtn>
<Vbtn type="success">註冊</Vbtn>
</div>
`
}
具名插槽
// 子組件
Vue.component("liItem", {
template:`
<li>
第一個槽
<slot name="idx-1"></slot>
第二個槽
<slot name="idx-2"></slot>
</li>
`
})
// 父組件
var App = {
template:`
<div>
<ul>
<liItem>
<h1 slot="idx-1">我是第一個槽</h1>
<h3 slot="idx-2">我是第二個槽</h3>
</liItem>
</ul>
</div>
`
}
七、過濾器
- 過濾器的作用:為頁面中的數據進行添油加醋的功能
- 分類
- 局部過濾器
- 全局過濾器
/* 局部過濾器 */
// 1.聲明過濾器
// 2. {{ 數據 | 過濾器的名字 }}
var App = {
data(){
return{
price:0,
msg:"hello filter"
}
},
template:`
<div>
<input type="number" v-model="price" />
<!-- 使用過濾器 -->
<h2>{{ price | myCurPrice }}</h2>
<h3>{{ price | myReverse }}</h3>
</div>
`,
filters:{
// 聲明過濾器
myCurPrice: function(val){
return "¥" + val
}
}
}
/* 全局過濾器 */
// 字元串反轉過濾器
Vue.filter("myReverse", function(val){
return val.split("").reverse().join("");
})
{{ 數據 | 過濾器的名字(可以傳值) }}
例:
{{ price | myReverse("這裡是傳入的值") }}
// 其中 arg 就是傳入的值
Vue.filter("myReverse", function(val, arg){
return val.split("").reverse().join("");
})
八、watch 監聽
watch 監聽的是單個屬性
基本的數據類型 -- 簡單監視
複雜的數據類型 -- 深度監視
- 監聽簡單數據類型
new Vue({
el:"",
data(){
return{
msg : ''
}
},
watch:{
msg: function(newVal, oldVal){
console.log(newVal, oldVal);
}
}
})
- 監聽複雜數據類型 obj, arr, 等 -- 深度監視
new Vue({
el:"",
data(){
return{
userList : [{name:"jack"}]
}
},
watch:{
userList: {
deep:true, // 深度監視
handler: function(newVal, oldVal){
console.log(newVal, oldVal);
}
}
}
})
九、計算屬性
- 計算屬性 getter
// html
<img :src="getCurSrc" />
<ul>
<li v-for="item,index in dataList" @click="clickHandler(index)" :class="{active: curIdx == index}">{{ index }}</li>
</ul>
// js
new Vue({
el:"",
data(){
return{
dataList:[{imgsrc:'1'},{imgsrc:'2'},{imgsrc:'3'}],
curIdx : 0
}
},
computed:{
// 計算屬性預設只有 getter
getCurSrc: function(){
return this.dataList[this.curIdx].imgsrc
}
},
methods:{
clickHandler(index){
this.curIdx = index;
}
}
})
- 計算屬性 setter
// js
new Vue({
computed:{
getCurSrc: {
set: function(newVal){
console.log(newVal);
this.curIdx = newVal;
},
get: function(){
return this.dataList[this.curIdx].imgsrc
}
}
},
methods:{
clickHandler(index){
// 點語法 set方法 和 get方法
// getter 方法
console.log(this.getCurSrc);
// 調用set方法
this.getCurSrc = index;
}
}
})
十、生命周期
- beforeCreate:組件創建之前會調用
- created:組件創建之後 會調用
- 在created這個方法中可以操作後端的數據,數據驅動視圖
- 應用:發起Ajax請求
- beforeMount:掛載數據到 DOM 之前會調用
- mounted:掛載數據到 DOM 之後會調用
- 應用:操作DOM
- beforeUpdate:在更新DOM之前 調用該鉤子
- 應用:可以獲取原始的DOM
- updated:在更新DOM之後 調用該鉤子
- 應用:可以獲取最新的DOM
- beforeDestroy:組件銷毀之前會調用
- destroyed:組件銷毀之後會調用
vue 內置組件 <keep-alive></keep-alive>
:能在組件的切換過程中將狀態保留在記憶體中,防止重覆渲染DOM。
- activated:組件被激活了
- deactivated:組件被停用了