专栏首页前端知否构建相同的组件Vue3 vs Vue2

构建相同的组件Vue3 vs Vue2

随着Vue3即将发布,许多人都在想”Vue2与Vue3有何不同?”

尽管我们之前已经写过有关重大变化的文章,但实际上并没有真正深入地了解我们的代码将如何变化。因此,为了显示这些更改,我们将在Vue2和Vue3中构建一个简单的表单组件。

在本文中,您将了解Vue2和Vue3之间的主要编程差异,并逐步成为一名更好的开发人员。

如果您想知道如何构建第一个Vue3应用程序,请查阅Vue3 Composition API教程及示例

让我们开始吧!

创建模板

对于大多数组件,Vue2和Vue3中的代码将非常相似。但是,Vue3支持Fragments,这意味着组件可以具有多个根节点。

在渲染列表中的组件时,可以减少不必要的包装div元素,这特别有用。在这种情况下,我们将为两个版本的Form组件保留一个根节点。

<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中,我们的响应式数据都包装在一个响应式状态变量中,因此我们需要访问该状态变量以获取我们的值。

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

设置数据

这是一个重大的区别:Vue2 Options API与Vue3 Composition API。

Options API将我们的代码分为不同的属性:数据,计算属性,方法等。但是,Composition API允许我们按功能而不是属性的类型对代码进行分组

假设对于表单组件,我们只有两个数据属性:用户名和密码。

Vue2代码:

export default {
  props: {
    title: String
  },

  data() {
    return {
      username: '',
      password: ''
    }
  }
}

在Vue 3.0中,我们必须通过使用新的setup()方法进行更多的工作,在该方法中应进行所有组件初始化。

另外,为了使开发人员能够更好地控制数据响应,我们可以直接访问Vue的 reactive API。

创建响应性数据包含三个步骤:

  • 从Vue中导入reactive
  • 使用reactive方法声明我们的数据
  • 让我们的setup()方法返回响应性数据,以便我们的模板可以访问它

代码如下:

import { reactive } from 'vue'

export default {
  props: {
    title: String
  },

  setup() {
    const state = reactive({
      username: '',
      password: ''
    })

    return { state }
  }
}

然后,在模板中,我们可以使用state.username和state.password访问它们

在Vue2与Vue3中创建方法

Vue2 Options API有一个单独的方法部分。在其中,我们可以定义所有方法并以所需的任何方式组织它们。

export default {
  props: {
    title: String
  },

  data() {
    return {
      username: '',
      password: ''
    }
  },

  methods: {
    login() {
      // login method
    }
  }
}

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

export default {
  props: {
    title: String
  },

  setup() {
    const state = reactive({
      username: '',
      password: ''
    })

    const login = () => {
      // login method
    }

    return {
      login,
      state
    }
  }
}

生命周期钩子

在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方法传递函数参数来使用它。

import { reactive, onMounted } from 'vue'

export default {
  props: {
    title: String
  },

  setup() {
    // ..

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

    // ...
  }
}

计算属性

让我们添加一个计算属性,将我们的用户名转换为小写字母。

为了在Vue2中完成此操作,我们需要添加computed字段到我们的options对象中。我们可以像这样定义我们的属性:

export default {
  // ..
  computed: {
    lowerCaseUsername () {
      return this.username.toLowerCase()
    }
  }
}

Vue3的设计允许开发人员导入他们使用的内容。本质上,它不希望开发人员必须包含从未使用过的东西,这在Vue2中正成为一个日益严重的问题。

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

然后,类似于我们之前创建响应式数据的方式,我们可以使一个响应式数据成为这样的计算值:

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中,我们可以轻松访问P。让我们添加一个简单的示例,例如在加载完成钩子上打印出标题属性:

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

但是在Vue3中,我们不再使用this来访问Props,发出事件和获取属性。现在setup()方法采用了两个参数:

  • props -对组件的props的访问,数据不可改变
  • context -Vue3公开的选定属性(emit,slot,attrs

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

setup(props) {
  // ...

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

  // ...
}

发出事件

同样,在Vue2中发出事件非常简单,但是Vue3使您可以更好地控制如何访问属性/方法。

假设在我们的情况下,我们想在按下“提交”按钮时向父组件发出一个登录事件。

Vue2代码只需要调用this.$emit并传入我们的payload对象即可。

login() {
  this.$emit('login', {
    username: this.username,
    password: this.password
  })
}

但是,在Vue3中,我们不能再直接使用this.$emit。

幸运的是,上下文context对象公开了emit方法。

我们要做的就是将context添加为setup()方法的第二个参数。我们将解构上下文对象,以使我们的代码更简洁。

然后,我们只需要调用emit发送事件即可。像以前一样,emit方法采用两个参数:

  • 事件名称
  • 与事件一起传递的payload对象
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中不同表现形式。编码愉快!

本文分享自微信公众号 - 前端知否(qianduanzhifou),作者:QETHAN

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ElementUI Table组件,如何在多页数据下勾选多行

    ElementUI Table组件,选择多行数据时使用 Checkbox。如下图:

    前端知否
  • Vue.js应用性能优化三

    在上一篇Vue.js应用性能优化二中,我们学习了足够强大的模式,可以显着提高应用程序的性能 - 按照路由分割代码。虽然按照路由拆分代码非常有用,但在用户访问我们...

    前端知否
  • Vue.js render函数那些事儿

    大多时候,我会使用template, vue单文件去渲染组件。虽然知道Vue中有个render函数,但却很少在项目中去主动使用它。使用最多的地方是在使用一些UI...

    前端知否
  • SQL注入攻击与防御举例

    以下是一段普普通通的登录演示代码,该脚本需要username和password两个参数,该脚本中sql语句没有任何过滤,注入起来非常容易,后续部分将逐步加强代码...

    KevinBruce
  • 解决samba访问特别慢的问题

    咪啪咪啪
  • CTF---Web入门第十题 Once More

    Once More分值:10 来源: iFurySt 难度:易 参与人数:4782人 Get Flag:2123人 答题人数:2166人 解题通过率:98%...

    Angel_Kitty
  • 技术干货 | 搜索那点事儿:Lucene文件存储和读取技术详解

    作者简介 ---- 刘光敏: 达观数据搜索组研发技术人员,负责搜索引擎架构的设计和研发,搜索集群健康状况监控模块的开发及维护等。 ---- Lucene是一个...

    达观数据
  • 万万没想到,微信解决电信公司一大“桎梏”:停机断网也能充话费

    自从微信诞生以来,它以势如破竹的态势抢占了数以亿计的用户,与此同时,其免费的信息和语音功能几乎将电信公司此前赖以生存的的语音业务完全摧毁,电信公司被迫走出“躺着...

    悲了伤的白犀牛
  • javascript计算两个时间差

      其实,javascript计算时间差的方式非常简单,如果是默认的Date()类型,直接相减就是相差的毫秒数。

    ydymz
  • 3.1 Contour绘制

    首先一起学习利用百度的开源项目绘制contour,百度搜索“echarts heatmap”,找到热力图的一个案例(http://echarts.baidu.c...

    周星星9527

扫码关注云+社区

领取腾讯云代金券