Vue基础
数据双向绑定

- 表单单选控制checkbox选中
![image]()
<!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.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div>
用户名<input type="text" v-model="username">---->{{username}}
<br>
用户密码<input type="text" v-model="pwd">---->{{pwd}}
<br>
记住密码<input type="checkbox" v-model="radio"> <!--选择框让绑定一个变量变量的值是布尔值 成立则选择不成了则不选中-->
<input type="text" v-model="name">----->{{name}}
</div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{username:'',
pwd:'',
radio:false,
name:'薛飞飞'
}
})
</script>
</body>
</html>
- 单选
- 单选通过value来控制radio的值控制显示
<!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">
<input type="radio" v-model="radio" value="男">男
<input type="radio" v-model="radio" value="女">女
<input type="radio" v-model="radio" value="保密">保密
<br><br>您选择的性别:{{radio}}
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
radio: '',
},
})
</script>
</html>

- 多选
![image]()
![image]()
<!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">
<input type="checkbox" v-model="many" value="篮球">篮球
<input type="checkbox" v-model="many" value="足球">足球
<input type="checkbox" v-model="many" value="棒球">棒球
<input type="checkbox" v-model="many" value="桌球">桌球
<br><br>您喜欢的球类:{{many}}
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
many: [],
},
})
</script>
</html>
全选购物车案列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
</head>
<body>
<!--赶紧跑公司好坑-->
<div id="app">
<div class="col-md-6 col-md-offset-3">
<h1>购物车</h1>
<table class="table table-striped">
<thead>
<tr>
<th>商品名</th>
<th>价格</th>
<th>数量</th>
<th>全选/全不选 <input type="checkbox" v-model="checkAll" @change="handleCheckAll"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in dataList">
<th scope="row">{{item.name}}</th>
<td>{{item.price}}</td>
<td><span @click="item.number++" class="btn">+</span>{{item.number}}<span class="btn"
@click="reduceNum(item)">-</span>
</td>
<td><input type="checkbox" v-model="checkGroup" :value="item" @change="handleOne"></td>
</tr>
</tbody>
</table>
价格:{{getPrice()}}
<br>
选中商品:{{checkGroup}}
<br>
<!-- {{checkAll}}-->
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
dataList: [
{name: '特斯拉', price: 3000000, number: 30},
{name: '众横四海', price: 46000000, number: 2},
{name: '苹果14pro', price: 8888, number: 14},
{name: '水杯', price: 9.9, number: 33},
],
checkGroup: [],
checkAll: false
},
methods: {
getPrice() {
var total = 0
for (i = 0; i < this.checkGroup.length; i++)
total += this.checkGroup[i].price * this.checkGroup[i].number
return total
},
handleCheckAll() {
if (this.checkAll) {
this.checkGroup = this.dataList
} else {
this.checkGroup = []
}
}
,
handleOne() {
if (this.checkGroup.length === this.dataList.length) {
this.checkAll = true
} else {
this.checkAll = false
}
}
,
reduceNum(item) {
if (item.number <= 1) {
alert('不能再减少了,亏本了')
} else {
item.number--
}
}
}
})
</script>
</body>
</html>

v-model进阶(了解)
lazy:等待input框的数据绑定时区焦点之后再变化
number:数字开头,只保留数字,后面的字母不保留;字母开头,都保留
trim:去除首位的空格

4 vue生命周期
官方原图

解析图


var vm=new Vue实例()
-1 实例创建,数据放到实例中
-2 挂在模板:el---》div
-3 改页面,改变量,都会相互影响 update
-4 销毁实例
4个过程,对应八个函数,依次执行(到某个过程就会执行某个函数)
beforeCreate 创建Vue实例之前调用,data,el都没有
created 创建Vue实例成功后调用(可以在此处发送异步请求后端数据),data有了,el没有的
beforeMount 渲染DOM之前调用 ,data有了,el没有
mounted 渲染DOM之后调用
beforeUpdate 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染)
updated 重新渲染完成之后调用
beforeDestroy 销毁之前调用
destroyed 销毁之后调用
- mount
挂载,把div挂载到组件中
![image]()
- update
修改组件内容
![image]()
- mounted(用得最多)
- 这时候可以向后端发送数据了
5 钩子函数(hook) AOP的体现:面向切面编程--》装饰器实现aop
6 vm实例:看不到它销毁 组件vc
7 组件:组件化开发
8 学习生命周期重点掌握的
-1 组件向后端发送请求,获取数据,应该放在 created 写,此时data已经有数据了
-2 destroyed做一些资源清理性的工作
9 小案例:组件创建,开启定时器,不停的打印hello,在destroyed中对定时器进行销毁
-补充:js 定时任务和延时任务
# 延时任务
setTimeout(()=>{
console.log('3s后执行我')
},3000)
#定时任务
setInterval(()=>{
console.log('hello')
},3000)
10 什么场景下用定时任务?
1 实时跟后端交互 基于http+定时任务 (websocket协议:服务端主动推送消息,手机app的消息推送)
2 秒杀场景:先提交秒杀请求,每隔3s,查询是否秒到
测试代码
<!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">
<child v-if="isShow"></child>
<br>
<button @click="terminate">删除子组件</button>
<button @click="reborn">显示子组件</button>
</div>
</body>
<script>
Vue.component('child', {
template: `
<div>
{{name}}
<button @click="name='Darker1'">更新数据1</button>
<button @click="name='Darker2'">更新数据2</button>
</div>`,
data() {
return {
name: 'Darker1',
}
},
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)
},
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')
},
})
let vm = new Vue({
el: '#box',
data: {
isShow: true
},
methods: {
terminate() {
this.isShow = false
},
reborn() {
this.isShow = true
}
}
})
</script>
</html>
5与后端交互
与后端交互
-js原生发送ajax请求:new HMLHTTPRequest(),浏览器兼容性不好,于是jquery基于它封装出
了jquery的ajax的方法,XMLHTTPRequest很多漏洞
1-jquery的ajax Vue中很少使用
handelclick() {
alert('正在向后端要数据')
$.ajax({
url: 'http://127.0.0.1:8000/index/',
type: 'get',
data: '',
success: data => { //data就是后端传入的数据是对象
this.username = data.name
this.age = data.age
}
})
},

