Vue与后端交互,Vue生命周期钩子,Vue组件
0与后端交互三种方式:✨
# 后端写了一堆接口
# 前端会了
#前后端要打通----》从前端发送ajax---》核心:使用js发送http请求,接收返回
-原生js,可以开启ajax,但是原生js开启,比较麻烦,需要做浏览器兼容,有坑(基本不写)
-jq,写了个兼容所有浏览器的 $.ajax(),不仅仅有ajax,还封装了很多dom操作
-如果vue中使用它,不合适
-axios:第三方的ajax包(咱们用)
-fetch: 原生js发送ajax请求,有的浏览器也不兼容
# 写个后端:flask
# pip3 install flask
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def index():
print('来了,老弟')
# 前后端分离后,一定会出跨域---》后面要解决的重点
# 在响应头中加入:Access-Control-Allow-Origin ,就就可以解决跨域
res = jsonify({'name': '彭于晏', 'age': 19})
res.headers = {'Access-Control-Allow-Origin': '*'}
return res
if __name__ == '__main__':
app.run()
0.1 使用jq的ajax
handleLoad() {
// 请求发送成功,后端执行了,但是被浏览器拦截了,因为有跨域问题
// 当前地址,如果向非浏览器地址栏中得地址发送请求,就会出现跨域
// 1 ajax请求方式 1 jquery的ajax
var _this = this
$.ajax({
url: 'http://127.0.0.1:5000',
type: 'get',
success: function (data) {
console.log(typeof data)
var res = JSON.parse(data)
_this.name = res.name
_this.age = res.age
}
})
}
0.2 使用fetch
handleLoad() {
// 2 使用js原生的fetch(目前也不用)
// fetch('http://127.0.0.1:5000').then(function (response) {
// // console.log(response)
// return response.json();
// }).then(function (res) {
// console.log(res);
// });
// 了解,箭头函数一会讲
fetch('http://127.0.0.1:5000').then(res=>res.json()).then(res=>{
console.log(res)
})
}
0.3 使用axios(以后用这个)
handleLoad() {
var _this = this
axios.get('http://127.0.0.1:5000').then(function (res) {
console.log(res.data)
_this.name = res.data.name
_this.age = res.data.age
})
}
箭头函数:
handleLoad() {
axios.get('http://127.0.0.1:5000').then(res=> {
this.name = res.data.name
this.age = res.data.age
})
}
1 计算属性✨
# 1 计算属性是基于它们的依赖变量进行缓存的
# 2 计算属性只有在它的相关依赖变量发生改变时才会重新求值,否则不会变(函数只要页面变化,就会重新运算)
# 3 计算属性就像Python中的property,可以把方法/函数伪装成属性
# 4 计算属性,必须有返回值
1.1 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>实现输入input中后名字首字母大写</h1>
<!-- <input type="text" v-model="username">-–>{{username.substring(0, 1).toUpperCase() + username.substring(1)}}-->
<input type="text" v-model="username">--->{{getUpperCase()}}
<br>
<input type="text" v-model="age">---->{{age}}
<h2>通过计算属性实现--->当属性用</h2>
<input type="text" v-model="username1">--->{{getName}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
username: '',
age: '',
username1: ''
},
methods: {
getUpperCase() {
console.log('函数执行我执行了')
return this.username.substring(0, 1).toUpperCase() + this.username.substring(1)
}
},
computed: {
getName() {
console.log('计算属性执行了')
return this.username1.substring(0, 1).toUpperCase() + this.username1.substring(1)
}
}
})
</script>
</html>
1.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">
<input type="text" v-model="search">
<hr>
<ul>
<li v-for="item in newdataList">{{item}}</li>
</ul>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
search: '',
dataList: ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf'],
},
computed: {
newdataList() {
return this.dataList.filter(item => item.indexOf(this.search) >= 0)
}
}
})
</script>
</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">
<h1>监听属性</h1>
<input type="text" v-model="username"> --->{{username}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
username: '',
},
watch: {
username(newValue, oldValue) {
console.log('老值', oldValue)
console.log('新值', newValue)
console.log('我发生变化了')
}
}
})
</script>
</html>
3 Vue生命周期✨
3.1.官网原图
3.2我理解的图
# new Vue()---->创建出来---》页面关闭---》被销毁掉----》整个整个过程经历了一个周期----》vue帮咱们提供了一些钩子函数[写了就会执行,不写就不执行],到某个阶段,就会触发某个函数的执行
# 8 个生命周期钩子函数
| 钩子函数 | 描述 |
| ------------- | ----------------------------- |
| beforeCreate | 创建Vue实例之前调用 |
| created | 创建Vue实例成功后调用(可以在此处发送异步请求后端数据) |
| beforeMount | 渲染DOM之前调用 |
| mounted | 渲染DOM之后调用 |
| beforeUpdate | 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染) |
| updated | 重新渲染完成之后调用 |
| beforeDestroy | 销毁之前调用 |
| destroyed | 销毁之后调用 |
# vue实例有生命周期,每个组件也有这8个生命周期
# 8个声明周期钩子,什么情况会用到
-created:用的最多,变量初始化完成了(data中得数据),在这里,我们发送ajax请求
-beforeDestroy:组件销毁之前会执行
-组件创建,就执行一个定时任务[每隔1s,打印一个helloworld]
-组件销毁,定时任务要销毁,如果定时任务不销毁,会一直执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>生命周期钩子</h1>
<input type="text" v-model="username"> --->{{username}}
<h1>使用组件</h1>
<button @click="handleShow">显示组件,隐藏组件</button>
<hr>
<child v-if="show"></child>
<hr>
</div>
</body>
<script>
// 组件有自己的html,css,js,事件。。。。
// `` 模板字符串,es6语法
// 在组件中,data必须是个函数,返回对象
//1 定义一个全局组件
Vue.component('child', {
template: `
<div>
<button @click="back">后退</button>
{{ name }}
<button @click="forword">前进</button>
</div>`,
data() {
return {
name: '首页',
t: null
}
},
methods: {
back() {
alert('后退了')
},
forword() {
alert('前进了')
}
},
beforeCreate() {
console.log('beforeCreate')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
created() {
console.log('created')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
// 启动一个定时器
this.t = setInterval(() => {
console.log('hello world')
}, 1000)
},
beforeMount() {
console.log('beforeMount')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
mounted() {
console.log('mounted')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
beforeUpdate() {
console.log('beforeUpdate')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
updated() {
console.log('updated')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
beforeDestroy() {
console.log('beforeDestroy')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
// 销毁定时器
clearInterval(this.t)
this.t = null
},
destroyed() {
console.log('destroyed')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
})
var vm = new Vue({
el: '#app',
data: {
username: '',
show: false
},
methods: {
handleShow() {
this.show = !this.show
}
}
// beforeCreate() {
// console.log('beforeCreate')
// },
// created() {
// console.log('created')
// },
// beforeMount() {
// console.log('beforeMount')
// },
// mounted() {
// console.log('mounted')
// },
// beforeUpdate() {
// console.log('beforeUpdate')
// },
// updated() {
// console.log('updated')
// },
// beforeDestroy() {
// console.log('beforeDestroy')
// },
// destroyed() {
// console.log('destroyed')
// },
})
</script>
</html>
4 组件介绍和使用✨
4.0 组件是什么?有什么用?
组件就是:扩展 HTML 元素,封装可重用的代码,目的是复用
例如:有一个轮播图,可以在很多页面中使用,一个轮播有js,css,html
组件把js,css,html放到一起,有逻辑,有样式,有html
组件的分类:
* 全局组件:可以放在根中,可以在所有组件中使用
* 局部组件:只能在当前组件中使用
4.1 定义全局组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>组件的使用</h1>
<hr>
<child></child>
<hr>
<h1>第二次出现</h1>
<child></child>
</div>
</body>
<script>
//1 定义一个全局组件,vue2中,组件必须在一个标签中
Vue.component('child', {
template: `
<div>
<button @click="back">后退</button>
{{ title }}
<button>前进</button>
</div>
`,
data() {
return {
title: '我是首页'
}
},
methods: {
back() {
console.log('退了')
}
}
})
/
var vm = new Vue({
el: '#app',
data: {},
})
</script>
</html>
注意点:
-
- 定义的组件(body中的位置)必须要放在Vue实例(这也是一个组件 根组件)中
-
- 局部组件 必须放在 全局组件/根组件 中,无法单独使用
-
- 定义的组件必须在Vue实例的上方
4.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">
<h1>组件的使用</h1>
<lqz></lqz>
</div>
</body>
<script>
//
var lqz={
template: `
<div>
<h1>我是局部组件</h1>
<img :src="url" alt="" height="400px">
</div>`,
data() {
return {
url: 'http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg'
}
},
methods: {}
}
// 根组件
var vm = new Vue({
el: '#app',
data: {},
// 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用
components: {
lqz
}
})
</script>
</html>
最后:
- 1 全局组件是使用Vue.component定义的,可以在全局任意组件中使用
- 2 局部组件是定义在某个组件内的:components,只能用在当前组件中
- 3 组件可以嵌套定义和使用
- 4 扩展:elementui,提供给咱们很多全局组件
5 组件间通信✨
# 组件嵌套,
-父组件被数据传递给子组件
-自定义属性
-1 在子组件中自定义属性,使用属性指令绑定父组件的变量
-2 在子组件中,使用props接受 ['属性名','属性名2']
-3 在子组件中,使用属性名即可
-子组件把数据传递给父组件
-自定义事件
-1 父组件中自定义事件:<lqz @myevent="handelEvent"></lqz>
-2 子组件中只要执行 this.$emit('myevent'),就会触发自定义事件对应的函数
5.1 组件间通信值父传子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>组件的使用</h1>
<hr>
<lqz :url="url" :myshow="true"></lqz>
<hr>
</div>
</body>
<script>
// 2
var lqz = {
template: `
<div>
<h1>我是局部组件</h1>
<img :src="url" alt="" height="400px">
<button @click="handleCheck">点我看myshow类型</button>
</div>`,
data() {
return {}
},
methods: {
handleCheck() {
console.log(this.myshow)
console.log(typeof this.myshow)
}
},
props: ['url', 'myshow']
}
// 根组件
var vm = new Vue({
el: '#app',
data: {
url: 'http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg',
},
// 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用
components: {
lqz,
}
})
</script>
</html>
5.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">
<h1>组件的使用</h1>
接受到的子组件输入的内容是:{{username}}
<hr>
<lqz @myevent="handelEvent"></lqz>
<hr>
</div>
</body>
<script>
// 2
var lqz = {
template: `
<div>
<h1>我是局部组件</h1>
<img :src="url" alt="" height="400px">
<br>
<input type="text" v-model="username">
<button @click="handleSend">传递到父组件</button>
</div>`,
data() {
return {
url: 'http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg',
username: ''
}
},
methods: {
handleSend() {
// 传递给父组件
this.$emit('myevent', this.username)
}
}
}
// 根组件
var vm = new Vue({
el: '#app',
data: {
username: ''
},
methods: {
handelEvent(username) {
console.log('父组件自定义事件的event执行了')
console.log(username)
this.username = username
}
},
// 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用
components: {
lqz,
}
})
</script>
</html>
补充:
# 以后前后端分离
-前端是前端(小程序)
-后端是后端,完全没联系
-后端只写接口,没有template和static
-media 要有
6 ref属性✨
# ref属性,vue提供的,写在标签上
可以写在普通标签:在vue中使用 this.$refs.名字 拿到dom对象,可以原生操作
可以写在组件上:在vue中使用 this.$refs.名字 拿到[组件]对象,组件属性,方法直接使用即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>ref属性放在普通标签上</h1>
<input type="text" v-model="username" ref="myinput">
<br>
<img src="http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg" alt="" height="300px" ref="myimg">
<h1>ref放在组件上</h1>
<hr>
<lqz ref="mylqz"></lqz>
<hr>
<button @click="handleClick">点我执行函数</button>
<br>
{{username}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
username: ''
},
methods: {
handleClick() {
console.log(this.$refs)
// 通过key,取到标签,拿到原生dom,通过dom操作,控制标签
// this.$refs.myinput.value = 'lqz'
// this.$refs.myimg.src='https://img2.woyaogexing.com/2021/09/22/3c686eb61fe34696840c478584b73d36!400x400.jpeg'
// 放在组件上---》现在在父组件中,能拿到子组件对象,对象中的属性和方法直接用即可
console.log(this.$refs.mylqz)
// this.$refs.mylqz.title = 'sb'
// this.username=this.$refs.mylqz.title
this.$refs.mylqz.handleBack()
}
},
components: {
lqz: {
template: `
<div>
<button @click="handleBack">后退</button>
{{ title }}
<button>前进</button>
</div>`,
data() {
return {
title: "首页"
}
},
methods: {
handleBack() {
alert('后退了')
}
}
}
}
})
</script>
</html>
合集:
Vue
分类:
python从入门到入狱
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能