Composition API
一、Composition API使用
1. 使用Vue3.0
先创建一个空文件夹,然后进入文件夹执行npm init -y
,再执行npm install vue@3.0.0-rc.1
安装vue3.0
创建index.html,vue3.0的使用
<body><div id="app">x: {
{ position.x }} <br>y: {
{ position.y }} <br></div><script type="module">import {
createApp } from './node_modules/vue/dist/vue.esm-browser.js'const app = createApp({
data () {
return {
position: {
x: 0,y: 0}}}})console.log(app)app.mount('#app')</script>
</body>
2. setup、reactive的使用
- createAPP:创建Vue对象
- setup:CompositionAPI的入口
- reactive:创建响应式对象
<body><div id="app">x: {
{ position.x }} <br>y: {
{ position.y }} <br></div><script type="module">import {
createApp, reactive } from './node_modules/vue/dist/vue.esm-browser.js'const app = createApp({
setup () {
// 第一个参数 props,响应式对象,不能被解构// 第二个参数 context, attrs、emit、slotsconst position = reactive({
x: 0,y: 0})return {
position}},mounted () {
this.position.x = 2}})console.log(app)app.mount('#app')</script>
</body>
二、 setup中的生命周期钩子函数
只需要在vue钩子函数首字母大写,并且钩子函数前面加上on,就可以了。特殊:原本的生命周期中的destroy对应的是onUnmounted。
<body><div id="app">x: {
{ position.x }} <br>y: {
{ position.y }} <br></div><script type="module">import {
createApp, reactive, onMounted, onUnmounted } from './node_modules/vue/dist/vue.esm-browser.js'function useMousePosition () {
const position = reactive({
x: 0,y: 0})const update = e => {
position.x = e.pageXposition.y = e.pageY}onMounted(() => {
window.addEventListener('mousemove', update)})onUnmounted(() => {
window.removeEventListener('mousemove', update)})return position}const app = createApp({
setup () {
const position = useMousePosition()return {
position}},mounted () {
this.position.x = 2}})console.log(app)app.mount('#app')</script>
</body>
三、reactive-toRefs-ref
reactive创建的响应式数据解构后不再是响应式,toRefs可以把响应式对象的所有属性也转化成响应式的,所以可以解构toRefs返回的对象,解构之后还是响应式数据。
reactive是将普通对象转化成响应式对象,而ref是将基本类型数据包装成了响应式对象。
ref的使用:
<body><div id="app"><button @click="increase">Button</button><span>{
{count}}</span></div><script type="module">import {
createApp, ref } from './node_modules/vue/dist/vue.esm-browser.js'function useCount () {
const count = ref(0) // 将基本类型数据转化成响应式对象return {
count,increase: () => {
count.value++}}}createApp({
setup () {
return {
...useCount()}}}).mount('#app')</script>
</body>
四、Computed
computed可以创建一个响应式数据,这个响应式数据依赖于其他响应式数据,就是计算属性。
-
第一种用法
- computed(() => count.value + 1)
-
第二种用法
const count = ref(1) const plusOne = computed({ get: () => count.value + 1,set: val => { count.value = val - 1} })
使用:
<body><div id="app"><button @click="push">Button</button><span>未完成:{
{activeCount}}</span></div><script type="module">import {
createApp, reactive, computed } from './node_modules/vue/dist/vue.esm-browser.js'const data = [{
text: '看书', complated: false },{
text: '敲代码', complated: false },{
text: '约会', complated: true },]createApp({
setup () {
const todos = reactive(data)const activeCount = computed(() => {
return todos.filter(item => !item.complated).length})return {
activeCount,push: () => {
todos.push({
text: '开会',complated: false})}}}}).mount('#app')</script>
</body>
五、watch
1. watch的三个参数
- 第一个参数:要监听的数据,得是reactive或ref返回的对象
- 第二个参数:监听到数据变化后执行的函数,这个函数有两个参数分别是新值和旧值
- 第三个参数:选项对象,deep和immediate
2. watch的返回值
- 取消监听的函数
使用:
<body><div id="app">请选择一个yes/no的问题:<input v-model.lazy="question"><p>{
{answer}}</p></div><script type="module">import {
createApp, ref, watch } from './node_modules/vue/dist/vue.esm-browser.js'createApp({
setup () {
const question = ref('')const answer = ref('')watch(question, async (newValue, oldValue) => {
const response = await fetch('https://www.yesno.wtf/api')const data = await response.json()answer.value = data.answer})return {
question,answer}}}).mount('#app')</script>
</body>
六、WatchEffect
- 是watch函数的简化版本,也用来监视数据的变化
- 接受一个函数作为参数,监听函数内响应式数据的变化
<body><div id="app"><button @click="increase">increase</button><button @click="stop">stop</button><p>{
{count}}</p></div><script type="module">import {
createApp, ref, watchEffect } from './node_modules/vue/dist/vue.esm-browser.js'createApp({
setup () {
const count = ref(0)const stop = watchEffect(() => {
console.log(count.value)})return {
count,stop,increase: () => count.value ++}}}).mount('#app')</script>
</body>