|
|
51CTO旗下网站
|
|
移动端

详细教程:在Vue2和Vue3中构建相同的组件

在本文的最后,将介绍Vue2和Vue3之间的主要编程差异,帮助大家了解,逐渐成为更好的开发人员。

作者:读芯术来源:今日头条|2020-03-25 18:23

过去,我们看过很多重大变革即将到来的文章,但是并没有真正深入研究代码将如何变化。

为了展示这些变化,小芯将在Vue2和Vue3中构建一个简单的表单组件。

在本文的最后,将介绍Vue2和Vue3之间的主要编程差异,帮助大家了解,逐渐成为更好的开发人员。

如果想知道如何建立第一个Vue3应用程序,请查看初学者的Vue3Alpha应用程序指南。

我们开始吧!

创建模板

对于大多数组件,Vue2和Vue3中的代码即使不完全相同,也是非常相似的。但是,Vue3支持片段,这意味着组件可以有多个根节点。

这在呈现列表中的组件以删除不必要的包装器div元素时特别有用。但是,在本例中,表单组件的两个版本都将只保留一个根节点。

  1. <template> 
  2.   <div> 
  3.     <h2> {{ title }} </h2> 
  4.     <input type='text'v-model='username' placeholder='Username' /> 
  5.     
  6.     <input type='password'v-model='password' placeholder='Password' /> 
  7.     <button @click='login'> 
  8.       Submit 
  9.     </button> 
  10.     <p> 
  11.       Values: {{ username + ' ' +password }} 
  12.     </p> 
  13.   </div> 
  14. </template> 

唯一真正的区别是如何访问数据。在Vue3中,响应式数据都封装在一个响应状态变量中,所以需要访问这个状态变量来获得值。

  1. <template> 
  2.   <div> 
  3.     <h2> {{ state.title }}</h2> 
  4.     <input type='text'v-model='state.username' placeholder='Username' /> 
  5.     
  6.     <input type='password'v-model='state.password' placeholder='Password' /> 
  7.     <button @click='login'> 
  8.       Submit 
  9.     </button> 
  10.     <p> 
  11.       Values: {{ state.username + ' ' +state.password }} 
  12.     </p> 
  13.   </div> 
  14. </template> 

设置数据

这就是主要的区别——Vue2选项API对战Vue3组合API。

选项 API将代码分成不同的属性:数据、计算属性、方法等等。同时,组合API允许根据函数而不是属性类型对代码进行分组。

对于表单组件,只有两个数据属性:一个username和一个password。

