亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

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

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

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

經(jīng)過了漫長地迭代,Vue 3.0 終于在上 2020-09-18 發(fā)布了,帶了翻天覆地的變化,使用了 Typescript 進行了大規(guī)模的重構,帶來了 Composition API RFC 版本,類似 React Hook 一樣的寫 Vue,可以自定義自己的 hook ,讓使用者更加的靈活,接下來總結一下 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 對象的原型上,難以實現(xiàn) TreeShaking。
  • 架構層面對跨平臺 dom 渲染開發(fā)支持不友好
  • CompositionAPI。愛 ReactHook 啟發(fā)
  • 更方便的支持了 jsx
  • Vue 3 的 Template 支持多個根標簽,Vue 2 不支持
  • 對虛擬 DOM 進行了重寫、對模板的編譯進行了優(yōu)化操作...

一、setup 函數(shù)

setup() 函數(shù)是 vue3 中,專門為組件提供的新屬性。它為我們使用 vue3 的 Composition API 新特性提供了統(tǒng)一的入口, setup 函數(shù)會在 beforeCreate 之后、created 之前執(zhí)行, vue3 也是取消了這兩個鉤子,統(tǒng)一用 setup 代替, 該函數(shù)相當于一個生命周期函數(shù),vue 中過去的 data,methods,watch 等全部都用對應的新增 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,是個 undefined
  • 返回值: return {}, 返回響應式數(shù)據(jù), 模版中需要使用的函數(shù)

二、reactive 函數(shù)

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

 
<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)建一個響應式的數(shù)據(jù)對象,ref() 函數(shù)調用的返回值是一個對象,這個對象上只包含一個 value 屬性, 只在 setup 函數(shù)內部訪問 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)建的響應式數(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 的值時,不需要使用.value屬性 
    console.log(obj.count); 
    return { 
       ...toRefs(obj) 
    } 
   } 
}); 
</script> 

四、isRef() 函數(shù)

isRef() 用來判斷某個值是否為 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)建出來的響應式對象,轉換為普通的對象,只不過,這個對象上的每個屬性節(jié)點,都是 ref() 類型的響應式數(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)造計算屬性,和過去一樣,它返回的值是一個 ref 對象。里面可以傳方法,或者一個對象,對象中包含 set()、get()方法

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

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

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

 
<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 
    }) 
    // 為計算屬性賦值的操作,會觸發(fā) set 函數(shù), 觸發(fā) set 函數(shù)后,age 的值會被更新 
    age.value = 100 
    return { 
      age, 
      computedAge 
    } 
  } 
}); 
</script> 

七、 watch() 函數(shù)

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

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 時會觸發(fā)watch 的回調, 打印變更前后的值 
    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 時會觸發(fā)watch 的回調, 打印變更后的值 
    age.value = 100 
    return { 
      age 
    } 
  } 
}); 
</script> 

7.3 同時監(jiān)聽多個值

 
<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 時會觸發(fā)watch 的回調, 打印變更前后的值, 此時需要注意, 更改其中一個值, 都會執(zhí)行watch的回調 
    state.age = 100 
    state.name = 'vue3' 
    return { 
      ...toRefs(state) 
    } 
  } 
}); 
</script> 

7.4 stop 停止監(jiān)聽

在 setup() 函數(shù)內創(chuàng)建的 watch 監(jiān)視,會在當前組件被銷毀的時候自動停止。如果想要明確地停止某個監(jiān)視,可以調用 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 時會觸發(fā)watch 的回調, 打印變更前后的值, 此時需要注意, 更改其中一個值, 都會執(zhí)行watch的回調 
    state.age = 100 
    state.name = 'vue3' 
 
    setTimeout(()=> { 
      stop() 
      // 此時修改時, 不會觸發(fā)watch 回調 
      state.age = 1000 
      state.name = 'vue3-' 
    }, 1000) // 1秒之后講取消watch的監(jiān)聽 
 
    return { 
      ...toRefs(state) 
    } 
  } 
}); 
</script> 

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

新版的生命周期函數(shù),可以按需導入到組件中,且只能在 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 來回去真實 dom 元素, 這個和 react 的用法一樣,為了獲得對模板內元素或組件實例的引用,我們可以像往常一樣在 setup()中聲明一個 ref 并返回它

  • 還是跟往常一樣,在 html 中寫入 ref 的名稱
  • 在steup 中定義一個 ref
  • steup 中返回 ref的實例
  • onMounted 中可以得到 ref的RefImpl的對象, 通過.value 獲取真實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) { 
    // 獲取真實dom 
    const elmRefs = ref<null | HTMLElement>(null); 
    onMounted (() => { 
      console.log(elmRefs.value); // 得到一個 RefImpl 的對象, 通過 .value 訪問到數(shù)據(jù) 
    }) 
 
    return { 
      elmRefs 
    } 
  } 
}); 
</script> 

十、vue 的全局配置

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

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

為組件渲染功能和觀察程序期間的未捕獲錯誤分配處理程序。錯誤和應用程序實例將調用處理程序

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

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

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

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

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

十一、Suspense 組件

在開始介紹 Vue 的 Suspense 組件之前,我們有必要先了解一下 React 的 Suspense 組件,因為他們的功能類似。

React.lazy 接受一個函數(shù),這個函數(shù)需要動態(tài)調用 import()。它必須返回一個 Promise,該 Promise 需要 resolve 一個 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ù)。當您從服務器檢索到組件定義時,應該調用 Promise 的解析回調。您還可以調用 reject(reason)來指示負載已經(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 完整組件模版結構

一個完成的 vue 3.x 完整組件模版結構包含了:組件名稱、 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 ++ 
      // 調用父組件的方法 
      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 ++ 
      // 調用父組件的方法 
      context.emit('emits-name', state.count) 
    } 
 
    return { 
      ...toRefs(state), 
      handleClick 
    } 
  } 
}); 
</script> 

vue 3 的生態(tài)

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

UI 組件庫

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

 

10分鐘讓你快速上手Vue3

 

分享到:
標簽:Vue3
用戶無頭像

網(wǎng)友整理

注冊時間:

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

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

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

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

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

答題星2018-06-03

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

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

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

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

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

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

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定