mysql約束、資料備份
前端目前形勢
前端發展史
1.HTML
(5)、CSS
(3)、JavaScript
(ES5、ES6):編寫一個個的頁面 -> 給後端(PHP、Python、Go、Java) -> 後端嵌入模板語法 -> 後端渲染完資料 -> 返回資料給前端 -> 在瀏覽器中檢視
2.Ajax的出現 -> 後臺傳送非同步請求,Render
+Ajax
混合
3.單用Ajax(載入資料,DOM渲染頁面):前後端分離的雛形
4.Angular框架的出現(1個JS框架):出現了“前端工程化
”的概念(前端也是1個工程、1個專案)
5.React、Vue框架:當下最火的2個前端框架(Vue
:國人喜歡用,React
6.移動開發(Android+IOS) + Web(Web+微信小程式+支付寶小程式) + 桌面開發(Windows桌面):前端 -> 大前端
7.一套程式碼在各個平臺執行(大前端):谷歌Flutter(Dart語言:和Java很像)
可以執行在IOS、Android、PC端
8.在Vue框架的基礎性上 uni-app:一套編碼 編到10個平臺
9.在不久的將來 ,前端框架可能會一統天下
介紹
Vue (讀音 /vjuː/
,類似於 view) 是一套用於構建使用者介面的漸進式框架
與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用
Vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合
漸進式框架
可以一點一點地使用它,只用一部分,也可以整個工程都使用它
網站
特點
- 易用
- 通過HTML、CSS、JavaScript構建應用
- 靈活
- 不斷繁榮的生態系統,可以在一個庫和一套完整框架之間自如伸縮
- 高效
- 20kB min+gzip 執行大小
- 超快虛擬DOM
- 最省心的優化
M-V-VM思想
介紹
MVVM 是Model-View-ViewModel
的縮寫,它是一種基於前端開發的架構模式,是一種事件驅動程式設計方式
Model
:vue物件的data屬性裡面的資料View
:vue中資料要顯示的HTML頁面,在vue中,也稱之為“檢視模板” (HTML+CSS)ViewModel
:vue中編寫程式碼時的vm物件,它是vue.js的核心,負責連線 View 和 Model資料的中轉,保證檢視和資料的一致性,所以前面程式碼中,data裡面的資料被顯示中p標籤中就是vm物件自動完成的(雙向資料繫結:JS中變數變了,HTML中資料也跟著改變)
特性
- 低耦合:
檢視
(View)可以獨立於Model變化和修改
,1個ViewModel可以繫結到不同的View上,當View變化的時候 Model可以不變,當Model變化的時候 View也可以不變 - 可複用:可以把一些檢視邏輯放在1個ViewModel中,讓很多View
重用這端檢視的邏輯
(以此減少程式碼冗餘) - 獨立開發:
開發
人員可以專注於業務邏輯
和資料的開發
(ViewModel),設計
人員可以專注於頁面設計
- 可測試:介面元素是比較難以測試的,而現在的測試可以
針對ViewModel
來編寫
MVVM的邏輯
元件化開發、單頁面開發
類似於DTL中的include,每一個元件的內容都可以被替換和複用
單頁面開發
- 只需要一個頁面,結合元件化開發來替換頁面中的內容
- 頁面的切換隻是元件的替換,頁面還是隻有一個index.html
版本
- 1.X:使用得較少
- 2.X:普遍使用
- 3.X:剛出沒多久,只有Beta版
引入方式
-
CDN的方式引入
-
下載後匯入
補充
- 解釋型的語言是需要直譯器的
- nodejs:一門後端語言
使用
模板語法
{{變數、js語法}}
指令之文字指令
v-html # 讓HTML字串渲染成標題
v-text # 標籤內容顯示js變數對應的值
v-show # 放一個布林值:為真 標籤就顯示;為假,標籤就隱藏
v-if # 放一個布林值:為真 標籤就顯示;為假,標籤就隱藏(刪除)
指令之事件指令
v-on:事件 # 觸發事件(不推薦)
@事件 # 觸發事件(推薦)
@[event] # 觸發event事件(可以是其他任意事件)
Style與Class
資料的繫結
:屬性名 = js變數/js語法
class: 字串、三目運算子、陣列、物件{red:true}
:class='js變數、字串、js陣列'
style: 字串、三目運算子、陣列[{backgreound:'red'}]、物件{red:true}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.cls_obj_red{
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<!-- <p :class="cls_obj">阿巴阿巴</p>-->
<!-- <p :style="style_obj">滴滴答答</p>-->
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
// cls_obj:{cls_obj_red:true}
// cls_obj:['cls_obj_red']
// cls_obj:'cls_obj_red'
// style_obj:'background-color:red'
// style_obj:[{backgroundColor:'red'},]
// style_obj:{backgroundColor:'red'}
}
})
</script>
</body>
</html>
條件渲染
指令 | 釋義 |
---|---|
v-if | 相當於: if |
v-else | 相當於:else |
v-else-if | 相當於:else if |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.cls_obj_red{
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<p v-if="show">嘀哩嘀哩</p>
<p v-if="type==1">1</p>
<p v-else-if="type==2">2</p>
<p v-else-if="type==3">3</p>
<p v-else="">Boom!</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
show:true,
type:1
}
})
</script>
</body>
</html>
列表渲染
v-if + v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div id="app">
<button @click="shopping_click" class="btn btn-primary">嗶哩嗶哩</button>
<table class="table table-hover table-striped">
<thead>
<tr>
<th>編號</th>
<th>商品名</th>
<th>單價</th>
</tr>
</thead>
<tbody>
<tr v-if="shopping.length==0">
<td>售罄</td>
<td>售罄</td>
<td>售罄</td>
</tr>
<tr v-else v-for="value,key in shopping">
<td>{{key+1}}</td>
<td>{{value.name}}</td>
<td>{{value.price}}</td>
</tr>
</tbody>
</table>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
shopping:[]
},
methods:{
shopping_click(){
this.shopping=[
{id:1,name:'小包子', price:188},
{id:2,name:'包子', price:288},
{id:3,name:'大包子', price:388}
]
}
}
})
</script>
</body>
</html>
v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="bootstrap.min.css">
<style>
.cls_obj_red{
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<p v-for="name in names">id:{{name.cid}} name: {{name.name}} age: {{name.age}}</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
names:[
{cid:1, name:'jerry', age:18},
{cid:2, name:'tom', age:19},
{cid:3, name:'嗶哩嗶哩', age:20}
]
}
})
</script>
</body>
</html>
陣列更新與檢測
<!--vue中使用的是虛擬DOM, 會和原生的DOM進行比較, 然後進行資料的更新,提高資料的重新整理速度(虛擬DOM用了diff演算法)-->
一定會觸發DOM的比較,如果有資料變了,頁面沒變,使用該方法賦值 ↓
Vue.set(vm.class_obj, 'background', true)
過濾
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div id="app">
<input type="text" @input="changeData" v-model="search" >
<p v-for="value in new_list">{{value}}</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
search:'',
list:['a', 'ab', 'b', 'bs'],
new_list:['a', 'ab', 'b', 'bs']
},
methods: {
changeData(){
this.new_list = this.list.filter(item=>{
return item.indexOf(this.search)>-1
})
}
}
})
</script>
</body>
</html>
事件修飾符
事件修飾符 | 釋義 |
---|---|
.stop | 只處理自己的事件,父控制元件冒泡的事件不處理(阻止事件冒泡) |
.self | 只處理自己的事件,子控制元件冒泡的事件不處理 |
.prevent | 阻止a連結的跳轉 |
.once | 事件只會觸發一次(適用於抽獎頁面) |
使用修飾符時,順序很重要,相應的程式碼會以同樣的順序產生
@click.prevent.self :會阻止所有的點選
@click.self.prevent :只會阻止對元素自身的點選
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件修飾符</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
<!-- <ul @click="handleUl">-->
<ul @click.self="handleUl">
<!-- <li v-for="data in dataList" @click="handleLi">{{data}}</li>-->
<li v-for="data in dataList" @click.stop="handleLi">{{data}}</li>
<li><a href="http://www.baidu.com">不攔截</a></li>
<li><a href="http://www.baidu.com" @click="handleLink($event)">點選攔截</a></li>
<li><a href="https://www.baidu.com" @click.prevent="handleLink">點選攔截</a></li>
<li><button @click.once="test">只執行一次</button></li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
dataList: ['1','22','333','4444']
},
methods: {
handleUl(ev){
console.log('ul被點選了')
},
handleLi(){
console.log('li被點選了')
ev.stopPropagation() // 點選事件停止 冒泡(向父元件傳遞時間)
},
handleLink(ev){
ev.preventDefault()
},
test(){
alert('只觸發1次')
}
}
})
</script>
</html>
資料的雙向繫結(v-model的使用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div id="app">
<input type="text" v-model="test">{{test}}
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
test:'',
}
})
</script>
</body>
</html>
按鍵修飾符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按鍵修飾符</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="name" @keyup="handelKey1">
<input type="text" v-model="name" @keyup.enter="handelKey2">
<!-- <button @click="handelClick">點我</button>-->
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: ''
},
methods: {
handelKey1(ev) {
console.log(ev)
if (ev.keyCode == 13) {
console.log('按下了回車')
}
},
handelKey2() {
console.log('回車鍵按下了')
},
handelClick(ev) {
console.log(ev)
}
}
})
</script>
</html>
表單控制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表單控制</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>checkbox的選中與不選中</h1>
<p>使用者名稱: <input type="text" v-model="name"></p>
<p>密碼: <input type="password" v-model="password"></p>
<p><input type="checkbox" v-model="isRem">記住密碼</p>
<button @click="submit">登入</button>
<hr>
<h1>性別單選:radio</h1>
<input type="radio" v-model="gender" value="1">男
<input type="radio" v-model="gender" value="2">女
<input type="radio" v-model="gender" value="3">其他
<br>
您選擇的性別是:{{gender}}
<hr>
<h1>愛好多選:checkbox</h1>
<input type="checkbox" v-model="hobby" value="1">籃球
<br>
<input type="checkbox" v-model="hobby" value="2">足球
<br>
<input type="checkbox" v-model="hobby" value="3">美女
<br>
您的愛好是:{{hobby}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: '',
password: '',
isRem: false,
gender: '',
hobby:[],
},
methods: {
submit() {
console.log(this.name)
console.log(this.password)
console.log(this.isRem)
}
}
})
</script>
</html>
購物車案例(全選、數量加減)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div id="app">
<table class="table-hover table table-striped">
<thead>
<tr>
<th>商品名</th>
<th>單價</th>
<th>數量</th>
<th>選擇 <input type="checkbox" v-model="allCheck" @change="allChange"></th>
</tr>
</thead>
<tbody>
<tr v-for="shop in shop_list">
<td>{{shop.name}}</td>
<td>{{shop.price}}</td>
<td><button class="btn btn-primary" @click="click_down(shop)">-</button>{{shop.num}}<button class="btn btn-primary" @click="shop.num++">+</button></td>
<td><input type="checkbox" :value="shop" v-model="check_list" @change="oneChange"></td>
</tr>
</tbody>
</table>
總價為: {{get_price()}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
shop_list:[
{name:'嗶哩', price:123, num:2},
{name:'書', price:323, num:3},
{name:'滴滴', price:223, num:4},
],
check_list:[],
allCheck:false
},
methods:{
get_price(){
let total = 0
if (this.check_list.length > 0){
for (i in this.check_list){
total += this.check_list[i].num * this.check_list[i].price
}
}
return total
},
allChange(){
if (this.allCheck){
this.check_list = this.shop_list
}else {
this.check_list=[]
}
},
oneChange(){
if (this.check_list.length === this.shop_list.length){
this.allCheck = true
}else {
this.allCheck = false
}
},
click_down(shop){
if (shop.num >1){
shop.num --
}else {
shop.num = 1
}
}
}
})
</script>
</body>
</html>
v-model進階
- .lazy :並不是實時改變,而是在失去焦點或者按回車時才會更新
- .number :將輸入轉換成Number型別
- .trim :可以自動過濾輸入首尾的空格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model進階</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- <input type="text" v-model.lazy="name"> 輸入內容是:{{name}}-->
<!-- <input type="text" v-model.number="name"> 輸入內容是:{{name}}-->
<input type="text" v-model.trim="name"> 輸入內容是:{{name}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: ''
},
})
</script>
</html>
Vue生命週期鉤子
鉤子函式 | 描述 |
---|---|
beforeCreate | 建立Vue例項之前呼叫 |
created | 建立Vue例項成功後呼叫(可以在此處傳送非同步請求後端資料) |
beforeMount | 渲染DOM之前呼叫 |
mounted | 渲染DOM之後呼叫 |
beforeUpdate | 重新渲染之前呼叫(資料更新等操作時,控制DOM重新渲染) |
updated | 重新渲染完成之後呼叫 |
beforeDestroy | 銷燬之前呼叫 |
destroyed | 銷燬之後呼叫 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model進階</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- <child v-if="isShow"></child>-->
</div>
</body>
<script>
//定義一個元件
Vue.component('child', {
template: `
<div>
{{name}}
<br>
{{age}}
<button @click="name='Darker1'">更新資料1</button>
<button @click="name='Darker2'">更新資料2</button>
</div>`,
data() {
return {
name: 'Darker1',
age: 19
}
},
beforeCreate() {
console.group('當前狀態:beforeCreate')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
},
created() {
console.group('當前狀態:created')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
},
beforeMount() {
console.group('當前狀態:beforeMount')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
},
mounted() {
console.group('當前狀態:mounted')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
//用的最多,向後端載入資料,建立定時器等
console.log("頁面已被vue例項渲染, data, methods已更新");
console.log('mounted')
this.t = setInterval(function () {
console.log('daada')
}, 3000)
clearInterval(this.t)
},
beforeUpdate() {
console.group('當前狀態:beforeUpdate')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
},
updated() {
console.group('當前狀態:updated')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
},
beforeDestroy() {
console.group('當前狀態:beforeDestroy')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
},
destroyed() {
console.group('當前狀態:destroyed')
console.log('當前el狀態:', this.$el)
console.log('當前data狀態:', this.$data)
console.log('當前name狀態:', this.name)
//元件銷燬,清理定時器
clearInterval(this.t)
this.t = null
console.log('destoryed')
},
})
var vm = new Vue({
el: '#app',
data: {
isShow: true
},
methods:{
init(){
console.log('init')
},
},
mounted() {
console.log('mounted執行;了')
//ajax向後端獲取資料
this.init()
},
})
</script>
</html>
與後端互動的幾種方式
向後端傳送ajax請求
三種方式
- jQuery的ajax
- fetch(原生)
- axios(用的最多)
jQuery的ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-for="data in data_list">
<h3>{{data.name}}</h3>
<img :src="data.poster" alt="">
<h5>導演:{{data.director}}</h5>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
data_list: []
},
methods: {
get_data() {
//傳送請求
// let _this=this
$.ajax({
url: 'http://127.0.0.1:5000/',
type: 'get',
success: (data) => {
let data_obj=JSON.parse(data)
// console.log(typeof data_obj)
this.data_list = data_obj.data.films
}
// success: function (data) {
// // console.log(data)
// _this.data_list = data
// }
})
}
},
mounted() {
this.get_data()
},
})
</script>
</html>
fetch(原生)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-for="data in data_list">
<h3>{{data.name}}</h3>
<img :src="data.poster" alt="">
<h5>導演:{{data.director}}</h5>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
data_list: []
},
methods: {
get_data() {
//傳送請求
fetch("http://127.0.0.1:5000/").then(res => res.json()).then(res => {
console.log(res.data.films)
this.data_list = res.data.films
})
}
},
mounted() {
this.get_data()
},
})
</script>
</html>
axios(用的最多)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<div v-for="data in data_list">
{[ data.name ]}
<img :src="data.poster" alt="">
{[ data.director ]}
{[ data.synopsis ]}
</div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
data_list:[]
},
delimiters:['{[', ']}'],
methods:{
get_data(){
axios({
url:'http://127.0.0.1:8090/index/',
methods:'get'
}).then(res=>{
this.data_list = res.data.data.films
})
}
},
mounted(){
this.get_data()
}
})
</script>
</body>
</html>
計算屬性
優點
- 在同一個頁面中使用多次計算屬性,不會多次執行
- 不需要加括號,直接使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model='name'>
<br>
您輸入的是:{{get_name()}}
<br>
您輸入的是2:{{get_name()}}
<hr>
<!-- 您輸入的是:{{name.substring(0,1).toUpperCase()+name.substring(1)}}-->
<!-- 計算屬性優點-->
<!-- 1 在同一個頁面中使用多次計算屬性,不會多次執行-->
<!-- 2 不需要加括號,直接使用-->
<br>
計算屬性:您輸入的是:{{upper_name}}
<br>
計算屬性2:您輸入的是:{{upper_name}}
計算屬性2:您輸入的是:{{upper_name}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name:''
},
computed:{
upper_name(){
console.log('計算屬性我執行了')
return this.name.substring(0,1).toUpperCase()+this.name.substring(1)
},
},
methods:{
get_name(){
console.log('get_name我執行了')
return this.name.substring(0,1).toUpperCase()+this.name.substring(1)
},
}
})
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model='search'>
<div v-for="data in new_list">
{{data}}
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
search: '',
data_list: ['aaa', 'abc', 'abcde', 'abcdef', 'bbb', 'bac']
},
computed: {
new_list() {
return this.data_list.filter(item => {
return item.indexOf(this.search) > -1
})
}
},
methods: {}
})
</script>
</html>
虛擬dom和diff演算法
其實呢不只是vue,react中在執行列表渲染時也會要求給每個元件新增key這個屬性。
key簡單點來說就是唯一標識,就像ID一樣唯一性
要知道,vue和react都實現了一套虛擬DOM,使我們可以不直接操作DOM元素,只操作資料便可以重新渲染頁面。而隱藏在背後的原理便是其高效的Diff演算法。
只做同層級的對比
按照key值比較,出現新的key就插入
通元件對比
具體實現
把樹按照層級分解
同key值比較
通元件對比
<div id="box">
<div v-if="isShow">111</div>
<p v-else>222</p>
<!--
{tag:div,value:111}
{tag:p,value:222}
直接不比較,直接刪除div,新增p
-->
<div v-if="isShow">111</div>
<div v-else>222</div>
<!--
{tag:div,value:111}
{tag:div,value:222}
比較都是div,只替換文字內容
-->
</div>
詳細:https://segmentfault.com/a/1190000020170310
元件
- 介紹
- 全域性元件
- 區域性元件
- 組建通訊之父傳子
介紹
1 元件的作用
擴充套件 HTML 元素,封裝可重用的程式碼,目的是複用
例如:
有一個輪播圖,可以在很多頁面中使用,一個輪播有js,css,html
元件把js,css,html放到一起,有邏輯,有樣式,有html
2 元件分類:區域性元件和全域性元件
全域性元件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<myheader></myheader>
<div>我是div</div>
<myheader></myheader>
</div>
</body>
<script>
// 定義一個全域性元件
// 元件可以有data,methods,computed....,但是data 必須是一個函式
Vue.component('myheader', {
template: `
<div>
<h1 style="background-color: greenyellow">我是全域性元件:{{name}}</h1>
<button @click="handleClick">點我彈出美女</button>
</div>
`,
data(){
return {
name:'lqz'
}
},
methods:{
handleClick(){
alert('美女')
}
},
mounted(){},
computed:{
}
})
var vm = new Vue({
el: '#app',
data: {},
})
</script>
</html>
區域性元件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<myheader></myheader>
<div>我是div</div>
<myheader></myheader>
<div></div>
</div>
</body>
<script>
// 定義一個全域性元件
//元件可以有data,methods,computed....,但是data 必須是一個函式
Vue.component('myheader', {
template: `
<div>
<h1 style="background-color: greenyellow">我是全域性元件:{{name}}</h1>
<button @click="handleClick">點我彈出美女</button>
<hr>
<child></child>
</div>
`,
data(){
return {
name:'lqz'
}
},
methods:{
handleClick(){
alert('美女')
}
},
mounted(){},
computed:{
},
components:{
child:{
template: `<div>
<span>{{age}}</span>
</div>`,
data(){
return {
age:19
}
},
methods:{
}
}
}
})
var vm = new Vue({
el: '#app',
data: {},
})
</script>
</html>
組建通訊之父傳子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<myheader :myname="name" :myshow="false"></myheader>
{{obj.length}}
</div>
</body>
<script>
// 定義一個全域性元件
//元件可以有data,methods,computed....,但是data 必須是一個函式
Vue.component('myheader', {
template: `
<div>
<h1 style="background-color: greenyellow">我是全域性元件:{{myname}}</h1>
<button @click="handleClick">點我彈出美女</button>
<br>
{{myshow}}
<hr>
<child v-if=""></child>
</div>
`,
data(){
return {
name:'lqz'
}
},
methods:{
handleClick(){
alert('美女')
}
},
mounted(){},
computed:{
},
components:{
child:{
template: `<div>
<span>{{age}}</span>
</div>`,
data(){
return {
age:19
}
},
methods:{
}
}
},
// props:['myname'] , //註冊一下
// 屬性驗證
props:{
myname:String,
myshow:Boolean
},
})
var vm = new Vue({
el: '#app',
data: {
name:'egon'
},
})
</script>
</html>
組建通訊之子傳父(通過自定義事件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<navbar @myevent="handleEvent"></navbar>
</div>
</body>
<script>
// 定義全域性元件
Vue.component('navbar', {
template: `
<div>
<h1>我是navbar</h1>
<hr>
<input type="text" v-model="name">
<br>
<button @click="handleClick">我是子元件的button</button>
</div>
`,
data() {
return {
name: 'lqz'
}
},
methods: {
handleClick() {
// 觸發父元件中myevent這個自定義事件對應的函式執行
this.$emit('myevent',this.name)
}
}
})
var vm = new Vue({
el: '#box',
data: {},
methods: {
handleEvent(name) {
console.log('我執行了')
console.log('從子元件傳遞的name:'+name)
}
}
})
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<navbar @myevent="handleEvent" v-if="myshow"></navbar>
</div>
</body>
<script>
// 定義全域性元件
Vue.component('navbar', {
template: `
<div>
<h1>我是navbar</h1>
<hr>
<button @click="handleClick">點我隱藏子元件</button>
</div>
`,
data() {
return {
// myshow: true
}
},
methods: {
handleClick() {
// 觸發父元件中myevent這個自定義事件對應的函式執行
// this.myshow = !this.myshow
this.$emit('myevent', false)
}
}
})
var vm = new Vue({
el: '#box',
data: {
myshow: true
},
methods: {
handleEvent(show) {
this.myshow = show
}
}
})
</script>
</html>
ref屬性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
ref放在標籤上,拿到的是原生節點
<br>
ref放在元件上,拿到的是元件物件(資料,方法,直接使用即可)
<hr>
<h1>ref用在標籤上</h1>
<input type="text" ref="myinput">
<button @click="handleClick">點我觸發事件</button>
<hr>
<h1>ref用在元件上</h1>
<navbar ref="mynavbar"></navbar>
</div>
</body>
<script>
// 定義全域性元件
Vue.component('navbar', {
template: `
<div>
<h3>我是navbar</h3>
<hr>
</div>
`,
data() {
return {
myshow: true
}
},
methods: {
handleClick(a) {
console.log('父元件呼叫我,傳入了:'+a)
}
}
})
var vm = new Vue({
el: '#box',
data: {
myshow: true
},
methods: {
handleClick() {
//this.$refs 取到一個物件,放著你在標籤上寫得ref對應的value值
//在父元件中直接取到了子元件的值(從子傳到父)
// console.log(this.$refs.mynavbar.myshow)
//從父傳子
// this.$refs.mynavbar.myshow='sss'
//呼叫子元件方法
this.$refs.mynavbar.handleClick('lqz')
}
}
})
</script>
</html>
事件匯流排
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<child1></child1>
<hr>
<child2></child2>
</div>
</body>
<script>
// 藉助事件匯流排,實現跨元件通訊
//定義一個事件匯流排
var bus=new Vue()
Vue.component('child1', {
template: `
<div>
<input type="text" v-model="msg">
<button @click="send_msg">傳送</button>
<hr>
</div>
`,
data() {
return {
msg: ''
}
},
methods:{
send_msg(){
bus.$emit('suibian',this.msg)
}
}
})
Vue.component('child2', {
template: `
<div>
<h5>我收到的內容是:{{recv_msg}}</h5>
</div>
`,
data() {
return {
recv_msg:''
}
},
mounted(){
bus.$on('suibian',msg=> {
this.recv_msg=msg
})
}
})
var vm = new Vue({
el: '#box',
data: {},
methods: {}
})
</script>
</html>
動態元件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<button @click="who='Home'">首頁</button>
<button @click="who='User'">使用者</button>
<button @click="who='Order'">訂單</button>
<keep-alive>
<component :is="who"></component>
</keep-alive>
</div>
</body>
<script>
Vue.component('Home', {
template: `
<div>
首頁
</div>
`,
data() {
return {}
},
})
Vue.component('User', {
template: `
<div>
使用者元件
<input type="text" v-model="name">
</div>
`,
data() {
return {
name: ''
}
},
})
Vue.component('Order', {
template: `
<div>
訂單頁面
</div>
`,
data() {
return {}
},
})
var vm = new Vue({
el: '#box',
data: {
who: 'Home'
},
})
</script>
</html>
插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<Home>阿斯頓傳送到</Home>
<Order>
<button slot="b" @click="handleClick">我是個按鈕</button>
</Order>
</div>
</body>
<script>
Vue.component('Home', {
template: `
<div>
首頁
<div>
<slot></slot>
</div>
</div>
`,
data() {
return {}
},
})
Vue.component('Order', {
template: `
<div>
訂單頁面
<slot name="a"></slot>
<br>
我是一行資料
<br>
<slot name="b"></slot>
</div>
`,
data() {
return {}
},
})
var vm = new Vue({
el: '#box',
data: {
who: 'Home'
},
methods:{
handleClick(){
console.log('我被點了')
}
}
})
</script>
</html>
Vue-CLI 搭建vue專案
1 ECMAScript,javascript,nodejs的關係
2 安裝nodejs(安裝直譯器)
3 java:sun---》oracle(甲骨文)----》有些包,收費
-安卓使用java開發,涉及到版權
-jdk:java開發工具包,做java開發,需要安裝它 1.5 1.8大更新 java 15
-jre:java執行環境,
-jvm:java虛擬機器,最少要佔200m記憶體空間
4 安裝node,一路下一步
node:就是python命令
npm:就是python的pip命令,npm下載模組慢,我們使用cmpm下載
cnpm:阿里提供的
npm install -g cnpm --registry=https://registry.npm.taobao.org
5 安裝vue腳手架
cnpm install -g @vue/cli
6 多出vue命令
vue create my-project: 創建出一個vue專案,等同於djagnoadmin createproject 名字
# OR
vue ui
7 開發
-使用pycharm開發vue專案
-裝vue外掛
8 執行起專案
-terminal中:npm run serve
vue專案目錄介紹
myfirstvue # 專案名
-node_modules # 該專案所有的依賴,如果要把專案給別人,這個資料夾要刪掉(很大)
-public # 資料夾
-favicon.ico #小圖示
-index.html # 整個vue專案的index.html,單頁面開發
-src # 核心
-store # 如果裝了vuex,就會有這個資料夾
-router #如果裝了vue router ,就會有這個資料夾
-assets # 存放資原始檔(js,css,img)
-components # 小元件(在這寫小元件)
-views #頁面元件(在這寫頁面元件)
main.js # 整個專案的入口,核心配置
App.vue # 根元件
-package.json # 專案的依賴,不能刪
-README.md # 介紹
vue元件介紹
每個元件有三部分組成
template:寫html
script:寫js
style:寫css
<template>
<div class="about">
<h1>寫html</h1>
</div>
</template>
<script>
js程式碼
</script>
<style>
css程式碼
</style>
vue-router的使用
1 以後,新建一個頁面元件,寫三部分
2 在router下的index.js內配置一下
const routes = [
{ // / 路徑,顯示Home這個頁面元件
path: '/',
name: 'Home',
component: Home
},
{
path: '/order',
name: 'Order',
component: Order
},
{
path: '/about',
name: 'About',
// component: () => import('../views/About.vue')
component: About,
}
]
3 在根vue中寫
<div id="app">
<router-view/>
</div>
4 以後要跳轉到某個頁面
<router-link to="/路徑">
<button>點我跳轉到order</button>
</router-link>
在專案中新建元件和使用
1 在components資料夾建立一個 xx.vue
2 在其他元件中使用
-在scripts中
import HelloWorld from '../components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
}
}
3 在html中直接使用
<HelloWorld/>
js匯入匯出語法(瞭解)
1 有一些變數,函式,想在其他地方都用,可以寫成一個包
新建一個資料夾,在資料夾中寫index.js
在內部寫函式,寫變數,最後一定要匯出
var name='lqz'
function add(a,b) {
return a+b
}
export default {
name,
add
}
2 在想用的位置,匯入使用即可
import xx from '../lqz'
console.log(xx.add(1,2))
使用axios
1 安裝 cnpm install axios
2 匯入使用
import axios from 'axios'
axios.get('api/index/').then(res => {})
前端代理
1 vue.config.js中module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true
}
}
},
}
2 使用axios傳送請求
mounted() {
axios.get('api/index/').then(res => {
console.log(res.data)
this.data_list = res.data.data.films
})
}
bootstrap和jq的使用
1 安裝
cnpm install jquery
cnpm install bootstrap@3
2 配置vue.config.js中
const webpack = require("webpack");
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
"window.$": "jquery",
Popper: ["popper.js", "default"]
})
]
}
};
3 main.js中
import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css'
elementui的使用
1 安裝
cnpm install element-ui -S
2 main.js中配置
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
願君前程似錦,歸來仍是少年