15Vue-API(一)

186 阅读2分钟

前序

以前我们使用的data()、computed()等等,在Composition API中都不会再使用了,API可以替代

认识Mixin

我们的Compositio API就是替代Mixin

图片.png 以前放在组件中的数据,我们都可以放在Mixin中 data/methods/computed等等

1.新建mixins文件夹,里面存放Mixin.js文件,书写代码

export const Mixin = {
    data(){
        return{
            message:"Hello"
        }
    },
    methods:{
        foo(){
            console.log('foo')
        }
    },
    //生命周期函数
    created(){
        console.log('created')
    }
}

2.App.vue

<template>
    <div>
       //引入mixins后,就可以使用里面的数据和方法
        <h2>{{message}}</h2>
        <button @click="foo"></button>
    </div>
</template>

<script>
    import {Mixin} from './Minix.js'
    export default{
        mixins:[Mixin],
        data(){
            return{
                
            }
        }
    }
</script>
Mixin的合并规则

优先保存自身组件中的数据 但是:生命周期都会被调用

图片.png

全局混入Mixin

图片.png

main.js

const app = createApp(App)

app.mixin({
    data(){
        return{}
    },
    methods:{
    }
});
Composition API

我们曾经使用的Options API的弊端

图片.png

同一个逻辑写一块,而不是像Options API一样如此分散

图片.png

图片.png

Home.vue

<template>
    <div>
        
    </div>
</template>

<script>
    export default{
 //尽管setup有参数props,但是还需要写props
        props:{
            message:{
                type:String,
                required:true
            }
        },
        //setup函数有哪些参数、有什么样的返回值
        //setup中,不可以使用this
        setup(props,context){
        //props:父组件传递过来的属性
        //因为不可以用this,所以用props拿数据
            console.log(props)
            
        context.attrs.id/class
        context.slots
        context.emit
        -->1.attrs[所有非prop的属性、class]
        -->2.slots[父组件传递过来的插槽]
        -->3.emit[组件需要发出事件时,可以用到]
        }    
    }
</script>

context的解构写法:

setup(props,{attrs,slots,emit}){
    //此时使用的时候,就不用再使用context调用
    console.log(attrs.id,attrs.class)
    console.log(slots)
    console.log(emit)
}    
setup的使用

图片.png setup的返回值

<template>
    {{title}}
</template>

<script>
export default{
    props:{
        message:{
            type:String,
            required:true
        }
    },
    
    setup(props,{attrs,slots,emit}){
        console.log(attrs.id,attrs.class)
        console.log(slots)
        console.log(emit)
    //return后的数据,可以在template中使用
        return{
            title:"标题"
        }
    },
    
}    
</script>

图片.png

实际上这里就算点了方法,页面展示的count也不会变,因为在vue2中,我们使用data的时候,实际上使用reactive()进行了包裹,因此这里我们没有包裹就只能展示最初始的数据,没有响应式。

图片.png

如何实现在Composition API中实现响应式功能? 我们需要学会儿Reactive API

Reactice API
{{state.count}}
setup(){
//绑定reactive()
//会数据劫持Proxy,然后调用Proxy.get(){},知道你取了counter的数据
    const state = reactive({
        counter:100
    })
    return{
        state,
    }
}

图片.png

setup中的this问题

图片.png

Ref API

图片.png

//counter变成了一个ref的可响应式的引用
let counter = ref(100)

这个时候如果我添加方法,对counter进行改变,此时counter已经是响应式的了。

但是counter已经是对象了,所以在方法中使用counter的值的时候需要:counter.value++;但是在template模板中使用ref对象,会自动解包的,直接使用{{counter}}

<template>{{counter}}</template>
increate(){counter.value++}

注:我们ref的解包只能是一个浅层解包(info是一个js的对象,在他里面写上ref过的counter,是不能解包的)

<template>
    {{info.counter.value}}
</template>

setup(){
    let counter = ref(100);
    const info = {
        counter
    }
}

但是如果最外层包裹的是一个reactive可响应对象,那么ref的数据是可以自动解包的(不推荐这样嵌套)

setup(){
    let counter = ref(100);
    const info = reactive({
        counter
    })
}
认识readonly

图片.png

import {ref,reactive,readonly} from 'vue'
setup(){
   const info = {name:"why"};
   const readonlyInfo = readonly(info)
   const readonlyInfo2 = reactive({
       name:"why"
   })
   const readonlyInfo3 = ref("why")
   
   const updateState = () =>{
       //readonlyInfo.name = "coderwhy"
       readonlyInfo2.name = "coderwhy"
       同样也是修改不了的
       
       ref需要通过value来修改
       readonlyInfo3.value="coderwhy"
       还是改不了
   }
   return{
       updateState
   }
   此时使用update方法,会输出warn警告
}