大前端学习- Vue 3.0 Composition API 快速入门

文章内容输出来源 拉勾教育大前端高薪训练营

本文主要围绕 Composition API 来讲解如何使用,分别是以下几个API 函数, 通过学习,可以让你可以更快上手 Composition API ,掌握 Vue.js 3.0 的新特性。

  • 生命周期钩子变化
  • reactive API
  • toRefs API
  • ref API
  • computed API变化
  • watch API变化
  • toRefs 原理
  • watchEffect API

1、Compostion API

安装Vue3.0 ,体验 createApp 的使用

npm install vue@3.0.0-rc.1

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Documenttitle>
head>
<body>
  <div id="app">
    x: {
    { position.x }}
    y: {
    { position.y }}
  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>
html>

Vue 3.0Vue2.0 的区别,成员要少很多,没有$开头, 使用方式和以前一样

大前端学习- Vue 3.0 Composition API 快速入门_第1张图片

2、生命周期钩子函数

setUp 函数

import {
      createApp, reactive, onMounted, onUnmounted } from './node_modules/vue/dist/vue.esm-browser.js'
const app = createApp({
     
  setup () {
     
    // 第一个参数 props
    // 第二个参数 context, attrs, emit, slots
    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 {
     
      position
    }
  }
})
console.log(app)
app.mount('#app')

当鼠标移动的时候显示鼠标移动的位置,当组件卸载时,鼠标移动的事件也要移除

大前端学习- Vue 3.0 Composition API 快速入门_第2张图片

将获取鼠标位置的方法封装到一个函数中,优化代码

import {
      createApp, reactive, onMounted, onUnmounted } from './node_modules/vue/dist/vue.esm-browser.js'
function useMousePosition () {
     
  // 第一个参数 props
  // 第二个参数 context, attrs, emit, slots
  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 position
}
const app = createApp({
     
  setup () {
     
    const position = useMousePosition()
    return {
     
      position
    }
  }
})
console.log(app)
app.mount('#app')

3、reactive、toRefs 、ref 函数

都是创建响应式数据的

先看上一节出现的小问题

import {
      createApp, reactive, onMounted, onUnmounted } from './node_modules/vue/dist/vue.esm-browser.js'
function useMousePosition () {
     
  // 第一个参数 props
  // 第二个参数 context, attrs, emit, slots
  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 position
}
const app = createApp({
     
  setup () {
     
    // const position = useMousePosition()
    const {
      x, y} = useMousePosition()
    return {
     
      x,
      y
    }
  }
})
console.log(app)
app.mount('#app')

useMousePosition进行解构后,数据不是响应式的了

这里的 position 是响应式对象,因为在useMousePosition中调用了reactive 函数,把传入的对象包装成了 Proxy 对象,也就是说 position 就是 proxy对象,当 position 访问 x, y的时候会调用代理中的 getter 拦截收集依赖,变化的时候会调用 setter

使用 toRefs

import {
      createApp, reactive, onMounted, onUnmounted, toRefs } from './node_modules/vue/dist/vue.esm-browser.js'
...
return toRefs(position)

toRefs原理

toRefs 要求传入的参数 必须为代理对象,当前的 position 就是 reactive返回的代理对象,如果不是的话,会发出警告,提示传递代理对象,
内部会创建一个新的对象,然后遍历传入代理对象的所有属性,把所有属性的值都转换成响应式对象,相当于将postionx, y属性转换成响应式对象,
挂在到新创建的对象上,最后把新创建的对象返回。内部为代理对象的每一个属性创建一个具有 value 属性,value属性具有 getter,setter, getter 中返回对象属性的值,
setter中给代理对象赋值。所以返回的每一个属性都是响应式的

ref 把普通数据转转换成响应式数据,ref 可以把基本类型包装成响应式数据

<div id="app">
  <button @click="increase">点击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>

4、Computed

第一种用法

  • wacth(() => { count.value + 1})

第二种用法

const count = ref(1)

const plusOne = computed({
     
  get: () => {
     
    count.value + 1
  },
  set: val => {
     
    conut.value = val - 1
  }
})
<div id="app">
  <button @click="push">点击button>
  未完成 {
    { activeCount }}
div>
<script type="module">
  import {
       createApp, reactive, computed } from './node_modules/vue/dist/vue.esm-browser.js'

  const  data = [
    {
      
      text: '看书',
      completed: false
    },
    {
      
      text: '敲代码',
      completed: false
    },
    {
      
      text: '学习',
      completed: false
    }
  ]

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

      return {
      
        activeCount,
        push: () => {
      
          todos.push({
      
            text: '开会',
            completed: false
          })
        }
      } 
    }
  }).mount('#app')
script>

5、Watch

Watch 的三个参数

  • 第一个参数: 要监听的数据
  • 第二个参数: 监听到数据变化后执行的函数,这个函数有两个参数分别是新值和旧值
  • 第三个参数: 选项对象, deep 和 immediate
    Watch 的返回值
  • 取消监听的函数

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Documenttitle>
head>
<body>
<div id="app">
  请问一个 yes/no 的问题
  <input v-model="question">input>
  {
    {answer}}
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>
html>

6、watchEffect

  • 是watch 函数的简化版本,也用来监视数据的变化
  • 接收一个函数作为参数,监听函数内响应式数据的变化

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Documenttitle>
head>
<body>
  <div id="app">
    <button @click="increase">increasebutton>
    <button @click="stop">stopbutton>
    <br>
    {
    {count}}
  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>
html>

完整代码请点击这里

你可能感兴趣的:(大前端学习,vue)