ref
push
reactive在封装一层
这三种方式都可以让在setup里面定义的data变为响应式的
定义单个 变量使用ref()
定义对象时,使用reactive比较好
toRefs setup 中return 返回数据的时候,使用toRefs包一下,就可以让数据是响应式的
ref用来处理基本类型数据,reactive用来处理对象(递归深度响应)
如果使用ref对象/数组,内部会自动将对象。数组转为reactive的代理对象
ref内部:通过给value属性添加getter/setter 来实现对数据的劫持
reactive内部:通过使用proxy来实现对象内部所有数据的劫持,并通过Reflect操作对象内部数据
ref的数据操作:在js中要.value,在模板中不需要(内部解析模板时会自动添加.value)
<template>
<div class="main">
<div class="loginBlock">
<div style="background: red">
{{ msg }} {{ tips }}{{ loginForms.username }}{{ loginForms.age }}
</div>
<div style="background: green">
<div v-for="(reft, index) in liRef" :key="index">{{ reft.name }}</div>
</div>
</div>
<div>{{ name }}来家里{{ counts }}次了</div>
<div class="addPlus">
<button @click="puls">-</button>
<input type="text" v-bind:value="num" />
<button @click="add">+</button>
</div>
</div>
</template>
<script>
import { ref, watch, defineComponent, reactive, watchEffect, toRefs } from 'vue'
export default defineComponent({
setup() {
let tips = ref('你好的')
let msg = ref('hellow')
let num = ref(0)
let state = reactive({
name: '自来熟',
counts: 47,
})
//toRefs 可以把一个响应式的对象转换为普通对象,该普通对象的每个property 都是个ref
let state2 = toRefs(state)
//定时器,更新数据(如果数据变化了,界面随之变化,肯定是响应式的数据)
setInterval(() => {
state2.name.value += '=='
}, 1000)
let liRef = ref([])
let loginForm = {
username: 'sandraLee',
age: 18,
}
const loginForms = reactive(loginForm)
let arr = [
{ id: 1, name: 'sandra' },
{ id: 2, name: 'poly' },
]
liRef.value = arr
console.log(liRef)
const add = () => {
num.value++
}
const puls = () => {
num.value--
}
watch(num, (v) => {
if (v < 0) {
num.value = 0
}
console.log('watch')
})
// watchEffect(() => {
// console.log('watchEffect', num.value)
// })
return {
liRef,
tips,
msg,
num,
loginForms,
add,
puls,
...state2,
}
},
})
</script>
<style lang="scss" scoped>
.main {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: #3579e6;
}
.loginBlock {
display: flex;
width: 500px;
height: 300px;
background: #fff;
}
</style>