属性侦听器
侦听器本质上是一个函数,如果要监听哪一个数据的变化,就把那个数据作为函数名
所有的侦听器,都定义在watch节点下
<div id="app">
<div>{{mag}}</div>
<button @click="but">修改mag属性,测试侦听</button>
<div>{{obj.name}}</div>
<button @click="but1">修改obj</button>
<div>{{obj2.age}}</div>
<button @click="but4">修改obj111</button>
<div>{{arr[1]}}</div>
</div>
<script>
new Vue({
el:"#app",
data:{
mag:"6666",
obj:{
name:"小明"
},
obj2:{
age:18
},
arr:[11,22,33,44],
},
methods: {
but(){
this.mag="修改成功,控制台打印6666"
},
but1(){
this.obj.name="小周"
},
but4(){
//只用修改引用数据的引用 才能触发侦听器属性
this.obj2={age:22}
}
},
watch:{
mag(){
//当mag的值发生改变,这里会打印,表示侦听到了,引用数据内部的属性值侦听器不会触发
console.log(6666);//这里不会打印obj引用数据内部的属性
},
//解决办法
obj:{
// 开启深度监听,只要对象中任何一个属性变化了,都会触发对象的侦听器
deep:true,
handler:()=>{
console.log("改变了");//这里侦听到了obj属性发生改变的值
}
},
obj2(){
console.log("obj改变了");
}
}
})
</script>
自定义指令
除了默认设置的核心指令( v-model 和 v-show 等),Vue 也允许注册自定义指令。在Vue里,代码复用的主要形式和抽象是组件。
<div id="app">
<h1 v-blue>66666</h1>
<!-- 后面使用该指令,功能复用 -->
<p v-blue>777</p>
<input v-blue type="text" v-model="age">
<h1 v-color="'red'">1111</h1>
<h2 v-color="mycolor">22222</h2>
<p v-color="'pink'">3333</p>
</div>
<script>
new Vue({
el: "#app",
data: {
age: 123,
mycolor: "green"
},
directives: {
// blue(el) {//el代表拿到该节点:DOM
// console.log(el);
// el.style.color = "blue"
// },
blue: {
inserted(el) {
el.style.color = "blue"
}
},
// color: {
// inserted(el, option) {
// console.log(el, option.value, 22222222222);
// el.style.color = option.value
// }
// },
color(el, option){//第一个参数是节点,第二个参数是对象
console.log(el, option.value, 22222222222);
el.style.color = option.value
}
}
})
</script>
生命周期函数
四个生命阶段:
1.创建阶段 数据劫持/代理 钩子函数:beforeCreate created
2.挂载阶段 模板编译成标准的html结构,并且挂载到页面上 beforeMount mounted
3.更新阶段 状态的改变 引起 视图的改变 beforeUpdate updated(可以多次触发 其他只触发一次)
4.卸载/销毁阶段 app的销毁 beforeUnmout unmouted
<div id="app">
<div>
<ul>
<li v-for="(item,index) in arr">{{item}}</li>
</ul>
</div>
<button @click="but">{{msg}}</button>
<img :src="url">
</div>
<script>
new Vue({
el: "#app",
data: {
arr: [],
msg:"点击",
url:"https://img1.baidu.com/it/u=2475127973,1009717621&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1662397200&t=d9d4f9613e3435d67c3fc2dd214a6a3f"
},
methods: {
but(){
this.url="https://img2.baidu.com/it/u=1814268193,3619863984&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1662397200&t=036d3b960ecfac319b85724ab3014d75"
}
},
beforeCreate() {
//基本上不用 this指向不清晰 数据也没有劫持
console.log("创建前");
},
created() {
//当created执行时创建阶段已经完成 data中的数据已经被劫持了
console.log("创建完成");
this.arr = [1, 2, 3, 4, 5, 6];
},
beforeMount() {
console.log("挂载前");
//挂载前 $el还是节点 因此还没有把template渲染成DOM
console.log(this.$el);//
},
mounted() {
console.log("挂载完成");
//可以用于获取vue渲染出来的dom节点
console.log(this.$el);
},
beforeUpdate() {
//这两个钩子中 不能网络请求新数据 去更新数据源
//会导致死循环
//数据源已经更新了,页面重新渲染前(并不是数据更新前) 触发的钩子
console.log("更新前",this.url)
},
updated() {
//页面已经重新渲染了触发的钩子
console.log("更新完成",this.url)
},
beforeDestroy() {
//vm对象销毁之前触发的钩子,this还在 可以做最后的操作
//保存用户的行为配置文件:播放器的进度 等等
console.log("销毁前");
},
destroyed() {
//后面在webpack环境下操作 无法操作this
//往往把当前组件中计时器清除了 可以把body的滚动条滚到顶部
console.log("销毁完成")
}
});
</script>
图形参考:
组件
全局组件
<body>
<div id="app">
<my-hello></my-hello>
</div>
<script>
// 全局组件,可以在所有vue实例中使用
Vue.component('my-hello', {
template: '<h3>{{name}}</h3>',
// 在组件中存储数据时,必须以函数形式,函数返回一个对象
data: function() {
return {
name: 'hello'
}
}
})
new Vue({
el:"#app"
})
</script>
局部组件
<div id="app">
<my-world></my-world>
</div>
<script>
// vue 中定义的都是局部组件 只能在当前vue实例中使用
new Vue({
el: "#app",
data: {
aaa: 'tom'
},
components: {
// 局部组件
'my-world': {
template: '<h3>{{age}}</h3>',
data: function() {
return {
age: 25
}
}
}
}
});
</script>