vue组合式风格
setup
所有使用到的响应式状态都应在setup函数里面定义。
<script>
// `setup` 是一个专门用于组合式 API 的特殊钩子函数
setup() {
const state = reactive({ count: 0 })
// 暴露 state 到模板
return {
state
}
}
</script>
注意这里state是一个响应式对象,在该对象里可以定义多个成员,每个成员被修改时都会触发响应式渲染。
当状态非常多时这种定义方法会非常繁琐,在script
标签中加上setup
可以简化操作。
<script setup>
import { reactive } from 'vue'
const state = reactive({ count: 0 })
function increment() {
state.count++
}
</script>
声明响应式状态
可以使用reactive()
创建响应式对象。
但是注意声明响应式对象必须使用const
reactive的缺陷:
- 仅对集合类型有效,对原始数据类型无效。
- 必须保持对响应式对象的相同引用,才能保证响应性不会丢失。
使用ref()可以创建任何值类型(包含原始数据类型)的响应式ref。
const count = ref(0)
console.log(count) // { value: 0 }
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
用value表示其值或者对其进行修改。当在模板中ref作为顶层属性被使用的时候,他会自动解包。不需要使用value
<template>
<div>
这是主组件
<div @click="solveRec">reactive:{{ rec.value }}</div>
<div @click="solveRef">ref:{{ re }}</div>
</div>
</template>
<script setup>
import {reactive,ref} from 'vue'
const rec = reactive({value:0})
const re = ref(0)
const solveRef = () => {
console.log("solveRef Called")
test(re)
}
const solveRec = () => {
console.log("solveRec Called")
test(rec)
}
const test = (e) => {
console.log("test Called",e.value)
e.value = 3;
}
</script>
当ref被签到在一个响应式对象中,被当作属性访问时,他会自动解包。
const count = ref(0)
const state = reactive({
count
})
console.log(state.count) // 0
state.count = 1
console.log(count.value) // 1
计算属性
与选项式中的计算属性类似。但是写法稍有区别。
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
<span>{{ publishedBooksMessage }}</span>
计算属性会基于其使用到的响应式依赖进行缓存,只有在其依赖被更新的时候其值才会呗重新计算。
生命周期钩子
与选项式类似,当你在组合式用法中需要根据生命周期执行一些函数时,可以使用生命周期钩子。
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
console.log(`the component is now mounted.`)
})
</script>
类似的还有onMounted
,onUpdated
,onUnmounted
vue生命周期
![组件生命周期图示](https://cn.vuejs.org/assets/lifecycle.16e4c08e.png)
侦听器
在很多情况下,你可能想要在某个响应式状态被修改时进行一些副作用操作,这时候可以用watch函数来监听这种变化并进行一些操作。
<script setup>
import { reactive, ref, watch } from 'vue'
const question = ref('')
const answer = reactive({new:'',old:''})
watch(question, async (newQuestion, oldQuestion) => {
answer.new=newQuestion
answer.old=oldQuestion
}
)
</script>
<template>
<p>
<input v-model="question" />
</p>
<p>old:{{ answer.old }}<br/>new:{{ answer.new }}</p>
</template>
这份代码监听了question的变化,并且根据question的变化改变了anwser
访问dom
在某些情况下可能需要直接对dom的操作。
使用ref可以获取到该dom。为模板中的dom节点声明一个ref属性,然后通过ref钩子就可以获取到该dom。
<script setup>
import { ref, onMounted } from 'vue'
const input = ref(null)
onMounted(() => {
input.value.focus()
})
</script>
<template>
<input ref="inputref" />
</template>
注意这里的ref的引用名字必须为inputref
,即需要与模板中声明的ref对应。