日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

經(jīng)過了漫長地迭代,Vue 3.0 終于在上 2020-09-18 發(fā)布了,帶了翻天覆地的變化,使用了 Typescript 進(jìn)行了大規(guī)模的重構(gòu),帶來了 Composition API RFC 版本,類似 React Hook 一樣的寫 Vue,可以自定義自己的 hook ,讓使用者更加的靈活,接下來總結(jié)一下 vue 3.0 帶來的部分新特性。

經(jīng)過了漫長地迭代,Vue 3.0 終于在上 2020-09-18 發(fā)布了,帶了翻天覆地的變化,使用了 Typescript 進(jìn)行了大規(guī)模的重構(gòu),帶來了 Composition API RFC 版本,類似 React Hook 一樣的寫 Vue,可以自定義自己的 hook ,讓使用者更加的靈活,接下來總結(jié)一下 vue 3.0 帶來的部分新特性。

  1. setup()
  2. ref()
  3. reactive()
  4. isRef()
  5. toRefs()
  6. computed()
  7. watch()
  8. LifeCycle Hooks(新的生命周期)
  9. Template refs
  10. globalProperties
  11. Suspense

Vue2 與 Vue3 的對比

  • 對 TypeScript 支持不友好(所有屬性都放在了 this 對象上,難以推倒組件的數(shù)據(jù)類型)
  • 大量的 API 掛載在 Vue 對象的原型上,難以實(shí)現(xiàn) TreeShaking。
  • 架構(gòu)層面對跨平臺 dom 渲染開發(fā)支持不友好
  • CompositionAPI。愛 ReactHook 啟發(fā)
  • 更方便的支持了 jsx
  • Vue 3 的 Template 支持多個(gè)根標(biāo)簽,Vue 2 不支持
  • 對虛擬 DOM 進(jìn)行了重寫、對模板的編譯進(jìn)行了優(yōu)化操作...

一、setup 函數(shù)

setup() 函數(shù)是 vue3 中,專門為組件提供的新屬性。它為我們使用 vue3 的 Composition API 新特性提供了統(tǒng)一的入口, setup 函數(shù)會在 beforeCreate 之后、created 之前執(zhí)行, vue3 也是取消了這兩個(gè)鉤子,統(tǒng)一用 setup 代替, 該函數(shù)相當(dāng)于一個(gè)生命周期函數(shù),vue 中過去的 data,methods,watch 等全部都用對應(yīng)的新增 api 寫在 setup()函數(shù)中

setup(props, context) { 
    context.attrs 
    context.slots 
    context.parent 
    context.root 
    context.emit 
    context.refs 
 
    return { 
 
    } 
  } 
  • props: 用來接收 props 數(shù)據(jù)
  • context 用來定義上下文, 上下文對象中包含了一些有用的屬性,這些屬性在 vue 2.x 中需要通過 this 才能訪問到, 在 setup() 函數(shù)中無法訪問到 this,是個(gè) undefined
  • 返回值: return {}, 返回響應(yīng)式數(shù)據(jù), 模版中需要使用的函數(shù)

二、reactive 函數(shù)

reactive() 函數(shù)接收一個(gè)普通對象,返回一個(gè)響應(yīng)式的數(shù)據(jù)對象, 想要使用創(chuàng)建的響應(yīng)式數(shù)據(jù)也很簡單,創(chuàng)建出來之后,在 setup 中 return 出去,直接在 template 中調(diào)用即可

 
<template> 
  {{name}} // test 
<template> 
 
<script lang="ts"> 
import { defineComponent, reactive, ref, toRefs } from 'vue'; 
export default defineComponent({ 
  setup(props, context) { 
 
    let state = reactive({ 
      name: 'test' 
    }); 
 
    return state 
  } 
}); 
</script> 

三、ref() 函數(shù)

ref() 函數(shù)用來根據(jù)給定的值創(chuàng)建一個(gè)響應(yīng)式的數(shù)據(jù)對象,ref() 函數(shù)調(diào)用的返回值是一個(gè)對象,這個(gè)對象上只包含一個(gè) value 屬性, 只在 setup 函數(shù)內(nèi)部訪問 ref 函數(shù)需要加.value

 
<template> 
    <div class="mine"> 
        {{count}} // 10 
    </div> 
</template> 
 
<script lang="ts"> 
import { defineComponent, ref } from 'vue'; 
export default defineComponent({ 
  setup() { 
    const count = ref<number>(10) 
    // 在js 中獲取ref 中定義的值, 需要通過value屬性 
    console.log(count.value); 
    return { 
       count 
    } 
   } 
}); 
</script> 

