组合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>

posted @ 2023-02-04 18:34  ben10044  阅读(23)  评论(0编辑  收藏  举报