ref基本用法
一、ref函数基本用法:
作用:定义一个响应式的数据
语法:const xxx = ref(initValue),创建一个包含响应式数据的引用对象(reference对象简称ref对象)
备注:
1. 基本数据类型:响应式依然是靠Object.defineProperty()的get和set完成的
2. 对象数据类型:内部求助了Vue3.0中的一个新函数 ==> reactive函数处理基本类型和对象类型
<template><div>{{ name }}</div><div>{{ age }}</div><div>{{ job.industry }}</div><div>{{ job.salary }}</div><button @click="change">按钮</button>
</template><script>
import { ref } from 'vue'
export default {name: 'App',setup() {let name = ref('张三')let age = ref(18)let job = ref({industry: '前端',salary: '30k'})function change() {console.log(name, age);name.value = '李四'age.value = 28job.value.industry = 'UI'job.value.salary = '60K'}return {name,age,job,change}}
}
</script>
reactive基本用法
reactive函数
作用:定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
语法:const 代理对象 = reactive(源对象)接收一个对象或数组,返回一个代理对象(proxy对象)
reactive定义的响应式数据是深层次的
内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作代码:
<template><div>{{ person.name }}</div><div>{{ person.age }}</div><div>{{ person.job.industry }}</div><div>{{ person.job.salary }}</div><button @click="change">按钮</button>
</template><script>
import { reactive } from 'vue'
export default {name: 'App',setup() {const person = reactive({name: '张三',age: 18,job: {industry: '前端',salary: '30k'}})function change() {person.name = '李四'person.age = 28person.job.industry = 'UI'person.job.salary = '60K'}return {person,change}}
}
</script>
ref和reactive对比
从定义数据角度对比:
1. ref用来定义:基本数据类型
2. reactive用来定义:对象或数字类型数据
3. 备注:ref也可以用来定义对象或数组类型数据,它内部会自动通过reactive转为代理对象从原理角度对比:
1. ref通过Object.defineProperty()的get和set来实现响应式(数据劫持)
2. reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据从使用角度对比:
ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
reactive定义的数据:操作数据和读取数据:均不需要.value
setup两个注意点
setup的两个注意点:1. setup执行的时机
在beforeCreate之前执行一次,this是undefined2. setup的参数:即setup(props, context){}
props:值为对象,包含组件外部传递过来,且组件内部声明接收了的属性
context:上下文对象attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrsslots: 收到的插槽内容,相当于this.$slotsemit:分发自定义事件的函数,相当于this.$emit具体案例:1. App.vue:<template><DemoComponent @hello="sayHello" sex="男"><template v-slot:about><div>关于</div></template><template v-slot:some><div>一些</div></template></DemoComponent>
</template><script>
import DemoComponent from './components/DemoComponent'export default {name: 'App',components: { DemoComponent },setup() {function sayHello() {console.log('我通过emit触发拉');}return {sayHello}}
}
</script>2. DemoComponent.vue:<template><div>{{ person.name }}</div><div>{{ person.age }}</div><div>{{ sex }}</div><button @click="handleClick">按钮</button><slot name="about" /><slot name="some" />
</template><script>
import { reactive } from 'vue'export default {name: 'DemoComponent',props: ['sex'],emits: ['hello'],setup(props, context) {console.log(props, 'props', context.slots);const person = reactive({name: '张三',age: 19,})function handleClick() {context.emit('hello', 1, 2, 3)}return {person,handleClick}}
}
</script>