web_前端開發JS框架篇-Vue基礎入門版-基礎語法

郝鑫芸發表於2020-11-09

vuejs概述

jQuery庫是針對jsdom封裝,封裝了好多原生jsdom操作繁瑣的地方,那Vuejs是針對 html+css+js的一個封裝 雖然vuejs沒有脫離這三大技術,但是 在原有基礎上進行了整合 推出了 元件化開發的概念。

MVC框架:

Model - - - View - - - Controllor
模型 - - - 檢視 - - - 控制者

框架(vue使用的):

Model - - - View - - - View - - - Model
模型 - - - 檢視 - - - 檢視 - - - 模型

資料直接對應頁面;
資料變化 頁面就變化;
頁面變化 資料就變化;
幹掉了 傳統MVC結構中的業務邏輯 直接使資料和頁面繫結;
讓頁面操作更簡單,所以Vue中沒有 js的dom操作

Vue特點:

  1. 簡單 易上手(精通難)
    一片html程式碼 結合json 實現vue效果
  2. 雙向資料繫結特點(不再需要dom操作)
    資料和頁面的效果直接繫結
    資料變化 頁面直接變化 幹掉了中間的業務邏輯(後面說)
  3. 個人團隊維護 開源 所以進步快
    尤雨溪帶隊開發的
  4. MVVM框架 非常好用
    在MVC框架基礎上的一個升級(後面說)
  5. Vuejs不支援IE8及以下
    只要是IE9+ 幾乎所有瀏覽器都支援
  6. 輕量級 更適合開發移動端(PC端一樣可以)
    因為Vue的效果比較簡單 所以Vue不適合開發向大型電商網站那樣複雜的頁面
  7. Vue開發PC端 最多的是開發 後臺管理頁面
  8. SPA 單頁面應用
    Single Page Web Application (單頁面 Web應用)

初步使用Vue搭建HelloWorld程式

<!--第二步 一片html程式碼-->
<div id="app">
    <h1>{{msg}}</h1>
</div>
//第一步: 引入vue.js檔案
<script src="vue.js"></script>
<script>
    //第三步 定義json渲染vue
    var vm=new Vue({
        el:"#app",
        data:{
            msg:"Hello World!"
        }
    })
</script>

vue的雙向資料繫結演示

<div id="app">
    <h1>{{msg}}</h1>
    <input type="text" v-model="msg">
</div>
<script src="vue.js"></script>
<script>
    var vm=new Vue({
        el:"#app",
        data:{
            msg:"Hello World!"
        }
    })
</script>

Vue基本結構的介紹

<!--第二步: 一片html程式碼 一般先定義一個統一的父元素,然後用vue去載入這一塊元素
    那麼以後這一塊元素內所有的位置 都按照vue的語法來載入-->
<div id="app">
<!--這個是 Mustache模板語法
    格式: {{js表示式}}  js表示式包括:  三目表示式  運算子表示式
                                            方法呼叫  變數
          這個語法表示一種模板  將來會受vue渲染並執行
          就想蒸蛋糕的那個模具一樣 會按照我們寫的格式進行載入並取得結果
-->
    <h1>{{msg}}</h1>
</div>
<!--第一步 : 引入vue.js檔案-->
<script src="vue.js"></script>
<script>
/*第三步:  定義json、渲染vue程式碼;
先把Vue物件建立出來,
構造方法需要傳入一個json進行vue物件的配置,
有點類似於 `$.ajax({})` 引數的大括號就是針對當前ajax進行配置*/
    var vm=new Vue({
    //掛載目標(表示:當前vue語法,掛載到哪一個目標元素上面去;一旦掛載,那麼該目標就按照vue語法載入)
		el:"#app", //值是一個字串 裡面傳入選擇器(一會講 都支援哪些選擇器)
		data:{ /*定義data是專門給掛載目標裡面所使用的所有變數賦值*/
			msg:"我是vue變數的值"
		}
    });
</script>

Vue所支援的選擇有哪些:

  1. id選擇器;

  2. class選擇器(如果有多個 只會選擇第一個);

  3. 元素選擇器;
    如果有多個 只會選擇第一個
    Vue2.x版本 不允許直接掛載到body上面去!!!
    Do not mount Vue to <html> or <body> - mount to normal elements instead.

  4. 子代/後代選擇器;

  5. 交集選擇器;

  6. 所有的css3選擇器 都支援;

var vm=new Vue({
    //ID選擇器
    // el:"#app",
    //class選擇器
    // el:".pox",
    //元素選擇器
    // el:"div",
    //子代/後代選擇器
    // el:"body>#app",
    //交集選擇器
    // el:"div#app",
    //所有css3選擇器也支援
    el:"div:nth-child(1)",
    data:{
        msg:"我是資料"
    }
})

vue所支援的渲染的資料型別

1.字串
2. number型別
3. boolean型別
4. 陣列型別
5. 物件型別
6. 內建物件型別

<div id="app">
    <h1>{{msg}}</h1>
    <h1>{{num}}</h1>
    <h1>{{boo}}</h1>
    <h1>{{arr}}</h1>
    <h1>{{json}}</h1>
    <h1>{{d}}</h1>
</div>
var vm=new Vue({
	el:"#app",
	data:{
		msg:"我是字串型別",
		num:5,
		boo:false,
		arr:["關羽","張飛","劉備"],
		json:{
			name:"小明",
			age:16
		},
		d:new Date()
	}

})

v-show指令的使用:

vue中提供了一些以v- 開頭的指令,專門寫到標籤上面的,那麼這些指令作用: 擴充套件標籤原有功能
該指令控制元素的顯示與隱藏 v-show="變數或者表示式"
變數或者表示式結果是true時 ,該元素顯示;否則false隱藏。
v-show指令:控制的是元素的 display 屬性。

<div id="app">
    <div id="box" v-show="boo"></div>
</div>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
	el:'#app',
	data:{
		boo:true
	}
});
</script>

v-if指令的使用:

v-if 指令:也是控制元素的顯示與隱藏。

  • v-if="變數或者表示式" 變數或者表示式為true時元素顯示、否則隱藏; 跟 v-if 搭配使用的就是 v-else, 如果v-if的條件為falsev-else的元素顯示; v-else沒有值
    跟隨v-if的變化而變化,跟if..else語句一樣。
  • v-else-if="變數或者表示式" 如果v-if裡面的條件是false 則繼續向下判斷
    v-else-ifv-else-if可以有多個 誰是true誰顯示。

使用注意點:

v-ifv-else-ifv-else標籤之間,不能有任何其他標籤 否則報錯!也就是保證v-if語句的完整性

v-if和v-show都是控制元素顯示隱藏,那麼區別在哪裡?

  • v-show 控制元素的顯示隱藏用的是 display屬性,也就是說不管條件是true還是false元素都會載入,只不過如果條件為false 元素設定display:none;
  • v-if 控制元素的顯示與隱藏用的是 載入與不載入 如果條件為false 則元素直接從dom中刪除,如果條件為true 則重新載入該元素。如果頁面載入時 條件為false 那麼該元素都不會存在到dom中。
  • 由以上結論可以看出:
    如果有一個或單個元素或者父元素下的一堆元素,短時間內進行多次的顯示隱藏 那麼推薦使用v-show
    如果一個元素是懶載入形式 暫時不用,等用到時在顯示載入,則推薦使用v-if
<div id="app">
    <!--<div id="box" v-if="boo"></div>
    <div id="pox" v-else></div>-->
    <ul>
        <li v-if="num==1">我是第一個li</li>
        <li v-else-if="num==2">我是第二個li</li>
        <li v-else-if="num==3">我是第三個li</li>
        <li v-else>我是第四個li</li>
    </ul>
</div>
var vm=new Vue({
	el:'#app',
	data:{
		boo:true,
		num:1,
	}
});

v-for指令的使用:

v-for指令:可以實現 遍歷陣列或者js物件;然後根據遍歷出來的數量載入指定數量的元素。
陣列、物件需要在vuedata裡面定義。

v-for指令遍歷陣列:

  • 格式1: <標籤 v-for="變數 in 陣列物件">{{變數}}</標籤>
  • 格式2: <標籤 v-for="(元素變數,索引標量) in arr">{{變數}}---{{索引}}</標籤>

v-for指令遍歷json物件:

  • 格式1: <標籤 v-for="屬性值 in json物件"></標籤>
  • 格式2: <標籤 v-for="(屬性值,屬性名) in json物件"></標籤>
  • 格式3: <標籤 v-for="(屬性值,屬性名,索引) in json物件"></標籤>
<div id="app">
<div v-for="k in arr">{{k}}</div>
<ul>
	<li v-for="(item,index) in arr">{{item}}====={{index}}</li>
	<li v-for="item in per">{{item}}</li>
	<li v-for="(item,key) in per">{{item}}====={{key}}</li>
	<li v-for="(value,key,index) in per">{{key}}====={{value}}===={{index}}</li>
</ul>
var vm=new Vue({
	el:'#app',
	data:{
		arr:["關羽","劉備","張飛","龐統","李白"],
		per:{
			name:"小強",
			age:18,
			gender:"男",
			location:"善知教育"
		}
	}
});

一些其他指令的使用

mustache語法是一種模板語法 在vue未載入到該語法程式碼時,則該語法看起來像是亂碼一樣,只有vue掛載成功了以後 才真正載入。
假設當前網速緩慢,比如下面程式碼我們用 setTimeout模擬網速緩慢,那麼頁面載入時 會優先顯示一個 花括號{{}},這樣給使用者的 帶來非常不好的體驗。

  • 那麼針對這種mustache語法使用時 先載入 花括號{{}},再載入內容的方式該如何處理呢?
    vue官方推出了一個v-cloak 指令:該指令的作用就是保證了 mustache語法在未載入出來之前 並不顯示,直到語法載入成功後 才顯示,但是需要css配合: [v-cloak]{display:none;}
    實現原理:
    在當前標籤使用了 v-cloak以後 那麼如果mustache語法未載入時 則標籤具有該屬性,跟css屬性選擇器配合 導致元素不顯示,直到mustache語法的值載入成功,則自動刪除該屬性 元素就顯示出來了。
<div id="app">
    <h1 v-cloak>{{msg}}</h1>
    <h1 v-html="str2">我是預設內容</h1>
    <h1 v-text="str2">我也是預設內容</h1>
</div>
setTimeout(()=>{
	var vm=new Vue({
		el:'#app',
		data:{
			msg:"HelloWorld!",
			str1:"我是str1的內容",
			str2:"<a href='http://www.baidu.com'>我是a標籤</a>"
		}
	});
},2000)

渲染內容的指令:

v-html="變數或者表示式"
v-text="變數或者表示式"
這兩個指令都是能夠把 變數或者表示式的值 作為當前標籤的內部內容來渲染,如果標籤原本內部有內容則覆蓋。
兩個指令的區別就是: 如果內容中有標籤 那麼v-html可以渲染標籤,v-text不可以渲染標籤 只會把內容原封不動渲染到頁面上。
這兩個指令也具有 渲染成功後才顯示的效果,所以有些地方如果要渲染一些變數內容 也可以使用該指令。

v-model指令的使用:

v-model指令:是專門用在輸入框上面 用來替代 輸入框的value屬性,讓輸入框的value可以關聯一個vue的變數,從而實現雙向資料繫結

  • 格式: <input type="text" v-model="變數">注意: 一旦輸入框使用了v-model 那麼就不要再定義 value屬性,因為v-model就代替value屬性。
  • 效果:
    一旦使用者修改輸入的內容 則對應的變數會發生值的改變,如果其他地方也用到了該內容,則也會發生改變。
  • 可以使用v-model標籤:inputtextarea標籤。
<div id="app">
    <input type="text" v-model="msg">
    <textarea v-model="msg" id="" cols="30" rows="10"></textarea>
    <h1>{{msg}}</h1>
    <h1 v-html="msg"></h1>
