count.value++;
};
// watch
watch(
() => count.value * 2,
val => {
console.log(`count * 2 is ${val}`);
}
);
// lifecycle
onMounted(() => {
console.log(`mounted`);
});
// expose bindings on render context
return {
count,
plusOne,
increment,
};
},
};
</script>
详解
setup
setup函数是Vue Function API 构建的函数式写法的主逻辑,当组件被创建时,就会被调用,函数接受两个参数,分别是父级组件传入的props和当前组件的上下文context。看下面这个例子,可以知道在context中可以获取到下列属性值:
const MyComponent = {
props: {
name: String
},
setup(props, context) {
console.log(props.name);
// context.attrs
// context.slots
// context.refs
// context.emit
// context.parent
// context.root
}
}
value & state
value函数创建一个包装对象,它包含一个响应式属性value:

那么为何要使用value呢,因为在JavaScript中,基本类型并没有引用,为了保证属性是响应式的,只能借助包装对象来实现,这样做的好处是组件状态会以引用的方式保存下来,从而可以被在setup中调用的不同的模块的函数以参数的形式传递,既能复用逻辑,又能方便地实现响应式。
直接获取包装对象的值必须使用.value,但是,如果包装对象作为另一个响应式对象的属性,Vue内部会通过proxy来自动展开包装对象。同时,在模板渲染的上下文中,也会被自动展开。
import { state, value } from 'vue-function-api';
const MyComponent = {
setup() {
const count = value(0);
const obj = state({
count,
});
console.log(obj.count) // 作为另一个响应式对象的属性,会被自动展开 obj.count++ // 作为另一个响应式对象的属性,会被自动展开
count.value++ // 直接获取响应式对象,必须使用.value
return {
count,
};
},
template: `<button @click="count++">{{ count }}</button>`,
};
如果某一个状态不需要在不同函数中被响应式修改,可以通过state创建响应式对象,这个state创建的响应式对象并不是包装对象,不需要使用.value来取值。
watch & computed
watch和computed的基本概念与 Vue 2.x 的watch和computed一致,watch可以用于追踪状态变化来执行一些后续操作,computed用于计算属性,用于依赖属性发生变化进行重新计算。