Vue2代码看起来是这样的——只需在数据属性中放入两个值。

  1. exportdefault { 
  2.   props: { 
  3.     title: String 
  4.   }, 
  5.   data () { 
  6.     return { 
  7.       username: '', 
  8.       password: '' 
  9.     } 
  10.   } 

在Vue3.0中,必须投入更多精力来使用一个新的setup()方法,所有的组件初始化都应该在这个方法中进行。

另外,为了让开发人员更好地控制响应,可以直接访问Vue的响应API。

创建响应式数据需要三个步骤:

  • 从vue中导入reactive
  • 使用响应式方法声明数据
  • 使用setup方法返回响应式数据以便模板可以访问

代码看起来有点像这样。

  1. import {reactive } from 'vue' 
  2.  
  3. export default { 
  4.   props: { 
  5.     title: String 
  6.   }, 
  7.   setup () { 
  8.     const state = reactive({ 
  9.       username: '', 
  10.       password: '' 
  11.     }) 
  12.      
  13.     return { state } 
  14.   } 

接着在模板中,可以使用诸如state.username和state.password来访问

在Vue2和Vue3中创建方法

Vue2选项API有一个单独的方法部分。这部分可以定义所有的方法,并以任何想要的方式进行组织。

  1. exportdefault { 
  2.   props: { 
  3.     title: String 
  4.   }, 
  5.   data () { 
  6.     return { 
  7.       username: '', 
  8.       password: '' 
  9.     } 
  10.   }, 
  11.   methods: { 
  12.     login () { 
  13.       // login method 
  14.     } 
  15.   } 

Vue3组合API中的setup方法也可以处理。它的工作原理与声明数据有些类似——必须先声明方法,然后返回,以便组件的其他部分可以访问它。

  1. exportdefault { 
  2.   props: { 
  3.     title: String 
  4.   }, 
  5.   setup () { 
  6.     const state = reactive({ 
  7.       username: '', 
  8.       password: '' 
  9.     }) 
  10.     const login = () => { 
  11.       // login method 
  12.     } 
  13.     return { 
  14.       login, 
  15.       state 
  16.     } 
  17.   } 

生命周期挂钩

Vue2可以直接从组件选项中访问生命周期挂钩。以下示例代码将等待挂载的事件。

  1. exportdefault { 
  2.   props: { 
  3.     title: String 
  4.   }, 
  5.   data () { 
  6.     return { 
  7.       username: '', 
  8.       password: '' 
  9.     } 
  10.   }, 
  11.   mounted () { 
  12.     console.log('component mounted') 
  13.   }, 
  14.   methods: { 
  15.     login () { 
  16.       // login method 
  17.     } 
  18.   } 

现在有了Vue3 组合API,几乎所有东西都在setup()方法中,包括挂载的生命周期挂钩。

然而,生命周期挂钩在默认情况下并不包括在内,因此必须导入在Vue3中被称为onmount的方法。这看起来与前面导入reactive是一样的。

然后,在setup方法中,通过传递函数来使用onmount方法。

  1. import {reactive, onMounted } from 'vue' 
  2.  
  3. export default { 
  4.   props: { 
  5.     title: String 
  6.   }, 
  7.   setup () { 
  8.     // .. 
  9.      
  10.     onMounted(() => { 
  11.       console.log('component mounted') 
  12.     }) 
  13.      
  14.     // ... 
  15.   } 

computed属性

添加一个computed属性,将用户名转换为小写字母。

为了在Vue2中实现这一点,向选项对象添加一个computed字段。从这里,可以像这样定义属性…

  1. exportdefault { 
  2.   // .. 
  3.   computed: { 
  4.     lowerCaseUsername () { 
  5.       return this.username.toLowerCase() 
  6.     } 
  7.   } 

Vue3的设计允许开发人员导入他们使用的东西,并且项目中没有不必要的包。本质上,他们不希望开发人员包含从未使用过的东西,这而这在Vue2中已经成为一个日益严重的问题。

因此,要在Vue3中使用computed属性,首先必须将computed导入到组件中。

然后,与之前创建响应式数据的方式类似,将一段响应式数据变成一个计算值,如下所示:

  1. import {reactive, onMounted, computed } from 'vue' 
  2.  
  3. export default { 
  4.   props: { 
  5.     title: String 
  6.   }, 
  7.   setup () { 
  8.     const state = reactive({ 
  9.       username: '', 
  10.       password: '', 
  11.       lowerCaseUsername: computed(()=> state.username.toLowerCase()) 
  12.     }) 
  13.      
  14.     // ... 
  15.   } 

访问Props

访问道具带来了Vue2和Vue3之间的一个重要区别——this意味着完全不同的东西。

在Vue2中,this几乎总是指向组件,而不是特定的属性。虽然这使事情表面上很容易,但它使类型支持成为一种痛苦。

然而,可以很容易地访问props——只需添加一个小例子,比如在挂载挂钩期间打印出title prop:

  1. mounted() { 
  2.     console.log('title: ' + this.title) 

但是在Vue3中不再使用它来访问props、触发事件和获取属性。相反,setup()方法有两个参数:

  • props - 对组件props的不可变访问
  • context - Vue3公开的上下文选择属性(emit、slot、attrs)

使用props参数,上面的代码将如下所示。

  1. mounted() { 
  2.     console.log('title: ' + this.title) 

触发事件

类似地,在Vue2中触发事件非常简单,但是Vue3对如何访问属性/方法提供了更多控制。

本例希望在按下“Submit”按钮时触发父组件的一个登录事件。

Vue2代码只需要调用this.$emit并传入有效负载对象。

  1. login (){ 
  2.       this.$emit('login', { 
  3.         username: this.username, 
  4.         password: this.password 
  5.       }) 
  6.  } 

然而在Vue3中,this现在含义不同了,得做出一点改变。

幸运的是,文本对象公开了emit,提供了与this.$emit相同的东西

所要做的就是添加context作为setup方法的第二个参数。将对c文本对象进行析构,使代码更简洁。

然后,只需调用emit来触发事件。与前面一样,emit方法有两个参数:

  • 事件名称
  • 与事件一起传递的有效负载对象
  1. setup(props, { emit }) { 
  2.     // ... 
  3.    
  4.     const login = () => { 
  5.       emit('login', { 
  6.         username: state.username, 
  7.         password: state.password 
  8.       }) 
  9.     } 
  10.      
  11.     // ... 

Vue2和Vue3的最后代码

太棒了!已经到了最后阶段。

Vue2和Vue3中的所有概念都是相同的,但是访问属性的一些方式发生了一点变化。

总的来说,笔者认为Vue3将帮助开发人员编写更有组织的代码——特别是在大型代码库中。这主要是因为组合API允许根据特定的特性将代码分组,甚至可以将功能提取到它们自己的文件中,并根据需要将它们导入到组件中。

下面是Vue2中的表单组件代码。

  1. <template> 
  2.   <div> 
  3.     <h2> {{ title }} </h2> 
  4.     <input type='text'v-model='username' placeholder='Username' /> 
  5.     
  6.     <input type='password'v-model='password' placeholder='Password' /> 
  7.        
  8.     <button @click='login'> 
  9.       Submit 
  10.     </button> 
  11.     <p> 
  12.       Values: {{ username + ' ' +password }} 
  13.     </p> 
  14.   </div> 
  15. </template> 
  16. <script> 
  17. export default { 
  18.   props: { 
  19.     title: String 
  20.   }, 
  21.   data () { 
  22.     return { 
  23.       username: '', 
  24.       password: '' 
  25.     } 
  26.   }, 
  27.   mounted () { 
  28.     console.log('title: ' + this.title) 
  29.   }, 
  30.   computed: { 
  31.     lowerCaseUsername () { 
  32.       return this.username.toLowerCase() 
  33.     } 
  34.   }, 
  35.   methods: { 
  36.     login () { 
  37.       this.$emit('login', { 
  38.         username: this.username, 
  39.         password: this.password 
  40.       }) 
  41.     } 
  42.   } 
  43. </script> 

下面是Vue3的。

  1. <template> 
  2.   <div> 
  3.     <h2> {{ state.title }}</h2> 
  4.     <input type='text'v-model='state.username' placeholder='Username' /> 
  5.     
  6.     <input type='password'v-model='state.password' placeholder='Password' /> 
  7.        
  8.     <button @click='login'> 
  9.       Submit 
  10.     </button> 
  11.     <p> 
  12.       Values: {{ state.username + ' ' +state.password }} 
  13.     </p> 
  14.   </div> 
  15. </template> 
  16. <script> 
  17. import { reactive, onMounted, computed } from 'vue' 
  18.  
  19. export default { 
  20.   props: { 
  21.     title: String 
  22.   }, 
  23.   setup (props, { emit }) { 
  24.     const state = reactive({ 
  25.       username: '', 
  26.       password: '', 
  27.       lowerCaseUsername: computed(()=> state.username.toLowerCase()) 
  28.     }) 
  29.      
  30.     onMounted(() => { 
  31.       console.log('title: ' +props.title) 
  32.     }) 
  33.      
  34.     const login = () => { 
  35.       emit('login', { 
  36.         username: state.username, 
  37.         password: state.password 
  38.       }) 
  39.     } 
  40.      
  41.     return { 
  42.       login, 
  43.       state 
  44.     } 
  45.   } 
  46. </script> 

希望本教程能够帮助了解Vue代码在Vue3中的一些不同之处。

【责任编辑:赵宁宁 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

 敏捷无敌之 Gitlab CI 持续集成

敏捷无敌之 Gitlab CI 持续集成

打破运维与研发壁垒
共5章 | KaliArch

99人订阅学习

秒杀高并发白话实战

秒杀高并发白话实战

主流高并发架构
共15章 | 51CTO崔皓

60人订阅学习

网络排障一点通

网络排障一点通

网络排障及优化调整案例
共20章 | 捷哥CCIE

470人订阅学习

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微