</div>
var vm=new Vue({
	el:'#app',
	data:{
		msg:"HelloWorld!"
	}
});

template模板標籤的使用

如果我們的指令想要控制的標籤元素(一堆標籤)不是單個標籤,那麼之前的做法是 再新增一個父元素標籤 然後把指令定義到統一的父元素標籤上面去。

無論是 v-if 還是v-for 還是v-show都是這樣做的,但是如果實際開發的需求不允許我們再新增一個父元素標籤了呢?

  • 所以我們需要用到vue中的template標籤
  • 該標籤是H5推出的標籤 但是Vue重新定義了它的功能,在vuetemplate標籤不渲染, 也就是說我們可以寫指令控制template裡面的元素,但是template本身又不渲染到頁面上。
  • 所以如果以後有想要控制多個元素的情況下 可以考慮使用template標籤
  • 但是 template標籤不能使用v-show指令!!!
  • v-iftemplate配合使用 可以實現分組管理
<!--<template>我是template標籤</template>-->
<div id="app">
      <!--<div v-for="(item,index) in arr">
          <div>{{item}}:我是第一個div</div>
          <div>{{item}}:我是第二個div</div>
          <div>{{item}}:我是第三個div</div>
      </div>    -->
   <!--<template v-for="(item,index) in arr">
       <div>{{item}}:我是第一個div</div>
       <div>{{item}}:我是第二個div</div>
       <div>{{item}}:我是第三個div</div>
   </template>-->
    <template v-if="boo">
        <div>我是一個div</div>
        <div>我也是</div>
    </template>
    <template v-else>
        <ul>
            <li>我是一個li</li>
            <li>我也是li</li>
        </ul>
    </template>
</div>
var vm=new Vue({
	el:'#app',
	data:{
		arr:["小明","小紅","大婷"],
		boo:true
	}
});

v-on繫結事件的指令使用

vue中 使用v-on指令來繫結事件:
格式: <標籤 v-on:不帶on的事件型別="事件方法名"></標籤>
暫時不需要事件物件時 驅動函式名可以不加括號

該事件要在Vuejson裡面定義:

methods:{
	驅動函式名:function(){}
}

v-on指令使用時 開發工具會提示新增名稱空間
xmlns:v-on="http://www.w3.org/1999/xhtml" 沒啥用 添不新增都行,不影響執行。

如果實在看不過去 我們v-on有簡化寫法:<標籤 @不帶on的事件名稱="事件驅動函式名"></標籤>
在事件的驅動函式裡面 通過this可以直接訪問data裡面的變數
注意: this.不能省略

var vm=new Vue({
	el:'#app',
	data:{
		msg:"我是預設內容"
	},
	methods:{
		show:function(){
			alert("你點我幹嘛")
		},
		show1:function(){
			console.log("滑鼠移入了");
		},
		getData(){
		  // console.log(this.msg);
		   this.msg="哈哈,新內容吧";
		}
	}
});
//補充: es6中 json物件繫結方法 可以向下面這樣去寫
var per={
	name:"小強",
	//es6的新寫法
	show(){
		console.log("我是show方法");
	}
}
per.show()
class Person{
	sayHi(){
	}
}

vue事件中的event使用

  • vue中的event事件物件需要在繫結事件的標籤上面傳入$event引數。
  • 格式: <標籤 @事件名稱="事件驅動函式($evnet)"> </標籤>
  • $event是固定寫法 必須這麼寫,然後在事件驅動函式裡面 第一個引數接收eventevent屬性跟原來學習的沒有任何差別。
  • 如果標籤上面繫結事件時 沒有傳入$event 那麼事件驅動函式也無法接收event
    幾種情況:
  1. 不需要event事件物件 而是傳入自定義資料
    <li v-for="(item,index) in arr" @click="getData(item,index)">{{item}}</li>
    標籤上面傳入幾個引數, 那麼事件驅動函式就可以用形參去接受。
  2. 如果需要event物件 還需要 傳入資料 那麼必須保證$event是在第一個引數位置:
    <li v-for="(item,index) in arr" @click="getData1($event,item,index)">{{item}}</li>
<div id="app">
<!--   <div id="box" @click="show($event)"></div>-->
   <div id="box" @click="show($event)"></div>
    <ul>
	<!--不使用event物件的情況下傳入引數-->
        <li v-for="(item,index) in arr" @click="getData(item,index)">{{item}}</li>
    </ul>
    <ol>
	<!--如果有event也有其他資料 那麼必須保證 $event在第一位-->
        <li v-for="(item,index) in arr" @click="getData1($event,item,index)">{{item}}</li>
    </ol>
</div>
var vm=new Vue({
	el:'#app',
	data:{
		msg:"HelloWorld!",
		arr:["關羽","劉備","張飛","袁紹","龐統"]
	},
	methods:{
		show(event){
			console.log(event);
		},
		getData(s,i){
			// console.log(s,i);
			this.arr.splice(i,1);
		},
		getData1(event,item,index){
			console.log(event,item+"---"+index);
		}
	}
});

vue中的事件修飾符

vue中阻止事件冒泡不用event物件 直接使用事件修飾符即可

  • 格式: <標籤 @事件名稱.修飾符="驅動函式"></標籤>
  • 修飾符有:
    stop: 阻止事件冒泡
    prevent: 阻止預設事件
    once: 該事件只能觸發一次
    self: 只有event.target===this的時候才觸發該事件
<div id="app">
<!--<div id="box" @contextmenu.prevent="demo" @click.once="boxclick($event)">-->
    <div id="box" @contextmenu.prevent="demo" @click.self="boxclick($event)">
<!--<div id="pox" @click.stop="poxclick"></div>-->
        <div id="pox"></div>
    </div>
</div>
<div id="app">
    /  這是第一種阻止瀏覽器預設行為   /
    <!--<div id="box" @contextmenu.prevent="demo" @click="boxclick">-->
    /  這是第二種阻止瀏覽器預設行為   /
    <div id="box" @contextmenu.slef.prevent="demo" @click="boxclick">
        <div id="pox" @click.stop="poxclick"></div>
    </div>
