组合api
选项api
选项api就是把一个个属性如data,method等,作为选项把内容传给组件的对象里
App.vue
<template>
<h1>{{ title }}</h1>
<button @click="changeTitle">变换</button>
</template>
<script>
export default {
data(){
return{
title:"hello world"
}
},
methods:{
changeTitle(){
this.title = "hello vue"
}
}
}
</script>
组合api
把所有的功能写到setup方法里
<template>
<h1>{{ title }}</h1>
<button @click="say">按钮</button>
</template>
<script>
export default {
//composition api 组合api
setup(){
let title = "hello world";
function say(){
alert("hello vue");
}
return{//用来暴露属性或方法等
title,
say
}
}
}
</script>
响应式变量
如果把title变了
function say(){
title = "hello vue"
}
按下按钮显示的hello world也还是不变,这就涉及到响应式的概念
如果title是响应式的,那title值变了,按下按钮后会跟着变,但现在的title只是普通的变量
要将title变为响应式的变量就要引入vue中的ref方法
import {ref} from "vue";
然后把hello world字符串用ref括起来变成响应式变量
let title = ref("hello world");
改变响应式变量的值用它的value属性
title.value = "hello vue"
<template>
<h1>{{ title }}</h1>
<button @click="say">按钮</button>
</template>
<script>
import {ref} from "vue";
export default {
//composition api 组合api
setup(){
let title = ref("hello world");
function say(){
title.value = "hello vue"
}
return{//用来暴露属性或方法等
title,
say
}
}
}
</script>
reactive方法可以将对象变成响应式的
<template>
<h1>{{ student.name }}</h1>
<button @click="change">按钮</button>
</template>
<script>
import {reactive} from "vue";
export default {
//composition api 组合api
setup(){
const student = reactive({name:"benson",age:18})
function change(){
student.name = "mike"
}
return{//用来暴露属性或方法等
student,
change
}
}
}
</script>
组合api的生命周期
对应写法
基本是在原来的生命周期上加个on,然后从vue中引入对应函数,再用回调实现
<script>
import {ref,reactive,onMounted} from "vue";
export default {
setup(){
onMounted(()=>{
console.log("hello world")
})
return{
}
}
}
</script>
setup函数执行于beforeCreate和created之前,也就是说setup函数里面无法使用data和methods方法中的数据。
所以需要return出去setup里面的数据才能被模板使用
当然在setup里面直接写语句也可以达到create周期的效果
<script>
import {ref,reactive,onMounted} from "vue";
export default {
setup(){
onMounted(()=>{
console.log("hello world")
})
console.log("created")
return{
}
}
}
</script>
实例
组合api的计算属性
<template>
<h1>
{{ number }}
</h1>
</template>
<script>
import {computed} from "vue"
export default {
setup(){
const number = computed(()=>{
return 100;
})
return {
number
}
}
}
</script>
实现计算器
<template>
<h1>苹果5元/斤</h1>
<button @click="decrease">-</button>
<span>{{ number }}</span>
<button @click="increase">+</button>
<h2>总价:{{ totalPrice }}</h2>
</template>
<script>
import {ref,computed} from "vue"
export default {
setup(){
const number = ref(0);
function decrease(){
if(number.value>0){
number.value--;
}
}
function increase(){
number.value++;
}
const totalPrice = computed(()=>{
return number.value*5;
});
return {
number,
decrease,
increase,
totalPrice
}
}
}
</script>
组合api的优势
优势在于便于抽离逻辑,提高复用性。在要写许多data和method的情况下,用组合api更简洁。
组合api实现水果列表
Fruitlist.vue
<template>
<h1>水果列表</h1>
<form @submit.prevent="insert">
<div>
<label for="">名称:</label>
<input type="text" v-model="name">
</div>
<div>
<label for="">价格:</label>
<input type="text" v-model.number="price">
</div>
<button>添加</button>
</form>
<ul>
<li v-for="item,index in list">
名称:{{item.name}}
价格:{{ item.price }}
数量:
<button @click="decrease(index)">-</button>
<span>{{ item.count }}</span>
<button @click="increase(index)">+</button>
</li>
</ul>
<h2>总价:{{ totalPrice }}</h2>
</template>
<script>
import {ref,reactive,computed} from "vue"
export default {
setup(){
const name = ref("")
const price = ref(0)
const list = reactive([])
function insert(){
const fruit = reactive({
name:name.value,
price:price.value,
count:1
})
list.push(fruit)
}
function decrease(i){
list[i].count--;
if(list[i].count === 0 && confirm("是否删除数据")){
list.splice(i,1);
}
}
function increase(i){
list[i].count++;
}
const totalPrice = computed(() =>{
let sum = 0;
list.forEach(v =>{
sum += (v.count*v.price);
})
return sum;
})
return{
name,
price,
list,
insert,
decrease,
increase,
totalPrice
}
}
}
</script>
App.vue
<template>
<Fruitlist></Fruitlist>
</template>
<script>
import Fruitlist from './components/Fruitlist.vue';
export default {
components:{
Fruitlist
}
}
</script>