快速搞懂Composition API

在Vue3.0中,对于编程语法方面最大的亮点应该就是Composition API,可以避免我们在Vue2.x中的碎片化编程的方式,易于后期维护。闲话不多说,我们学习一下Composition API的主要思想和使用,在整个过程中我们会使用鼠标位置显示的小栗子来讲解。

实例代码

setup

setup是组合式(Composition)编程的入口,setup接受两个值:props 和 context,在这里我们先不讲解;返回一个对象,我们将需要返回的内容放在这个对象中,这样在组件其余部分(比如:计算属性、方法、生命周期钩子等等)都可以访问到。

setup在组件创建之前执行,也就是说在setup千万不要调用this,因为是undefined,同样也不要访问data property、computed property 或 methods,因为也是访问不到滴。

<body>
    <div id="app">
        X: {{position.x}}  <br/>
        y: {{position.y}}
    </div>
    <script type="module">
        import {createApp} from './node_modules/vue/dist/vue.esm-browser.js'
        createApp( {
            setup() {
                let position = {
                    x: 0,
                    y: 0
                }
                return {
                    position
                }
            },
            mounted() {
                console.log(this.position)
                this.position.x = 100
             }
        }).mount("#app");        
    </script>
</body>

reactive

在上述例子中,position不是响应式的数据,所以在mounted中,我们改变其值,页面不会变化,可以通过reactive使数据变为响应式数据。

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

生命周期函数

虽然vue有声明周期函数,但是因为我们将来要把一个功能抽离到一个函数中,所有在setup中要用到声明周期函数。在setup中使用生命周期函数的话,需要前面加on,并且首字母大写。在上面的例子中,我们在onMounted中监听鼠标滑动事件,在onUnmounted函数中去除鼠标监听事件。

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

onMounted(()=> {
    
    window.addEventListener("mousemove",updataMousePosition)
}) 

onUnmounted(()=> {
    window.removeEventListener("mousemove",updataMousePosition)
})

提取函数

Composition API 的核心思想就是将不同的功能封装到不同的函数中,因此我们将上边获取鼠标移动位置,封装成一个函数。

function getMousePosition() {
	let position = reactive({
	        x: 0,
	        y: 0
	 })
	  const updataMousePosition = (e)=>{
	      position.x = e.pageX
	      position.y = e.pageY
	  };
	
	  onMounted(()=> {
	      
	      window.addEventListener("mousemove",updataMousePosition)
	  }) 
	
	  onUnmounted(()=> {
	      window.removeEventListener("mousemove",updataMousePosition)
	  })
	
	  return position;
}

setup() {
  let position =  getMousePosition()  
  return {
     position
  }
},

toRefs

toRefs 会将响应式对象的属性,变成相应式的,方便我们结构某个响应式对象,传递给toRefs函数的参数必须是代理对象,不然会警告。

function getMousePosition() {
   let position = reactive({
            x: 0,
            y: 0
        })
    ......
  return toRefs(position);      
}

setup() {
    let {x,y} =  getMousePosition()  
    return {
       x, y
    }
},

reactive 和 ref

reactive 是将引入类型的数据变成响应式数据;而ref是将基本类型的数据转化为响应式数据。

<body>
    <div id="app">
        <button @click="increase">+</button>
        <span>{{count}}</span>
    </div>
    <script type="module">
        import {ref, createApp} from './node_modules/vue/dist/vue.esm-browser.js'
        function useCount() {
            let count = ref(0)
            return {
                count,
                increase:()=> {
                    count.value += 1;
                }
            }
        }
        createApp({
            setup() {
                return {
                    ...useCount()
                }
            }
        }).mount("#app")
        
    </script>
</body>

computed

当对一个响应式数据做某种处理后,展示可以使用computed,computed有两种使用方法:

  1. 接受一个getter函数,返回一个不变的响应式对象
  2. 使用具有 get 和 set 函数的对象
    在这里演示第一种用法
 createApp({
     setup() {
      let todo = reactive(todos)

      let noComputedCount = computed(()=> todo.filter(item=>!item.isCompleted).length)
      console.log(noComputedCount)
      return {
          noComputedCount,
          plus:()=>{
              todo.push({
                  item:"吃饭",
                  isCompleted: false
              }) 
          }

      }

     }
 }).mount("#app")

watch 监听数据的变化

在vue3.0中watch的使用和Vue2.0基本一致,在传参时有个变化,在vue2.x中,第一个参数是字符串,而在vue3.0中是要监听的响应式对象。

<body>
    <div id="app">
        <div>请输入问题:<input type="text" v-model="question"></div>
        <div>答案:{{answer}}</div>

    </div>
    <script type="module">
        import {createApp, watch, ref} from './node_modules/vue/dist/vue.esm-browser.js'
        import debounce from './node_modules/lodash-es/debounce.js'

        createApp({
            setup() {
                let question = ref("")
                let answer = ref("")
                const getData = async () => {

                    let data =  await fetch('https://www.yesno.wtf/api')
                    answer.value = data.statusText
                  
                }
                watch(question,debounce(getData, 300))
              
                return {
                    question,
                    answer
                }
            }
        }).mount("#app");
    </script>
</body>

watchEffect

watchEffect的作用和watch一致,只不过在语法上有点不一样,watchEffect接收一个函数,在函数内的响应式对象有变化时,这个函数就会被执行一次。watchEffect返回暂停函数,当这个函数被调用后,watchEffect就不起作用了。

<body>
    <script type="module">
        import {createApp, watchEffect, ref} from './node_modules/vue/dist/vue.esm-browser.js'
        createApp({
            setup() {
                let count = ref(0)
                let stop = watchEffect(()=>{
                    console.log(count.value)
                })
                return {
                    count,
                    stop,
                    increase:()=>{
                        count.value += 1;
                    }
                }
            }
        }).mount("#app")
    </script>
</body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值