• Welcome to Journal web site.

我是 PHP 程序员

- 开发无止境 -

Next
Prev

Vue3 组合API

Data: 2017-10-05 14:44:01Form: JournalClick: 10

# Vue3 组合API

# 一、组合式 API (Compositon API)

  • 官网:https://v3.cn.vuejs.org/guide/composition-api-introduction.htmlopen in new window

  • ​官网:https://v3.cn.vuejs.org/guide/composition-api-setup.htmlopen in new window

  • 官网:https://v3.cn.vuejs.org/api/composition-api.htmlopen in new window

  • Vue3 新增的开发模式,把条条框框的js代码(data、methods、components、props),都放到一起

  • 使用传统的option配置方法写组件的时候问题,随着业务复杂度越来越高,代码量会不断的加大;由于相关业务的代码需要遵循option的配置写到特定的区域,导致后续维护非常的复杂,同时代码可复用性不高,而composition-api就是为了解决这个问题而生的。

  • Composition API字面意思是组合API,它是为了实现基于函数的逻辑复用机制而产生的。主要思想是,我们将它们定义为从新的 setup 函数返回的JavaScript变量,而不是将组件的功能(例如state、methods、computed等)定义为对象属性。


# 二、setup 方法

  • setup() 函数是vue3中专门新增的方法,可以理解为 Composition Api 的入口
  • Vue3.2 版本新写法:除以下2种情况外,都应优先使用 script setup 语法
    • 需要在非单文件组件中使用组合式 API 时。
    • 需要在基于选项式 API 的组件中集成基于组合式 API 的代码时。

# 1、setup 使用

// 打开 src/Views/Home.vue
// 1、创建setup方法
// 1.1、创建一个常量
// 1.2、无须 return 返回
<template>
    <div>
        <div>{{ data }}</div>
    </div>
</template>
<script setup>
    const data = 10;
</script>
// 打开 src/Views/Home.vue
// 1、创建setup方法
// 1.1、创建一个常量
// 1.2、必须 return 返回,才能给模版使用
<template>
    <div>
        <div>{{ data }}</div>
    </div>
</template>
<script>
export default {
    name: "Home",
    setup() {
        const data = 10;
        return {
            data
        }
    }
};
</script>

# 2、setup 使用 js 方法

// 打开 src/Views/Home.vue
// 1、点击方法,不能使用
<template>
    <div>
        <div>{{ data }}</div>
        <button @click="data++">++</button>
    </div>
</template>
<script setup>
    const data = 10;
</script>

//  2、reactive 返回对象的响应式副本
//  所有的 api 都是方法、函数
<template>
    <div>
        <div>{{ data.number }}</div>
        //  2.2、使用 reactive 方法创建的数据,就能相应了
        <button @click="data.number++">++</button>
        //  2.3、执行方法
        <button @click="jian()">++</button>
    </div>
</template>
<script setup>
    // 2.1、引入 reactive 方法
    import {reactive} from 'vue';
    // 2.2、使用reactive方法,创建数据
    const data = reactive({
        number : 10
    })
    // 2.4、创建方法
    const jian = () => {
        data.number--;
    }
</script>
// 打开 src/Views/Home.vue
// 1、点击方法,不能使用
<template>
    <div>
        <div>{{ data }}</div>
        <button @click="data++">++</button>
    </div>
</template>
<script>
export default {
    name: "Home",
    setup() {
        const data = 10;
        return {
            data
        }
    }
};
</script>

//  2、reactive 返回对象的响应式副本
//  所有的 api 都是方法、函数
<template>
    <div>
        <div>{{ data.number }}</div>
        //  2.2、使用 reactive 方法创建的数据,就能相应了
        <button @click="data.number++">++</button>
        //  2.3、执行方法
        <button @click="jian()">++</button>
    </div>
</template>
<script>
// 2.1、引入 reactive 方法
import {reactive} from 'vue';
export default {
    name: "Home",
    setup() {
        // 2.2、使用reactive方法,创建数据
        const data = reactive({
            number : 10
        })
        // 2.4、创建方法
        const jian = () => {
            data.number--;
        }
        // 2.5、方法也要return
        return {
            data,
            jian
        }
    }
};
</script>

# 3、setup 计算属性

<template>
    <div>
        <div>{{ data.number }}</div>
        // 1.3、使用数据
        <div>{{ data.jisuan }}</div>
        <button @click="data.number++">++</button>
        <button @click="jian()">++</button>
    </div>
