一、表單控制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="div">
<h1>表單控制</h1>
<hr>
<p>用戶名:<input type="text" v-model="username"></p>
<p>密碼:<input type="password" v-model="password"></p>
<p>
性別:<br>
男:<input type="radio" v-model="gender" value="1">
女:<input type="radio" v-model="gender" value="2">
</p>
<p>記住密碼:<input type="checkbox" v-model="set_pwd"></p>
<p>
愛好:<br>
運動:<input type="checkbox" v-model="hobby" value="運動">
健身:<input type="checkbox" v-model="hobby" value="健身">
旅游:<input type="checkbox" v-model="hobby" value="旅游">
</p>
<button @click="handleSubmit">提交</button>
</div>
<script>
var vm = new Vue({
el:'#div',
data:{
username:'',
password:'',
gender:'',// radio單選,多個radio綁定同一個變量,選中某個,就對應(yīng)value值
set_pwd:false,// checkbox 單選是true或false
hobby:[],// checkbox 多選是數(shù)組類型,必須一開始定義就是數(shù)組,多個checkbox綁定一個變量
},
methods:{
handleSubmit(){
console.log(this.username,this.password,this.gender,this.set_pwd,this.hobby)
}
}
})
</script>
</body>
</html>
二、購物車案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="../js/vue.js"></script>
<style>
#table{
margin-top:50px;
margin-bottom:30px;
}
input[type='checkbox']{
cursor:pointer;
}
.btn{
border:1px solid rgb(138, 138, 138);
}
</style>
</head>
<body>
<div id="div" class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<h1 class="text-center" id="table">購物車商品結(jié)算清單</h1>
<table class="table table-hover table-bordered">
<thead>
<tr>
<th class="text-center">商品id</th>
<th class="text-center">商品名</th>
<th class="text-center">商品價格</th>
<th class="text-center">商品數(shù)量</th>
<th class="text-center">
全選or全不選 <input type="checkbox" v-model="xuan" @change="CheckAll">
</th>
<th class="text-center">刪除加購</th>
</tr>
</thead>
<tbody>
<tr v-for="data in shoplist">
<td class="text-center">{{data.id}}</td>
<td class="text-center">{{data.name}}</td>
<td class="text-center">{{data.price}}</td>
<td class="text-center">
<span @click="CheckRemove(data)" class="btn">-</span>
<span v-if="nm_count==true" @click="qieh">{{data.count}}</span>
<input v-else type="number" class="form-control-static" @change="number(data)" v-model="data.count" @blur="qieh">
<span @click="CheckAdd(data)" class="btn">+</span>
</td>
<td class="text-center">
<input type="checkbox" @change="Checkxuan" v-model="Bymore" :value="data">
</td>
<td class="text-center"><button class="btn btn-danger" @click="CheckDel(data)">刪除</button></td>
</tr>
</tbody>
</table>
<h5>當前選中商品:{{Bymore}}</h5>
<h3>購物車結(jié)算金額為:¥{{CountPrice()}}</h3>
</div>
</div>
</div>
<script>
var vm = new Vue({
el:'#div',
data:{
xuan:false,
shoplist:[
{id:1,name:'巧克力',price:66,count:5},
{id:2,name:'奶糖',price:3,count:8},
{id:3,name:'辣條',price:6,count:4},
{id:4,name:'果汁',price:9,count:55},
{id:5,name:'薯片',price:12,count:33},
],
Bymore:[],
nm_count:true,
},
methods:{
CountPrice(){ //對勾選物品進行實時總價格計算
var total = 0
for(var item of this.Bymore){
total += item.price*item.count
}
return total
},
CheckAll(){ //全選或全不選狀態(tài)監(jiān)控
if(this.xuan==true){
this.Bymore=this.shoplist
}else{
this.Bymore=[]
}
},
number(data){ //對coun數(shù)量設(shè)置最少不能小于1
if(data.count<1){
data.count=1
}
},
Checkxuan(){ //對單選進行監(jiān)控,商品全勾選自動給全選勾上,否則不勾
if(this.Bymore.length==this.shoplist.length){
this.xuan=true
}else{this.xuan=false}
},
CheckAdd(data){ //點擊事件,添加商品數(shù)量
data.count++
},
CheckRemove(data){ //點擊事件,減去商品數(shù)量,限制大于1
if (data.count>1){
data.count--
}
},
CheckDel(data){ //點擊對商品列表進行刪除
if(this.shoplist.indexOf(data)>0){
console.log(this.shoplist.splice(this.shoplist.indexOf(data),1))
}
},
qieh(){ //對商品數(shù)量進行自選添加數(shù)量
this.nm_count=!this.nm_count
//console.log(this.nm_count)
}
}
})
</script>
</body>
</html>
三、v-model進階
v-model雙向數(shù)據(jù)綁定,還可以對輸入框數(shù)據(jù)進行一定的限定。
v-modle | 釋義 |
---|---|
lazy | 等待input框的數(shù)據(jù)綁定時區(qū)焦點之后再變化 |
number | 以數(shù)字開頭并只保留后面的數(shù)字,不保留字母;字母開頭都保留 |
trim | 去除首位的空格 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="div">
<h1>v-model進階用法</h1><p/>
默認v-model----><input type="text" v-model="name">------->{{name}}<p/>
lazy----><input type="text" v-model.lazy="name1">------->{{name1}}<p/>
number----><input type="text" v-model.number="name2">------->{{name2}}<p/>
trim----><input type="text" v-model.trim="name3">------->{{name3}}
</div>
<script>
var vm = new Vue({
el:'#div',
data:{
name:'',
name1:'',
name2:'',
name3:'',
},
methods:{
}
})
</script>
</body>
</html>
四、與后端交互
跨域問題解決,三種交互方法
與后端交互統(tǒng)一使用json編碼格式
與后端交互涉及到跨域問題后,該如何解決跨域問題?
- 當前端發(fā)送請求,后端響應(yīng)了,但是前端還是報錯,這是因為:
跨域問題
的存在,瀏覽器檢測到前端與后端不是來自同一個域
,所以認為這是不安全的,最終也就攔截了該資源的傳遞 - 想要解決這個問題,就要實現(xiàn):CORS,也就是跨域資源共享
- 瀏覽器的原因,只要不是向地址欄中的【域:地址和端口】發(fā)送請求,拿到的數(shù)據(jù),瀏覽器就會攔截
- 攔截例子:跨域問題
- 解決:在后端響應(yīng)頭中添加
headers={'Access-Control-Allow-Origin':'*'}
- 瀏覽器的原因,只要不是向地址欄中的【域:地址和端口】發(fā)送請求,拿到的數(shù)據(jù),瀏覽器就會攔截
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script>
<script src="../js/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<title>Document</title>
</head>
<body>
<div id="div">
<h1>jquery的ajax與后端交互</h1><p/>
<!--一般不會在vue中使用jQuery的ajax發(fā)送請求,很多功能用不到-->
<h4>username: {{username}}</h4>
<h4>age:{{age}}</h4>
<button @click="clicksubmit1">點擊獲取數(shù)據(jù)</button>
<p/>
<hr>
<h1>JS的fetch與后端交互</h1>
<!--提供了一個 JavaScript 接口,用于訪問和操縱 HTTP 管道的一些具體部分-->
<h4>username: {{username}}</h4>
<h4>age:{{age}}</h4>
<button @click="clicksubmit2">點擊獲取數(shù)據(jù)</button>
<p/>
<hr>
<h1>axios與后端交互</h1>
<!--第三方ajax,只有ajax沒有別的功能,很小,底層基于XMLHttprequest-->
<h4>username: {{username}}</h4>
<h4>age:{{age}}</h4>
<button @click="clicksubmit3">點擊獲取數(shù)據(jù)</button>
</div>
<script>
var vm = new Vue({
el:'#div',
data:{
username:'',
age:'',
},
methods:{
//方式1:jQuery的ajax方式
clicksubmit1(){
//向后端發(fā)送請求,拿到數(shù)據(jù),賦值給username、age
$.ajax({
url:'http://127.0.0.1:8000/submit/',
method:'get',
success:data=>{
console.log(typeof data)
this.username=data.username
this.age=data.age
}
})
},
//方式2:原生js(fetch)發(fā)送請求
clicksubmit2(){
//向后端發(fā)送請求,拿到數(shù)據(jù),賦值給username、age
// fetch('http://127.0.0.1:8000/submit/')
// .then(function(response){
// return response.json();
// })
// .then(function(data){
// console.log(data);
// });
//箭頭函數(shù)
fetch('http://127.0.0.1:8000/submit/')
.then(response=>{
return response.json();
})
.then(data=>{
this.username=data.username
this.age=data.age
});
},
//方式3:axios
clicksubmit3(){
//向后端發(fā)送請求,拿到數(shù)據(jù),賦值給username、age
axios.get('http://127.0.0.1:8000/submit/')
.then(result => {
console.log(result.data);
this.username=result.data.username
this.age=result.data.age
}).catch(error => {
console.log(error);
});
}
}
})
</script>
</body>
</html>
跨域問題詳解
前端發(fā)送ajax請求,后端會有跨域的攔截,原因是:同源策略。同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響??梢哉fWeb是構(gòu)建在同源策略基礎(chǔ)之上的,瀏覽器只是針對同源策略的一種實現(xiàn)。
-請求的url地址,必須與瀏覽器上的url地址處于同域上,也就是域名,端口,協(xié)議相同.
-發(fā)送ajax請求的地址,必須跟瀏覽器上的url地址處于同域上 域[域名,地址,端口,協(xié)議]
-請求成功,數(shù)據(jù)庫返回,但是瀏覽器攔截
# 補充:瀏覽器中輸入域名,沒有加端口
-www.baidu.com---->dns--->解析成地址 192.168.2.3----》沒有加端口,默認是80
-dns解析,先找本地的host文件
-可以修改本地的host做映射
如何解決跨域問題?
1-CORS:后端代碼控制,上面案例采用的方式
# cors: #xss,csrf---跨站請求偽造
跨域資源共享:后端技術(shù),就是在響應(yīng)頭中加入 固定的頭,就會運行前端訪問了
'CORS基本流程'
1.瀏覽器發(fā)出CORS簡單請求
只需要在頭信息之中增加一個Origin字段。
2.瀏覽器發(fā)出CORS非簡單請求
會在正式通信之前,增加一次HTTP查詢請求,稱為”預(yù)檢”請求(preflight)。
瀏覽器先詢問服務(wù)器,當前網(wǎng)頁所在的域名是否在服務(wù)器的許可名單之中,
以及可以使用哪些HTTP動詞和頭信息字段。
只有得到肯定答復(fù),瀏覽器才會發(fā)出正式的XMLHttpRequest請求,否則就報錯。
'什么是簡單請求,什么是非簡單請求'
# 符合如下條件,就是簡單請求
(1) 請求方法是以下三種方法之一:
HEAD
GET
POST
(2)HTTP的頭信息不超出以下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三個值application/x-www-form-urlencoded、
multipart/form-data、text/plain
'演示簡單和非簡單請求'
-如果是簡單,直接發(fā)送真正的請求
-如果是非簡單,先發(fā)送options,如果運行,再發(fā)真正的
1) 方式一:后端添加請求頭
# 前端發(fā)送axios不添加請求頭---簡單請求
created() {
this.$axios.get(this.$settings.BASE_URL+ '/home/banner/').then(res=>{
console.log(res)
})
},
# 允許的前端地址
return APIResponse(data=res.data, headers={
"Access-Control-Allow-Origin": "http://192.168.1.47:8080"}) # {code:100,msg:成功,data=[{},{}]}
# 允許所有前端地址
return APIResponse(data=res.data,headers={'Access-Control-Allow-Origin':'*'}) # {code:100,msg:成功,data=[{},{}]}
2) 方式二:編寫中間件
解決跨域問題和請求頭攜帶數(shù)據(jù)
# 1.重寫process_response方法
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
def process_response(self, request, response):
if request.method == 'OPTIONS': # 解決非簡單請求的請求頭
response["Access-Control-Allow-Headers"] = "*"
# 允許前端的地址,所有請求頭允許
response["Access-Control-Allow-Origin"] = "*"
return response
# 2. 注冊中間件
MIDDLEWARE = [
'utils.common_middle.CorsMiddleWare'
]
3) 方式三:第三方模塊django-cors-headers
# 第一步:安裝
pip install django-cors-headers
# 第二步:配置app
INSTALLED_APPS = [
'corsheaders'
]
# 第三步:配置中間件
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
]
# 第四步:在配置文件配置
# 允許所有域
CORS_ORIGIN_ALLOW_ALL = True
# 允許的請求方式
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
# 允許請求頭中加的東西
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
'token',
)
2-Nginx反向代理 (常用)
3-JSONP:很老不會用了,它只能發(fā)get請求
4-搭建Node代理服務(wù)器
五、計算屬性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="div">
<h1>計算屬性普通函數(shù)方式------>函數(shù)會重寫計算</h1>
姓名:<input type="text" v-model="name">------>{{getName()}} <p/><br>
<hr>
<p>
<h1>計算屬性Computed</h1>
年齡:<input type="text" v-model="age">------> {{NewAge}}<p/><br>
</div>
<script>
var vm = new Vue({
el:'#div',
data:{
name:'',
age:'',
},
methods:{
//只要頁面刷新(加載頁面),函數(shù)就會執(zhí)行,無論跟函數(shù)是否有關(guān)系
getName(){
console.log('名字首字母大寫了!')
return this.name.substring(0,1).toUpperCase()+this.name.substring(1)
}
},
computed:{
//方法當屬性來用,不加括號,只要computed里面的方法才能不加括號,一定要有返回值
NewAge(){
console.log('計算屬性----執(zhí)行了')
return Number(this.age)+20
}
}
})
</script>
</body>
</html>
1) 重寫過濾案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="div">
<h1>過濾案例重寫使用computed</h1>
<input type="text" v-model="search" >
<ul>
<li v-for="item in NewDatelist">{{item}}</li>
</ul>
</div>
<script>
var vm = new Vue({
el:'#div',
data:{
search:'',
datelist:['a', 'at', 'atom', 'be', 'beyond', 'bee', 'c', 'cs', 'csrf'],
},
computed:{
NewDatelist(){
return this.datelist.filter(item => item.indexOf(this.search) >= 0)
}
}
})
</script>
</body>
</html>
六、監(jiān)聽屬性
監(jiān)聽一個屬性的變化 只要它發(fā)生變化 就執(zhí)行一個函數(shù)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="div">
<h1>監(jiān)聽屬性</h1>
<button @click="type='Python'">Python</button> |
<button @click="type='Java'">Java</button>
<br>
<hr>
{{type}}
</div>
<script>
var vm = new Vue({
el:'#div',
data:{
type:'',
},
watch:{
type(){
console.log('向后端發(fā)送請求')
console.log(this.type)
}
}
})
</script>
</body>
</html>
七、Vue生命周期
對官網(wǎng)的生命周期進行理解注解的
八個生命周期鉤子函數(shù)
函數(shù) | 釋義 |
---|---|
beforeCreate | 創(chuàng)建Vue實例之前調(diào)用 |
created | 創(chuàng)建Vue實例成功后調(diào)用(可以在此處發(fā)送異步請求后端數(shù)據(jù)) |
beforeMount | 渲染DOM之前調(diào)用 |
mounted | 渲染DOM之后調(diào)用 |
beforeUpdate | 重新渲染之前調(diào)用(數(shù)據(jù)更新等操作時,控制DOM重新渲染) |
updated | 重新渲染完成之后調(diào)用 |
beforeDestroy | 銷毀之前調(diào)用 |
destroyed | 銷毀之后調(diào)用 |
從vue實例創(chuàng)建開始直到實例被銷毀,總共經(jīng)歷了8個生命周期鉤子
【只要寫了就會執(zhí)行】
函數(shù)文章來源:http://www.zghlxwxcb.cn/news/detail-811751.html
鉤子:反序列化驗證---》鉤子函數(shù)
學(xué)名[專門名字]---》面向切面編程(AOP)
OOP:面向?qū)ο缶幊?
'用途'
1 頁面加載完成,向后端發(fā)請求拿數(shù)據(jù)
寫在created中 發(fā)送ajax請求
有的人放在mounted中加載(也可以放,不過頁面數(shù)據(jù)已經(jīng)有了,
請求來數(shù)據(jù)更新,就執(zhí)行了Update,效率上不如在created中)
2 組件中有定時任務(wù),組件銷毀,要銷毀定時任務(wù)
beforeDestroy
-組件一創(chuàng)建,created中啟動一個定時器
-組件被銷毀,beforeDestroy銷毀定時器
'補充延時器和定時器'
-定時器
setInterval(()=>{
console.log('每隔3s執(zhí)行')
},3000)
-延時器
setTimeout( ()=>{
console.log('延時器,3s后執(zhí)行')
},3000)
實操案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="div">
<h1>vue生命周期</h1>
<button @click="doubleShow">點擊顯示組件或消失</button>
<hr>
<!--全局組件,自定義-->
<child v-if="show==true"></child>
</div>
<script>
//全局組件
Vue.component('child',{
// 里面寫html內(nèi)容,必須包在一個標簽中
template:`
<div>
<button @click="onClick">點擊更新</button>
<br>
{{title}}
</div>
`,
data(){ // data必須是方法,返回對象
return {
title:'vue生命周期',
t:null,
}
},
methods:{
onClick(){
this.title='新的vue生命周期'
}
},
beforeCreate(){ //組件創(chuàng)建前執(zhí)行,html,js都是空的
console.group('當前狀態(tài):beforeCreate')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
},
Created(){ // 組件創(chuàng)建完畢執(zhí)行,js有值了,但是html還是空的
console.group('當前狀態(tài):Created')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
//創(chuàng)建定時器,每隔3秒打印hello world
this.t=setInterval(()=>{
console.log('hello world')
},3000)
},
beforeMount(){ //掛載模版之前執(zhí)行,js有值了,但是html還是空的
console.group('當前狀態(tài):beforeMount')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
},
mounted(){ //掛載模版完畢執(zhí)行,js有值,html也有了
console.group('當前狀態(tài):mounted')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
},
beforeUpdate(){ //重新渲染之前執(zhí)行,只要頁面發(fā)生變化或js變化就會執(zhí)行
console.group('當前狀態(tài):beforeUpdate')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
},
updated(){ //重新渲染完畢執(zhí)行,
console.group('當前狀態(tài):updated')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
},
beforeDestroy(){ //銷毀之前執(zhí)行,資源清理工作
console.group('當前狀態(tài):beforeDestory')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
},
destroyed(){ //銷毀之后執(zhí)行,
console.group('當前狀態(tài):destroyed')
console.log('當前el狀態(tài):',this.$el)
console.log('當前data狀態(tài):',this.$data)
//銷毀定時器
clearInterval(this.t)
this.t=null
}
})
//根組件
var vm = new Vue({
el:'#div',
data:{
show:false,
},
methods:{
doubleShow(){
this.show=!this.show
}
}
})
</script>
</body>
</html>
文章來源地址http://www.zghlxwxcb.cn/news/detail-811751.html
到了這里,關(guān)于Vue入門三(表單控制|購物車案例|v-model進階|與后端交互|計算屬性|監(jiān)聽屬性|Vue生命周期)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!