如何在Vue2與Vue3中構建相同的組件

隨着Vue3即將發佈,許多人都在想「 Vue2與Vue3有何不一樣?」javascript

爲了顯示這些更改,咱們將在Vue2和Vue3中構建一個簡單的表單組件。html

在本文結尾,你將瞭解Vue2和Vue3之間的主要編程差別,並逐步成爲一名更好的開發人員。前端

建立咱們的模板

對於大多數組件,Vue2和Vue3中的代碼即便不徹底相同,也是很是類似的。可是,Vue3支持Fragments,這意味着組件能夠具備多個根節點。vue

在渲染列表中的組件以刪除沒必要要的包裝div元素時,這特別有用。可是,在這種狀況下,咱們將爲兩個版本的Form組件保留一個根節點。java

Vue2react

<template>
  <div class='form-element'>
    <h2> {{ title }} </h2>
    <input type='text' v-model='username' placeholder='Username' />
    
    <input type='password' v-model='password' placeholder='Password' />

    <button @click='login'>
      Submit
    </button>
    <p> 
      Values: {{ username + ' ' + password }}
    </p>
  </div>
</template>
複製代碼

惟一真正的區別是咱們訪問數據的方式。在Vue3中,咱們的響應式數據都包裝在響應式狀態變量中——所以咱們須要訪問該狀態變量以獲取咱們的值。編程

Vue3數組

<template>
  <div class='form-element'>
    <h2> {{ state.title }} </h2>
    <input type='text' v-model='state.username' placeholder='Username' />
    
    <input type='password' v-model='state.password' placeholder='Password' />

    <button @click='login'>
      Submit
    </button>
    <p> 
      Values: {{ state.username + ' ' + state.password }}
    </p>
  </div>
</template>
複製代碼

設置Data

這是主要的區別——Vue2 Options API與Vue3 Composition APIide

Options API將咱們的代碼分爲不一樣的屬性:數據,計算屬性,方法等。同時,Composition API容許咱們按功能而不是屬性類型對代碼進行分組。函數

假設對於表單組件,咱們只有兩個數據屬性:usernamepassword

Vue2代碼看起來是這樣的——咱們只需在 data 屬性中放入兩個值。

Vue2

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  }
}
複製代碼

在Vue 3.0中,咱們必須投入更多的精力來使用一個新的 setup() 方法,全部的組件初始化都應該在這個方法中進行。

另外,爲了使開發人員可以更好地控制響應式,咱們能夠直接訪問Vue的響應式API。

建立響應式數據涉及三個步驟:

  • 從Vue導入 reactive
  • 使用 reactive 方法聲明咱們的數據
  • 讓咱們的 setup() 方法返回reactive數據,以便咱們的模板能夠訪問它

在代碼方面,它將看起來像這樣。

Vue3

import { reactive } from 'vue'

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: ''
    })

    return { state }
  }
}
複製代碼

而後,在模板中,咱們像 state.usernamestate.password 同樣訪問它們

在Vue2與Vue3中建立方法

Vue2 Options API有一個單獨的方法部分。在其中,咱們能夠定義全部方法並以所需的任何方式組織它們。

Vue2

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login () {
      // login method
    }
  }
}
複製代碼

Vue3 Composition API中的setup方法也能夠處理方法。它的工做方式與聲明數據有些相似——咱們必須先聲明咱們的方法,而後返回它,以便組件的其餘部分能夠訪問它。

Vue3

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: ''
    })

    const login = () => {
      // login method
    }
    return { 
      login,
      state
    }
  }
}
複製代碼

生命週期鉤子函數

在Vue2中,咱們能夠直接從組件選項訪問生命週期鉤子函數。對於咱們的示例,咱們將等待 mounted 事件。

Vue2

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  },
  mounted () {
    console.log('component mounted')
  },
  methods: {
    login () {
      // login method
    }
  }
}
複製代碼

如今有了Vue3 Composition API,幾乎全部內容都在 setup() 方法內部,這包括 mounted 的生命週期鉤子。

可是,默認狀況下不包括生命週期掛鉤,所以咱們必須導入 onMounted 方法,做爲Vue3中調用的方法,這看起來與早期導入 reactive 相同。

而後,在咱們的 setup() 方法中,能夠經過將 onMounted 方法傳遞給函數來使用它。

Vue3

import { reactive, onMounted } from 'vue'

export default {
  props: {
    title: String
  },
  setup () {
    // ..

    onMounted(() => {
      console.log('component mounted')
    })

    // ...
  }
}
複製代碼

計算屬性

讓咱們添加一個計算屬性,將咱們的用戶名轉換爲小寫字母。爲了在Vue2中完成此操做,咱們將一個計算字段添加到咱們的options對象中。

Vue2

export default {
  // .. 
  computed: {
    lowerCaseUsername () {
      return this.username.toLowerCase()
    }
  }
}
複製代碼

Vue3的設計容許開發人員導入他們使用的內容,而在項目中沒有使用的不須要導入。本質上,他們不但願開發人員必須包含他們從未使用過的東西,這在Vue2中已經成爲一個日益嚴重的問題。

