既昨天的内容继续往下。
四、Watch(熟悉)
watch的作用可以监控一个值的变换,并调用因为变化需要执行的方法。可以通过watch动态改变关联的状态。
简单点说,就是实时监听某个数据的变化。
1、普通监听
<template>
<div class="home">
<input type="text" v-model="msg">
<h3>{{msg}}</h3>
</div>
</template>
<script>
export default {
name: 'Home',
data(){
return {
msg: "你好,世界"
}
},
watch: {
msg(val, oldVal){
console.log(val, oldVal)
}
}
}
</script>
2、立即监听
如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。
<template>
<div class="home">
<input type="text" v-model="num">
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
num: 20
};
},
watch: {
num: {
handler(val, oldVal) {
console.log(val, oldVal);
},
// 组件注入页面时就立即监听
immediate: true
}
}
};
</script>
3、深度监听
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
<template>
<div class="home">
<h3>{{obj.age}}</h3>
<button @click="btnClick">按钮</button>
</div>
</template>
<script>
export default {
name: 'Home',
data(){
return {
obj: {
name: "Lucy",
age: 13
}
}
},
methods: {
btnClick(){
this.obj.age = 33;
}
},
watch: {
obj: {
handler(val, oldVal){
console.log(val.age, oldVal.age) // 33 33
},
deep: true
}
}
}
</script>
4、deep优化
<template>
<div class="home">
<h3>{{obj.age}}</h3>
<button @click="btnClick">按钮</button>
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
obj: {
name: "Lucy",
age: 13
}
};
},
methods: {
btnClick() {
this.obj.age = 33;
}
},
watch: {
// 通过点语法获取对象中的属性,然后转为字符串,即是对深度监听的优化
"obj.age": {
handler(val, oldVal) {
console.log(val, oldVal);
},
deep: true,
immediate: true, // 此时监听的数据不是一个对象,可以使用immediate
}
}
};
</script>
5、Watch与Computed的区别
- watch中的函数是不需要调用的,computed内部的函数调用的时候不需要加()
- watch(属性监听),监听的是属性的变化,而computed(计算属性),是通过计算而得来的数据
- watch需要在数据变化时执行异步或开销较大的操作时使用,而对于任何复杂逻辑或一个数据属性,在它所依赖的属性发生变化时,也要发生变化,这种情况下,我们最好使用计算属性computed。
- computed 属性的结果会被缓存,且computed中的函数必须用return返回最终的结果
- watch 一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;
6、Watch与Computed的使用场景
-
computed
- 当一个结果受多个属性影响的时候就需要用到computed
- 最典型的例子: 购物车商品结算的时候
-
watch
- 当一个数据的变化需要有往外操作的时候就需要用watch
- 搜索数据
-
总结:
- 一个值的结果受其他值的影响,用computed
- 一个值的变化将时刻影响其他值,用watch
五、Mixins混入(掌握)
mixins就是定义一部分公共的方法或者计算属性,然后混入到各个组件中使用,方便管理与统一修改。同一个生命周期,混入对象会比组件的先执行。
1、导出mixins
在src下创建 mixins/index.js
,写入:
export const MixinsFn = {
created() {
console.log("这是mixins触发的created")
}
}
2、引用mixins
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<script>
import { MixinsFn } from '@/mixins/index.js'
export default {
created(){
console.log("这是about触发的created")
},
mixins: [MixinsFn]
}
</script>
我们会发现,mixins中的created
比 about中的created
优先执行。
六、ref与$refs(掌握)
vue中获取页面里的某个元素(标签或组件),可以给它绑定ref属性,有点类似于给它添加id名。然后通过refs来进行绑定这个元素
1、简单使用
<template>
<div class="">
<h3 ref="title">{{msg}}</h3>
<button @click="btnclick">按钮</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "你好"
};
},
methods: {
btnclick() {
console.log(this.$refs.title); // 得到h3标签
}
}
};
</script>
<style lang = "less" scoped>
</style>
2、子组件中的数据获取及方法调用
子组件:
<template>
<div class="">
<h4>{{num}}</h4>
</div>
</template>
<script>
export default {
data() {
return {
num: 100
};
},
methods: {
subFn(){
console.log('子组件中的方法')
}
}
};
</script>
<style lang = "less" scoped>
</style>
父组件:
<template> <div class=""> <Sub ref="sub" /> <button @click="btnclick">按钮</button> </div></template> <script>import Sub from '../components/Sub'export default { methods: { btnclick() { console.log(this.$refs.sub.num); // 100 this.$refs.sub.subFn(); // '子组件中的方法' } }, components: { Sub }};</script> <style lang = "less" scoped></style>
七、(重点)KeepAlive
<keep-alive>
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
KeepAlive用于处理组件缓存。有什么用呢?想象一个业务场景:
这里,我们新创建两个页面, You.vue
和 Me.vue
,并且都实现累加功能。
1、修改App.vue
// 将原本的:<router-view/>// 修改为:<keep-alive> <router-view/></keep-alive>
这样,我们实现了整个项目中每个页面的缓存,显然我们不想这么做,我们只想针对某些页面,这时,我们修改一下:
<keep-alive> <router-view v-if="$route.meta.keepAlive" /></keep-alive><router-view v-if="!$route.meta.keepAlive" />
那这里的 $route.meta.keepAlive
存在于哪里呢?
2、Router中的meta
这是写在路由文件中的字段,我们去 router/index.js
中,将我们要缓存的 Me.vue
页面加上meta:
import Vue from 'vue'import VueRouter from 'vue-router'import Home from '../views/Home.vue'Vue.use(VueRouter)const routes = [ ..., { path: '/me', name: 'Me', component: () => import('../views/Me.vue'), meta: { keepAlive: true } }, { path: '/you', name: 'You', component: () => import('../views/You.vue') }]const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes})export default router
八、Vue生命周期
**生命周期钩子函数:**就是生命周期事件的别名;
初始
**beforeCreate:**实例刚刚在内存中被创建出来,此时还没有初始化 data
和 methods
属性。
**created:**实例已经在内存中创建好,此时 data
和methods
已经创建好,此时还没有开始编译模板
挂载
**beforeMount:**此时已经完成了模板编译,但是还没有挂载到页面中;
**mounted:**这个时候已经把编译好的模板挂载到页面指定的容器里;
更新
**beforeUpdate:**状态更新之前执行此函数,此时的 data
中的数据是最新,但是界面上显示的还是旧的,因为此时还没有开始重新渲染DOM节点;
**updated:**实例更新完毕之后调用此函数,此时data
中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了;
<template> <div> <p ref="run">{{ num }}</p> <button @click="num++">按钮</button> </div></template><script>import Comp from "@/components/Comp7Ch.vue";export default { data() { return { num: 20, isC: true, }; }, components: { }, methods: { fn() { console.log("这是函数"); }, }, beforeCreate() { // 组件创建之前执行的函数,(数据、方法、标签都获取不到) console.log("1.1--beforeCreate", this.num, this.fn, this.$refs.run); }, created() { // 发起异步请求,获取数据 // 组件创建之后执行的函数,(数据、方法已经可以获取,标签获取不到) console.log("1.2--created", this.num, this.fn, this.$refs.run); }, beforeMount() { // 组件挂载数据之前执行的函数,(数据、方法已经可以获取,标签获取不到) console.log("2.1--beforeMount", this.num, this.fn, this.$refs.run); }, mounted() { // 组件挂载数据之后执行的函数,(数据、方法、标签都可以获取得到) console.log("2.2--mounted", this.num, this.fn, this.$refs.run); }, beforeUpdate() { // 界面更新之前的函数 console.log("3.1--beforeUpdate", this.num, this.fn, this.$refs.run); }, updated() { // 界面更新之后的函数 console.log("3.2--update", this.num, this.fn, this.$refs.run); },};</script> <style lang = "less" scoped></style>
销毁
**beforeDestroy:**实例销毁之前调用,在这一步,实例让然完全可用。
**destroyed:**实例销毁后调用,调用后,Vue实例指向的所以东西会被解绑,所有的事件监听器会被移除,所有的子实力也会被销毁。
新建一个名为:Comp7Ch.vue
的子页面:
<template> <div> 这是comp7的子组件 </div></template><script>export default { data () { return { } }, beforeDestroy() { // 组件销毁之前执行这个函数, 回收 和清理工作, 比如清除定时器,清除全局事件 console.log("4.1---beforeDestroy"); }, destroyed() { console.log("4.2---destroyed"); },}</script> <style lang = "less" scoped> </style>
在刚刚那个页面进行引入,观察他的页面销毁时执行的顺序与内容:
<template> <div> <p ref="run">{{ num }}</p> <button @click="num++">按钮</button> <Comp v-if="isC" /> <button @click="isC = !isC">按钮2</button> </div></template><script>import Comp from "@/components/Comp7Ch.vue";export default { data() { return { num: 20, isC: true, }; }, components: { Comp, }, ......
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!