如何在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


文章首发于公众号 《前端外文精选》,私信回复:大礼包,送某网精品视频课程网盘资料,准能为你节省很多钱!

相关文章
相关标签/搜索