</div>
var vm=new Vue({
	el:'#app',
	data:{
		msg:"HelloWorld!"
	},
	methods:{
	boxclick(event){
		alert("你點到了box");
		console.log(event.target);
		},
		poxclick(){
			alert("你點到了pox")
	
		},
		demo(){
			alert("你右鍵點選了")
		}
	}
});

v-bind指令的初步使用

v-bind指令是專門用來給標籤的原有屬性繫結變數的,也就是說 讓標籤的原有屬性 的值可以是vue的一個變數,變數值改變 屬性值就改變

使用格式:<標籤 v-bind:屬性名="變數或者表示式"></標籤>
此處注意: 一旦使用v-bind 那麼屬性值必須是一個合法的變數或者表示式,不能是直接一箇中文或者其他的值 否則會報錯
v-bind的簡化寫法:<標籤 :屬性名="變數或者表示式"></標籤>

v-bind指令之class屬性的繫結

v-bind能繫結任何標籤的原生屬性 同樣也包括classstyle屬性
那麼 v-bind繫結class時有下面這麼幾種情況:
第一種: 繫結一個字串變數 字串裡面都是class類名

<div id="box" :class="msg">
data:{
	msg:"fz co"
}

第二種: 繫結一個陣列變數 陣列裡面都是字串 每一個字串就是一個class

<div id="box" :class="arr">
arr:["fz","co","ml"]

第三種: 繫結一個json物件 json的鍵就是class名字 值是布林值
布林值為true表示當前class啟用
布林值為false 表示當前class不啟用

<div id="box" :class="json">
    json:{
      fz:true,
      co:false,
      ml:false,
      mt:false
  }

第四種:繫結一個陣列字面量

<div id="box" :class='["fz","co","ml"]'>

第五種:繫結json字面量

<div id="box" :class='{fz:true,co:false,ml:false,mt:false}'>

v-bind指令之style屬性的繫結

v-bind指令繫結style的方式:
第一種:
繫結一個長字串 字串裡面定義 行內樣式的寫法

<div id="box" :style="msg">
data:{
	msg:"font-size:25px;color:#fff;margin-left:30px"
}

第二種:
繫結一個json物件 json物件的鍵值對用來定義css屬性名和屬性值

<div id="box" :style="json" @click="show">
json:{
	fontSize:"30px",
	color:"#fff",
	"margin-left":"50px",
	"margin-top":"100px"
}

第三種:
繫結一個json字面量值

<div id="box" :style='{fontSize:"30px", color:"#fff","margin-left":"50px","margin-top":"100px"}' @click="show">

第四種(知道就行)
繫結一個陣列物件

<div id="box" :style='arr' @click="show">
arr:[
	{fontSize:"30px",color:"#fff",},
	{"margin-left":"50px",},
	{"margin-top":"100px"}
]

vue-resource互動手段的使用

Vue本身是不具有互動能力的 需要像JQ使用外掛那個樣子 進行擴充套件使用,Vue中比較好用的互動第三方 是vue-resource(舊),和Axios兩種互動手段。
現在主流的都是Axios 只不過很多之前的老專案裡面還依然還有Vue-resource的程式碼。

關於各種第三方的程式碼 都去github網站去搜尋 www.github.com
vue-resource的使用:
第一步: 引入vue核心檔案
第二步:引入vue-resource檔案
第三步: 通過this.$http.get/post方法 進行互動訪問

發起get請求:

this.$http.get(伺服器地址,提交的引數).then(成功的回撥,失敗回撥);
在成功的回撥裡面 使用 引數.bodyText獲取返回的資料

get方式給伺服器提交資料:

  1. 位址列拼接
this.$http.get("php/01.getData.php?username=小強&password=123456").then(data=>{
	this.msg=data.bodyText;
})
  1. 通過get方法的第二個引數提交
this.$http.get("伺服器地址",{
	params:{
  		1:值1,
  		2:值2
	}
}).then(成功的回撥)
<h1>{{msg}}</h1>
<button @click="getData">發起一個get請求</button>
getData(){
	/*this.$http.get("php/01.getData.php").then(function (data) {
		console.log(data.bodyText);
		this.msg=data.bodyText
	},function (err) {})*/
	
	/* this.$http.get("php/01.getData.php?username=小強&password=123456").then(data=>{
		this.msg=data.bodyText;
	})*/
	this.$http.get("php/01.getData.php",{
		params:{
			username:"小美",
			password:"111111"
		}
	}).then(data=>{
		this.msg=data.bodyText;
	})
},

發起一個post請求

this.$http.post("伺服器地址",要提交的引數).then(成功的回撥,失敗的回撥);
post請求方法向伺服器提交引數:

this.$http.post("伺服器地址",
	{
		1:值1,
		2:值2
	},
	{
		emulateJSON:true
		//這個鍵值對的意思就是自動拼接那個POST提交引數的請求頭
		//application/x-www-form-urlencoded
}).then(成功的回撥,失敗的回撥)
第二個引數是一個長字串  鍵值對的拼接
<h1>{{msg}}</h1>
<button @click="postData">發起一個post請求</button>
postData(){
	/* this.$http.post("php/01.postData.php").then(data=>{
	this.msg=data.bodyText
	})*/
	
	this.$http.post("php/01.postData.php",{
		username:"小強",
		password:"123456"
	},
	{
		emulateJSON:true
	}).then(data=>{
		this.msg=data.bodyText;
	})
},

發起一個跨域請求:

<button @click="corsData">發起一個跨域請求</button>
this.$http.jsonp("跨域伺服器的地址",{
	jsonp:"cb"  //改變預設的callback鍵名的屬性
}).then(成功的回撥,失敗的回撥)
corsData(){
	this.$http.jsonp("http://localhost/2020-11-01/php/01.corsData.php",{
		jsonp:"cb"
	}).then(data=>{
		console.log(data.bodyText);
	})
}