在 reactive 對象中訪問 ref 創(chuàng)建的響應(yīng)式數(shù)據(jù)

<template> 
    <div class="mine"> 
        {{count}} -{{t}} // 10 -100 
    </div> 
</template> 
 
<script lang="ts"> 
import { defineComponent, reactive, ref, toRefs } from 'vue'; 
export default defineComponent({ 
  setup() { 
    const count = ref<number>(10) 
    const obj = reactive({ 
      t: 100, 
      count 
    }) 
    // 通過reactive 來獲取ref 的值時(shí),不需要使用.value屬性 
    console.log(obj.count); 
    return { 
       ...toRefs(obj) 
    } 
   } 
}); 
</script> 

四、isRef() 函數(shù)

isRef() 用來判斷某個(gè)值是否為 ref() 創(chuàng)建出來的對象

<script lang="ts"> 
import { defineComponent, isRef, ref } from 'vue'; 
export default defineComponent({ 
  setup(props, context) { 
    const name: string = 'vue' 
    const age = ref<number>(18) 
    console.log(isRef(age)); // true 
    console.log(isRef(name)); // false 
 
    return { 
      age, 
      name 
    } 
  } 
}); 
</script> 

五、toRefs() 函數(shù)

toRefs() 函數(shù)可以將 reactive() 創(chuàng)建出來的響應(yīng)式對象,轉(zhuǎn)換為普通的對象,只不過,這個(gè)對象上的每個(gè)屬性節(jié)點(diǎn),都是 ref() 類型的響應(yīng)式數(shù)據(jù)

<template> 
  <div class="mine"> 
    {{name}} // test 
    {{age}} // 18 
  </div> 
</template> 
 
<script lang="ts"> 
import { defineComponent, reactive, ref, toRefs } from 'vue'; 
export default defineComponent({ 
  setup(props, context) { 
    let state = reactive({ 
      name: 'test' 
    }); 
 
    const age = ref(18) 
 
    return { 
      ...toRefs(state), 
      age 
    } 
  } 
}); 
</script> 

六、computed()

該函數(shù)用來創(chuàng)造計(jì)算屬性,和過去一樣,它返回的值是一個(gè) ref 對象。里面可以傳方法,或者一個(gè)對象,對象中包含 set()、get()方法

6.1 創(chuàng)建只讀的計(jì)算屬性

import { computed, defineComponent, ref } from 'vue'; 
export default defineComponent({ 
  setup(props, context) { 
    const age = ref(18) 
 
    // 根據(jù) age 的值,創(chuàng)建一個(gè)響應(yīng)式的計(jì)算屬性 readOnlyAge,它會根據(jù)依賴的 ref 自動計(jì)算并返回一個(gè)新的 ref 
    const readOnlyAge = computed(() => age.value++) // 19 
 
    return { 
      age, 
      readOnlyAge 
    } 
  } 
}); 
</script> 

6.2 通過 set()、get()方法創(chuàng)建一個(gè)可讀可寫的計(jì)算屬性

 
<script lang="ts"> 
import { computed, defineComponent, ref } from 'vue'; 
export default defineComponent({ 
  setup(props, context) { 
    const age = ref<number>(18) 
 
    const computedAge = computed({ 
      get: () => age.value + 1, 
      set: value => age.value + value 
    }) 
    // 為計(jì)算屬性賦值的操作,會觸發(fā) set 函數(shù), 觸發(fā) set 函數(shù)后,age 的值會被更新 
    age.value = 100 
    return { 
      age, 
      computedAge 
    } 
  } 
}); 
</script> 

七、 watch() 函數(shù)

watch 函數(shù)用來偵聽特定的數(shù)據(jù)源,并在回調(diào)函數(shù)中執(zhí)行副作用。默認(rèn)情況是懶執(zhí)行的,也就是說僅在偵聽的源數(shù)據(jù)變更時(shí)才執(zhí)行回調(diào)。

7.1 監(jiān)聽用 reactive 聲明的數(shù)據(jù)源

 
<script lang="ts"> 
import { computed, defineComponent, reactive, toRefs, watch } from 'vue'; 
interface Person { 
  name: string, 
  age: number 
} 
export default defineComponent({ 
  setup(props, context) { 
    const state = reactive<Person>({ name: 'vue', age: 10 }) 
 
    watch( 
      () => state.age, 
      (age, preAge) => { 
        console.log(age); // 100 
        console.log(preAge); // 10 
      } 
    ) 
    // 修改age 時(shí)會觸發(fā)watch 的回調(diào), 打印變更前后的值 
    state.age = 100 
    return { 
      ...toRefs(state) 
    } 
  } 
}); 
</script> 

