Initial commit
This commit is contained in:
242
docs/vue/composition.md
Normal file
242
docs/vue/composition.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# 组合式API
|
||||
|
||||
## setup函数
|
||||
|
||||
### 基本用法
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { ref, reactive, computed, watch, onMounted } from 'vue'
|
||||
|
||||
// 响应式数据
|
||||
const count = ref(0)
|
||||
const state = reactive({
|
||||
name: 'Vue',
|
||||
version: 3
|
||||
})
|
||||
|
||||
// 计算属性
|
||||
const doubleCount = computed(() => count.value * 2)
|
||||
|
||||
// 方法
|
||||
function increment() {
|
||||
count.value++
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
console.log('组件已挂载')
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p>Count: {{ count }}</p>
|
||||
<p>Double: {{ doubleCount }}</p>
|
||||
<button @click="increment">+1</button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## ref与reactive
|
||||
|
||||
### ref
|
||||
|
||||
用于基本类型和需要替换整个对象的场景。
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const count = ref(0)
|
||||
const user = ref({ name: '张三' })
|
||||
|
||||
// 访问需要 .value
|
||||
console.log(count.value)
|
||||
console.log(user.value.name)
|
||||
|
||||
// 重新赋值
|
||||
user.value = { name: '李四' }
|
||||
</script>
|
||||
```
|
||||
|
||||
### reactive
|
||||
|
||||
用于对象类型,返回原始对象的代理。
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const state = reactive({
|
||||
count: 0,
|
||||
user: {
|
||||
name: '张三',
|
||||
age: 25
|
||||
}
|
||||
})
|
||||
|
||||
// 直接访问,不需要 .value
|
||||
console.log(state.count)
|
||||
console.log(state.user.name)
|
||||
|
||||
// 修改属性
|
||||
state.count++
|
||||
state.user.age = 26
|
||||
</script>
|
||||
```
|
||||
|
||||
## 组合式函数
|
||||
|
||||
### 创建组合式函数
|
||||
|
||||
```javascript
|
||||
// useCounter.js
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
export function useCounter(initialValue = 0) {
|
||||
const count = ref(initialValue)
|
||||
|
||||
const doubleCount = computed(() => count.value * 2)
|
||||
|
||||
function increment() {
|
||||
count.value++
|
||||
}
|
||||
|
||||
function decrement() {
|
||||
count.value--
|
||||
}
|
||||
|
||||
function reset() {
|
||||
count.value = initialValue
|
||||
}
|
||||
|
||||
return {
|
||||
count,
|
||||
doubleCount,
|
||||
increment,
|
||||
decrement,
|
||||
reset
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 使用组合式函数
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useCounter } from './useCounter'
|
||||
|
||||
const { count, doubleCount, increment, decrement, reset } = useCounter(10)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p>Count: {{ count }}</p>
|
||||
<p>Double: {{ doubleCount }}</p>
|
||||
<button @click="increment">+1</button>
|
||||
<button @click="decrement">-1</button>
|
||||
<button @click="reset">Reset</button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 鼠标位置追踪
|
||||
|
||||
```javascript
|
||||
// useMouse.js
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
export function useMouse() {
|
||||
const x = ref(0)
|
||||
const y = ref(0)
|
||||
|
||||
function update(event) {
|
||||
x.value = event.pageX
|
||||
y.value = event.pageY
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('mousemove', update)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('mousemove', update)
|
||||
})
|
||||
|
||||
return { x, y }
|
||||
}
|
||||
```
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useMouse } from './useMouse'
|
||||
|
||||
const { x, y } = useMouse()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p>鼠标位置: {{ x }}, {{ y }}</p>
|
||||
</template>
|
||||
```
|
||||
|
||||
## provide/inject
|
||||
|
||||
### 提供数据
|
||||
|
||||
```vue
|
||||
<!-- 祖先组件 -->
|
||||
<script setup>
|
||||
import { provide, ref } from 'vue'
|
||||
|
||||
const theme = ref('dark')
|
||||
const user = ref({ name: '张三' })
|
||||
|
||||
provide('theme', theme)
|
||||
provide('user', user)
|
||||
provide('updateTheme', (newTheme) => {
|
||||
theme.value = newTheme
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
### 注入数据
|
||||
|
||||
```vue
|
||||
<!-- 后代组件 -->
|
||||
<script setup>
|
||||
import { inject } from 'vue'
|
||||
|
||||
const theme = inject('theme', 'light') // 默认值
|
||||
const user = inject('user')
|
||||
const updateTheme = inject('updateTheme')
|
||||
|
||||
function toggleTheme() {
|
||||
updateTheme(theme.value === 'dark' ? 'light' : 'dark')
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## toRef与toRefs
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { reactive, toRef, toRefs } from 'vue'
|
||||
|
||||
const state = reactive({
|
||||
name: '张三',
|
||||
age: 25,
|
||||
city: '北京'
|
||||
})
|
||||
|
||||
// toRef - 单个属性
|
||||
const nameRef = toRef(state, 'name')
|
||||
|
||||
// toRefs - 所有属性
|
||||
const { name, age, city } = toRefs(state)
|
||||
|
||||
// 解构后的ref保持响应性
|
||||
name.value = '李四'
|
||||
console.log(state.name) // 李四
|
||||
</script>
|
||||
```
|
||||
Reference in New Issue
Block a user