vue 的8个生命周期钩子函数
钩子函数 | 描述 |
---|---|
beforeCreate | 创建Vue实例之前调用 |
created | 创建Vue实例成功后调用(可以在此处发送异步请求后端数据) |
beforeMount | 渲染DOM之前调用 |
mounted | 渲染DOM之后调用 |
beforeUpdate | 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染) |
updated | 重新渲染完成之后调用 |
beforeDestroy | 销毁之前调用 |
destroyed | 销毁之后调用 |
create
let vm = new Vue()
let vm = new Vue({
el: '#box',
data: {
isShow: true // 修改这个内容
},
methods: {
handleClick() {
console.log('我是根组件')
}
}
})
destroyed
组件销毁 - 给组件写一个定时器
setTimeout() // 延迟3s干什么事
setInterval() // 延迟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: `
{{name}}
`,
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>
1 向后端发送ajax请求
2 三种方式
- 之前学过jq的ajax函数
$.ajax({})
- fetch:原生的,不需要导入js文件 (不是所有浏览器都支持,谷歌浏览器支持)
- axios:vue中用的最多的
polyfill: https://github.com/camsong/fetch-ie8
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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>
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def index():
res = make_response('hello world')
# 运行所有域向我发请求(解决跨域问题)
res.headers['Access-Control-Allow-Origin']='*'
return res
if __name__ == '__main__':
app.run()
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="./js/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">
<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() {
//发送请求
// axios.get('http://127.0.0.1:5000/').then(res => {
// // res.data才是真正后端返回的响应体中的内容
// console.log(res.status)
// this.data_list = res.data.data.films
//
// })
axios({
url: 'http://127.0.0.1:5000/',
methods: 'get',
}).then(res => {
// res.data才是真正后端返回的响应体中的内容
console.log(res.status)
this.data_list = res.data.data.films
})
}
},
mounted() {
this.get_data()
},
})
script>
html>
计算缓存 VS methods-计算属性是基于它们的依赖进行缓存的。
-计算属性只有在它的相关依赖发生改变时才会重新求值
计算属性优点
1 在同一个页面中使用多次计算属性,不会多次执行
2 不需要加括号,直接使用
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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>
<br>
计算属性:您输入的是:{{upper_name}}
<br>
计算属性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>Titletitle>
<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>
Vue2.0 v-for 中 :key 有什么用呢?
1 v-for循环的时候,经常看到有个自定义属性 key
2 key是一个唯一值,为了虚拟dom替换的时候,效率高
Vue的两大核心:1.数据驱动界面改变,2.组件化
什么是组件?什么是组件化?
在前端开发中组件就是把一个很大的界面拆分为多个小的界面,每一个小的界面就是一个组件
将大界面拆分成小界面就是组件化
组件化的好处:
可以简化Vue实例的代码
可以提高复用性
-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
-组件把js,css,html放到一起,有逻辑,有样式,有html
Vue中如何创建组件?
创建组件构造器
注册已经创建好的组件
使用注册好的组件
全局组件:整个项目中都能使用的组件
局部组件:只能再局部使用
通过
Vue.component
来创建组件
组件可以有data,methods,computed…,但是data 必须是一个函数
Vue.component('my-component-name', {
// ... 选项 ...
})
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="./js/vue.js">script>
head>
<body>
<div id="app">
<myheader>myheader>
<div>我是divdiv>
<myheader>myheader>
div>
body>
<script>
// 定义一个全局组件
//组件可以有data,methods,computed....,但是data 必须是一个函数
Vue.component('myheader', {
template: `
我是全局组件:{{name}}
`,
data(){
return {
name:'lqz'
}
},
methods:{
handleClick(){
alert('美女')
}
},
mounted(){},
computed:{
}
})
var vm = new Vue({
el: '#app',
data: {},
})
script>
html>
在components
选项中定义你想要使用的组件:
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="./js/vue.js">script>
head>
<body>
<div id="app">
<myheader>myheader>
<div>我是divdiv>
<myheader>myheader>
<div>div>
div>
body>
<script>
Vue.component('myheader', {
template: `
我是全局组件:{{name}}
`,
data(){
return {
name:'lqz'
}
},
methods:{
handleClick(){
alert('美女')
}
},
mounted(){},
computed:{
},
components:{
child:{
template: `
{{age}}
`,
data(){
return {
age:19
}
},
methods:{
}
}
}
})
var vm = new Vue({
el: '#app',
data: {},
})
script>
html>
1 父子组件传值 (props down, events up)
2 父传子之属性验证props:{name:Number}Number,String,Boolean,Array,Object,Function,null(不限制类型)
3 事件机制a.使用 $on(eventName) 监听事件b.使用 $emit(eventName) 触发事件
4 Ref<input ref="mytext"/> this.$refs.mytext
5 事件总线var bus = new Vue();* mounted生命周期中进行监听
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="./js/vue.js">script>
head>
<body>
<div id="app">
<myheader :myname="name" :myshow="false">myheader>
{{obj.length}}
div>
body>
<script>
Vue.component('myheader', {
template: `
我是全局组件:{{myname}}
{{myshow}}
`,
data(){
return {
name:'lqz'
}
},
methods:{
handleClick(){
alert('美女')
}
},
mounted(){},
computed:{
},
components:{
child:{
template: `
{{age}}
`,
data(){
return {
age:19
}
},
methods:{
}
}
},
// props:['myname'] , //注册一下
// 属性验证
props:{
myname:String,
myshow:Boolean
},
})
var vm = new Vue({
el: '#app',
data: {
name:'egon'
},
})
script>
html>
this.$emit('myEvent') //自定义事件
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="js/vue.js">script>
head>
<body>
<div id="box">
<navbar @myevent="handleEvent">navbar>
div>
body>
<script>
// 定义全局组件
Vue.component('navbar', {
template: `
我是navbar
`,
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>Titletitle>
<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: `
我是navbar
`,
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放在标签上,拿到的是原生节点
ref放在组件上,拿到的是组件对象,
通过这种方式实现子传父(this.$refs.mychild.text)
通过这种方式实现父传子(调用子组件方法传参数)
<input ref="input">
methods: {
// 用来从父级组件聚焦输入框
focus: function () {
this.$refs.input.focus()
}
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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: `
我是navbar
`,
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>
var bus=new Vue()
Vue.component('child1', {
methods:{
send_msg(){
bus.$emit('suibian',this.msg)
}
}
})
Vue.component('child2', {
mounted(){
bus.$on('suibian',msg=> {
this.recv_msg=msg
})
}
})
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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: `
`,
data() {
return {
msg: ''
}
},
methods:{
send_msg(){
bus.$emit('suibian',this.msg)
}
}
})
Vue.component('child2', {
template: `
我收到的内容是:{{recv_msg}}
`,
data() {
return {
recv_msg:''
}
},
mounted(){
bus.$on('suibian',msg=> {
this.recv_msg=msg
})
}
})
var vm = new Vue({
el: '#box',
data: {},
methods: {}
})
script>
html>
1 <component> 元素,动态地绑定多个组件到它的 is 属性
2 <keep-alive> 保留状态,避免重新渲染
<keep-alive>
<component :is="who">component>
keep-alive>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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: `
首页
`,
data() {
return {}
},
})
Vue.component('User', {
template: `
用户组件
`,
data() {
return {
name: ''
}
},
})
Vue.component('Order', {
template: `
订单页面
`,
data() {
return {}
},
})
var vm = new Vue({
el: '#box',
data: {
who: 'Home'
},
})
script>
html>
a. 单个slot
b. 具名slot
*混合父组件的内容与子组件自己的模板-->内容分发
*父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="js/vue.js">script>
head>
<body>
<div id="box">
<Home>aaaHome>
<Order>
<button slot="b" @click="handleClick">我是个按钮button>
Order>
div>
body>
<script>
Vue.component('Home', {
template: `
首页
`,
data() {
return {}
},
})
Vue.component('Order', {
template: `
订单页面
我是一行数据
`,
data() {
return {}
},
})
var vm = new Vue({
el: '#box',
data: {
who: 'Home'
},
methods:{
handleClick(){
console.log('我被点了')
}
}
})
script>
html>