vue中有很多有关数据的操作方法,比如父子组件数据的传递,子组件修改父组件数据,props,computed,watch,sync等,今天就来总结一下这些操作方法的使用
computed是计算属性
computed是计算属性:减少模板{{}}的复杂度。 在模板中放入太多的逻辑会让模板过重且难以维护。对于任何复杂逻辑,你都应当使用计算属性 把复杂的运算逻辑写到computed的函数里面,再在模板里引用就使逻辑变得简单明了了 使用方法: computed与data并列,将一系列操作封装成一个方法,放到computed里,调用时直接写方法名,不用加( )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
new Vue({
el: "#app" ,
data:{
user:{
email: "dong@qq.com" ,
nickname: "oldUath" ,
phone: "12812345678"
}
},
//计算属性
computed:{
displayName(){
//返回一个结果
const user= this .user
return user.nickname ||user.phone||user.email
}
},
template:`
<div>
{{displayName}}
</div>
`
})
|
watch侦听器
watch:侦听器:观察Vue实例上的数据变动,只要指定的数据改变就会执行预定的函数 当需要在数据变化时执行异步或开销较大的操作时;
watch使用方法一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<div id= "app" >
{{msg}}
<br>
改变了吗? {{isChange}}
<button @click= "change" >改变</button>
</div>
new Vue({
el: "#app" ,
data: {
//这是第一层数据
msg: '欲穷千里目' ,
isChange: 'No' ,
user:{
//这是第二层数据
name: "oldUath" ,
phone: '18312345678'
}
},
watch:{
//只要msg改变,这个方法就会执行,第一层数据只需要写 数据名(){}就可以
msg(val,oldVal){
this .isChange = 'Yes'
},
//第二层数据需要'','user.name'(){}
'user.name' (){
console.log( 'user.name变了' )
}
},
methods:{
change(){
this .msg = '更上一层楼'
}
}
})
|
注意:在vue里面如果把一个对象原封不动的再赋值给他,那么他的地址就变了
1
2
|
//obj:{a:'a'}
obj.a+= 'hi' //才是监听obj时,因为obj地址没有发生变化,所以不会执行监听obj的事件
|
可以使用 deep:true这个是代表让watch往深处监听,值变了就相当于改变了
1
2
3
4
5
6
|
watch:{
obj(){
handle(){console.log( 'obj变了' )
},
deep: true
}
|
使用方法二: vm.$watch('监听的变量',调用的函数,{immediate:true})
与方法一的效果相同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
const vm = new Vue({
el: "#app" ,
data: {
msg: '欲穷千里目' ,
isChange: 'No' ,
user:{
name: "oldUath" ,
phone: '18312345678'
}
},
methods:{
change(){
this .msg = '更上一层楼'
}
}
})
vm.$watch( 'msg' , function (){
console.log( 'n变了' )
},{immediate: true })
|
父组件给子组件传递数据: Props
父组件要想给子组件传入数据,需要在子组件种使用Props引入变量
父组件要给子组件出入 money="100"
先在父组件种传入
1
2
|
//在父组件调用子组件
<Child :money= "100" ><Child>
|
再在子组件种引入数据,引入money这个变量
1
2
3
4
5
6
7
8
9
10
11
|
<template>
<div class= "red" >
+ {{money}}元
<button>花钱</button>
</div>
</template>
<script>
export default {
+ props:[ 'money' ]
}
</script>
|
此时子组件只能使用父组件的数据,而不能修改
子组件修改父组件的数据(.sync原理)
组件不能直接修改props外部的数据
使用$emit进行修改
在子组件使用 $emit(‘参数1',参数2)
当前实例继承了eventBus,可以触发一个事件
在子组件写$emit,第一个参数是事件名,第二个参数是修改后的值
1
2
|
<!-- $emit()触发一个事件,update:money是事件名 -->
<button @click= "$emit('update:money',money-10)" >花钱</button>
|
在父组件使用 $event接受参数2;
$event就是接收子组件参数2返回的结果的
1
2
3
|
<!-- 传给子组件一个money值,v-on是监听子组件的update:money事件,
$event获取子组件事件的结果-->
<Child :money= "total" v-on:update:money= "total = $event" />
|
简化结果: sync
父组件这一大段代码太麻烦了,vue把它封装成了一个修饰符
1
|
<Child :money.sync= "total" />
|
子组件还是那样写
这个只解决了父子组件的通信问题,兄弟组件的通信问题呢?
兄弟组件通信:emit/emit/on
这种方法通过一个空的Vue实例作为*事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。 具体实现方式
1
2
3
|
var Event= new Vue();
Event.$emit(事件名,数据); //传递事件数据
Event.$on(事件名,data => {}); //接受数据
|
举个例子:A组件向C组件传递信息,ABC是相邻组件
首先在A组件提供事件数据使用$emit,第一个参数是数据名,要与接收数据的on的第一个参数相同;第二个参数是数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<template id= "a" >
<div>
<h3>A组件:{{name}}</h3>
<button @click= "send" >将数据发送给C组件</button>
</div>
</template>
<script>
var Event = new Vue(); //定义一个空的Vue实例
var A = {
template: '#a' ,
data() {
return {
name: 'tom'
}
},
methods: {
send() {
Event.$emit( 'data-a' , this .name);
}
}
}
</script>
|
在C组件接受数据 $on,第一个参数是数据名,第二个参数用来接收数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<template id= "c" >
<div>
<h3>C组件:{{name}},{{age}}</h3>
</div>
</template>
<script>
var Event = new Vue(); //定义一个空的Vue实例
var C = {
template: '#c' ,
data() {
return {
name: '' ,
age: ""
}
},
mounted() { //在模板编译完成后执行
Event.$on( 'data-a' ,name => {
this .name = name; //箭头函数内部不会产生新的this,这边如果不用=>,this指代Event
})
}
}
</script>
|
总结
-
父子之间传递数据用
props
和$emit
-
兄弟之间传递数据用
$emit
和$on
-
父组件向孙子组件传递数据使用
provide
和inject
以上就是vue 数据操作相关总结的详细内容,更多关于vue 数据操作的资料请关注服务器之家其它相关文章!
原文链接:https://juejin.cn/post/6906371672018780173