</template>
<script setup>
    // 1.1、引入 computed 方法
    import {reactive,computed} from 'vue';
    // 1.2、computed 计算属性
    const data = reactive({
        number : 10,
        jisuan : computed( ()=>data.number * data.number )
    })
    const jian = () => {
        data.number--;
    }
</script>
<template>
    <div>
        <div>{{ data.number }}</div>
        // 1.3、使用数据
        <div>{{ data.jisuan }}</div>
        <button @click="data.number++">++</button>
        <button @click="jian()">++</button>
    </div>
</template>
<script>
// 1.1、引入 computed 方法
import {reactive,computed} from 'vue';
export default {
    name: "Home",
    setup() {
        // 1.2、computed 计算属性
        const data = reactive({
            number : 10,
            jisuan : computed( ()=>data.count * data.count )
        })
        const jian = () => {
            data.number--;
        }
        return {
            data,
            jian
        }
    }
};
</script>

# 4、setup 里面没有 this

// 1、setup 方法里没 this,因为它是最先运行的
<template>
    <div>
        <div>{{ name }}</div>
    </div>
</template>
<script>
export default {
    name: "Home",
    data() {
        return {
            name: "php中文网"
        }
    },
    // 1.1、打印结果是 setup 先运行
    beforeCreate() {
        console.log("beforeCreate");
        // 1.2、这个打印this.name,空值,但不报错,说明有this
        console.log(this.name);
    },
    created() {
        console.log("created");
        // 1.3、这个打印this.name,就有值,说明已经运行了data
        console.log(this.name);
    },
    beforeMount() {
        console.log("beforeMount");
    },
    setup() {
        console.log("setup");
        // 1.4、这个打印this.name,就会报错,说明没有this,就是这样设计的
        console.log(this.name);
    }
};
</script>

# 三、组件

# 1、组件传值

// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        # 1.1、使用one组件,传2个值,前2个值会被props接收,后2个值不会被props接收
        <one one="1111" two="2222" three="3333" four="4444"></one>
    </div>
</template>
<script setup>
import One from "../components/One.vue";
</script>

// 2、打开组件 src/components/One.vue
<template>
    <div>
        one = {{ one }} 
        two = {{ two }} 
    </div>
</template>
<script setup>
# 2.2、引入 useAttrs 方法
import { useAttrs } from 'vue'
const attrs = useAttrs()
# 2.3、没有被props接收的数据,未声明的数据。
console.log(attrs);

# 2.4、defineProps 接收传值
const props = defineProps(['one','two'])
# 2.5、defineProps 接收传值,并设置属性
const props = defineProps({
    one: {
        type: String
    },
    two : {
        type: String
    }
})
</script>
// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        # 1.1、使用one组件,传4个值,前2个值会被props接收,后2个值不会被props接收
        <one one="1111" two="2222" three="3333" four="4444"></one>
    </div>
</template>
<script>
import One from "../components/One.vue";
export default {
    components: {
        One
    }
};
</script>

# 2、打开组件 src/components/One.vue
<template>
    <div>
        one = {{ one }} 

        two = {{ two }} 
    </div>
</template>
<script>
    export default {
        name: "One",
        # 2.2、接收2个传值
        props: {
            one: {
                type: String,
            },
            two: {
                type: String,
            }
        },
        # 2.3、在setup里不能使用this,就无法使用props的数据
        # 2.4、setup方法,第一个参数:就是props里接收的数据,参数名可以更改
        # 2.5、第二个参数:没有被props接收的数据,未声明的数据。
        setup(props,context) { // setup(props,{attrs,slots}) 也可以解构赋值 展开
            console.log(props);
            console.log(context); // 里面有attrs参数,就是未接收的数据
            console.log(context.attrs); // Attribute (非响应式对象,等同于 $attrs)
        }
    };
</script>

# 2、插槽

// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        <one one="1111"></one>
        <one one="1111">
            # 1.1、插槽传值
            <div>这是插槽被替换了</div>
        </one>
    </div>
</template>
<script setup>
import One from "./components/One.vue";
</script>

// 2、打开组件 src/components/One.vue
<template>
    <div>
        one = {{ one }}
        # 2.2、插槽
        <slot>插槽</slot>
    </div>
</template>
<script setup>
# 2.3、引入插槽方法
import { useSlots } from 'vue'
const slots = useSlots()
# 2.4、插槽 (非响应式对象,等同于 $slots)
console.log(slots)
# 2.5default() 获取外面传的子内容,必须父组件传了插槽,才有方法。
console.log(slots.default())

const props = defineProps(['one']);
</script>
Name:
<提交>