vue流程控制 + 事件处理
目录
style和class使用
# class 可以 = 字符串,数组(用的多),对象
new Vue({
el:'#app',
data:{
class_str: 'yellow-back size-100',
class_array: ['yellow-back',],
class_obj: {'pink-back': true, 'size-40': false},
},
methods:{
Click1(){
this.class_str = 'pink-back size-40'
this.class_array = ['pink-back','size-40']
this.class_obj['pink-back'] = false
}
}
})
# style 可以等于 :字符串,数组,对象(用的多)
new Vue({
el:'#app',
data:{
style_str:'font-size: 60px;background-color: aqua',
style_array: [{'font-size': '90px'}, {backgroundColor: 'aqua'}],
style_obj: {'font-size': '90px', backgroundColor: 'aqua'}
},
methods:{
Click1(){
this.style_obj['backgroundColor'] = 'pink'
}
}
})
条件渲染
v-if
v-else-if
v-else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
</style>
</head>
<body>
<div id="app">
您的成绩是:
<p v-if="score>90">优秀</p>
<p v-else-if="score>=60 && score<=90">良好</p>
<p v-else>不及格</p>
</div>
</body>
<script>
var vm=new Vue({
el: '#app',
data: {
score:80
},
})
</script>
</html>
v-for遍历数字,数组,对象
v-for
可以循环数字,字符串,数组,对象
# 循环变量之数字
<p v-for="item in number">数字:{{item}}</p>
# 循环变量之字符串
<p v-for="item in name">字符串循环:{{item}}</p>
# 循环变量之数组----注意循环时,索引是第二个变量
<p v-for="(item,index) in good_list">数组循环:第{{index}}个是{{item}}</p>
# 循环变量之对象----循环key和value,第二个变量是key
<p v-for="(value,key) in obj">对象循环:key值是:{{key}},value值是:{{value}}</p>
key值解释和数组的检测与更新
v-for 循环,key值的解释
# 别人写v-for循环,在标签内部会有一个key属性:
-element-ui:饿了么团队开源的vue的ui组件库
-<el-carousel-item v-for="item in 4" :key="item">
vue中使用的是虚拟DOM,会和原生的DOM进行比较,然后进行数据的更新,提高数据的刷新速度(虚拟DOM用了diff算法)
在v-for循环数组、对象时,建议在控件/组件/标签写1个key属性,【属性值唯一】
页面更新之后,会加速DOM的替换(渲染)
:key="变量"
# 提高页面刷新速度
# 如果要加key属性,一定要设置成唯一的
# 要么干脆不加
数组的检测与更新
# 有时候,我们用一些数组,对象的方法更新数组或对象时,发现页面没有变化
# 使用如下方式更新即可
handleClick5() {
// vm.$set(vm.obj,'xx','uu') 这个可以
Vue.set(vm.obj, 'gender', '未知')
alert('ss')
}
事件处理之过滤案例
input 标签的事件
change
:只要内容发生变化,就会触发
blur
:失去焦点,会触发
input
:只要输入内容,就触发
# 用户名1--input事件:
<input type="text" v-model="name1" @input="handleInput"> --->{{name1}}
# 用户名2--change事件:
<input type="text" v-model="name2" @change="handleChange"> --->{{name2}}
# 用户名3--blur事件:
<input type="text" v-model="name3" @blur="handleBlur"> --->{{name3}}
<script>
var vm = new Vue({
el: '#app',
data: {
name1: '',
name2: '',
name3: ''
},
methods:{
handleInput(){
console.log(this.name1)
},
handleChange(){
console.log(this.name2)
},
handleBlur(){
console.log(this.name3)
}
}
})
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>过滤案例</h1>
<input type="text" v-model="myText" @input="handleInput">
<hr>
<p v-for="item in newList">{{item}}</p>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
myText: '',
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
newList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
},
methods: {
handleInput() {
this.newList = this.dataList.filter(item=> {
// 只要myText在数组中某个字符串中有,就留着,没有就不留
// if (item.indexOf(this.myText) >= 0) {
// return true
// } else {
// return false
// }
return item.indexOf(this.myText) >= 0
})
},
}
})
// 补充1:数组的过滤方法
// var l =['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf']
// var ll=l.filter(function (item){
//
// return false
// })
// console.log(ll)
// 补充2:判断子字符串是否在字符串中 大于等于0,表示子字符串在字符串中
// var name='qq'
// var s='lqz is nb'
// var res=s.indexOf(name)
// console.log(res)
// 补充3 ,es6的箭头函数
// var l = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf']
// var ll = l.filter(item => {
// return false
// })
// console.log(ll)
// var obj = {
// 'f': function (item) {
// console.log(item)
// }
// }
// var obj = {
// 'f': item => 99
//
// }
// obj['f']('999')
//
//
// var f = function (item, key) {
// }
// var f1 = (item, key) => {
// }
</script>
</html>
事件处理之事件修饰符
修饰事件
.stop
只处理自己的事件,父控件冒泡的事件不处理(阻止事件冒泡)
.self
只处理自己的事件,子控件冒泡的事件不处理
.prevent
阻止a链接的跳转
.once
事件只会触发一次(适用于抽奖页面)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>事件修饰符</h1>
<ul @click.self="handleUl">
<li @click="handelLi">第一行</li>
<li>第二行</li>
</ul>
<hr>
<a href="http://www.baidu.com" @click.prevent="handlePrevent">点我看美女</a>
<hr>
<button @click.once="handleOnce">秒杀</button>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
handelLi() {
alert('li被点了')
},
handleUl() {
alert('ul被点了')
},
handlePrevent(){
console.log('a标签被点了,不跳转')
// 跳转
location.href='http://www.cnblogs.com'
},
handleOnce(){
console.log('秒到了')
}
}
})
// 补充1:数组的过滤方法
// var l =['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf']
// var ll=l.filter(function (item){
//
// return false
// })
// console.log(ll)
// 补充2:判断子字符串是否在字符串中 大于等于0,表示子字符串在字符串中
// var name='qq'
// var s='lqz is nb'
// var res=s.indexOf(name)
// console.log(res)
// 补充3 ,es6的箭头函数
// var l = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf']
// var ll = l.filter(item => {
// return false
// })
// console.log(ll)
// var obj = {
// 'f': function (item) {
// console.log(item)
// }
// }
// var obj = {
// 'f': item => 99
//
// }
// obj['f']('999')
//
//
// var f = function (item, key) {
// }
// var f1 = (item, key) => {
// }
</script>
</html>
数据的双向绑定
input 标签的内容发生变化,js变量就发生变化,js变量变化,内容就变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>v-model</h1>
用户名:<input type="text" v-model="name"> --->{{name}}
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: ''
},
})
</script>
</html>
事件处理之按键修饰符
按下或者抬起某个键盘上的键(Enter,Esc),就可以触发某个事件
<div id="app">
// 每一个键都会监听
普通: <input type="text" v-model="myText" @keydown="handleDown($event)">
// 只监听Enter键
监控enter:<input type="text" v-model="myText" @keydown.enter="handleDown1">
</div>
<script>
new Vue({
el:'#app',
data:{
myText:''
},
methods:{
handleDown(event){
console.log(event.key)
},
handleDown1(){
console.log('回车')
}
}
})
</script>
表单控制
checkbox
与radio
<!--checkbox单选(布尔值)-->
<input type="text" placeholder="用户名" v-model="username">
<input type="password" placeholder="密码" v-model="password">
<br>
记住密码: <input type="checkbox" v-model="check_rem">
<!--checkbox单选(布尔值)-->
<br>
<!--checkbox多选(数组)-->
爱好:
<br>
<input type="checkbox" v-model="check_many" value="1">吃
<input type="checkbox" v-model="check_many" value="2">喝
<input type="checkbox" v-model="check_many" value="3">拉
<input type="checkbox" v-model="check_many" value="4">撒
<!--checkbox多选(数组)-->
<br>
<!--radio(字符串)-->
<input type="text" placeholder="用户名" v-model="username">
<input type="password" placeholder="密码" v-model="password">
<br>
性别:
<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}}
<!--radio(字符串)-->
</div>
<script>
new Vue({
el:'#app',
data:{
username:'',
password:'',
check_rem:false,
check_many:[],
gender:''
},
methods:{
}
})
</script>
购物车实例
实现多选
全选
数量加减
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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="row">
<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="all" @change="checkboxAll"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in datalist">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td><button @click="item.number++">+</button>{{item.number}}<button @click="downClick(item)">-</button></td>
<td><input type="checkbox" v-model="Group" :value="item"></td>
</tr>
</tbody>
</table>
<!-- 购物车表单-->
<hr>
总价:{{getPrice()}}
<br>
选中:{{Group}}
</div>
</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
datalist: [
{name: '金梅', price: 99, number: 2},
{name: '钢板', price: 59, number: 1},
{name: '水壶转', price: 89, number: 5},
{name: '特斯拉', price: 230000, number: 3},
],
Group: [],
all:false
},
methods: {
// 总价格计算
getPrice() {
let total = 0
for (i in this.Group) {
total += this.Group[i].price * this.Group[i].number
}
return total
},
// 全选
checkboxAll(){
if(this.all){
this.Group = this.datalist
}else {
this.Group = []
}
},
// 数量减
downClick(item){
if(item.number <= 1){
alert('xxx')
}else {
item.number--
}
}
}
})
</script>
</html>
js的4种for循环
var total = 0
// 循环方式一
for (i = 0; i < this.checkGroup.length; i++) {
total += this.checkGroup[i].price * this.checkGroup[i].number
}
// 循环方式二 forEach 对象,数组的方法
this.checkGroup.forEach(function (value,index){
total+=value.price*value.number
})
// 循环方式三 for in
for (i in this.checkGroup){ // i 是索引
total += this.checkGroup[i].price * this.checkGroup[i].number
}
// 循环方式四 for of
for (item of this.checkGroup) { // item 是索引
total += item.price * item.number
}
return total
v-model进阶
lazy
:等待input框的数据绑定失去焦点之后再变化
number
:数字开头,只保留数字,后面的字母不保留;字母开头,都保留
trim
:去除首位的空格
<div id="app">
<!-- lazy:-->
<input type="text" v-model.lazy="myText"> {{myText}}
<hr>
<!-- number:-->
<input type="text" v-model.number="myText2"> {{myText2}}
<hr>
<!-- trim:-->
<input type="text" v-model.trim="myText3"> {{myText3}}
</div>
<script>
new Vue({
el:'#app',
data:{
myText: '',
myText2: '',
myText3: '',
}
})
</script>
vue生命周期
钩子函数 | 描述 |
---|---|
beforeCreate | 创建Vue实例之前调用 |
created | 创建Vue实例成功后调用(可以在此处发送异步请求后端数据) |
beforeMount | 渲染DOM之前调用 |
mounted | 渲染DOM之后调用 |
beforeUpdate | 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染) |
updated | 重新渲染完成之后调用 |
beforeDestroy | 销毁之前调用 |
destroyed | 销毁之后调用 |
<div id="app">
<button @click="handleShow">点击生成和销毁组件</button>
<child v-if="show"></child>
</div>
<script>
// Vue对象
Vue.component('child', {
template: `
<div>
<h1>{{ name }}</h1>
<button @click="handleClick">点击弹出巨大</button>
</div>
`,
data() {
return {
name: '↓',
t: ''
}
},
methods: {
handleClick() {
alert('xxx')
}
},
// 8个钩子函数
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
this.t=setInterval(()=>{
console.log('3秒计时器')
},3000)
},
beforeMount(){
console.log('beforeMount')
},
mounted(){
console.log('mounted')
},
beforeUpdate(){
console.log('beforeUpdate')
},
updated(){
console.log('updated')
},
beforeDestroy(){
console.log('beforeDestroy')
clearInterval(this.t)
this.t = null
},
destroyed(){
console.log('destroyed')
}
})
new Vue({
el: '#app',
data:{
show:false
},
methods: {
handleShow(){
this.show = !this.show
}
}
})
</script>
vue与后端交互
向后端发送ajax请求
方案一:jq的ajax ----> 在vue中不推荐
方案二:js原始官方 ----> fetch方法
方案三:第三方 ----> axios
handleClick() {
// 发送ajax请求 使用jq的ajax
$.ajax({
'url': 'http://127.0.0.1:5000/index',
'type': 'get',
success: data => {
this.name = data.name
this.age = data.age
}
})
}
handleClick() {
// 发送ajax请求--使用原始的fetch
fetch('http://127.0.0.1:5000/index').then(res => res.json()).then(res => {
console.log(res)
this.name = res.name
this.age = res.age
})
// fetch('http://127.0.0.1:5000/index').then(function (res){return res.json()})
}
handleClick() {
// 发送ajax请求--使用axios
axios.get('http://127.0.0.1:5000/index').then(res => {
console.log(res.data)
this.name = res.data.name
this.age = res.data.age
})
}
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<button @click="ajaxClick">点击向后端发送请求</button>
<br>
{{username}}
<br>
{{addr}}
<br>
{{phone}}
</div>
</body>
<script>
new Vue({
el:'#app',
data:{
username:'xxx',
addr:'xxx',
phone:'xxx'
},
methods:{
ajaxClick(){
// axios
axios.get('http://127.0.0.1:8000/user/').then(res => {
console.log(res.data)
this.username = res.data.name
this.addr = res.data.addr
this.phone = res.data.phone
})
}
}
})
</script>
</html>
后端
# views.py
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
# Create your views here.
class UserView(APIView):
def get(self, request):
return Response({
"name": "一汽大众",
"addr": "芜湖",
"phone": "6666"
}, headers={'Access-Control-Allow-Origin': '*'})
# 需要在响应头中加入 {'Access-Control-Allow-Origin': '*'}
# urls.py
from django.contrib import admin
from django.urls import path
from app01.views import UserView
urlpatterns = [
path('admin/', admin.site.urls),
path('user/',UserView.as_view())
]