Axios互動手段的使用

axios是現在Vue中使用最多的互動手段;axiosJQajax用法很像。
axios互動的原理使用的就是promise語法,一旦引入axios.js 那麼全域性就會有一個axios方法。

第一種: axios.get() 發起簡單get請求

axios.get(伺服器地址,給伺服器提交的引數)
  .then(成功的回撥)
  .catch(失敗的回撥)

通過回撥函式的引數 呼叫data屬性 取得返回資料。
提交引數: 位址列拼接。

getSimpleData(){
	/*axios.get("php/02.getData.php")
		.then(data=>{
			console.log(data.data);
			this.msg=data.data
		})*/
	
	axios.get("php/02.getData.php?username=小強&password=123456")
	.then(data=>{
		console.log(data.data);
		this.msg=data.data
	})
},

第二種: axios.post() 發起簡單的post請求

axios.post(伺服器地址,提交的引數)
  .then(成功的回撥)
  .catch(失敗的回撥)

提交引數:
第二個引數傳入一個字串
字串定義 鍵=值&鍵=值

postSimpleData(){
	axios.post("php/02.postData.php")
		.then(data=>{
			this.msg=data.data;
		})
	
	axios.post("php/02.postData.php","username=小強&password=123456")
	.then(data=>{
	this.msg=data.data;
	})
},

第三種: axios({ }) 進行各項屬性配置的axios請求

  • 常用屬性:
    method:“GET/POST”,
    url:“伺服器地址”,
    params/data:“提交的引數”
axios({
	屬性配置
  })
  .then(成功的回撥)
  .catch(失敗的回撥)

axios方法的get方式提交引數:

  1. 位址列拼接
    url:“伺服器地址?鍵=值&鍵=值”
  2. 通過屬性params提交
axios({
	params:{
		1:值1,
		2:值2
	}
})
getData(){
	/*axios({
		method:"get",
		url:"php/02.getData.php"
	}).then(data=>{
		// console.log(data);
		this.msg=data.data
	})*/
	//提交引數
	axios({
		method:"get",
		url:"php/02.getData.php",
		params:{
			username:"小白白",
			password:"123456"
		}
	}).then(data=>{
		this.msg=data.data;
	})
}

axios方法post方式提交引數:

  1. 通過data屬性提交
   axios({
       data:"鍵1=值1&鍵2=值2"
   })
  1. 通過data屬性 值是一個URLSearchParams物件 提交引數
var mydata=new URLSearchParams();
mydata.append("鍵1","值1");
mydata.append("鍵2","值2");

axios({
	data:mydata
})
postData(){
	/*axios({
	    method:"post",
	    url:"php/02.postData.php"
	}).then(data=>{
	    this.msg=data.data;
	})*/
	
	/*axios({
		 url:"php/02.postData.php",
		 method:"post",
		 data:"username=小砌牆&password=666666"
	}).then(data=>{
	 	this.msg=data.data
	})*/

	var myData=new URLSearchParams();
	myData.append("username","小百強");
	myData.append("password","888888");
	
	axios({
	    url:"php/02.postData.php",
	    method:"post",
	    data:myData
	
	}).then(data=>{
	    this.msg=data.data
	})
}

Vue的生命週期以及鉤子函式

所謂 生命週期 是指:從什麼時候誕生 在什麼時候銷燬。
那麼Vue的生命週期 就表示 Vue 例項從什麼是建立,中間經歷了哪些過程,最後什麼時候銷燬。
Vue 的生命週期 在每個階段都會有對應的函式被系統自動執行,一旦當前Vue物件過渡到了指定階段,那麼該階段的宣告週期對應的函式就會被呼叫,這些函式又叫鉤子函式(一共十個 我們目前學習八個)
beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed

生命週期的鉤子函式是跟data同級定義的;

生命週期的鉤子函式作用:

是為了能夠幫助我們在Vue例項的不同階段暴露不同函式,從而我們可以做對應的事情;
實際開發中使用最多的就是mounted方法,這個鉤子函式有點 類似於 window.onload
鉤子函式都可以通過 this. 呼叫當前Vue例項中data的變數 和 methods裡面的方法。

var vm=new Vue({
	data:{
	  msg:"HelloWorld!"
	},
	methods:{
	
	},
	beforeCreate(){
	  alert("Vue例項建立之前")
	},
	created(){
	  alert("Vue例項建立成功!")
	},
	beforeMount(){
	  alert("Vue例項掛載之前")
	},
	mounted(){
	  alert("Vue例項掛載成功")
	},
	beforeUpdate(){
	  alert("data資料更新前")
	},
	updated(){
	  alert("data資料更新完成後")
	},
	beforeDestroy(){
	  alert("Vue例項銷燬前");
	},
	destroyed(){
	  alert("Vue例項銷燬成功")
	}
});
//如果Vue物件建立時 沒有定義el屬性
//則可以通過動態的Vue物件呼叫$mount("選擇器")方法來進行掛載
vm.$mount("#app");
//vm.destroy() 銷燬當前Vue例項

在這裡插入圖片描述

Vue例項本身自帶的屬性跟方法

Vue建構函式裡面傳入的 物件 繫結的屬性跟方法,按原理來說並不屬於Vue物件本身的,但是為了能夠方便訪問,所以系統自動給Vue物件也繫結一份一模一樣的,只不過是$開頭的。

var options={
    el:'#app',
    data:{
        msg:"HelloWorld!"
    }
}
var vm=new Vue(options);
//獲取data物件
console.log(vm.$data);
//獲取el掛載目標
console.log(vm.$el);
vm.$mount() 動態掛載目標  如果已經定義el屬性 那麼該方法不生效
vm.$destroy()  銷燬當前vue物件

Vue例項自定義屬性跟方法

如果 Vue 的構造方法中的 options 物件繫結了自定義屬性跟方法,那麼 訪問方式 : vm.$options.屬性名

var vm=new Vue({
  el:'#app',
  data:{
    msg:"HelloWorld!"
  },
  name:"小白白"
});
console.log(vm.$options);
console.log(vm.$options.name);

