##1.生命周期
###1.1 初始期
四个钩子一个周期只能执行一次
// 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
beforeCreate() {
// 生命周期可以执行,实例被创建,数据还没有被添加到实例上
console.log({...this});
// console.log(this)
// 不可以在这里操作数据
console.log(this.msg);//undfined
// alert("running")
},
//在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el property 目前尚不可用。
created() {
// 数据可以被访问和修改
console.log({...this});
console.log(this.msg);
this.msg = "hi";
// 可以在这里发送数据请求(可以对数据对数据进行修改了)
},
// 在挂载开始之前被调用:相关的 render 函数首次被调用。
beforeMount() {
// 页面没有被更新,显示的内容还是原模板
console.log(this.$el);// 当前的页面内容
console.log(document.querySelector("p"))
document.querySelector("p").title = "abc"
},
//实例被挂载后调用,这时 el 被新创建的 vm.$el 替换了。如果根实例挂载到了一个文档内的元素上,当 mounted 被调用时 vm.$el 也在文档内。注意 mounted 不会保证所有的子组件也都一起被挂载
mounted() {
// 页面完成了挂载
console.log(this.$el);
// 这里可以进行DOM操作的内容
console.log(document.querySelector("p"))
},
####1.2
// 数据更新时调用,发生在虚拟 DOM 打补丁(patch)之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
beforeUpdate() {
console.log("beforeUpdate")
// 数据更新后
console.log(this.msg);
},
//由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
updated() {
console.log("updated");
// DOM更新完毕,可以操作更新后的DOM
console.log(this.msg);
// this.msg = "AAAAA"
},
###1.3 销毁
//实例销毁之前调用。在这一步,实例仍然完全可用
beforeDestroy() {
console.log("beforeDestroy");
// 比较常见的功能就是关闭定时器,结束数据请求
clearInterval(this.timer)
},
//实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
destroyed() {
console.log("destroyed")
},
##2.监听属性
2.1被监听的函数发生变化时,监听函数会执行
let vm = new Vue({
el:"#app",
data:{
n:1
},
watch:{
// n 这个监听属性函数会在 data n 发生变化时执行
// 参数分别是 更新前的数据和更新后的数据
n(newVal,oldVal){
console.log(newVal,oldVal)
console.log("n发生的变化")
}
},
methods:{
add(){
this.n++;
},
}
})
####2.2 深度监听: 数组的变化不能被监听到
let vm = new Vue({
el:"#app",
data:{
list:[{
n:1
},{
n:2
}]
},
watch:{
// 不能用这种写法监听数组
/* list(){
console.log("list 变化")
} */
// 数组成员的变化使用深度监听
list:{
deep:true,// 开启深度监听
handler(newVal,oldVal){
console.log(newVal[0].n,oldVal[0].n)
console.log("list 变化")
}
}
},
methods:{
}
})
和函数的区别
函数需要去调用,监听属性的方法是被监听的数据发生变化时自动执行
监听属性内可以执行异步操作
##3.计算属性
依赖的数据发生变化,自动执行,获取新的计算结果
<div id="app">
<input type="text" v-model.number = "n" @input="fn">
<button @click="add">+</button>
<!-- 可以像data中的数据一样被渲染 -->
<p>{{newN}}</p>
</div>
<script>
let vm = new Vue({
el:"#app",
data:{
n:1
},
// 定义计算属性
computed:{
newN(){
// 计算结果时计算函数的返回值
return this.n*this.n;
}
},
methods:{
add(){
this.n++;
this.fn()
},
//
fn(){
console.log("n发生的变化")
}
}
})
get,set
// 定义计算属性
computed: {
/* newN(){
// 计算结果时计算函数的返回值
return this.n*this.n;
} */
newN: {
// 获取 依赖值值发生变化时触发
get() {
return this.n * this.n;
},
// 直接设置 计算属性的值时触发
// val 被设置的值
set(val) {
console.log("直接设置newN")
console.log(val)
}
}
},
计算属性和监听属性区别
计算属性必须要有返回值
监听属性名称必须是被监听的数据
使用途径:
监听属性:监听一个数据,修改多个数据
计算属性:多个依赖的数据变化,计算一个新的数据
使用场景:
监听属性:大开销的操作或者时异步操作
计算属性:复杂运算上
##3.1过滤器
<!-- 过滤器是用来格式化文本 -->
<!--
{{被过滤的数据 | 过滤器 }}
{{被过滤的数据 | 过滤器(参数) }}
-->
<div id="app">
<p>{{timeStamp1 | formatTime("yyyy-mm")}}</p>
<p>{{timeStamp2 | formatTime("yyyy年mm月")}}</p>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
timeStamp1:1610529871038,
timeStamp2:1410529171038
},
// 定义过滤器
filters:{
// 参数val 被过滤的数据
// arg : 过滤器传入的参数
formatTime(val,arg){
console.log(val)
let d = new Date(val);
let year = d.getFullYear();
let month = d.getMonth()+1;
let str = "";
if(arg=="yyyy-mm"){
str = `${year}-${month}`
}else if(arg=="yyyy年mm月"){
str = `${year}年${month}月`
}
// 过滤的结果时 函数的返回值
return str;
}
},
})