前言

vue3.0 Rc(候选公布版本)曾经于7月18上线,离正式版本公布曾经不远了,鉴于此,自己就通过@vue/composition-api 这个 Vue Composition API 来当时体验下3.0的新个性,为当前能疾速上手新版本做筹备。

筹备工作

下载与引入

  • 下载体验版api
 npm i @vue/composition-api
  • 引入与应用
 1. 在main.js中要引入全副的api  import VueCompositionApi from '@vue/composition-api' Vue.use(VueCompositionApi)  2. 在页面中按需引入api  import { 须要应用的api } from '@vue/composition-api'
tips: main.js和部分页面都须要引入,不能只在页面中引入。

开发与应用

reactive和toRefs

reactive创立响应式数据,toRefs把一般数据转换成响应式数据

<template>  <div class="home">    <span>{{name}}</span>    <span>{{num}}</span>    <button @click="btn">按钮</button>    <button @click="btn2">按钮2</button>  </div></template><script>// reactive 创立响应式数据对象 --相似dataimport { reactive, toRefs } from '@vue/composition-api'export default {  name: 'Home',  setup () {    // state对象    const state = reactive({      name: 'hello world'    })    // modelData     const modelData = reactive({      num: 1    })    const btn = () => modelData.num++    const btn2 = () => {      state.name = '我是不双向绑定的数据,没有toRefs转换不可更改'      return state    }    return {      ...state,      ...toRefs(modelData), //把数据转换为响应式      btn, // 事件      btn2    }  }}</script>

tips:

  1. setup中是没有this
  2. 数据、办法都写在setup外面。
  3. 办法里扭转值需return这个值
  4. 用了...运算符后应用reactive创立进去的数据都不是响应式数据了,须要应用toRefs转换为ref()类型的响应式数据

