# Composition API

createApp

main.js

// 创建一个vue实例
import { createApp } from 'vue'
import App from './App.vue'

// 挂载应用实例
createApp(App).mount('#app')

setup


<template>
  <div>{{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    setup() {
      // setup 是 Composition API 的入口,接收两个参数 props context
      // props 接收外部传入的参数,props是响应式的对象不能被解构
      // context 是一个对象有三个成员, attr/emit/slots
      // setup是在props解析完毕,在组件被创建之前执行,无法通过 this 获取组件实例

      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      return {
        // setup返回一个对象,该对象上的属性将合并到组件模板的渲染上下文中
        readersNumber,
        book
      }
    }
  }
</script>

reactive, onMounted, onUnmounted, toRefs, ref

  • ref: 接受一个参数值并返回一个响应式且可改变的 ref 对象。ref 对象拥有一个指向内部值的单一属性 .value。
  • reactive: 接收一个普通对象然后返回该普通对象的响应式代理。等同于 2.x 的 Vue.observable()
  • toRefs 转换所有key为响应式数据
<template>
  <div>
    x: {{ x }}
    <br />
    y: {{ y }}
    <br>
  </div>
</template>

<script>

import { reactive, onMounted, onUnmounted, toRefs } from 'vue'

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

function useMousePosition() {

  const position = reactive({
    x: 0,
    y: 0,
  })

  const update = (e) => {
    position.x = e.pageX
    position.y = e.pageY
  }

  onMounted(() => {
    window.addEventListener('mousemove', update)
  })

  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })

  return toRefs(position)
}

export default {
  name: 'App',
  setup () {
    const { x, y } = useMousePosition()
    return {
      x,
      y,
    }
  }
}
</script>

computed

  • computed: 传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象。

<template>
  <div>
    x: {{ x }}
    <br />
    y: {{ y }}
    <br>
  </div>
</template>

<script>

import { reactive, computed } from 'vue'

const data = [
  { text: "炉石", completed: false },
  { text: "下棋", completed: false },
  { text: "LOL", completed: true }
]

export default {
  name: 'App',
  setup() {
    const todos = reactive(data)

    const activeCount = computed(()=>{
      return todos.filter(item => !item.completed).length
    })

    return {
      activeCount,
      push: () => {
        todos.push({
          text: '绝地求生',
          completed: false
        })
      }
    }
  }
}

</script>

watch

  • watch API 完全等效于 2.x this.$watch (以及 watch 中相应的选项)。watch 需要侦听特定的数据源,并在回调函数中执行副作用。默认情况是懒执行的,也就是说仅在侦听的源变更时才执行回调。

<template>
  <div>
    <p>
      yes/no
      <input v-model="question" />
    </p>
    <p>{{ answer }}</p>
  </div>
</template>

<script>

import { ref, watch } from 'vue'

export default {
  name: 'App',
  setup() {
    const question = ref('')
    const answer = ref('')
    watch(question, async (newValue, oldValue) => {
      const respones = await fetch('https://www.yesno.wtf/api')
      const data = await respones.json()
      answer.value = data.answer
    })

    return {
      question,
      answer
    }
  }
}


</script>

watchEffect

  • 它在响应跟踪依赖项的同时立即运行函数,并在依赖项发生更改时重新运行函数。

<template>
  <div>
    <button @click="increase">increase</button>
    <button @click="stop">Stopping the Watcher</button>  // 停止
  </div>
</template>

<script>

import { ref, watchEffect } from 'vue'

export default {
  name: 'App',
  setup () {
    const count = ref(0)
    const stop = watchEffect(()=>{
      console.log(count.value)
    })

    return {
      count,
      stop,
      increase: () => {
        count.value++
      }
    }
  }
}
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值