Vue3 嚐鮮

Github源碼: vue-next
前言

也沒啥好說的,直奔主題 javascript

在這裏插入圖片描述

Vue3 相對於 Vue2 有那些更改?
  • Object.defineProperty => Proxy
  • 重構了虛擬DOM
  • OptionApi => Composition API

如何調試

首先,在GitHub上拉取最新代碼css

$ git pull https://github.com/vuejs/vue-next.git
$ cd vue-next && yarn
複製代碼

下載完成以後打開代碼, 開啓sourceMap 一、tsconfig.json 把sourceMap字段修改成true html

在這裏插入圖片描述
二、rollup.config.js 在 rollup.config.js中,手動鍵入 output.sourcemap = true
在這裏插入圖片描述
三、 yarn dev
在這裏插入圖片描述
四、在根目錄建立一個demo目錄用於存放示例代碼 並在demo目錄下建立html、js文件,引入構建後的vue文件
在這裏插入圖片描述

第一個Hello World!!!

/demo/index.html前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style> .container { text-align: center; font-size: 24px; padding: 32px; } </style>
    <script src="../packages/vue/dist/vue.global.js"></script>
</head>

<body>
    <div id="app"></div>
</body>
<script src="./index.js"></script>
</html>
複製代碼

/demo/index.jsvue

