关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

想知道Vue3与Vue2的区别?五千字教程助你快速上手Vue3!(下)

发布时间:2023-06-26 15:00:46

EventBus/mitt


兄弟组件通信可以通过一个事件中心EventBus实现,既新建一个Vue实例来进行事件的监听,触发和销毁。


在Vue3中没有了EventBus兄弟组件通信,但是现在有了一个替代的方案mitt.js,原理还是 EventBus

  • 选项式API
//组件1   传值 import Bus from './bus.js' export default {  data(){  return {  msg:'子组件元素'  }  },  methods:{  sendMsg(){  Bus.$emit('sendMsg','兄弟的值')  }  } } " _ue_custom_node_="true">//组件2   组件2  import Bus from './bus.js' export default {  created(){  Bus.$on('sendMsg',(val)=>{  console.log(val);//兄弟的值  })  } } " _ue_custom_node_="true">//bus.js import Vue from "vue" export default new Vue()

   

  • 组合式API

首先安装mitt

npm i mitt -S

   

然后像Vue2中bus.js一样新建mitt.js文件

mitt.js


import mitt from 'mitt' const Mitt = mitt() export default Mitt

     

//组件1  传值import { defineComponent } from "vue"; import Mitt from './mitt.js' export default defineComponent({  setup() {  const sendMsg = () => {  Mitt.emit('sendMsg','兄弟的值')  }  return {  sendMsg  }  }, }); " _ue_custom_node_="true">//组件2   组件2  import { defineComponent, onUnmounted } from "vue"; import Mitt from './mitt.js' export default defineComponent({  setup() {  const getMsg = (val) => {  console.log(val);//兄弟的值  }  Mitt.on('sendMsg', getMsg)  onUnmounted(() => {  //组件销毁 移除监听  Mitt.off('sendMsg', getMsg)  })  }, }); " _ue_custom_node_="true">

   

  • setup语法糖
//组件1  传值import Mitt from './mitt.js' const sendMsg = () => {  Mitt.emit('sendMsg', '兄弟的值') } " _ue_custom_node_="true">//组件2   组件2  import { onUnmounted } from "vue"; import Mitt from './mitt.js' const getMsg = (val) => {  console.log(val);//兄弟的值 } Mitt.on('sendMsg', getMsg) onUnmounted(() => {  //组件销毁 移除监听  Mitt.off('sendMsg', getMsg) }) " _ue_custom_node_="true">

   


v-model和sync



v-model大家都很熟悉,就是双向绑定的语法糖。这里不讨论它在input标签的使用;只是看一下它和sync在组件中的使用


我们都知道Vue中的props是单向向下绑定的;每次父组件更新时,子组件中的所有props都会刷新为最新的值;但是如果在子组件中修改 props ,Vue会向你发出一个警告(无法在子组件修改父组件传递的值);可能是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得混乱难以理解。


但是可以在父组件使用子组件的标签上声明一个监听事件,子组件想要修改props的值时使用$emit触发事件并传入新的值,让父组件进行修改。

为了方便vue就使用了v-modelsync语法糖。

  • 选项式API
//父组件    完整写法   -->   { {msg}}  import Child from './Child' export default {  components: {  Child  },  data(){  return {  msg:'父组件值'  }  }  } " _ue_custom_node_="true">//子组件   改变父组件值 export default {  data(){  return {  msg:'子组件元素'  }  },  methods:{  changePval(){  //点击则会修改父组件msg的值  this.$emit('update:changePval','改变后的值')  }  } } " _ue_custom_node_="true">

   

  • setup语法糖

因为使用的都是前面提过的知识,所以这里就不展示组合式API的写法了

//父组件    完整写法   -->   { {msg}}  import Child from './Child' import { ref } from 'vue' const msg = ref('父组件值') " _ue_custom_node_="true">//子组件  改变父组件值import { defineEmits } from 'vue'; const emits = defineEmits(['changePval']) const changePval = () => {  //点击则会修改父组件msg的值  emits('update:changePval','改变后的值') } " _ue_custom_node_="true">

   

总结

vue3中移除了sync的写法,取而代之的式v-model:event的形式

v-model:changePval="msg"或者:changePval.sync="msg"的完整写法为@update:changePval="msg=$event"

所以子组件需要发送update:changePval事件进行修改父组件的值


路由



vue3和vue2路由常用功能只是写法上有些区别

  • 选项式API
  路由跳转 export default {  beforeRouteEnter (to, from, next) {  // 在渲染该组件的对应路由被 confirm 前调用  next()  },  beforeRouteEnter (to, from, next) {  // 在渲染该组件的对应路由被 confirm 前调用  next()  },  beforeRouteLeave ((to, from, next)=>{//离开当前的组件,触发  next()  }),  beforeRouteLeave((to, from, next)=>{//离开当前的组件,触发  next()  }),  methods:{  toPage(){  //路由跳转  this.$router.push(xxx)  }  },  created(){  //获取params  this.$route.params  //获取query  this.$route.query  } } " _ue_custom_node_="true">

   


  • 组合式API
  路由跳转 import { defineComponent } from 'vue' import { useRoute, useRouter } from 'vue-router' export default defineComponent({  beforeRouteEnter (to, from, next) {  // 在渲染该组件的对应路由被 confirm 前调用  next()  },  beforeRouteLeave ((to, from, next)=>{//离开当前的组件,触发  next()  }),  beforeRouteLeave((to, from, next)=>{//离开当前的组件,触发  next()  }),  setup() {  const router = useRouter()  const route = useRoute()  const toPage = () => {  router.push(xxx)  }  //获取params 注意是route  route.params  //获取query  route.query  return {  toPage  }  }, }); " _ue_custom_node_="true">

   

  • setup语法糖

我之所以用beforeRouteEnter作为路由守卫的示例是因为它在setup语法糖中是无法使用的;大家都知道setup中组件实例已经创建,是能够获取到组件实例的。而beforeRouteEnter是再进入路由前触发的,此时组件还未创建,所以是无法用在setup中的;如果想在setup语法糖中使用则需要再写一个script 如下:

  路由跳转 export default {  beforeRouteEnter(to, from, next) {  // 在渲染该组件的对应路由被 confirm 前调用  next()  }, }; " _ue_custom_node_="true">import { useRoute, useRouter,onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router' const router = useRouter() const route = useRoute() const toPage = () => {  router.push(xxx) } //获取params 注意是route route.params //获取query route.query //路由守卫 onBeforeRouteUpdate((to, from, next)=>{//当前组件路由改变后,进行触发  next() }) onBeforeRouteLeave((to, from, next)=>{//离开当前的组件,触发  next() }) " _ue_custom_node_="true">

   


写在最后



通过以上写法的对比会发现setup语法糖的形式最为便捷而且更符合开发者习惯;未来Vue3的开发应该会大面积使用这种形式。目前Vue3已经成为了Vue的默认版本,后续维护应该也会以Vue3为主;所以还没开始学习Vue3的同学要抓紧了!

Vue3文档地址



/template/Home/leiyu/PC/Static