Vue生命期钩子,Vue组件
| 钩子函数 | 描述 |
| beforeCreate | 创建Vue示例之前调用 |
| created | 创建Vue实例成功后调用(可以在此处发送异步请求后端数据) |
| beforeMount | 渲染DOM之前调用 |
| mounted | 渲染DOM之后调用 |
| beforeUpdate | 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染) |
| updated | 重新渲染完成之后调用 |
| beforeDestroy | 销毁之前调用 |
| destroyed | 销毁之后调用 |

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> <script src="./js/vue.js"></script> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3" style="margin-top: 20px"> <div id="app"> {{name}} </div> </div> </div> </div> </body> <script> var vm = new Vue({ el: '#app', data: { name:'lqz' }, methods: {}, beforeCreate() { console.log('当前状态:beforeCreate') }, created() { console.log('当前状态:created') }, beforeMount() { console.log('当前状态:beforeMount') }, mounted() { console.log('当前状态:mounted') //用的最多,向后端加载数据,创建定时器等 //挂在,三秒后执行一个任务 // setTimeout(()=> { // console.log('lqz is nb') // },3000) this.t = setInterval(function () { console.log('lqz is nb') }, 3000) }, beforeUpdate() { console.log('当前状态:beforeUpdate') }, updated() { console.log('当前状态:updated') }, beforeDestroy() { console.log('当前状态:beforeDestroy') }, destroyed() { console.log('当前状态:destroyed') clearInterval(this.t) this.t = null console.log('destoryed') }, }) </script> </html>
组件
jquery-ajax、fetch和axios
jquery的ajax(不推荐使用)
fetch(不是所有浏览器都支持,谷歌浏览器支持)
axios(基本都是用它)
前后端交互之jquery-ajax
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<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 class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3" style="margin-top: 20px">
<div id="app">
<button @click="handle_load">点我加载数据</button>
<hr>
拿回来的数据是:{{name}}
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name:'lqz'
},
methods: {
handle_load(){
$.ajax({
url:'http://127.0.0.1:5000/',
type:'get',
success:data=> {
this.name=data
}
})
}
},
mounted() {
//跟后端交互,写在这,而不要使用button
console.log('当前状态:mounted')
this.handle_load()
},
})
</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()
前后端交互之fetch
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="./js/vue.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3" style="margin-top: 20px">
<div id="app">
<ul>
<li v-for="film in films_list">
<img :src="film.poster" alt="" width="60px" height="80px">
<span>{{film.name}}</span>
<hr>
</li>
</ul>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
films_list: []
},
methods: {
handle_load() {
fetch('http://127.0.0.1:5000/home').then(data => data.json()).then(data => {
console.log(data)
if (data.status == 0) {
this.films_list = data.data.films
} else {
alert('加载出错')
}
})
}
},
mounted() {
//跟后端交互,写在这,而不要使用button
console.log('当前状态:mounted')
this.handle_load()
},
})
</script>
</html>
前后端交互之axios
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3" style="margin-top: 20px">
<div id="app">
<ul>
<li v-for="film in films_list">
<img :src="film.poster" alt="" width="60px" height="80px">
<span>{{film.name}}</span>
<hr>
</li>
</ul>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
films_list: []
},
methods: {
handle_load() {
axios.get('http://127.0.0.1:5000/home').then(data => {
//data.data才是后端响应的数据
console.log(data)
if (data.data.status == 0) {
this.films_list = data.data.data.films
} else {
alert('加载出错')
}
})
}
},
mounted() {
//跟后端交互,写在这,而不要使用button
console.log('当前状态:mounted')
this.handle_load()
},
})
</script>
</html>
计算属性
计算属性的特点:只要返回的结果没有发生变化,那么计算属性就只会被执行一次
计算属性的应用场景:由于计算属性会将返回的结果缓存起来,所以如果返回的数据不经常发生变化
那么使用计算属性的性能就会比使用函数的性能高
把输入的首字母大写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="./js/vue.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3" style="margin-top: 20px">
<!-- 这个就是MVVM中的 View -->
<div id="app">
{{name}}
<input type="text" v-model="s">
<hr>
<!-- s.slice 从第0个位置截到第一个位置转成大写,只是第一个字母。还得把后面的字母加上,从第一个截到最后拼上-->
输入的值是:{{s.slice(0,1).toUpperCase()+s.slice(1)}}
<hr>
<!-- 写一个函数,跟上面一样,缺点:只要页面有值变化,它会触发update的执行,
不管是函数还是其它还会再执行一次 -->
输入的值是:{{to_upper()}}
<hr>
输入的值是(计算属性) :{{str_s}}
</div>
</div>
</div>
</div>
</body>
<script>
// 这个就是MVVM中的View Model
var vm = new Vue({
el: '#app',
// 这个就是MVVM中的Model
data: {
s:'',
name:''
},
// 专门用于定义计算属性的
computed:{
str_s(){
// 计算属性的特点:只要返回的结果没有发生变化,那么计算属性就只会被执行一次
//只有该方法中使用的值发生变化,才会重新计算
console.log('计算属性的方法,我执行了')
return this.s.slice(0,1).toUpperCase()+this.s.slice(1)
}
},
//专门用于存储监听事件回调函数
methods:{ // 函数的特点:每次调用都会执行
to_upper(){
console.log('我执行了')
return this.s.slice(0,1).toUpperCase()+this.s.slice(1)
}
},
})
</script>
</html>
重写过滤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="./js/vue.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3" style="margin-top: 20px">
<div id="app">
<p><input type="text" v-model="mytext" @input="handleChange"></p>
<ul>
<li v-for="data in newdatalist">{{data}}</li>
</ul>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
mytext: '',
datalist: ['aaa', 'abc', 'abcde', 'abcdef', 'bbb', 'bac'],
},
computed: {
newdatalist() {
var newlist = this.datalist.filter(item => {
return item.indexOf(this.mytext) > -1
})
return newlist
}
},
})
</script>
</html>
虚拟dom优化问题
1 v-for循环的时候,经常看到有个自定义属性 key
2 key是一个唯一值,为了虚拟dom替换的时候,效率高
组件化开发介绍
Vue的两大核心:1.数据驱动界面改变,2.组件化
什么是组件?什么是组件化?
在前端开发中组件就是把一个很大的界面拆分为多个小的界面,每一个小的界面就是一个组件
将大界面拆分成小界面就是组件化
组件化的好处:
可以简化Vue实例的代码
可以提高复用性
-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
-组件把js,css,html放到一起,有逻辑,有样式,有html
Vue中如何创建组件?
创建组件构造器
注册已经创建好的组件
使用注册好的组件
全局组件:整个项目中都能使用的组件
局部组件:只能再局部使用
注册全局组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<myhead></myhead>
<hr>
<myhead></myhead>
</div>
</body>
<script>
Vue.component('myhead', {
template: `
<div>
<button @click="handleClick">我是个按钮:点我看美女</button>
<button>我又是一个按钮</button>
</div>
`,
methods: {
handleClick(){
alert('美女')
}
},
})
var vm = new Vue({
el: '#app',
data: {},
methods: {
}
})
</script>
</html>
注册局部组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<myhead></myhead>
<hr>
</div>
</body>
<script>
Vue.component('myhead', {
template: `
<div>
<button @click="handleClick">我是个按钮:点我看美女</button>
<button>我又是一个按钮--{{name}}</button>
{{show}}
<hr>
看到美女了
<child></child>
</div>
`,
methods: {
handleClick() {
alert('美女')
}
},
components:{
child:{
template:`
<div>
<img src="./img/1.jpg" alt="" v-show="show" height="60px" width="60px">
<button @click="handleRemove">点我图片消失</button>
</div>
`,
data(){
return {
show:true
}
},
methods:{
handleRemove(){
this.show=!this.show
}
}
}
},
data(){
return {name:'lqz'}
},
})
var vm = new Vue({
el: '#app',
data: {},
methods: {}
})
</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生命周期中进行监听
父传子
在子组件上新增属性 <myhead myname="lqz"></myhead> 在子组件中:定义,myname要跟新增的属性名一致 props:['myname'] 在子组件中就可以使用myname变量了,从父组件传入的 注意加不加:的区别 <myhead :myname="lqz"></myhead>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- <myhead myname="lqz"></myhead>-->
<!-- <hr>-->
<!-- <myhead :myname="name"></myhead>-->
<hr>
<myhead :mybool="false"></myhead>
</div>
</body>
<script>
Vue.component('myhead', {
template: `
<div>
<button>我是按钮</button>
我的名字是:
<br>
传入的布尔值是:{{typeof mybool}}
</div>
`,
// props:['myname','mybool']
//类型限制
props: {
mybool: Boolean,
}
})
var vm = new Vue({
el: '#app',
data: {
name: '迪丽热巴'
},
})
</script>
</html>
通过事件实现子传父
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<myhead @myevent="handleParent" @egon="handleEgon"></myhead>
</div>
</body>
<script>
Vue.component('myhead', {
template: `
<div>
<button @click="handleChild">我是按钮</button>
</div>
`,
data(){
return {
n:100,
m:200
}
},
methods:{
handleChild(){
console.log('子组件的按钮被点击了')
// this.$emit('myevent') //触发自定义的事件执行(触发myevent的执行)
// this.$emit('myevent',this.n,this.m) //触发自定义的事件执行(触发myevent的执行)
// this.$emit('egon')
}
},
mounted(){
this.$emit('egon')
}
})
var vm = new Vue({
el: '#app',
data: {
n:0,
m:0,
},
methods:{
handleParent(n,m){
console.log('自定义的事件执行了')
this.n=n
this.m=m
console.log(n)
console.log(m)
},
handleEgon(){
console.log('egon被打了')
}
}
})
</script>
</html>
通过ref实现父子通信
<!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" placeholder="我是父组件的1" ref="myinput">
<input type="text" placeholder="我是父组件的2" ref="myinput2">
<input type="password" placeholder="我是父组件的3" ref="myinput3">
<button @click="handleParentButton">点我执行一个函数</button>
<hr>
<myhead ref="mychild"></myhead>
</div>
</body>
<script>
Vue.component('myhead', {
template: `
<div>
<button>我是按钮</button>
</div>
`,
data(){
return {
name:'lqz'
}
},
methods:{
tgc(name){
this.name=name
alert(name)
}
},
})
var vm = new Vue({
el: '#app',
data: {
},
methods:{
handleParentButton(){
console.log('父组件的button按钮被点击了')
//
// console.log(this.$refs.myinput3.value)
// console.log(this.$refs.myinput3.type)
console.log(this.$refs.mychild.tgc('lqz is big'))
}
}
})
//ref属性如果加在普通标签上,通过this.$refs.myinput,取到的就是这个标签
//ref属性如果加在组件上,通过this.$refs.mychild,取到的就是这个组件,拿到组件的值,拿到组件的方法,并且可以执行
</script>
</html>
通过事件总线实现组件通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<myhead></myhead>
<hr>
<child1></child1>
</div>
</body>
<script>
// 定义一个事件总线
var bus = new Vue() //new一个vue的实例,就是中央事件总线
Vue.component('myhead', {
template: `
<div>
<button>我是按钮</button>
来自另一个组件的数据: <span v-text="recv"></span>
</div>
`,
mounted() {
//生命周期,当前组件dom创建完后悔执行
console.log('当前组件dom创建完后悔执行')
//订阅消息
bus.$on('suibian', (item) => {
console.log('收到了', item)
this.recv=item
})
},
data(){
return {
recv:''
}
}
})
Vue.component('child1', {
template: `
<div>
<input type="text" v-model="input_1">
<button @click="handleClick">点我</button>
</div>`,
methods: {
handleClick() {
bus.$emit('suibian', this.input_1) //发布消息,名字跟订阅消息名一致
}
},
data(){
return {
input_1:''
}
}
})
var vm = new Vue({
el: '#app',
data: {},
})
//ref属性如果加在普通标签上,通过this.$refs.myinput,取到的就是这个标签
//ref属性如果加在组件上,通过this.$refs.mychild,取到的就是这个组件,拿到组件的值,拿到组件的方法,并且可以执行
</script>
</html>
动态组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="who='myhead1'">显示组件1</button>
<button @click="who='myhead2'">显示组件2</button>
<button @click="who='myhead3'">显示组件3</button>
<keep-alive>
<component :is="who"></component>
</keep-alive>
</div>
</body>
<script>
Vue.component('myhead1', {
template: `
<div>
<button> myhead1的按钮</button>
<div>
我是组件1111的样子
</div>
</div>
`,
})
Vue.component('myhead2', {
template: `
<div>
<button >myhead2的按钮</button>
<div>
我是组件222的样子
<input type="text">
</div>
</div>
`,
})
Vue.component('myhead3', {
template: `
<div>
<button >myhead3的按钮</button>
<div>
我是组件333的样子
<button>点我</button>
<hr>
<span>xxx</span>
</div>
</div>
`,
})
var vm = new Vue({
el: '#app',
data: {
who: 'myhead1'
},
})
//ref属性如果加在普通标签上,通过this.$refs.myinput,取到的就是这个标签
//ref属性如果加在组件上,通过this.$refs.mychild,取到的就是这个组件,拿到组件的值,拿到组件的方法,并且可以执行
</script>
</html>


浙公网安备 33010602011771号