const { reactive } = Vue
var App = {
  template: ` <div class="container"> {{message}} </div>`,
  setup() {
  	const state = reactive({message: "Hello World!!!"})
	return {
		...state
	}
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在瀏覽器打開我們編寫的html文件, java

在這裏插入圖片描述
這裏的服務器環境使用 serve庫來建立的,有興趣的話能夠看下 serve

anyway,我們接着看我們的/demo/index.js文件,能夠看到,我們用了setup, reactive等函數,這就是Vue3的Composition API,相對於Vue2的組件來講 3 可讓咱們很簡單的經過組合API的方式建立一個 基於Vue3 響應式 Web 應用。 下邊我會經過一個個的demo爲你們詳細解釋這些API。react

接下來我們實現一個雙向綁定的demo!!!git

雙向綁定的demo

const { reactive } = Vue
let App = {
  template: ` <div class="container"> <input v-model="value"/>{{value}} </div>`,
  setup() {
    return reactive({ value: '' })
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
setup是幹啥的?? setup其實是一個組件的入口,它運行在組件被實例化時候,props 屬性被定義以後,實際上等價於 2 版本的 beforeCreateCreated 這兩個生命週期。

setup接受兩個參數,第一個參數是props, 另外一個參數是context,因此你們在使用2.0時習慣的在this下獲取屬性的方式 ,在 vue3.0 中,變成了:github

setup(props, ctx) {
  console.log(props, ctx)
}
複製代碼

不過在模板中仍然能夠直接使用props的屬性值,例如:shell

let Child = {
  template: `<div>{{title}}</div>`,
  setup(props, context) {
    console.log(props)
  }
}

let App = {
  template: ` <div class="container"> <Child title="test props"/> </div>`,
  components: { Child }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
在這裏插入圖片描述

reactive???以前用的 data呢??? 在Vue3中,咱們能夠把數據通過 reactive 加工變成響應式的對象,用於模版的渲染數據, 固然Vue的向下兼容 仍是容許咱們使用data的方式實現,但既然Vue3出新的寫法了,何不嘗試一波呢

計數器 demo

const { reactive, toRefs } = Vue
let App = {
  template: ` <div class="container"> count: {{count}} <button @click="handlerCountAdd"> Click ++ </button> </div>`,
  setup() {
    const state = reactive({ count: 0 })
    const handlerCountAdd = () => {
      state.count++
    }
    return { ...toRefs(state), handlerCountAdd }
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
這個toRefs是??????????? 在說這個以前 我想先說下 ref ,vue3提供的ref讓咱們有機會建立單個的響應式的對象,在setup函數中return出去以後,在模板中可直接訪問,例:

const App = {
  template: ` <div class="container"> {{value}} </div>`,
  setup() {
    const value = ref(1)
    return value
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
能夠看到 vulue已經被渲染到頁面上。 那上文提到的 reactive建立的響應式對象 在模板中訪問的話,則須要 state.xxx, 例:

const App = {
  template: ` <div class="container"> {{state.value}} </div>`,
  setup() {
    const state = reactive({ value: 'reactive' })
    return { state }
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

這樣訪問屬性確實有點麻煩,vue3提供的toRefs正是爲咱們解決這個問題的,toRefs把一組的響應式對象拆成單個的響應式對象,就可以在模板中直接訪問了,及:

const App = {
  template: ` <div class="container"> {{value}} </div>`,
  setup() {
    const state = reactive({ value: 'reactive' })
    return toRefs(state)
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

反轉字符串 demo

let App = {
  template: ` <div class="container"> value: <input v-model="value"/> <br/> rvalue: {{rvalue}} </div>`,
  setup() {
    const state = reactive({
      value: '',
      rvalue: computed(() =>
        state.value
          .split('')
          .reverse()
          .join('')
      )
    })
    return toRefs(state)
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
這個demo中 咱們用到了 computed計算屬性實現了反轉字符串的功能,這個函數雖然簡單,可是功能很強大,正如vue官網所說:對於任何複雜邏輯,你都應當使用計算屬性。

數據響應式

你們都知道, 在Vue3中實現數據響應式的方案由Vue2中的Object.defineProperty 換成了 Proxy,關於數據響應式的Api上邊說到了一些,還剩下effect和watch沒有說起到,effect是數據響應式中重要的一部分,watch和computed都是基於 effect 的,下邊來看下代碼

let App = {
  template: ` <div class="container"> count: {{count}} <button @click="handlerCountAdd"> Click ++ </button> </div>`,
  setup() {
    const state = reactive({ count: 0, value: 1 })
    const handlerCountAdd = () => {
      state.count++
    }
    watch(
      () => state.count,
      val => {
        console.log('watch', state.count)
        console.log('watch', state.value)
      }
    )
    effect(() => {
      console.log('effect', state.count)
      console.log('effect', state.value)
    })
    return { ...toRefs(state), handlerCountAdd }
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
代碼是基於上邊計數器的demo來實現的,能夠看到我們點擊click++的時候,effect和watch均可以監聽到我們數據的變化,從而根據業務做出相應的操做, 看到這裏,你們可能會有一個疑問,那就是,既然effect和watch都能監聽到數據的變化,那二者有什麼區別呢?

首先,effect 在響應式數據變化的時候就會執行,執行次數根據響應式數據的個數來決定,例如

let App = {
  template: ` <div class="container"> <button @click="handlerCountAdd"> Click ++ </button> </div>`,
  setup() {
    const r = ref(1)
    const s = ref(1)
    const t = ref(1)
    const handlerCountAdd = () => {
      r.value *= 1
      s.value *= 2
      t.value *= 3
    }
    effect(() => {
      console.log('effect', [r.value, s.value, t.value])
    })
    return { handlerCountAdd }
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
如上圖所示: 咱們點擊一次同時更新三個ref,effect就會被執行三次。

而watch則點擊一次 ,只會觸發執行一次

let App = {
  template: ` <div class="container"> <button @click="handlerCountAdd"> Click ++ </button> </div>`,
  setup() {
    const state = reactive({ count: 0, value: 1 })
    const r = ref(1)
    const s = ref(1)
    const t = ref(1)
    const handlerCountAdd = () => {
      r.value *= 1
      s.value *= 2
      t.value *= 3
    }
    watch([r, s, t], val => {
      console.log('watch', val)
    })
    return { handlerCountAdd }
  }
}
Vue.createApp().mount(App, '#app')
複製代碼

在這裏插入圖片描述
vue3 Watch的源碼在 這裏有興趣的小夥伴能夠研究研究

好了,vue3Composition Api中經常使用的一些函數在咱上邊的demo中使用了,接下來我們對比一下2和3的生命週期函數有什麼改變

Vue2 Vue3
beforeCreate setup(替代)
created setup(替代)
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted
errorCaptured onErrorCaptured
Tips: 爲何不直接運行 yarn dev,而要先開啓sourceMap?

雖然Vue官方說能夠直接運行run dev 就能夠對其進行調試,但是運行該命令後,是生成事後的代碼,不能對其編寫的ts源碼進行調試。

在這裏插入圖片描述
開啓了sourcemap以後,在編譯時會生成對應的sourcemap文件,而後贊麼就能夠在瀏覽器愉快的使用斷點調試Vue的源代碼了

Thank You

篇幅很大,感謝你們耐心觀看,文中若有錯誤歡迎指正。

在這裏插入圖片描述

我是 Colin,能夠加我微信 zw_898396209 與我交流,備註交流。

感謝H5獸超進化前端菜雞獸指正文章中的問題

相關文章
相關標籤/搜索