2-js原生提供了fetch,官方主推,ie浏览器不支持
handelclick1() {
alert('正在向后端要数据')
fetch('http://127.0.0.1:8000/index/').then(res1=>res1.json()).then(res=>{
console.log(res) // 将数据传给res1 然后转换之后再次传给第二个res返回的是真实的数据对象
console.log('res1类型是',typeof (res1))
console.log('res类型是',typeof (res))
console.log(res.name,res.age)
this.username1=res.name
this.age1=res.age
})
}

3-axios:vue中常用方法,他也是封装HMLHTTPRequest
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <!--第三方axios模块-->
handelclick2() {
alert('正在向后端要数据')
axios.get('http://127.0.0.1:8000/index/').then(res => {
console.log(res)
this.username2 = res.data.name;
this.age2 = res.data.age
})
// 倒入第三方模块 直接使用get请求.get post 请求.post即可括号内写个地址
},

朝后端请求数据代码演示
后端
class IndexView(APIView):
def get(self, request):
# res = {'name': 'lqz', 'age': 18}
res = Response({'name': 'lqz', 'age': 18})
# res = JsonResponse({'name': 'lqz', 'age': 18})
res['Access-Control-Allow-Origin'] = '*' # 后端跨域请求需要在请求头中携带此参数 否则无法发送请求可以配置文件配置
return res
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <!--第三方axios模块-->
</head>
<body>
<div id="app">
<div>
<h1>jquery阿贾克斯后端获取数据</h1>
<button @click="handelclick">点我朝后端要数据</button>
<br>
<p>username----->: <span v-text="username"></span></p>
<p>age----->:<span v-text="age"></span></p>
</div>
<div>
<h1>js原生fetch朝后端获取数据</h1>
<button @click="handelclick1">点我朝后端要数据</button>
<br>
<p>username1----->: <span v-text="username1"></span></p>
<p>age1----->:<span v-text="age1"></span></p>
</div>
<div>
<h1>axios第三方朝后端获取数据</h1>
<button @click="handelclick2">点我朝后端要数据</button>
<br>
<p>username2----->: <span v-text="username2"></span></p>
<p>age2----->:<span v-text="age2"></span></p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
username: '',
age: '',
username1: '',
age1: '',
username2: '',
age2: ''
}, methods: {
handelclick() {
alert('正在向后端要数据')
$.ajax({
url: 'http://127.0.0.1:8000/index/',
type: 'get',
data: '',
success: data => {
console.log('data类型是', typeof (data))
this.username = data.name
this.age = data.age
}
})
},
handelclick1() {
alert('正在向后端要数据')
fetch('http://127.0.0.1:8000/index/').then(res1 => res1.json()).then(res => {
console.log(res) // 将数据传给res1 然后转换之后再次传给第二个res返回的是真实的数据对象
console.log('res1类型是', typeof (res1))
console.log('res类型是', typeof (res))
console.log(res.name, res.age)
this.username1 = res.name
this.age1 = res.age
})
},
handelclick2() {
alert('正在向后端要数据')
axios.get('http://127.0.0.1:8000/index/').then(res => {
console.log(res)
this.username2 = res.data.name;
this.age2 = res.data.age
}) // 倒入第三方模块 直接使用get请求.get post 请求.post即可括号内写个地址
},
}
})
</script>
</html>


跨域请求可在配置文件中配置需要下载第三方库
# 1、安装第三方库 django-cors-headers
# 2、在settings.py中添加'corsheaders.middleware.CorsMiddleware',在SessionMiddleware和CommonMiddleware的中间
# 3、在INSTALLED_APPS里添加“corsheaders”
INSTALLED_APPS = [
'search.apps.SearchConfig',
'data.apps.DataConfig',
'record_data.apps.RecordDataConfig',
'deleted_data.apps.DeletedDataConfig',
'mgmt.apps.MgmtConfig',
'c_test.apps.CTestConfig',
'rest_framework',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders', # 新增
]
# 4、在中间件中添加corsheaders.middleware.CorsMiddleware,django.middleware.common.CommonMiddleware
MIDDLEWARE = [
# 'utils.middleware.ExceptionMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # 新增/必须在common中间件上面
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 5、在settings.py底部增加
CORS_ALLOW_CREDENTIALS = True # 允许携带cookie
CORS_ORIGIN_ALLOW_ALL = True # 放行所有
CORS_ORIGIN_WHITELIST = ('*') # 白名单
# CORS_ALLOW_METHODS:字符串列表,允许用哪些HTTP请求方法。
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
# CORS_ALLOW_HEADERS:字符串列表,允许使用哪些非标准HTTP请求头。
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)






浙公网安备 33010602011771号