7.2 監(jiān)聽用 ref 聲明的數(shù)據(jù)源

 
<script lang="ts"> 
import { defineComponent, ref, watch } from 'vue'; 
interface Person { 
  name: string, 
  age: number 
} 
export default defineComponent({ 
  setup(props, context) { 
    const age = ref<number>(10); 
 
    watch(age, () => console.log(age.value)); // 100 
 
    // 修改age 時(shí)會觸發(fā)watch 的回調(diào), 打印變更后的值 
    age.value = 100 
    return { 
      age 
    } 
  } 
}); 
</script> 

7.3 同時(shí)監(jiān)聽多個(gè)值

 
<script lang="ts"> 
import { computed, defineComponent, reactive, toRefs, watch } from 'vue'; 
interface Person { 
  name: string, 
  age: number 
} 
export default defineComponent({ 
  setup(props, context) { 
    const state = reactive<Person>({ name: 'vue', age: 10 }) 
 
    watch( 
      [() => state.age, () => state.name], 
      ([newName, newAge], [oldName, oldAge]) => { 
        console.log(newName); 
        console.log(newAge); 
 
        console.log(oldName); 
        console.log(oldAge); 
      } 
    ) 
    // 修改age 時(shí)會觸發(fā)watch 的回調(diào), 打印變更前后的值, 此時(shí)需要注意, 更改其中一個(gè)值, 都會執(zhí)行watch的回調(diào) 
    state.age = 100 
    state.name = 'vue3' 
    return { 
      ...toRefs(state) 
    } 
  } 
}); 
</script> 

7.4 stop 停止監(jiān)聽

在 setup() 函數(shù)內(nèi)創(chuàng)建的 watch 監(jiān)視,會在當(dāng)前組件被銷毀的時(shí)候自動停止。如果想要明確地停止某個(gè)監(jiān)視,可以調(diào)用 watch() 函數(shù)的返回值即可,語法如下:

 
<script lang="ts"> 
import { set } from 'lodash'; 
import { computed, defineComponent, reactive, toRefs, watch } from 'vue'; 
interface Person { 
  name: string, 
  age: number 
} 
export default defineComponent({ 
  setup(props, context) { 
    const state = reactive<Person>({ name: 'vue', age: 10 }) 
 
    const stop =  watch( 
      [() => state.age, () => state.name], 
      ([newName, newAge], [oldName, oldAge]) => { 
        console.log(newName); 
        console.log(newAge); 
 
        console.log(oldName); 
        console.log(oldAge); 
      } 
    ) 
    // 修改age 時(shí)會觸發(fā)watch 的回調(diào), 打印變更前后的值, 此時(shí)需要注意, 更改其中一個(gè)值, 都會執(zhí)行watch的回調(diào) 
    state.age = 100 
    state.name = 'vue3' 
 
    setTimeout(()=> { 
      stop() 
      // 此時(shí)修改時(shí), 不會觸發(fā)watch 回調(diào) 
      state.age = 1000 
      state.name = 'vue3-' 
    }, 1000) // 1秒之后講取消watch的監(jiān)聽 
 
    return { 
      ...toRefs(state) 
    } 
  } 
}); 
</script> 

八、LifeCycle Hooks(新的生命后期)

新版的生命周期函數(shù),可以按需導(dǎo)入到組件中,且只能在 setup() 函數(shù)中使用, 但是也可以在 setup 自定義, 在 setup 中使用

 
<script lang="ts"> 
import { set } from 'lodash'; 
import { defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onErrorCaptured, onMounted, onUnmounted, onUpdated } from 'vue'; 
export default defineComponent({ 
  setup(props, context) { 
    onBeforeMount(()=> { 
      console.log('beformounted!') 
    }) 
    onMounted(() => { 
      console.log('mounted!') 
    }) 
 
    onBeforeUpdate(()=> { 
      console.log('beforupdated!') 
    }) 
    onUpdated(() => { 
      console.log('updated!') 
    }) 
 
    onBeforeUnmount(()=> { 
      console.log('beforunmounted!') 
    }) 
    onUnmounted(() => { 
      console.log('unmounted!') 
    }) 
 
    onErrorCaptured(()=> { 
      console.log('errorCaptured!') 
    }) 
 
    return {} 
  } 
}); 
</script> 

