Vue学习笔记10:compositionAPI

148 阅读3分钟

1.认识Mixin

由于组件和组件之间有时候存在相同的代码逻辑,我们希望对相同的代码逻辑进行抽取。 Mixin提供了一种非常灵活的方式帮我们进行 mixin是一个对象,比如: demoMixin.js

export const demoMixin = {
    data(){
        return {
            msg:'hello mixin'
        }
    },
    methods:{
        foo(){
            console.log('demo mixin')
        }
    },
    created(){
        console.log('created')
        this.foo()
    }
}

App.vue

<template>
  <div>{{msg}}</div>
  <button @click="foo">1111</button>
</template>

<script>

import {demoMixin} from "./components/01_mixin和extend/demoMixin.js"
export default {
  name: 'App',
  mixins:[demoMixin],
}
</script>

可见,即使我们没有定义过msg变量和foo方法,我们依然可以通过混入,直接调用

mixin混入的合并规则:

1.对于data中相同的变量名:冲突时,优先当前组件的变量

2.声明周期合并时,将多个声明周期钩子放入数组中,全部执行

3.对象类型合并时,直接合并

全局混入Mixin:

main.js

import { createApp } from 'vue'
import App from './App.vue'
import { demoMixin } from './components/01_mixin和extend/demoMixin'

const app = createApp(App)

app.mixin(demoMixin)

app.mount('#app')

这样,所有的组件就可以用demomixin中的数据和方法了!

2.extends

extends在扩展继承第三方组件上功劳很大,不仅保留了原组件的所有功能,还能按照你所需覆盖原有功能,和mixins的区别是:mixins不会覆盖方法和生命周期钩子,但是extends会。

<template>
  <div>
      <h2>home</h2>
      <div>{{msg}}</div>
  </div>
</template>

<script>
import titleVue from "./title.vue"
export default {
  extends:titleVue,
}
</script>

3.composition API

在optionAPI中,单文件中的一个功能模块的代码是分离开的,过于分散,难以阅读和理解。因此vue3提出了全新的api

vue3的灵魂:setup函数

3.1 setup的参数

<template>
  <div>
      <h2>new API</h2>
      <button @click="btnClick">按钮</button>
  </div>
</template>

<script>
export default {
    props:{
        message:String
    },
    // setup函数的参数:props,context
    // setup函数的返回值
    // setup中没有绑定this,不能使用
    setup(props,context){
        // props,父组件传递过来的属性
        console.log(props)
        // context包含三个属性 1.attrs,2.slots,3.emit
        const {attrs,slots,emit} = context
         
    }
}
</script>

setup接受两个参数 props和context:

props: 接受父组件传递过来的属性

context: 包含三个属性-attrs、slots和emit

3.2 setup的返回值

setup可以返回一个对象,其中的属性可以在template中使用

setup(props,context){
        // props,父组件传递过来的属性
        console.log(props)
        // context包含三个属性 1.attrs,2.slots,3.emit
        const {attrs,slots,emit} = context
        let counter = 0
        const increment = ()=>{
            counter++
        }
         
         return {
             title:'add the counter',
             name:'wjm',
             counter,
             increment
         }
    }

返回的属性和方法都可以在template中使用,但此时,setup返回对象中的数据并不是响应式的;

reactive API

如果想要为setup中的数据提供响应式的特性,我们可以用vue提供的reactive对要响应式的数据进行包裹

<script>
import {reactive} from 'vue'
export default {
    props:{
        message:String
    },
    setup(props,context){
        const {attrs,slots,emit} = context
        const state = reactive({
            counter:0
        })
        const increment = ()=>{
            state.counter++
        }        
         return {
             title:'add the counter',
             name:'wjm',
             state,
             increment
         }
    }
}
</script>

ref API

也可以使用vue提供的ref

<script>
import {ref} from 'vue'
export default {
    setup(props,context){
        let counter = ref(0)
        const increment = ()=>{
            //需要修改时,对value属性修改
            counter.value++
        }
         
         return {
             title:'add the counter',
             name:'wjm',
             counter,
             increment
         }
    }
}
</script>

调用ref方法后,返回一个可变的响应式对象,其内部的值是在value属性中保存的

如果要在template中使用时,vue会帮我们自动解包,直接使用即可,不必调用value

ref的解包只能是一个浅层解包,将ref包裹进对象后就不能解包了

readonly API

如果我们传入给其他组件的响应式对象,希望其使用,但是不能被修改,vue3为我们提供了readonly方法

readonly会返回原生对象的只读代理,(set方法被劫持的proxy)

<script>
import {reactive,ref,readonly} from 'vue'
export default {
  setup(){
    //   普通对象
    const info1 = {name:'wjm'};
    const readonlyInfo1 = readonly(info1)

    // 响应式对象 reactive
    const info2 = reactive({
        name:'wjm'
    })
    const readonlyinfo2 = readonly(info2)
    // 响应式对象 ref
    const info3 = ref('wjm')
    const readonlyinfo3 = readonly(info3)

    const updateState = ()=>{
        info3.value = 'mr wu'
    }

    return {
        updateState
    }

  }
}
</script>

3.3 setup不绑定this

在setup被调用之前,data,computed,methods等都没有被解析;源码中,options处理部分在setup的调用时,没有绑定任何this,所以无法在setup中获取this