VUE知识点总结
由于本人目前的技术栈是vue,所以不做基础知识介绍了,主要讲一下其他的知识点。
父子组件钩子函数执行顺序
我们用P代表父组件 C代表子组件
在组件创建阶段,父子组件钩子函数执行顺序为,从上向下:
P beforeCreate
P created
P beforeMount
C beforeCreate
C created
C beforeMount
C mounted
P mounted
其实比较好理解,当父组件挂载模板进行渲染时,才开始创建子组件。
当数据引起视图层更新时,为:
P beforeUpdate
C beforeUpdate
C updated
P updated
父组件必定要子组件更新完毕,才能进入updated生命周期
当组件销毁时为:
P beforeDestory
C beforeDestory
C destroyed
P destroyed
同理,父组件必定要子组件销毁完毕,才能进入destroyed生命周期
双向props
一般来说props用于父组件向子组件传递数据,而这种数据传递是单向的,若想让其转换为双向,可用.sync修饰符
<child :prop1.sync="something"></child>
在子组件修改prop1,并将改动传递给父组件
this.$emit('update:prop1', newVal);
其实这只是一个语法糖,背后还是发生了子组件向上传递事件,触发父组件数据更新。
同时,再探究下
1、props传递一个基础数据类型,在子组件直接修改数据,报错
2、props传递一个对象(引用类型),修改对象属性,成功。修改对象引用地址,报错(但子组件视图更新)
路由
router.push("login")
用router.push进行路由跳转时,若传入的参数前无“/”,则url会变成 “当前路由容器path + 新的路由”(主要考虑有嵌套路由的情况)。若传入的参数前有“/”,则url会变成 “当前域 + 路由”
假设当前URL
http://www.a.com/register
http://www.a.com/homepage/register // 嵌套路由
我们执行
router.push("login")
则url会变成
http://www.a.com/login
http://www.a.com/homepage/login
若执行
router.push("/login")
则URL会变成
http://www.a.com/login
http://www.a.com/login
修饰符
用在v-model上的
.number // 将用户输入的数据由字符串转换为数字
.lazy // 将表单控制中监听的事件从input转换为change
.trim // 将用户输入的字符串头尾部的空格去掉
用在监听事件上的
.prevent // 阻止默认事件
.stop // 阻止事件冒泡
.native // 给自定义组件添加原生事件
.once // 事件只触发一次
用在props上的
.sync // 将props值可以双向传递,在子组件内部可以修改父组件的数据
闪烁
使用v-cloak指令,绑定在页面元素上
<div v-cloak>
{{msg}}
</div>
在CSS中设置
[v-cloak] {
display: none;
}
原理:
先通过样式隐藏内容,然后将模板中的值进行替换,完成后再显示最终的结果。
批量注册
如何保证使用VUE语法的时候,vuejs已经加载进来了
这个问题是之前有个面试官问我的,这样写代码会有问题
<body>
<div id="app">
{{msg}}
</div>
<!-- 在这里用script标签引入vuejs -->
<script>
new Vue({
/// 逻辑
})
</script>
</body>
我当时只想到一个方法
方法1:将引入vuejs的script标签放在body标签上面,先全部引入
后来我才想到另一个方法
方法2:用document.onload,在页面资源都加载完毕后,在执行vue方法即可。
<script>
document.onload = () => {
new Vue({
// .....
})
}
</script>
当时咋就没想到呢?
v-model的原理
v-model本质上是一个语法糖,可以理解成两个部分
- 用v-bind绑定响应式数据
- 监听页面的input事件,触发事件的时候将data中的数据更新
vue.extend的应用
首先创建一个vue组件
<template>
<div class="toast" v-show="showToast">
{{ msg }}
</div>
</template>
<script>
export default {
data() {
return {
showToast: false,
msg: ''
}
},
mounted() {
setTimeout(() => {
this.showToast = false
}, 2000)
}
}
</script>
<style scoped>
.toast {
width: 200px;
height: 50px;
line-height: 50px;
background: salmon;
text-align: center;
color: #fff;
position: fixed;
top: 20px;
right: 20px;
}
</style>
然后,用extend将其扩展为一个子类,并封装为一个函数
import Vue from 'vue'
import Main from './index.vue'
const Toast = Vue.extend(Main)
const toast = (options) => {
options = options || {}
options = Object.assign(options, {
showToast: true
})
const instance = new Toast({
data: options
})
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
return instance.vm
}
export default toast
我们将toast挂在到Vue原型属性上
import toast from '../src/extends/toast/index'
Vue.prototype.$toast = toast
在全局任何一个地方调用
this.$toast({
msg: '哈哈哈'
})
出现弹窗