- toRefs
用来解构props 属性,如果不用 toRefs 直接用 es6 解构,props 的属性就不是响应式的了,所以需要我们把所有的 props 转成 ref
import { toRefs } from 'vue'
setup(props) {
const { title } = toRefs(props)
console.log(title.value)
}
toRef
针对某个可选的 prop 属性
如果 title 是可选的 prop,则传入的 props 中可能没有 title 。在这种情况下,toRefs 将不会为 title 创建一个 ref 。你需要使用 toRef 替代它
import { toRef } from 'vue'
setup(props) {
const title = toRef(props, 'title')
console.log(title.value)
}
- context
1). expose
如果我们的 setUp 直接返回了一个 jsx ,这时我么还想同时返回一个方法让父组件使用我们就可以使用 expose,不需要 return 直接可以暴露给父组件使用
- 子组件
import { h, ref } from 'vue'
export default {
setup(props, { expose }) {
const count = ref(0)
const increment = () => ++count.value
expose({
increment
})
return () => h('div', count.value)
}
}
- 父组件
const testRef = ref()
const onClick = () => {
testRef.value.increment?.()
}
return (
<div onClick={onClick}>
<Parent ref={testRef}/>
</div>
)
- Provide / Inject
Provide 提供一个属性或者方法给其他组件用(要确保Provide 传递的数据是只读的),其他组件可以通过 Inject 使用
- A.tsx
import { provide, reactive, readonly, ref } from 'vue'
setup() {
const location = ref('North Pole')
const geolocation = reactive({
longitude: 90,
latitude: 135
})
const updateLocation = () => {
location.value = 'South Pole'
}
provide('location', readonly (location))
provide('geolocation', readonly (geolocation))
provide('updateLocation', updateLocation)
return () => (<B />)
}
- B.tsx
import { inject } from 'vue'
export default {
setup() {
const userLocation = inject('location', 'The Universe')
const userGeolocation = inject('geolocation')
const updateUserLocation = inject('updateLocation')
return {
userLocation,
userGeolocation,
updateUserLocation
}
}
}
- watchEffect
只有回调里使用了的ref变了才会执行
const testRef = ref(0)
const xRef = ref(0)
watchEffect(() => {
console.log(xRef.value, 'iii')
})
// 等价于
useEffect(() => {}, [xRef.value])
上面的代码只有 xRef.value 变了才会执行
- watch
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
)
// 直接侦听ref
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})
// 侦听多个
const firstName = ref('')
const lastName = ref('')
watch([firstName, lastName], (newValues, prevValues) => {
console.log(newValues, prevValues)
})
firstName.value = 'John' // logs: ["John", ""] ["", ""]
lastName.value = 'Smith' // logs: ["John", "Smith"] ["John", ""]
- reactive
对象类型的 ref,可以直接通过变量.属性访问不需要通过 value
const testRef = reactive({number: 1})
console.log(restRef.number)
- setup
setup 对于普通表达式和语句如果不是在 return 里只会执行一次
比如:
setup: (props, context) => {
const current = ref(0)
const array = [
{name: 'lifa'},
{name: 'hh'}
]
// 这里因为我们的value只是一个普通的变量所以只会在初始化的时候执行一次
//也就是初始值 lifa,所以下面我们点击切换的时候,即使点击 hh,value 值也不会变化
const value = array[current.value].name
const onClick = (index) => {
current.value = index
}
// 上面这部分代码只会在初始化的时候执行一次
// return 里面的代码每次重新 render 都会重新执行
return () => (
<div>
<div style={{marginBottom: '20px'}}>{array.map((item, index) => <div onClick={() => onClick(index)} style={{marginBottom: '10px', fontSize: '16px'}}>{item.name}</div>)}</div>
<div>{value}</div>
</div>
)
}
如果想要我们的value变化有两种方式
1). 写在 return 里(不推荐)
setup: (props, context) => {
const current = ref(0)
const array = [
{name: 'lifa'},
{name: 'hh'}
]
const onClick = (index) => {
current.value = index
}
return () => {
const value = array[current.value].name
return (
<div>
<div style={{marginBottom: '20px'}}>{array.map((item, index) => <div onClick={() => onClick(index)} style={{marginBottom: '10px', fontSize: '16px'}}>{item.name}</div>)}</div>
<div>{value}</div>
</div>
)
}
}
2). 使用 computed
setup: (props, context) => {
const current = ref(0)
const array = [
{name: 'lifa'},
{name: 'hh'}
]
const value = computed(() => {
return array[current.value].name
})
const onClick = (index) => {
current.value = index
}
return () => (
<div>
<div>{array.map((item, index) => <div onClick={() => onClick(index)}>{item.name}</div>)}</div>
<!--注意这里得用.value-->
<div>{value.value}</div>
</div>
)
}
- toRaw
将 proxy 数据转化为原始数据
const formData = reactive({
name: '',
sign: '',
})
const onSubmit = (event: Event) => {
console.log(formData, 'fff')
event.preventDefault()
}
上面不加 toRaw 结果如下
加 toRaw 就是原始对象
console.log(toRaw(formData), 'fff') // {name: '', sign: ''}
网友评论