computed計算屬性的使用

如果有需要是一個變數是根據另一個或者多個變數的值變化而發生變化時,需要用到計算屬性,該變數需要定義到computed裡面。
格式:

computed:{
	變數:function(){
	    此處可以寫程式碼;
	    最後一定要return一個值,
	    return的這個值就是當前變數的新值
	    return 新值;
	}
}

計算屬性裡面定義的變數 跟 data 裡面定義的變數沒有任何區別,頁面該怎麼用就怎麼用;

計算屬性的值 會隨著 關聯的變數的值 變化而變化,就是說只要變數出現在計算屬性的程式碼中,那麼這個變數值發生改變計算屬性就會被觸發

計算屬性裡面的變數的值 不能直接更改,涉及到setget方法,所以暫時記住 計算屬性的值不能直接更改。

<div id="app">
  <button @click="change">點選改變a的值</button>
  <h1>a的值:{{a}}</h1>
  <h1>b的值:{{b}}</h1>
  <h1>c的值:{{c}}</h1>
</div>
var vm=new Vue({
  el:'#app',
  data:{
      a:10,
      c:99
  },
  computed:{
      b:function(){
          console.log("b的計算屬性方法被觸發");
          return this.a*10+5
      }
  },
  methods:{
      change(){
          this.a=200;
      }
  }
});

Vue中使用key管理重複元素

因為 Vue 的虛擬 DOM 演算法的原因,會導致有些時候使用v-if或者v-for時,如果元素內容相同時,會導致渲染錯誤,因為 vue 會預設的複用元素,從而減少 DOM 操作,如果不想複用元素,那麼必須給當前元素繫結 key屬性,定義獨一無二的值,防止複用!

<div id="app">
  <template v-if="boo">
    <h4>手機號註冊</h4>
    <label for="">手機號:</label>
    <input type="text" key="mobile" placeholder="請輸入手機號">
    <input type="button" value="提交" >
  </template>
  <template v-else>
    <h4>郵箱號註冊</h4>
    <label for="">郵箱號:</label>
    <input type="text" key="email" placeholder="請輸入郵箱號">
    <input type="button" value="提交" >
  </template>
  <p>
    <button @click="change">切換註冊方式</button>
  </p>
</div>
var vm=new Vue({
  el:'#app',
  data:{
    boo:true
  },
  methods:{
    change(){
      this.boo=!this.boo;
    }
  }
});

通過上面切換註冊方式的程式碼我們看到,儘管切換了另一套佈局,但是因為兩套佈局裡面都有input,雖然inputplaceholder屬性值不一樣,但是系統預設複用了切換之前的輸入框物件,然後只是把placeholder屬性的值替換一下,所以如果不想保留使用者輸入的資訊,也就是不想使用預設的複用,想要重新渲染,那麼兩個input必須新增不同的key就好了。

那麼同理 v-for 也要給迴圈出來的每個元素新增 key 防止複用,在ws開發工具中 v-for 不新增key 不報錯,但是在vsCodev-for不新增key會有報錯提示,有紅線<li v-for="(item,index) in arr" :key="index"></li>

Vue鍵盤事件的按鍵修飾符

Vue中:
event.key 在按鍵事件中表示當前按鍵的名稱
event.keyCode 在按鍵事件中表示當前按鍵碼

如果鍵盤事件想要觸發指定按鍵以前的做法:

if(event.key=="Enter"){
  console.log("按回車了");
}

現在只需要使用案件修飾符即可:

@keydown.按鍵名稱/鍵盤碼="驅動函式"

表示觸發指定按鍵才觸發該事件。

<div id="app">
  <input type="text" @keydown="show($event)">
  <input type="text" @keydown.Enter="show($event)">
  <input type="text" @keydown.up="show($event)">
  <input type="text" @keydown.65="show($event)">
  <input type="text" @keydown.a="show($event)">
</div>
var vm=new Vue({
  el:'#app',
  data:{
   msg:"HelloWorld!"
  },
  methods:{
    show(event){
      console.log(event.key);
      console.log(event.keyCode);
      if(event.key=="Enter"){
        console.log("按回車了");
      }
      console.log("觸發了麼?");
    }
  }
});

自定義過濾器

自定義過濾器的使用

能夠監聽指定的變數的值是否符合定製的規範

自定義過濾器格式: {{變數 | 過濾器名字}}

Vue裡面跟data同級的位置定義:

filters:{過濾器名字:function(引數){
  引數就是當前 過濾器使用的那個位置的變數的值
  return  當前變數的新值;
}

如果過濾器裡面不return 那麼當前變數沒有值。

過濾器filter和計算屬性computed的區別:

  • 過濾器是針對當前過濾器所在的位置的那個變數格式的檢查;
  • 計算屬性是至少兩個變數 其中一個變數根據另一個變數的值變化而變化;

過濾器可以使用的位置:

mustache語法v-bind指令

<div id="app">
  <h1>{{a | check}}</h1>
  <input type="text" v-model="a">
  <input type="text" v-model="b">
  <img src="image/chang.png" :width="b | checkNum" alt="">
</div>
var vm=new Vue({
  el:'#app',
  data:{
    a:50,
    b:"",
    boo:false
  },
  filters:{
    check:function(a){
      // console.log(a);
      if(a<0 || a>9999) {
        return "Error!";
      }
      return a;
    },
    checkNum(a){
      if(/^\d{1,}$/.test(a)){
        return parseInt(a)
      }else{
        return 100;
      }
    }
  }
});

過濾器之時間轉換器案例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    h1{
        text-align: center;
        color:orange;
    }
  </style>
</head>
<body>
<div id="app">
  <h1>{{msg | change}}</h1>
</div>
<script src="vue.js"></script>
<script>
  var vm=new Vue({
  el:'#app',
    data:{
      msg:new Date(),
    },
    filters:{
      change:function (d) {
        let year = d.getFullYear();
        let month = d.getMonth() + 1;
        let day = d.getDate();
        let hour = d.getHours();
        let minute = d.getMinutes();
        let second = d.getSeconds();
        month = month > 9 ? month : "0" + month;
        day = day > 9 ? day : "0" + day;
        hour = hour > 9 ? hour : "0" + hour;
        minute = minute > 9 ? minute : "0" + minute;
        second = second > 9 ? second : "0" + second;

        return year+"年 "+month+"月 "+day+"日 "+hour+"時 "+minute+"分 "+second+"秒";
      }
    },
    mounted(){
      //vue掛載成功以後 啟動一個定時器
      setInterval(()=>{
        this.msg=new Date();
      },1000)
    }
  });
</script>
</body>
</html>

全域性註冊過濾器的使用

目前為止我們學習的都是單個vue物件,如果有多個vue物件,那麼就可以分別掛載不同的目標,實現不同的渲染。

如果我在 vm1 中定義 filters(過濾器) ,那麼vm2是不能使用!!!

Vueoptipons物件裡面定義的 過濾器 那麼只能在當前vue物件中使用,也就是當前vue物件掛載的目標可以使用 其他vue物件掛載的目標不能使用!

如果想要所有Vue物件都可以使用 那麼就要定義全域性的過濾器:

Vue.filter("過濾器名字",回撥函式(引數就是當前變數的值){return })
<div id="app">
  <h1>{{msg | check}}</h1>
  <h1>{{msg | checkhaha}}</h1>
</div>
<div id="box">
  <h1>{{msg | checkhaha}}</h1>
</div>
//全域性註冊過濾器
Vue.filter("checkhaha",function(a){
  if(a.length>5){
    return "Error!"
  }
  return a;
})
console.log(Vue.computed);

var vm1=new Vue({
  el:'#app',
  data:{
    msg:"我是vm1的msg"
  },
  filters:{
    check(a){
      if(a.length>10){
        return "字數超過了!!"
      }
      return a;
    }
  }
});

var vm2=new Vue({
  el:'#box',
  data:{
    msg:"我是vm2的msg"
  }
});

watch資料監聽器的使用

目的是為了監聽某些變數值變化時,我們需要做一些其他功能。

格式:
在Vue的$options裡面 定義
watch:{
	被監聽的data裡面的變數:function(引數1,引數2){
		引數1,是當前變數改變後的值,引數2是變數改變前的舊值
	}
}

淺層監聽–監聽器預設是淺層監聽

如果監聽器所監聽的變數是基本資料型別,那麼值改變監聽器就會監聽到;但是如果監聽器監聽的是物件型別,那麼預設物件地址改變時才會監聽到,換句話說,如果物件的屬性發生變化時,預設無法監聽

區域性監聽器(只能在當前Vue中使用)

在Vue中註冊的區域性監聽器進行深層監聽

格式:
watch:{
	被監聽的變數:{
	     handler:function(newVal,oldVal){
	     },
	     deep:true
	}
}

全域性監聽器:

淺層監聽

vue例項物件.$watch("被監聽的變數",function(newVal,oldVal){
	//這種格式預設淺層監聽
})

深層監聽

vue例項物件.$watch("被監聽的變數",{
   handler:function(newVal,oldVal){
   },
   deep:true
})
<div id="app">
  <input type="text" v-model="msg">
  <h1>{{msg}}</h1>
  <h1>per的值:{{per}}</h1>
  <p> <button @click="change">改變per的值</button></p>
</div>
var vm=new Vue({
  el:'#app',
  data:{
    msg:"HelloWorld!",
    per:{name:"小白",age:16}
  },
  methods:{
    change(){
     /* 地址改變深淺監聽無變化
     this.per={
          location:"文化大廈",
          gender:"男"
      }*/
      /*地址不變值改變 淺層監聽不能監聽到*/
     this.per.name="大黃";
    }
  },
  watch:{
    //每次msg的值發生改變都會觸發該方法
    msg:function(newVal,oldVal){
      console.log("msg值發生變化了,新值:"+newVal+"--舊值:"+oldVal); 
    },
   /* 這種格式預設淺層監聽
    per:function(newVal,oldVal){
      console.log("per值發生變化了",newVal);
    }*/
    
   /*深層監聽*/
    per:{
       handler:function (newVal,oldVal) {
           console.log("per值發生變化了",newVal);
       },
       deep:true
    }
  }
});
//全域性深層監聽
vm.$watch("per",{
handler:function(newVal,oldVal){
  console.log("我是全域性監聽per,被觸發了",newVal);
},
deep:true
})

$watch()不是靜態方法 而是 Vue例項的方法

filter()方法是Vue的靜態方法 Vue.filter()

Vue結合Animtae.css框架的動畫

Animate.css框架主要針對盒子的進入和離開的動畫

  1. 首先我們得定義一個盒子具有進入離開效果;
  2. 通過link標籤引入Animate.css
  3. 把具有進入離開的盒子外面套一層 transition標籤;
    transition標籤vue中載入完,是不顯示的標籤,專門用來設定動畫的一個標籤,功能類似template
  4. 在transition開始標籤裡面定義 進入和離開的屬性;
    進入enter-active-class;
    離開leave-active-class;
  5. 進入離開的class裡面定義 animated 框架的動畫類名
    不要忘記animated 最基本的類名
<style>
  #box{
      width: 200px;
      height: 200px;
      background-color: hotpink;
  }
</style>

<link rel="stylesheet" href="css/animate.css">

<div id="app">
  <button @click="change">點選切換</button>
  //兩個類名
  <transition
    enter-active-class="animated bounceInDown"
    leave-active-class="animated fadeOutDown"
  >

    <div id="box" v-show="boo"></div>
      
  </transition>

</div>
var vm=new Vue({
  el:'#app',
  data:{
    boo:true
  },
  methods:{
    change(){
      this.boo=!this.boo
    }
  }
});

Computed計算屬性的set和get

在computed裡面定義的 變數 都是 計算屬性 ,不能直接更改計算屬性本身的值,需要定義當前計算屬性的get和set方法 來賦值。