所以,要在Vue3中使用計算屬性,咱們首先必須將 computed 導入到組件中。

而後,相似於咱們以前建立 reactive 數據的方式,咱們可使一條 reactive 數據成爲這樣的計算值:

Vue3

import { reactive, onMounted, computed } from 'vue'

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: '',
      lowerCaseUsername: computed(() => state.username.toLowerCase())
    })

    // ...
  }
}
複製代碼

訪問屬性(Props)

訪問Props帶來了Vue2和Vue3之間的一個重要區別——這意味着徹底不一樣的東西

在Vue2中,這幾乎老是引用組件,而不是特定的屬性,雖然這使事情表面上很容易,但它使類型支持成爲一種痛苦。

以往,咱們均可以輕鬆訪問Props——讓咱們添加一個簡單的示例,例如在mounted的鉤子上打印出標題prop:

Vue2

mounted () {
  console.log('title: ' + this.title)
}
複製代碼

可是在Vue3中,咱們再也不使用它來訪問Props、發出事件和獲取屬性。

相反,setup() 方法採用兩個參數:

  • props——對組件prop的不可變訪問
  • context——Vue3公開的選定屬性(emit、slots、 attrs)

使用props參數,上面的代碼將以下所示。

Vue3

setup (props) {
  // ...

  onMounted(() => {
    console.log('title: ' + props.title)
  })

  // ...
}
複製代碼

發送事件(Emitting Events)

相似地,在Vue2中發出事件很是簡單,可是Vue3爲你提供了對如何訪問屬性/方法的更多控制。

例如,在咱們的例子中,咱們想在按下「Submit」按鈕時向父組件發出登陸事件。

Vue2代碼只須要調用 this.$emit並傳入咱們的有效參數對象便可。

Vue2

login () {
  this.$emit('login', {
    username: this.username,
    password: this.password
  })
 }
複製代碼

然而,在Vue3中,咱們如今知道這再也不意味着一樣的事情,因此咱們必須作得不一樣。

幸運的是,上下文對象(context)公開了 emit,這使咱們擁有與此相同的東西。

咱們要作的就是將 context 添加爲 setup() 方法的第二個參數,咱們將解構上下文對象,以使咱們的代碼更簡潔。

而後,咱們只須要調用emit發送事件便可。而後,像之前同樣,emit方法採用兩個參數:

  • 事件名稱
  • 與事件一塊兒傳遞的有效參數對象

Vue3

setup (props, { emit }) {
  // ...

  const login = () => {
    emit('login', {
      username: state.username,
      password: state.password
    })
  }

  // ...
}
複製代碼

最終的Vue2與Vue3代碼!

如你所見,Vue2和Vue3中的全部概念都是相同的,可是咱們訪問屬性的某些方式已經有所變化。

總的來講,我認爲Vue3將幫助開發人員編寫更有組織的代碼——特別是在大型代碼庫中。這主要是由於Composition API容許你按特定功能將代碼分組在一塊兒,甚至能夠將功能提取到本身的文件中,而後根據須要將其導入組件中。

Vue2中用於表單組件的完整代碼:

<template>
  <div class='form-element'>
    <h2> {{ title }} </h2>
    <input type='text' v-model='username' placeholder='Username' />
    
    <input type='password' v-model='password' placeholder='Password' />

    <button @click='login'>
      Submit
    </button>
    <p> 
      Values: {{ username + ' ' + password }}
    </p>
  </div>
</template>
<script> export default { props: { title: String }, data () { return { username: '', password: '' } }, mounted () { console.log('title: ' + this.title) }, computed: { lowerCaseUsername () { return this.username.toLowerCase() } }, methods: { login () { this.$emit('login', { username: this.username, password: this.password }) } } } </script>
複製代碼

這是在Vue3中的完整代碼:

<template>
  <div class='form-element'>
    <h2> {{ state.title }} </h2>
    <input type='text' v-model='state.username' placeholder='Username' />
    
    <input type='password' v-model='state.password' placeholder='Password' />

    <button @click='login'>
      Submit
    </button>
    <p> 
      Values: {{ state.username + ' ' + state.password }}
    </p>
  </div>
</template>
<script> import { reactive, onMounted, computed } from 'vue' export default { props: { title: String }, setup (props, { emit }) { const state = reactive({ username: '', password: '', lowerCaseUsername: computed(() => state.username.toLowerCase()) }) onMounted(() => { console.log('title: ' + props.title) }) const login = () => { emit('login', { username: state.username, password: state.password }) } return { login, state } } } </script>
複製代碼

我但願本教程有助於重點介紹Vue代碼在Vue3中看起來不同凡響的某些方式。若有其餘疑問,請留下你的意見!


原文:learnvue.co/2020/02/bui…

做者:Matt Maribojoc


文章首發於公衆號 《前端外文精選》,私信回覆:大禮包,送某網精品視頻課程網盤資料,準能爲你節省很多錢!

相關文章
相關標籤/搜索