九、Template refs

通過 refs 來回去真實(shí) dom 元素, 這個(gè)和 react 的用法一樣,為了獲得對模板內(nèi)元素或組件實(shí)例的引用,我們可以像往常一樣在 setup()中聲明一個(gè) ref 并返回它

  • 還是跟往常一樣,在 html 中寫入 ref 的名稱
  • 在steup 中定義一個(gè) ref
  • steup 中返回 ref的實(shí)例
  • onMounted 中可以得到 ref的RefImpl的對象, 通過.value 獲取真實(shí)dom
 
<template> 
  <!--第一步:還是跟往常一樣,在 html 中寫入 ref 的名稱--> 
  <div class="mine" ref="elmRefs"> 
    <span>1111</span> 
  </div> 
</template> 
 
<script lang="ts"> 
import { set } from 'lodash'; 
import { defineComponent, onMounted, ref } from 'vue'; 
export default defineComponent({ 
  setup(props, context) { 
    // 獲取真實(shí)dom 
    const elmRefs = ref<null | HTMLElement>(null); 
    onMounted (() => { 
      console.log(elmRefs.value); // 得到一個(gè) RefImpl 的對象, 通過 .value 訪問到數(shù)據(jù) 
    }) 
 
    return { 
      elmRefs 
    } 
  } 
}); 
</script> 

十、vue 的全局配置

通過 vue 實(shí)例上 config 的配置,包含 Vue 應(yīng)用程序全局配置的對象。您可以在掛載應(yīng)用程序之前修改下面列出的屬性:

const App = Vue.createApp({})  
app.config = {...} 

為組件渲染功能和觀察程序期間的未捕獲錯(cuò)誤分配處理程序。錯(cuò)誤和應(yīng)用程序?qū)嵗龑⒄{(diào)用處理程序

app.config.errorHandler = (err, vm, info) => {} 

可以在應(yīng)用程序內(nèi)的任何組件實(shí)例中訪問的全局屬性,組件的屬性將具有優(yōu)先權(quán)。這可以代替 Vue 2.xVue.prototype 擴(kuò)展:

const app = Vue.createApp({})  
app.config.globalProperties.$http = 'xxxxxxxxs' 

可以在組件用通過 getCurrentInstance() 來獲取全局 globalProperties 中配置的信息,getCurrentInstance 方法獲取當(dāng)前組件的實(shí)例,然后通過 ctx 屬性獲得當(dāng)前上下文,這樣我們就能在 setup 中使用 router 和 vuex, 通過這個(gè)屬性我們就可以操作變量、全局屬性、組件屬性等等

setup( ) { 
  const { ctx } = getCurrentInstance(); 
  ctx.$http 
} 

十一、Suspense 組件

在開始介紹 Vue 的 Suspense 組件之前,我們有必要先了解一下 React 的 Suspense 組件,因?yàn)樗麄兊墓δ茴愃啤?/p>

React.lazy 接受一個(gè)函數(shù),這個(gè)函數(shù)需要?jiǎng)討B(tài)調(diào)用 import()。它必須返回一個(gè) Promise,該 Promise 需要 resolve 一個(gè) default export 的 React 組件。

 

import React, { Suspense } from 'react'; 
 
 
const myComponent = React.lazy(() => import('./Component')); 
 
 
function MyComponent() { 
  return ( 
    <div> 
      <Suspense fallback={<div>Loading...</div>}> 
        <myComponent /> 
      </Suspense> 
    </div> 
  ); 
} 

Vue3 也新增了 React.lazy 類似功能的 defineAsyncComponent 函數(shù),處理動態(tài)引入(的組件)。defineAsyncComponent 可以接受返回承諾的工廠函數(shù)。當(dāng)您從服務(wù)器檢索到組件定義時(shí),應(yīng)該調(diào)用 Promise 的解析回調(diào)。您還可以調(diào)用 reject(reason)來指示負(fù)載已經(jīng)失敗

import { defineAsyncComponent } from 'vue' 
 
const AsyncComp = defineAsyncComponent(() => 
  import('./components/AsyncComponent.vue') 
) 
 
app.component('async-component', AsyncComp) 

Vue3 也新增了 Suspense 組件:

<template> 
  <Suspense> 
    <template #default> 
      <my-component /> 
    </template> 
    <template #fallback> 
      Loading ... 
    </template> 
  </Suspense> 
</template> 
 