每一個計算屬性內部預設對應有兩個方法:

get方法 和set方法
每次我們獲取當前計算屬性的值 都是預設呼叫 get方法 進行獲取值。

如果我們想要手動的修改當前計算屬性的值
必須手動定義 set方法 因為每次給計算屬性賦值都是通過 set方法;

在set方法中也不能直接給當前計算屬性賦值
因為計算屬性本來就是依賴於其他屬性存在而存在的屬性,要想改變計算屬性的值 就得改變被依賴的變數的那個值

var vm=new Vue({
  el:'#app',
  data:{a:10,msg:0},
  computed:{
   /* b:function () {
        return this.a*10;
    }*/
    b:{
      get:function () {
        console.log("當前是get方法,你是不是要獲取b的值???");
        return this.a*10
      },
      set:function (val) {
        this.a=val;
      }
    }
  },
  methods:{
    show(){
     // this.b=this.msg
     // this.a=this.msg
     this.b=this.msg
    }
  }
});

計算屬性分get和set方法,我們每次再給他賦值的時候都預設呼叫set方法,每次獲取值的時候預設呼叫get方法,如果想要改變計算屬性本身的值,就要複寫,自己定義get和set方法

元件的概述

什麼是元件? 元件的意義在哪裡? 為什麼說Vue是元件化開發

所謂元件分為廣義和狹義的理解:

廣義: 封裝了自己獨立的資料和頁面的一個單獨內容
狹義理解: 單獨的一個標籤 既包含html內容也包含css和js內容

原生html開發的弊端:

  1. 原來的開發html我們是按照頁面級別來進行分塊的
    比如: index.html index.css index.js detail.html detail.css detail.js
    如果其中一塊html不想要了 那麼首先從這麼大頁面中刪除一塊html 比較費勁

  2. 原來的開發css我們也是按照頁面級別來進行分塊的
    刪除了html部分 也要找到對應的css部分刪除

  3. 原來的開發js我們也是按照頁面級別來進行分塊的
    刪除html部分 也要找到對應js部分進行刪除

總結: 也就是說 我們所有內容都是互相依賴 互相耦合度比較高的程式碼,所以vue推出了元件化的概念

元件化:

把html+css+js單獨封裝成一個標籤內容
例如: <lunbo></lunbo> 就會呈現一個輪播圖,有html 有css 同樣也就js。

所以元件化開發的優點/意義:

讓頁面結構看起來更清晰 很方便的修改頁面元素,頁面的組合顯得更簡單。

全域性元件的建立

Vue的元件分為全域性元件和區域性元件

全域性元件的註冊:

Vue.component("元件的標籤名",{
    元件的鍵值對配置(template屬性 methods屬性  data屬性)
})
<div id="app">
  <h1>當前是vm物件掛載的目標</h1>
<!--    引用全域性元件-->
  <aaa></aaa>
  <aaa></aaa>
</div>

<div id="app1">
  <h1>當前是vm1物件掛載的目標</h1>
  <aaa></aaa>
</div>
Vue.component("aaa",{
  //template定義當前元件的頁面內容
  // template:"<h1>我是aaa元件</h1>"
  template:"<ul><li>我是新聞1</li><li>我是新聞2</li><li>我是新聞3</li></ul>"
})
var vm=new Vue({
  el:'#app',
  data:{ }
});

var vm1=new Vue({
  el:"#app1"
})

區域性元件的建立

在vue的$options裡面定義:

components:{
    元件的標籤名:{
        template屬性 methods屬性  data屬性
    }
}
<div id="app">
  <h1>{{msg}}</h1>
  <aaa></aaa>
  <bbb></bbb>
</div>

<div id="app1">
  <h1>{{msg}}</h1>
  <!-- 報錯 因為aaa和bbb是vm的區域性元件
  <aaa></aaa>
  <bbb></bbb>-->
</div>
var vm=new Vue({
  el:'#app',
  data:{msg:"我是vm的掛載目標"},
  components:{
    aaa:{
      template:"<h1>我是aaa元件的內容</h1>"
    },
    bbb:{
      template:"<h2>我是bbb元件的內容</h2>"
    }
  }
});

var vm1=new Vue({
  el:"#app1",
  data:{
      msg:"我是vm1掛載的目標"
  }
})

元件的資料和事件的渲染

<div id="app">
  <aaa ></aaa>
<!--
  <aaa ></aaa>
  <aaa ></aaa>
  <aaa ></aaa>
-->
  <bbb></bbb>
</div>

全域性元件的資料和事件的使用:

Vue.component("元件的標籤名",{
  template:"元件的模板",
  methods:{
    元件的驅動函式
  },
  data:function(){
    return{
      元件的資料
    }
  }
})
Vue.component("aaa",{
  template:"<h1 @click='show'>我是aaa元件---{{msg}}</h1>",
  data:function(){
    return {msg:"我是元件變數"}
  },
  methods:{
    show(){alert("點我aaa幹嘛")}
  }
})
Vue.component("aaa",{
  template:"<h1 @click='show'>我是aaa元件---{{msg}}</h1>",
  data:function(){
    return {msg:"我是元件變數"},
  methods:{
    show(){alert("點我aaa幹嘛")}
  }
})

想要給元件繫結資料和事件 就要操作元件的template裡面
因為只有元件的template才是元件真正頁面所在位置

區域性元件的資料和事件的使用:

在Vue的$options裡面定義

components:{
  元件標籤名:{
    template:"元件的模板",
    data:function(){
      return{
        元件的資料
      }
    },
    methods:{
      元件的驅動函式
    }
  }
}
var vm=new Vue({
  el:'#app',
  data:{msg:"HelloWorld!"},
  components:{
    bbb:{
      template:"<h2 @click='show'>我是bbb元件---{{msg}}</h2>",
      data(){
        return {msg:"我是bbb元件的資料"}
      },
      methods:{
        show(){alert("點我bbb幹嘛")},
      },
    },
  },
});

相關文章