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

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

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

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

經過了漫長地迭代,Vue 3.0 終于在上 2020-09-18 發布了,帶了翻天覆地的變化,使用了 Typescript 進行了大規模的重構,帶來了 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 對象上,難以推倒組件的數據類型)
  • 大量的 API 掛載在 Vue 對象的原型上,難以實現 TreeShaking。
  • 架構層面對跨平臺 dom 渲染開發支持不友好
  • CompositionAPI。愛 ReactHook 啟發
  • 更方便的支持了 jsx
  • Vue 3 的 Template 支持多個根標簽,Vue 2 不支持
  • 對虛擬 DOM 進行了重寫、對模板的編譯進行了優化操作...

一、setup 函數

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

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

二、reactive 函數

reactive() 函數接收一個普通對象,返回一個響應式的數據對象, 想要使用創建的響應式數據也很簡單,創建出來之后,在 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() 函數

ref() 函數用來根據給定的值創建一個響應式的數據對象,ref() 函數調用的返回值是一個對象,這個對象上只包含一個 value 屬性, 只在 setup 函數內部訪問 ref 函數需要加.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 創建的響應式數據

<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() 函數

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

<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() 函數

toRefs() 函數可以將 reactive() 創建出來的響應式對象,轉換為普通的對象,只不過,這個對象上的每個屬性節點,都是 ref() 類型的響應式數據

<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()

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

6.1 創建只讀的計算屬性

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

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

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

七、 watch() 函數

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

7.1 監聽用 reactive 聲明的數據源

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

7.2 監聽用 ref 聲明的數據源

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

7.3 同時監聽多個值

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

7.4 stop 停止監聽

在 setup() 函數內創建的 watch 監視,會在當前組件被銷毀的時候自動停止。如果想要明確地停止某個監視,可以調用 watch() 函數的返回值即可,語法如下:

 
<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 時會觸發watch 的回調, 打印變更前后的值, 此時需要注意, 更改其中一個值, 都會執行watch的回調 
    state.age = 100 
    state.name = 'vue3' 
 
    setTimeout(()=> { 
      stop() 
      // 此時修改時, 不會觸發watch 回調 
      state.age = 1000 
      state.name = 'vue3-' 
    }, 1000) // 1秒之后講取消watch的監聽 
 
    return { 
      ...toRefs(state) 
    } 
  } 
}); 
</script> 

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

新版的生命周期函數,可以按需導入到組件中,且只能在 setup() 函數中使用, 但是也可以在 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 訪問到數據 
    }) 
 
    return { 
      elmRefs 
    } 
  } 
}); 
</script> 

十、vue 的全局配置

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

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

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

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

可以在應用程序內的任何組件實例中訪問的全局屬性,組件的屬性將具有優先權。這可以代替 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 接受一個函數,這個函數需要動態調用 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 函數,處理動態引入(的組件)。defineAsyncComponent 可以接受返回承諾的工廠函數。當您從服務器檢索到組件定義時,應該調用 Promise 的解析回調。您還可以調用 reject(reason)來指示負載已經失敗

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', 
  // 父組件傳子組件參數 
  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', 
  // 父組件傳子組件參數 
  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 的生態

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

UI 組件庫

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

 

10分鐘讓你快速上手Vue3

 

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

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

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

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

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

運動步數有氧達人2018-06-03

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

每日養生app2018-06-03

每日養生,天天健康

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

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