<script lang='ts'> 
 import { defineComponent, defineAsyncComponent } from "vue"; 
 const MyComponent = defineAsyncComponent(() => import('./Component')); 
 
export default defineComponent({ 
   components: { 
     MyComponent 
   }, 
   setup() { 
     return {} 
   } 
}) 
 
 
</script> 

十二、vue 3.x 完整組件模版結(jié)構(gòu)

一個(gè)完成的 vue 3.x 完整組件模版結(jié)構(gòu)包含了:組件名稱、 props、components、setup(hooks、computed、watch、methods 等)

 

<template> 
  <div class="mine" ref="elmRefs"> 
    <span>{{name}}</span> 
    <br> 
    <span>{{count}}</span> 
    <div> 
      <button @click="handleClick">測試按鈕</button> 
    </div> 
 
    <ul> 
      <li v-for="item in list" :key="item.id">{{item.name}}</li> 
    </ul> 
  </div> 
</template> 
 
<script lang="ts"> 
import { computed, defineComponent, getCurrentInstance, onMounted, PropType, reactive, ref, toRefs } from 'vue'; 
 
interface IState { 
  count: 0, 
  name: string, 
  list: Array<object> 
} 
 
export default defineComponent({ 
  name: 'demo', 
  // 父組件傳子組件參數(shù) 
  props: { 
    name: { 
      type: String as PropType<null | ''>, 
      default: 'vue3.x' 
    }, 
    list: { 
      type: Array as PropType<object[]>, 
      default: () => [] 
    } 
  }, 
  components: { 
    /// TODO 組件注冊 
  }, 
  emits: ["emits-name"], // 為了提示作用 
  setup (props, context) { 
    console.log(props.name) 
    console.log(props.list) 
 
 
    const state = reactive<IState>({ 
      name: 'vue 3.0 組件', 
      count: 0, 
      list: [ 
        { 
          name: 'vue', 
          id: 1 
        }, 
        { 
          name: 'vuex', 
          id: 2 
        } 
      ] 
    }) 
 
    const a = computed(() => state.name) 
 
    onMounted(() => { 
 
    }) 
 
    function handleClick () { 
      state.count ++ 
      // 調(diào)用父組件的方法 
      context.emit('emits-name', state.count) 
    } 
 
    return { 
      ...toRefs(state), 
      handleClick 
    } 
  } 
}); 
</script> 
 
<template> 
  <div class="mine" ref="elmRefs"> 
    <span>{{name}}</span> 
    <br> 
    <span>{{count}}</span> 
    <div> 
      <button @click="handleClick">測試按鈕</button> 
    </div> 
 
    <ul> 
      <li v-for="item in list" :key="item.id">{{item.name}}</li> 
    </ul> 
  </div> 
</template> 
 
<script lang="ts"> 
import { computed, defineComponent, getCurrentInstance, onMounted, PropType, reactive, ref, toRefs } from 'vue'; 
 
interface IState { 
  count: 0, 
  name: string, 
  list: Array<object> 
} 
 
export default defineComponent({ 
  name: 'demo', 
  // 父組件傳子組件參數(shù) 
  props: { 
    name: { 
      type: String as PropType<null | ''>, 
      default: 'vue3.x' 
    }, 
    list: { 
      type: Array as PropType<object[]>, 
      default: () => [] 
    } 
  }, 
  components: { 
    /// TODO 組件注冊 
  }, 
  emits: ["emits-name"], // 為了提示作用 
  setup (props, context) { 
    console.log(props.name) 
    console.log(props.list) 
 
 
    const state = reactive<IState>({ 
      name: 'vue 3.0 組件', 
      count: 0, 
      list: [ 
        { 
          name: 'vue', 
          id: 1 
        }, 
        { 
          name: 'vuex', 
          id: 2 
        } 
      ] 
    }) 
 
    const a = computed(() => state.name) 
 
    onMounted(() => { 
 
    }) 
 
    function handleClick () { 
      state.count ++ 
      // 調(diào)用父組件的方法 
      context.emit('emits-name', state.count) 
    } 
 
    return { 
      ...toRefs(state), 
      handleClick 
    } 
  } 
}); 
</script> 

vue 3 的生態(tài)

  • 官網(wǎng)
  • 源碼
  • vite 構(gòu)建器
  • 腳手架:https://cli.vuejs.org/
  • vue-router-next
  • vuex4.0

UI 組件庫

  • vant2.x
  • Ant Design of Vue 2.x
  • element-plus

 

10分鐘讓你快速上手Vue3

 

分享到:
標(biāo)簽:Vue3
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定