1、Options API==>Composition API
2、setup
import {toRefs} from 'vue'
export default {
name: 'demo',
props:{
name: String,
},
// setup()作为在组件内使用Composition API的入口点。
// 执行时机是在beforeCreate和created之间,不能使用this获取组件的其他变量,
// 而且不能是异步。setup返回的对象和方法,都可以在模版中使用。
setup(props, context){
// 这里需要使用toRefs来进行解构
// 这里的props与vue2基本一致,当然这里的name也可以直接在template中使用
const { name }=toRefs(props);
console.log(name.value);
// context是一个上下文对象
//【从原来 2.x 中 this 选择性地暴露了一些 property(attrs/emit/slots)】
// 属性,同vue2的 $attrs
console.log(context.attrs);
// 插槽
console.log(context.slots);
// 事件,同vue2的 $emit
console.log(context.emit);
// 生命周期钩子
onMounted(() => {})
}
}
注意点:
- 注意 props 对象是响应式的,watchEffect 或 watch 会观察和响应 props 的更新,不要解构 props 对象,那样会使其失去响应性
- attrs 和 slots 都是内部组件实例上对应项的代理,可以确保在更新后仍然是最新值。所以可以解构,无需担心后面访问到过期的值
this在 setup()中不可用。由于 setup() 在解析 2.x 选项前被调用,setup() 中的 this 将与 2.x 选项中的 this 完全不同。同时在 setup() 和 2.x 选项中使用 this 时将造成混乱
3、ref和reactive
|
| ref | reactive | | —- | —- | —- | | 入参 | 基本类型 | 引用类型 | | 返回值 | 响应式且可变的 ref 对象 | 响应式代理(Proxy) | | 访问方式 | 1.ref 对象拥有一个指向内部值的单一属性.value
2.在dom和setup()的return中会自动解套
3.ref 作为 reactive 对象的 property 被访问或修改时,也将自动解套 | 直 |
A、ref简单的计数
<template>
<div>
<p><button @click="add">{{count}}</button></p>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
setup(){
// ref 对我们的值创建了一个响应式引用
var count = ref(0);
const add = ()=>{
count.value++
}
return {
count, // return返回会自动解套【在模板中不需要.value】
add
}
}
}
</script>
B、reactive
// reactive
// 接收一个普通对象然后返回该普通对象的响应式代理
<template>
<div>
<p><button @click="state.add">{{state.count}}</button></p>
</div>
</template>
<script>
import {reactive} from 'vue'
export default {
setup(){
var state = reactive({
count:1,
add(){
state.count++
}
})
return {
state
}
}
}
</script>
Tips:不能对reactive执行解构
问题 & 注意点: 因为reactive是组合函数【对象】,所以必须始终保持对这个所返回对象的引用以保持响应性,不能解构该对象或者展开
C、toRefs
用来提供解决此约束的办法——它将响应式对象的每个 property 都转成了相应的 ref【把对象转成了ref】
<template>
<div>
<p><button @click="add">{{count}}</button></p>
</div>
</template>
<script>
import {reactive, toRefs} from 'vue'
export default {
setup(){
const state = reactive({
count:1,
add(){
state.count++
}
})
const refState = toRefs(state)
return {
...refState
}
}
}
</script>
4、自定义Hooks
A、Hooks/CountHook.js
<template>
<div>
<p><button @click="add">{{count}}</button></p>
</div>
</template>
<script>
import {reactive, toRefs} from 'vue'
export default {
setup(){
const state = reactive({
count:1,
add(){
state.count++
}
})
const refState = toRefs(state)
return {
...refState
}
}
}
</script>
B、父页面
<template>
<div>
<button @click="add">{{count}}</button>
</div>
</template>
<script>
import {useCounter} from './Hooks/CityHook'
export default {
setup(){
return {
...useCounter()
}
}
}
</script>
5、计算和侦听
A、计算属性
<template>
<div>
<button @click="add">{{count}}</button>
<p>{{double}}</p>
</div>
</template>
<script>
import { ref } from '@vue/reactivity'
import { computed } from '@vue/runtime-core';
export default {
setup(){
const count = ref(0);
const add=()=>{
count.value++
}
//不支持修改,只读属性
const double = computed(()=>{
return count.value*2
})
return {
count,
add,
double
}
}
}
</script>
B、计算属性get-set
<template>
<div>
<input type="checkbox" v-model="checkState">
</div>
</template>
<script>
import { ref,computed } from 'vue'
export default {
setup(){
let state = ref(false);
let checkState = computed({
get:()=>state.value,
set:(val)=>{
state.value = val
}
})
return {
checkState
}
}
}
</script>
C、watch ref监听一个值
<template>
<div><button @click="add">{{count}}</button></div>
</template>
<script>
import { ref } from '@vue/reactivity'
import { watch } from '@vue/runtime-core';
export default {
setup(){
let count = ref(0);
const add = ()=>{
count.value++
}
watch(count,(count,prevCount)=>{
console.log(count,prevCount)
})
return {
count,
add
}
}
}
</script>
D、watch reactive
<template>
<div><button @click="add">{{count}}</button></div>
</template>
<script>
import { reactive,toRefs } from '@vue/reactivity'
import { watch } from '@vue/runtime-core';
export default {
setup(){
let state = reactive({
count:1,
add(){
state.count++
}
})
let refState = toRefs(state);
watch(state,()=>{
console.log(state.count)
})
return {
...refState
}
}
}
</script>
优化 箭头函数
<template>
<div><button @click="add">{{count}}</button></div>
</template>
<script>
import { reactive,toRefs } from '@vue/reactivity'
import { watch } from '@vue/runtime-core';
export default {
setup(){
let state = reactive({
count:1,
add(){
state.count++
}
})
let refState = toRefs(state);
watch(()=>state.count,()=>{
console.log(state.count)
})
return {
...refState
}
}
}
</script>
F、watch监听多个值
以数组的形式监听多个值
6、多个根节点
<template>
<div>hello</div>
<div>world</div>
</template>