手记

Vue3 组合api入口函数setup的基本使用

Vue3.0 生命周期函数变更
在Vue2.x中,实现一个功能,需要在data中新增数据,在methods/computed/watch中新增业务逻辑,数据和业务逻辑是分离的,不利于管理
Vue3.0推出了Composition API(组合API),也叫做注入API,setup()是组合API的入口函数,可以直接在里面定义变量和方法(数据和业务逻辑),通过对象的形式返回暴露出去

执行时机
setup执行顺序是在beforeCreate之前的

生命周期函数
与 2.x 版本生命周期相对应的组合式 API :onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted
新增的钩子函数onRenderTracked、onRenderTriggered,两个钩子函数都接收一个 DebuggerEvent,与 watchEffect 参数选项中的 onTrack 和 onTrigger 类似

<template>
  <div>
    {{ message }}
    <van-button type="primary" @click="changeMessage">修改</van-button>
    <van-button type="primary" @click="go">跳转</van-button>
  </div>
</template>

<script>
import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  onRenderTracked,
  onRenderTriggered,
  ref,
  getCurrentInstance
} from 'vue';
export default {
  name: "temp",
  setup() {
    const { ctx } = getCurrentInstance();

    let message = ref("你好");

    const changeMessage = () => {
      message.value = "hello";
    }

    onBeforeMount(() => {
      console.log("挂载前");
    })
    onMounted(() => {
      console.log("挂载");
    })
    onBeforeUpdate(() => {
      console.log("更新前");
    })
    onUpdated(() => {
      console.log("更新");
    })
    onBeforeUnmount(() => {
      console.log("销毁前");
    })
    onUnmounted(() => {
      console.log("销毁");
    })

    onRenderTracked(() => {
      console.log("onRenderTracked");
    })

    onRenderTriggered(() => {
      console.log("onRenderTriggered");
    })

    const go = () => {
      ctx.$router.push({
        path: "/cart"
      })
    }

    return {
      message,
      changeMessage,
      go
    }
  }
}
</script>

基本使用

  1. ref单值
<template>
  <div>
    {{ message }}
    <van-button type="primary" @click="changeMessage">修改</van-button>
  </div>
</template>

<script>
import {
  ref
} from 'vue';
export default {
  name: "temp",
  setup() {
    // 它其实是用proxy代理了一个对象  `{ value: '你好' }`
    let message = ref("你好");

    const changeMessage = () => {
      message.value = "hello";
    }
  
    return {
      message
    }
  }
}
</script>

修改变量值有两种方法:
setup中暴露一个函数,直接去修改.value;
在methods中定义一个方法,在此方法的内部通过this.XX=新值来修改

<script>
import {
  ref
} from 'vue';
export default {
  name: "temp",
  setup() {
    let message = ref("你好");

    const changeMessage = () => { // 方式一
      message.value = "hello";
    }
  
    return {
      message,
      changeMessage
    }
  },
  methods: {
    changeMessageC() {  // 方式二
      this.message = "helloC"
    }
  }
}
</script>
  1. reactive对象
<template>
  <div>
    {{ obj.name }}
    {{ obj.arr }}
    <van-button type="primary" @click="changeData">修改</van-button>
  </div>
</template>

<script>
import {
  reactive
} from 'vue';
export default {
  name: "temp",
  setup() {
    let obj = reactive({
      name: "张三",
      arr: []
    });

    const changeData = () => {
      obj.name = "ZS";
      obj.arr.push("1", "2");
    }
  
    return {
      obj,
      changeData
    }
  }
}
</script>

要修改这个值,有两种方式:
在setup中暴露一个函数,直接去修改 ;
在methods中定义一个方法,在内部通过this.ojb.XX=新值 来修改

<script>
import {
  reactive
} from 'vue';
export default {
  name: "temp",
  setup() {
    let obj = reactive({
      name: "张三",
      arr: []
    });

    const changeData = () => { // 方式一
      obj.name = "ZS";
      obj.arr.push("1", "2");
    }
  
    return {
      obj,
      changeData
    }
  },
  methods: {
    changeDataC() {  // 方式二
      this.obj.name = "ZSC"
      this.obj.arr.push("3");
    }
  }
}
</script>
  1. reactive对象+toRefs

通过引入toRefs包装一个reactive对象,然后再展开,就可以省略obj这个前缀了

<template>
  <div>
    {{ name }}
    {{ arr }}
  </div>
</template>

<script>
import {
  reactive,
  toRefs
} from 'vue';
export default {
  name: "temp",
  setup() {
    let obj = reactive({
      name: "张三",
      arr: []
    });
  
    return {
      ...toRefs(obj)
    }
  }
}
</script>
  1. 定义计算属性

通过computed(回调)的方式来计算属性,然后在setup中返回即可。

<template>
  <div>
    <div>
      原始值: {{ obj.count }}
      <van-button type="primary" @click="add">修改</van-button>
    </div>
    <div>2倍原始值: {{ doubleB }}</div>
  </div>
</template>

<script>
import {
  reactive,
  computed
} from 'vue';
export default {
  name: "temp",
  setup() {
    let obj = reactive({
      count: 1
    });

    const add = () => { // 修改原始值
      obj.count++;
    }
  
    const doubleB = computed(() => {
      return 2 * obj.count;
    })
    return {
      obj,
      add,
      doubleB
    }
  }
}
</script>
  1. watch​​​​​​​
<template>
  <div>
    {{ obj.count }}, {{ a }}
    <br />
    <van-button type="primary" @click="obj.count+=1">原址obj.count+1</van-button>
    <van-button type="primary" @click="a+=1">原值a+1</van-button>
  </div>
</template>

<script>
import {
  ref,
  reactive,
  watch
} from 'vue';
export default {
  name: "temp",
  setup() {
    const a = ref(0);

    // reactive: 会对对象进行包装
    const obj = reactive({
      count: 0
    })
    
    // 通过watch来监听
    watch(a, () => {
      console.log("变量a改变了")
    })

    watch(() => obj.count, () => {
      console.log("obj.count改变了")
    })
  
    return {
      a,
      obj
    }
  }
}
</script>
  1. 使用路由
<template>
  <div>
    <van-button type="primary" @click="go">跳转</van-button>
  </div>
</template>

<script>
import {
  getCurrentInstance
} from 'vue';
export default {
  name: "temp",
  setup() {
    const { ctx } = getCurrentInstance();

    const go = () => {
      ctx.$router.push({
        path: "/cart"
      })
    }
    
    return {
      go
    }
  }
}
</script>
  1. vuex使用
<template>
  <div>
    {{ goodsList }}
  </div>
</template>

<script>
import {
  ref,
  nextTick
} from "vue";
import { useStore } from "vuex";
export default {
  name: "temp",
  setup() {
    const store = useStore(); // 使用vuex
    let goodsList = ref([]);
    
    const addCar = () => { // 添加购物车
      // 调用vuex cart模块mutations中的addToCar方法
      store.commit("cart/addToCar", {
        id: 2,
        title: "临时数据",
        desc: "描述",
        thumb_path: imgUrl,
        sell_price: 12.8,
        count: 10,
        select: false
      })
    }

    const getGoodsList = () => { // 获取购物车数据
      nextTick(() => {
        goodsList.value = store.getters.shopCar;
      });
    }

    getGoodsList();

    return {
      goodsList,
      addCar,
      getGoodsList,
    }
  }
}
</script>

代码地址
gitee.com/smallgrey/new-features-of-vue3

0人推荐
随时随地看视频
慕课网APP