ref(举荐)

    • reactive一样创立响应式数据,但更举荐应用。
    <template> <div class="RefCom">   <span>{{refCount}}</span>   <button @click="refCount+=1">+1</button> </div></template><script>import { ref, reactive } from '@vue/composition-api'export default { name: 'RefCom', setup (props, { root }) {   const refCount = ref(0) //创立响应式数据   console.log(refCount.value)   const data = reactive({     refCount   })   console.log(data.refCount)   data.refCount++   console.log(data.refCount)   return {     ...data,     refCount   } }}</script>
    • 模板上的ref--获取dom
    //父组件<template>  <div class="Father">    <h1 ref="h1Ref">父组件</h1>    <som ref="somRef"></som>  </div></template><script>import som from './Som'import { ref, onMounted } from '@vue/composition-api'export default {  name: 'Father',  components: {    som  },  setup (props, { root }) {    const h1Ref = ref(null) //赋值null    const somRef = ref(null)    onMounted(() => {      console.log(h1Ref.value, 'h1的dom')      console.log(somRef.value, 'som的dom')    })    return {      h1Ref,  //要和模板上ref值雷同      somRef    }  }}</script>
     //子组件 <template>  <div class="Som">    <h3>子组件</h3>  </div></template><script>export default {  name: 'som',  setup (props, { root }) {}}</script>

    tips:

    1. ref括号里的值就是refCount的值,括号里的值能够是各种类型的值。
    2. setup要通过xxx.value获取ref转换的值。
    3. 模板中无需通过xxx.value展现数据,间接{{xxx}}即可,在return时曾经进行了转换了。
    4. ref包裹创立进去的值是个对象,外面就一个属性value
    5. reactive包裹ref创立的值不须要通过XXX.value拜访
    6. 新的ref会笼罩旧的ref的值
    7. 通过isRef能够判断是否是ref创立进去的。

    computed

    计算属性:可创立可读可写的计算属性。

    <template>  <div class="RefCom">    <span>原值:{{refCount}}</span> |    <span>      计算属性值:{{ onlyReadComputed      }}    </span> |    <button @click="refCount+=1">+1</button>  </div></template><script>import { ref, computed } from '@vue/composition-api'export default {  name: 'RefCom',  setup (props, { root }) {    const refCount = ref(0)    // 只读的计算属性    const onlyReadComputed = computed(() => refCount.value + 1)    // 可读可写的计算属性    const rwComputed = computed({      get: () => refCount.value + 1,      set: value => {        refCount.value = value - 1      }    })    console.log(onlyReadComputed, '只读计算属性的值')    rwComputed.value = 11    console.log(rwComputed, '可读可写计算属性的值')    return {      refCount,      rwComputed,      onlyReadComputed    }  }}</script>

    watch

    监听数据的变动

    <template> <div class="RefCom">   <span>{{refCount}}</span>   <span>{{name}}</span>   <button @click="stopWatch">进行watch</button>   <input v-model="inputValue" /> </div></template><script>import { ref, reactive, watch, toRefs } from '@vue/composition-api'export default { name: 'watch', setup (props, { root }) {   const refCount = ref(0)   const inputValue = ref('')   const state = reactive({     name: '张总'   })   /* ---监听单个--- */   // ref   const stop = watch(     refCount,     (newValue, oldValue) => {       console.log(refCount.value)       console.log('新值:' + newValue, '旧的值:' + oldValue)     }   )   const stopWatch = () => {     stop()   }   // reactive   watch(     () => state.name,     (newValue, oldValue) => {       // console.log(refCount.value)       console.log('新值:' + newValue, '旧的值:' + oldValue)     }   )   /* ---监听多个--- */   watch(     [() => refCount, () => state.name],     ([newRefCount, newName], [oldRefCount, oldName]) => {       console.log('newRefCount:' + newRefCount.value, 'newName:' + newName)       console.log('oldRefCount:' + oldRefCount.value, 'oldName:' + oldName)     }   )   setTimeout(() => {     refCount.value++   }, 1000)   setTimeout(() => {     state.name = '李总'   }, 3000)   // 异步打印   const asyncPrint = (val) => {     return setTimeout(() => {       console.log(val)     }, 1000)   }   // ref   watch(     inputValue,     (newValue, oldValue, clean) => {       const timeId = asyncPrint(newValue)       // 每当数据变动的时候革除定时器       clean(() => clearTimeout(timeId))     }   )   return {     ...toRefs(state),     refCount,     stopWatch,     inputValue   } }}</script>

    tips:

    1. refreactive的值的监听办法不同,reactive需用办法返回值,() => xxx,ref可间接应用。
    2. 当监听多个时,不论是ref还是reactive创立的值,都须要用办法返回
    3. 在监听多个值时,用数组来解构新旧值时,新值和旧值别离在不同的数组里,和vue2.x不一样。
    4. watch监听返回新值、旧值时还返回了个函数,以后函数在watch被反复执行stop操作时产生,可做些革除操作。常见利用场景有防抖。
    5. 防抖:就是对于频繁触发的事件增加一个延时同时设定一个最小触发距离,如果触发距离小于设定的距离,则革除原来的定时,从新设定新的定时;如果触发距离大于设定距离,则保留原来的定时,并设置新的定时;防抖的后果就是频繁的触发转变为触发一次

    生命周期

    • beforeCreate -> setup()
    • created -> setup
    • beforeMount -> onBeforeMount
    • mounted -> onMounted
    • beforeUpdate -> onBeforeUpdate
    • updated -> onUpdated
    • beforeDestroy -> onBeforeUnmount
    • destroyed -> onUnmounted
    • errorCaptured -> onErrorCaptured
    <template>  <div class="Father">   </div></template><script>import { onMounted, onUpdated, onBeforeUnmount } from '@vue/composition-api'export default {  name: 'Father',  setup (props, { root }) {    onMounted(() => {      console.log('onMounted')    })    onUpdated(() => {      console.log('onUpdated')    })    onBeforeUnmount(() => {      console.log('onBeforeUnmount')    })  }}</script>

    tips:

    1. 去除了beforeCreatecreated生命周期,间接就在setup中,setup执行程序 是beforeCreate后,created
    2. 其余生命周期就在本来前加上on,性能没有什么变动,且定义在setup函数中
    3. 举荐申请都放在onMounted

    依赖注入

    • provide
    //父组件<template>  <div class="Father">    <h1>父组件</h1>    <button @click="color='red'">红色</button>    <button @click="color='blue'">蓝色</button>    <button @click="color='yellow'">黄色</button>    <som></som>  </div></template><script>import som from './Som'import { provide, ref } from '@vue/composition-api'export default {  name: 'Father',  components: {    som  },  setup (props, { root }) {    const color = ref('red') //响应式的值,父组件批改可影响子孙后代    //注入值    provide('color', color)    return {      color    }  }}</script>
     //子组件 <template>  <div class="Som">    <h3>子组件</h3>    <Grandson />  </div></template><script>import Grandson from './Grandson'export default {  name: 'som',  components: {    Grandson  },  setup (props, { root }) { }}</script>
    • inject
    //孙子组件<template>  <div class="Grandson">    <h5 :style="{color:color}">孙子组件</h5>  </div></template><script>import { inject } from '@vue/composition-api'export default {  name: 'Grandson',  setup (props, { root }) {  //接管值    const color = inject('color')     return {      color    }  }}</script>

    路由跳转

    <template>  <div class="home">    <button @click="jump">跳转</button>  </div></template><script>export default {  name: 'Home',  setup (props, { root }) {   const jump = () => root.$router.push('/about')    return {      jump    }  }}</script>
    tips: root指代的就是vue对象,即this,且名字是不可更改的。

    props

    //父<template>  <div class="about">    <h1>This is an about page</h1>    <div>{{num}}</div>    <button @click="btn">减少</button>    <HelloWorld msg="我是props传进去的值" />  </div></template>//子<template>  <div class="hello">    <h1>{{ msg }}</h1>  </div></template><script>export default {  name: 'HelloWorld',  props: {    msg: String  },  setup (props) {    console.log(props)  }}</script>

    未完待续~~~