目录
Vue监听的介绍
1、虽然Vue的计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器
2、vue通过watch选项提供了一个更通用的方法,来响应数据的变化
3、当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的
一、监听
1、简单的监听
<body>
<div id="app">
<h1>{{a}}</h1>
<button @click="add">+</button>
</div>
<script>
const app = new Vue({
el:'#app',
data:{
a:0,
},
watch:{
a(newVal,oldVal){
console.log('新',newVal,'旧',oldVal);
console.log('变了变了');
}
},
methods:{
add(){
this.a++
}
},
})
</script>
</body>
2、对象的监听
(1)写法:在watch中需要handler和deep结合(注意单词不要拼写错,不然会报错)
(2)区别简单监听
①错误:用简单监听来监听对象,会出现新旧值始终指向同一个空间,无法监听到旧值的问题
<body>
<div id="app">
<input type="text" v-model="userInfo.name">
</div>
<script>
const app = new Vue({
el:'#app',
data:{
userInfo:{
name:'申小兮',
},
},
watch:{
userInfo:{
handler(newInfo,oldInfo){
console.log(newInfo,oldInfo);
},
deep:true,
},
},
})
</script>
</body>
②正确:用ES6学习的方法深拷贝,使得新旧值指向各自的空间
<body>
<div id="app">
<input type="text" v-model="userInfo.name">
</div>
<script>
const app = new Vue({
el:'#app',
data:{
userInfo:{
name:'申小兮',
},
},
watch:{
newUserInfo:{
handler(newInfo,oldInfo){
console.log(newInfo,oldInfo);
},
deep:true,
},
},
computed:{
newUserInfo(){
return JSON.parse(JSON.stringify(this.userInfo))
}
}
})
</script>
</body>
3、immediate立即触发
页面一进入就会触发
<body>
<div id="app">
<h1>{{a}}</h1>
<button @click="add">+</button>
</div>
<script>
const app = new Vue({
el:'#app',
data:{
a:0,
},
watch:{
a:{
handler(newVal,oldVal){
console.log(newVal,oldVal);
},
immediate:true
}
},
methods:{
add(){
this.a++
}
},
})
</script>
</body>
二、创建组件
1、具体步骤
(1)创建组件构造器:Vue.extend({})
(2)参数:template,代表模板,类似于html,通过模板字符串设置标签块
注意:模板字符串有多个标签时,一定要用div标签嵌套包裹,否则会报错
(3)注册:Vue.component("组件名称",组件内容)
(4)使用:把组件名称当作标签直接用
<body>
<div id="app">
<!-- 4、使用 -->
<my-advertising></my-advertising>
</div>
<script>
// 1、创建构造器
const cpn = Vue.extend({
// 2、参数
template:`
<div>
<h1>广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
`,
})
// 3、注册
Vue.component('my-advertising',cpn)
const app = new Vue({
el:'#app',
})
</script>
</body>
2、创建组件语法糖
省略创建构造器Vue.extend({})步骤,直接进行注册Vue.component(),在注册步骤里面设置参数template,使编写更快捷
<body>
<div id="app">
<my-advertising></my-advertising>
</div>
<script>
Vue.component('my-advertising',{
template:`
<div>
<h1>广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
`,
})
const app = new Vue({
el:'#app',
})
</script>
</body>
三、全局组件和局部组件
注意:一个html文件里面,不应该出现两个vue实例,但是下面需要演示全局和局部的效果,小编会建两个vue实例🧐
1、全局、局部普通写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../vue.js"></script>
<style>
#app{
background-color: red;
}
#demo{
background-color: skyblue;
}
</style>
</head>
<body>
<div id="app">
<my-advertising></my-advertising>
<!-- <cpn-name></cpn-name>局部组件,只能在注册过的局部显示,在这里无法显示且报错 -->
</div>
<div id="demo">
<my-advertising></my-advertising><!-- 全局组件,在哪里都可以显示 -->
<cpn-name></cpn-name><!-- 这个局部组件只能在demo里面使用 -->
</div>
<script>
// 全局
Vue.component('my-advertising',{
template:`
<div>
<h1>广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
`,
})
// 局部
const cpn = Vue.extend({
template:`
<div>
<h1>局部广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
`,
})
const app = new Vue({
el:'#app',
})
const demo = new Vue({
el:'#demo',
components:{cpnName:cpn},
})
</script>
</body>
</html>
2、局部语法糖写法
<script>
// 全局
Vue.component('my-advertising',{
template:`
<div>
<h1>广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
`,
})
const app = new Vue({
el:'#app',
})
const demo = new Vue({
el:'#demo',
components:{
cpnName:{
template:`
<div>
<h1>局部广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
`,
}
},
})
</script>
四、父组件和子组件
1、new Vue实例
我们定义的new Vue实例就是一个组件,可以看作根组件
<body>
<div id="app">
<son></son>
</div>
<script>
const cpn = Vue.extend({
template:`
<h1>Vue实例的子组件</h1>
`,
})
const app = new Vue({
el:'#app',
components:{son:cpn}
})
</script>
</body>
2、参数调用子组件标签
<body>
<div id="app">
<father></father>
</div>
<script>
Vue.component('son',{
template:`
<h1>子组件</h1>
`,
})
Vue.component('father',{
template:`
<div>
<h1>父组件</h1>
<son></son>
</div>
`,
})
const app = new Vue({
el:'#app',
})
</script>
</body>
五、模板抽离写法
把html部分抽离出来,然后再挂载
1、script法
<body>
<div id="app">
<my-advertising></my-advertising>
</div>
<script type="text/template" id="cpn">
<div>
<h1>广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
</script>
<script>
const app = new Vue({
el:'#app',
components:{
myAdvertising:{template:'#cpn'}
}
})
</script>
</body>
2、template法
<body>
<div id="app">
<my-advertising></my-advertising>
</div>
<template id="cpn">
<div>
<h1>广告标题</h1>
<p>广告内容</p>
<p>广告结尾</p>
</div>
</template>
<script>
const app = new Vue({
el:'#app',
components:{
myAdvertising:{template:'#cpn'}
}
})
</script>
</body>
六、组件数据
1、组件:一个单独模块的封装
2、模块:包含html、data、method...
注意:该模块的data是一个函数
<body>
<div id="app">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<template id="cpn1">
<div>
<h1>姓名:{{name}}</h1>
</div>
</template>
<template id="cpn2">
<div>
<h1>年龄:{{age}}</h1>
</div>
</template>
<script>
const app = new Vue({
el:'#app',
components:{
cpn1:{
template:'#cpn1',
data(){
return {
name:'申小兮',
};
},
},
cpn2:{
template:'#cpn2',
data(){
return {
age:'18',
}
}
}
}
})
</script>
</body>