목차
선택 API 및 결합 API
ref andactive
watch和computed
组件通信
props
emit
attrs和listeners
provide/inject
parent/children
expose&ref
EventBus/mitt
v-model和sync
路由
写在最后
웹 프론트엔드 View.js Vue3과 Vue2의 차이점은 무엇입니까? 다 비교해 보세요!

Vue3과 Vue2의 차이점은 무엇입니까? 다 비교해 보세요!

Jun 23, 2022 pm 03:37 PM
vue vue.js vue3

Vue3과 Vue2의 차이점은 무엇인가요? 다음 기사에서는 Vue3과 Vue2를 포괄적으로 비교하고 Vue3과 Vue2의 차이점에 대해 설명합니다. 도움이 되기를 바랍니다.

Vue3과 Vue2의 차이점은 무엇입니까? 다 비교해 보세요!

저는 Vue3가 출시된 이후로 매우 관심이 있었고 이를 회사의 프로덕션에 적용하려고 생각하고 있었습니다. 그러나 많은 불확실성을 고려하여 일시적으로 몇 가지 작은 기능을 결합한 API를 발견했습니다. form은 개발(개인적인 느낌)에 매우 적합합니다. 특히 Vue3.2가 설정 구문 설탕을 출시한 후 매우 인기가 있었습니다.

나중에 회사의 거의 모든 새 프로젝트에서는 Vue3를 사용합니다. 저는 거의 반년 동안 Vue3으로 개발을 해왔기 때문에 Vue2와 Vue3에 대한 비교 및 ​​요약을 하기 위해 이 글을 썼습니다. 더 많은 친구들을 더 빠르게 돕기 위해 Vue3을 시작해보세요. (동영상 공유 학습: vuejs 비디오 튜토리얼)

이 글은 주로 선택적 API, 결합 API 및 설정 구문 설탕을 사용하여 직접적인 차이점을 실현합니다.

선택 API 및 결합 API

먼저 하나를 구현합니다. 동일한 논리(클릭 페이지 데이터 전환) 직접적인 차이점을 살펴보세요

  • Optional API
<template>
<div @click="changeMsg">{{msg}}</div>
</template>
<script>
export default  {
  data(){
    return {
     msg:&#39;hello world&#39;
    }
  },
  methods:{
    changeMsg(){
      this.msg = &#39;hello juejin&#39;
    }
  }
}
</script>
로그인 후 복사
  • Combined API
<template>
 <div @click="changeMsg">{{msg}}</div>
</template>

<script>
import { ref,defineComponent } from "vue";
export default defineComponent({
setup() {
    const msg = ref(&#39;hello world&#39;)
    const changeMsg = ()=>{
      msg.value = &#39;hello juejin&#39;
    }
return {
  msg,
  changeMsg
};
},
});
</script>
로그인 후 복사
  • setup 구문 sugar
<template>
  <div @click="changeMsg">{{ msg }}</div>
</template>

<script setup>
import { ref } from "vue";

const msg = ref(&#39;hello world&#39;)
const changeMsg = () => {
  msg.value = &#39;hello juejin&#39;
}
</script>
로그인 후 복사

요약:

후속 시계를 포함한 선택적 API 데이터 및 방법 , 계산 등은 별도로 관리되는 반면, 결합된 API는 관련 로직을 하나로 묶습니다(네이티브 js 개발과 유사).

설정 구문 설탕을 사용하면 변수 메서드를 사용하여 반환을 작성할 필요가 없으며 후속 구성 요소와 사용자 지정 지침까지 템플릿에서 자동으로 얻을 수 있습니다.

ref andactive

우리 모두는 결합된 API에서 데이터 함수의 데이터가 반응형이고 데이터의 데이터가 변경되면 페이지도 변경되지만 결합된 API에는 데이터 함수가 존재하지 않는다는 것을 모두 알고 있습니다. API 어떻게? 그래서 이 문제를 해결하기 위해 Vue3에서는 변수를 반응형 데이터로 만들기 위해 ref 및 반응 함수를 도입했습니다. js에 값을 추가하려면 .value를 추가해야 합니다.

    reactive는 복잡한 데이터 유형 ref를 정의하는 데 더 권장되며 기본 유형을 정의하는 데 더 권장됩니다
생명주기
  • 다음 표에는 Vue2와 Vue3의 생명주기 차이

Vue2( 선택적 API)

Vue3(설정)

Description

beforeCreate--인스턴스 생성 후 DOM이 마운트되기 전에 호출mountedonMountedDOM 마운트 완료 호출beforeUpdateonBeforeUpdate데이터 업데이트 전에 호출updatedonUpdate d데이터 업데이트 후 호출됨beforeDestroyonBeforeUnmount구성 요소가 삭제되기 전에 호출됩니다destroyedonUnmounted구성 요소가 삭제된 후 호출

举个常用的onBeforeMount的例子

  • 选项式Api
<script>
export default  {
  mounted(){
    console.log(&#39;挂载完成&#39;)
  }
}
</script>
로그인 후 복사
  • 组合式Api
<script>
import { onMounted,defineComponent } from "vue";
export default defineComponent({
setup() {
onMounted(()=>{
  console.log(&#39;挂载完成&#39;)
})
return {
onMounted
};
},
});
</script>
로그인 후 복사
  • setup语法糖
<script setup>
import { onMounted } from "vue";
onMounted(()=>{
  console.log(&#39;挂载完成&#39;)
})
</script>
로그인 후 복사

从上面可以看出Vue3中的组合式API采用hook函数引入生命周期;其实不止生命周期采用hook函数引入,像watch、computed、路由守卫等都是采用hook函数实现

总结

Vue3中的生命周期相对于Vue2做了一些调整,命名上发生了一些变化并且移除了beforeCreate和created,因为setup是围绕beforeCreate和created生命周期钩子运行的,所以不再需要它们。

生命周期采用hook函数引入

watch和computed

  • 选项式API
<template>
  <div>{{ addSum }}</div>
</template>
<script>
export default {
  data() {
    return {
      a: 1,
      b: 2
    }
  },
  computed: {
    addSum() {
      return this.a + this.b
    }
  },
  watch:{
    a(newValue, oldValue){
      console.log(`a从${oldValue}变成了${newValue}`)
    }
  }
}
</script>
로그인 후 복사
  • 组合式Api
<template>
  <div>{{addSum}}</div>
</template>
<script>
import { computed, ref, watch, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const a = ref(1)
    const b = ref(2)
    let addSum = computed(() => {
      return a.value+b.value
    })
    watch(a, (newValue, oldValue) => {
     console.log(`a从${oldValue}变成了${newValue}`)
    })
    return {
      addSum
    };
  },
});
</script>
로그인 후 복사
  • setup语法糖
<template>
  <div>{{ addSum }}</div>
</template>
<script setup>
import { computed, ref, watch } from "vue";
const a = ref(1)
const b = ref(2)
let addSum = computed(() => {
  return a.value + b.value
})
watch(a, (newValue, oldValue) => {
  console.log(`a从${oldValue}变成了${newValue}`)
})
</script>
로그인 후 복사

Vue3中除了watch,还引入了副作用监听函数watchEffect,用过之后我发现它和React中的useEffect很像,只不过watchEffect不需要传入依赖项。

那么什么是watchEffect呢?

watchEffect它会立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。

比如这段代码

<template>
  <div>{{ watchTarget }}</div>
</template>
<script setup>
import { watchEffect,ref } from "vue";
const watchTarget = ref(0)
watchEffect(()=>{
  console.log(watchTarget.value)
})
setInterval(()=>{
  watchTarget.value++
},1000)
</script>
로그인 후 복사

首先刚进入页面就会执行watchEffect中的函数打印出:0,随着定时器的运行,watchEffect监听到依赖数据的变化回调函数每隔一秒就会执行一次

总结

computed和watch所依赖的数据必须是响应式的。Vue3引入了watchEffect,watchEffect 相当于将 watch 的依赖源和回调函数合并,当任何你有用到的响应式依赖更新时,该回调函数便会重新执行。不同于 watch的是watchEffect的回调函数会被立即执行,即({ immediate: true })

组件通信

Vue中组件通信方式有很多,其中选项式API和组合式API实现起来会有很多差异;这里将介绍如下组件通信方式:

인스턴스 생성 전created
beforeMount onBeforeMount
方式Vue2Vue3
父传子propsprops
子传父$emitemits
父传子$attrsattrs
子传父$listeners无(合并到 attrs方式)
父传子provideprovide
子传父injectinject
子组件访问父组件$parent
父组件访问子组件$children
父组件访问子组件$refexpose&ref
兄弟传值EventBusmitt

props

props是组件通信中最常用的通信方式之一。父组件通过v-bind传入,子组件通过props接收,下面是它的三种实现方式

  • 选项式API
//父组件

<template>
  <div>
    <Child :msg="parentMsg" />
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components:{
    Child
  },
  data() {
    return {
      parentMsg: &#39;父组件信息&#39;
    }
  }
}
</script>


//子组件

<template>
  <div>
    {{msg}}
  </div>
</template>
<script>
export default {
  props:[&#39;msg&#39;]
}
</script>
로그인 후 복사
  • 组合式Api
//父组件

<template>
  <div>
    <Child :msg="parentMsg" />
  </div>
</template>
<script>
import { ref,defineComponent } from &#39;vue&#39;
import Child from &#39;./Child.vue&#39;
export default defineComponent({
  components:{
    Child
  },
  setup() {
    const parentMsg = ref(&#39;父组件信息&#39;)
    return {
      parentMsg
    };
  },
});
</script>

//子组件

<template>
    <div>
        {{ parentMsg }}
    </div>
</template>
<script>
import { defineComponent,toRef } from "vue";
export default defineComponent({
    props: ["msg"],// 如果这行不写,下面就接收不到
    setup(props) {
        console.log(props.msg) //父组件信息
        let parentMsg = toRef(props, &#39;msg&#39;)
        return {
            parentMsg
        };
    },
});
</script>
로그인 후 복사
  • setup语法糖
//父组件

<template>
  <div>
    <Child :msg="parentMsg" />
  </div>
</template>
<script setup>
import { ref } from &#39;vue&#39;
import Child from &#39;./Child.vue&#39;
const parentMsg = ref(&#39;父组件信息&#39;)
</script>

//子组件

<template>
    <div>
        {{ parentMsg }}
    </div>
</template>
<script setup>
import { toRef, defineProps } from "vue";
const props = defineProps(["msg"]);
console.log(props.msg) //父组件信息
let parentMsg = toRef(props, &#39;msg&#39;)
</script>
로그인 후 복사

注意

props中数据流是单项的,即子组件不可改变父组件传来的值

在组合式API中,如果想在子组件中用其它变量接收props的值时需要使用toRef将props中的属性转为响应式。

emit

子组件可以通过emit发布一个事件并传递一些参数,父组件通过v-onj进行这个事件的监听

  • 选项式API
//父组件

<template>
  <div>
    <Child @sendMsg="getFromChild" />
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components:{
    Child
  },
  methods: {
    getFromChild(val) {
      console.log(val) //我是子组件数据
    }
  }
}
</script>

// 子组件

<template>
  <div>
    <button @click="sendFun">send</button>
  </div>
</template>
<script>
export default {
  methods:{
    sendFun(){
      this.$emit(&#39;sendMsg&#39;,&#39;我是子组件数据&#39;)
    }
  }
}
</script>
로그인 후 복사
  • 组合式Api
//父组件

<template>
  <div>
    <Child @sendMsg="getFromChild" />
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { defineComponent } from "vue";
export default defineComponent({
  components: {
    Child
  },
  setup() {
    const getFromChild = (val) => {
      console.log(val) //我是子组件数据
    }
    return {
      getFromChild
    };
  },
});
</script>

//子组件

<template>
    <div>
        <button @click="sendFun">send</button>
    </div>
</template>

<script>
import { defineComponent } from "vue";
export default defineComponent({
    emits: [&#39;sendMsg&#39;],
    setup(props, ctx) {
        const sendFun = () => {
            ctx.emit(&#39;sendMsg&#39;, &#39;我是子组件数据&#39;)
        }
        return {
            sendFun
        };
    },
});
</script>
로그인 후 복사
  • setup语法糖
//父组件

<template>
  <div>
    <Child @sendMsg="getFromChild" />
  </div>
</template>
<script setup>
import Child from &#39;./Child&#39;
const getFromChild = (val) => {
      console.log(val) //我是子组件数据
    }
</script>

//子组件

<template>
    <div>
        <button @click="sendFun">send</button>
    </div>
</template>
<script setup>
import { defineEmits } from "vue";
const emits = defineEmits([&#39;sendMsg&#39;])
const sendFun = () => {
    emits(&#39;sendMsg&#39;, &#39;我是子组件数据&#39;)
}
</script>
로그인 후 복사

attrs和listeners

子组件使用$attrs可以获得父组件除了props传递的属性和特性绑定属性 (class和 style)之外的所有属性。

子组件使用$listeners可以获得父组件(不含.native修饰器的)所有v-on事件监听器,在Vue3中已经不再使用;但是Vue3中的attrs不仅可以获得父组件传来的属性也可以获得父组件v-on事件监听器

  • 选项式API
//父组件

<template>
  <div>
    <Child @parentFun="parentFun" :msg1="msg1" :msg2="msg2"  />
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components:{
    Child
  },
  data(){
    return {
      msg1:&#39;子组件msg1&#39;,
      msg2:&#39;子组件msg2&#39;
    }
  },
  methods: {
    parentFun(val) {
      console.log(`父组件方法被调用,获得子组件传值:${val}`)
    }
  }
}
</script>

//子组件

<template>
  <div>
    <button @click="getParentFun">调用父组件方法</button>
  </div>
</template>
<script>
export default {
  methods:{
    getParentFun(){
      this.$listeners.parentFun(&#39;我是子组件数据&#39;)
    }
  },
  created(){
    //获取父组件中所有绑定属性
    console.log(this.$attrs)  //{"msg1": "子组件msg1","msg2": "子组件msg2"}
    //获取父组件中所有绑定方法    
    console.log(this.$listeners) //{parentFun:f}
  }
}
</script>
로그인 후 복사
  • 组合式API
//父组件

<template>
  <div>
    <Child @parentFun="parentFun" :msg1="msg1" :msg2="msg2" />
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { defineComponent,ref } from "vue";
export default defineComponent({
  components: {
    Child
  },
  setup() {
    const msg1 = ref(&#39;子组件msg1&#39;)
    const msg2 = ref(&#39;子组件msg2&#39;)
    const parentFun = (val) => {
      console.log(`父组件方法被调用,获得子组件传值:${val}`)
    }
    return {
      parentFun,
      msg1,
      msg2
    };
  },
});
</script>

//子组件

<template>
    <div>
        <button @click="getParentFun">调用父组件方法</button>
    </div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
    emits: [&#39;sendMsg&#39;],
    setup(props, ctx) {
        //获取父组件方法和事件
        console.log(ctx.attrs) //Proxy {"msg1": "子组件msg1","msg2": "子组件msg2"}
        const getParentFun = () => {
            //调用父组件方法
            ctx.attrs.onParentFun(&#39;我是子组件数据&#39;)
        }
        return {
            getParentFun
        };
    },
});
</script>
로그인 후 복사
  • setup语法糖
//父组件

<template>
  <div>
    <Child @parentFun="parentFun" :msg1="msg1" :msg2="msg2" />
  </div>
</template>
<script setup>
import Child from &#39;./Child&#39;
import { ref } from "vue";
const msg1 = ref(&#39;子组件msg1&#39;)
const msg2 = ref(&#39;子组件msg2&#39;)
const parentFun = (val) => {
  console.log(`父组件方法被调用,获得子组件传值:${val}`)
}
</script>

//子组件

<template>
    <div>
        <button @click="getParentFun">调用父组件方法</button>
    </div>
</template>
<script setup>
import { useAttrs } from "vue";

const attrs = useAttrs()
//获取父组件方法和事件
console.log(attrs) //Proxy {"msg1": "子组件msg1","msg2": "子组件msg2"}
const getParentFun = () => {
    //调用父组件方法
    attrs.onParentFun(&#39;我是子组件数据&#39;)
}
</script>
로그인 후 복사

注意

Vue3中使用attrs调用父组件方法时,方法前需要加上on;如parentFun->onParentFun

provide/inject

provide:是一个对象,或者是一个返回对象的函数。里面包含要给子孙后代属性

inject:一个字符串数组,或者是一个对象。获取父组件或更高层次的组件provide的值,既在任何后代组件都可以通过inject获得

  • 选项式API
//父组件
<script>
import Child from &#39;./Child&#39;
export default {
  components: {
    Child
  },
  data() {
    return {
      msg1: &#39;子组件msg1&#39;,
      msg2: &#39;子组件msg2&#39;
    }
  },
  provide() {
    return {
      msg1: this.msg1,
      msg2: this.msg2
    }
  }
}
</script>

//子组件

<script>
export default {
  inject:[&#39;msg1&#39;,&#39;msg2&#39;],
  created(){
    //获取高层级提供的属性
    console.log(this.msg1) //子组件msg1
    console.log(this.msg2) //子组件msg2
  }
}
</script>
로그인 후 복사
  • 组合式API
//父组件

<script>
import Child from &#39;./Child&#39;
import { ref, defineComponent,provide } from "vue";
export default defineComponent({
  components:{
    Child
  },
  setup() {
    const msg1 = ref(&#39;子组件msg1&#39;)
    const msg2 = ref(&#39;子组件msg2&#39;)
    provide("msg1", msg1)
    provide("msg2", msg2)
    return {
      
    }
  },
});
</script>

//子组件

<template>
    <div>
        <button @click="getParentFun">调用父组件方法</button>
    </div>
</template>
<script>
import { inject, defineComponent } from "vue";
export default defineComponent({
    setup() {
        console.log(inject(&#39;msg1&#39;).value) //子组件msg1
        console.log(inject(&#39;msg2&#39;).value) //子组件msg2
    },
});
</script>
로그인 후 복사
  • setup语法糖
//父组件
<script setup>
import Child from &#39;./Child&#39;
import { ref,provide } from "vue";
const msg1 = ref(&#39;子组件msg1&#39;)
const msg2 = ref(&#39;子组件msg2&#39;)
provide("msg1",msg1)
provide("msg2",msg2)
</script>

//子组件

<script setup>
import { inject } from "vue";
console.log(inject(&#39;msg1&#39;).value) //子组件msg1
console.log(inject(&#39;msg2&#39;).value) //子组件msg2
</script>
로그인 후 복사

说明

provide/inject一般在深层组件嵌套中使用合适。一般在组件开发中用的居多。

parent/children

$parent: 子组件获取父组件Vue实例,可以获取父组件的属性方法等

$children: 父组件获取子组件Vue实例,是一个数组,是直接儿子的集合,但并不保证子组件的顺序

  • Vue2
import Child from &#39;./Child&#39;
export default {
  components: {
    Child
  },
  created(){
    console.log(this.$children) //[Child实例]
    console.log(this.$parent)//父组件实例
  }
}
로그인 후 복사

注意父组件获取到的$children并不是响应式的

expose&ref

$refs可以直接获取元素属性,同时也可以直接获取子组件实例

  • 选项式API
//父组件

<template>
  <div>
    <Child ref="child" />
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components: {
    Child
  },
  mounted(){
    //获取子组件属性
    console.log(this.$refs.child.msg) //子组件元素

    //调用子组件方法
    this.$refs.child.childFun(&#39;父组件信息&#39;)
  }
}
</script>

//子组件 

<template>
  <div>
    <div></div>
  </div>
</template>
<script>
export default {
  data(){
    return {
      msg:&#39;子组件元素&#39;
    }
  },
  methods:{
    childFun(val){
      console.log(`子组件方法被调用,值${val}`)
    }
  }
}
</script>
로그인 후 복사
  • 组合式API
//父组件

<template>
  <div>
    <Child ref="child" />
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
import { ref, defineComponent, onMounted } from "vue";
export default defineComponent({
  components: {
    Child
  },

  setup() {
    const child = ref() //注意命名需要和template中ref对应
    onMounted(() => {
      //获取子组件属性
      console.log(child.value.msg) //子组件元素

      //调用子组件方法
      child.value.childFun(&#39;父组件信息&#39;)
    })
    return {
      child //必须return出去 否则获取不到实例
    }
  },
});
</script>

//子组件

<template>
    <div>
    </div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
    setup() {
        const msg = ref(&#39;子组件元素&#39;)
        const childFun = (val) => {
            console.log(`子组件方法被调用,值${val}`)
        }
        return {
            msg,
            childFun
        }
    },
});
</script>
로그인 후 복사
  • setup语法糖
//父组件

<template>
  <div>
    <Child ref="child" />
  </div>
</template>
<script setup>
import Child from &#39;./Child&#39;
import { ref, onMounted } from "vue";
const child = ref() //注意命名需要和template中ref对应
onMounted(() => {
  //获取子组件属性
  console.log(child.value.msg) //子组件元素

  //调用子组件方法
  child.value.childFun(&#39;父组件信息&#39;)
})
</script>

//子组件

<template>
    <div>
    </div>
</template>
<script setup>
import { ref,defineExpose } from "vue";
const msg = ref(&#39;子组件元素&#39;)
const childFun = (val) => {
    console.log(`子组件方法被调用,值${val}`)
}
//必须暴露出去父组件才会获取到
defineExpose({
    childFun,
    msg
})
</script>
로그인 후 복사

注意

通过ref获取子组件实例必须在页面挂载完成后才能获取。

在使用setup语法糖时候,子组件必须元素或方法暴露出去父组件才能获取到

EventBus/mitt

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

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

  • 选项式API
//组件1
<template>
  <div>
    <button @click="sendMsg">传值</button>
  </div>
</template>
<script>
import Bus from &#39;./bus.js&#39;
export default {
  data(){
    return {
      msg:&#39;子组件元素&#39;
    }
  },
  methods:{
    sendMsg(){
      Bus.$emit(&#39;sendMsg&#39;,&#39;兄弟的值&#39;)
    }
  }
}
</script>

//组件2

<template>
  <div>
    组件2
  </div>
</template>
<script>
import Bus from &#39;./bus.js&#39;
export default {
  created(){
   Bus.$on(&#39;sendMsg&#39;,(val)=>{
    console.log(val);//兄弟的值
   })
  }
}
</script>

//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 &#39;mitt&#39;
const Mitt = mitt()
export default Mitt
로그인 후 복사
//组件1
<template>
     <button @click="sendMsg">传值</button>
</template>
<script>
import { defineComponent } from "vue";
import Mitt from &#39;./mitt.js&#39;
export default defineComponent({
    setup() {
        const sendMsg = () => {
            Mitt.emit(&#39;sendMsg&#39;,&#39;兄弟的值&#39;)
        }
        return {
           sendMsg
        }
    },
});
</script>

//组件2
<template>
  <div>
    组件2
  </div>
</template>
<script>
import { defineComponent, onUnmounted } from "vue";
import Mitt from &#39;./mitt.js&#39;
export default defineComponent({
  setup() {
    const getMsg = (val) => {
      console.log(val);//兄弟的值
    }
    Mitt.on(&#39;sendMsg&#39;, getMsg)
    onUnmounted(() => {
      //组件销毁 移除监听
      Mitt.off(&#39;sendMsg&#39;, getMsg)
    })

  },
});
</script>
로그인 후 복사
  • setup语法糖
//组件1

<template>
    <button @click="sendMsg">传值</button>
</template>
<script setup>
import Mitt from &#39;./mitt.js&#39;
const sendMsg = () => {
    Mitt.emit(&#39;sendMsg&#39;, &#39;兄弟的值&#39;)
}
</script>

//组件2

<template>
  <div>
    组件2
  </div>
</template>
<script setup>
import { onUnmounted } from "vue";
import Mitt from &#39;./mitt.js&#39;
const getMsg = (val) => {
  console.log(val);//兄弟的值
}
Mitt.on(&#39;sendMsg&#39;, getMsg)
onUnmounted(() => {
  //组件销毁 移除监听
  Mitt.off(&#39;sendMsg&#39;, getMsg)
})
</script>
로그인 후 복사

v-model和sync

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

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

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

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

  • 选项式API
//父组件

<template>
  <div>
   <!-- 
      完整写法
      <Child :msg="msg" @update:changePval="msg=$event" /> 
      -->
    <Child :changePval.sync="msg" />
    {{msg}}
  </div>
</template>
<script>
import Child from &#39;./Child&#39;
export default {
  components: {
    Child
  },
  data(){
    return {
      msg:&#39;父组件值&#39;
    }
  }
  
}
</script>

//子组件

<template>
  <div>
    <button @click="changePval">改变父组件值</button>
  </div>
</template>
<script>
export default {
  data(){
    return {
      msg:&#39;子组件元素&#39;
    }
  },
  methods:{
    changePval(){
       //点击则会修改父组件msg的值
      this.$emit(&#39;update:changePval&#39;,&#39;改变后的值&#39;)
    }
  }
}
</script>
로그인 후 복사
  • setup语法糖

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

//父组件

<template>
  <div>
    <!-- 
      完整写法
      <Child :msg="msg" @update:changePval="msg=$event" /> 
      -->
    <Child v-model:changePval="msg" />
    {{msg}}
  </div>
</template>
<script setup>
import Child from &#39;./Child&#39;
import { ref } from &#39;vue&#39;
const msg = ref(&#39;父组件值&#39;)
</script>

//子组件

<template>
    <button @click="changePval">改变父组件值</button>
</template>
<script setup>
import { defineEmits } from &#39;vue&#39;;
const emits = defineEmits([&#39;changePval&#39;])
const changePval = () => {
    //点击则会修改父组件msg的值
    emits(&#39;update:changePval&#39;,&#39;改变后的值&#39;)
}
</script>
로그인 후 복사

总结

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

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

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

路由

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

  • 选项式API
<template>
  <div>
     <button @click="toPage">路由跳转</button>
  </div>
</template>
<script>
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.$router.params
    //获取query
    this.$router.query
  }
}
</script>
로그인 후 복사
  • 组合式API
<template>
  <div>
    <button @click="toPage">路由跳转</button>
  </div>
</template>
<script>
import { defineComponent } from &#39;vue&#39;
import { useRoute, useRouter } from &#39;vue-router&#39;
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
    }
  },
});
</script>
로그인 후 복사
  • setup语法糖

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

<template>
  <div>
    <button @click="toPage">路由跳转</button>
  </div>
</template>
<script>
export default {
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    next()
  },
};
</script>

<script setup>
import { useRoute, useRouter,onBeforeRouteLeave, onBeforeRouteUpdate } from &#39;vue-router&#39;
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() 
})

</script>
로그인 후 복사

写在最后

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

Vue3文档地址:

https://staging-cn.vuejs.org/

本文转载自:https://juejin.cn/post/7111129583713255461

【相关视频教程推荐:web前端

위 내용은 Vue3과 Vue2의 차이점은 무엇입니까? 다 비교해 보세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

vue.js vs. React : 프로젝트 별 고려 사항 vue.js vs. React : 프로젝트 별 고려 사항 Apr 09, 2025 am 12:01 AM

vue.js는 중소형 프로젝트 및 빠른 반복에 적합한 반면 React는 크고 복잡한 응용 프로그램에 적합합니다. 1) vue.js는 사용하기 쉽고 팀이 불충분하거나 프로젝트 규모가 작는 상황에 적합합니다. 2) React는 더 풍부한 생태계를 가지고 있으며 고성능 및 복잡한 기능적 요구가있는 프로젝트에 적합합니다.

Vue 용 버튼에 기능을 추가하는 방법 Vue 용 버튼에 기능을 추가하는 방법 Apr 08, 2025 am 08:51 AM

HTML 템플릿의 버튼을 메소드에 바인딩하여 VUE 버튼에 함수를 추가 할 수 있습니다. 메소드를 정의하고 VUE 인스턴스에서 기능 로직을 작성하십시오.

Vue에서 부트 스트랩을 사용하는 방법 Vue에서 부트 스트랩을 사용하는 방법 Apr 07, 2025 pm 11:33 PM

vue.js에서 bootstrap 사용은 5 단계로 나뉩니다 : Bootstrap 설치. main.js.의 부트 스트랩 가져 오기 부트 스트랩 구성 요소를 템플릿에서 직접 사용하십시오. 선택 사항 : 사용자 정의 스타일. 선택 사항 : 플러그인을 사용하십시오.

vue.js로 JS 파일을 참조하는 방법 vue.js로 JS 파일을 참조하는 방법 Apr 07, 2025 pm 11:27 PM

vue.js에서 JS 파일을 참조하는 세 가지 방법이 있습니다. & lt; script & gt; 꼬리표;; mounted () 라이프 사이클 후크를 사용한 동적 가져 오기; Vuex State Management Library를 통해 수입.

Vue에서 시계를 사용하는 방법 Vue에서 시계를 사용하는 방법 Apr 07, 2025 pm 11:36 PM

vue.js의 시계 옵션을 사용하면 개발자가 특정 데이터의 변경 사항을들을 수 있습니다. 데이터가 변경되면 콜백 기능을 트리거하여 업데이트보기 또는 기타 작업을 수행합니다. 구성 옵션에는 즉시 콜백을 실행할지 여부와 DEEP를 지정하는 즉시 포함되며, 이는 객체 또는 어레이에 대한 변경 사항을 재귀 적으로 듣는 지 여부를 지정합니다.

Vue 다중 페이지 개발은 무엇을 의미합니까? Vue 다중 페이지 개발은 무엇을 의미합니까? Apr 07, 2025 pm 11:57 PM

VUE 멀티 페이지 개발은 vue.js 프레임 워크를 사용하여 응용 프로그램을 구축하는 방법입니다. 여기서 응용 프로그램은 별도의 페이지로 나뉩니다. 코드 유지 보수 : 응용 프로그램을 여러 페이지로 분할하면 코드를보다 쉽게 ​​관리하고 유지 관리 할 수 ​​있습니다. 모듈 식 : 각 페이지는 쉬운 재사용 및 교체를 위해 별도의 모듈로 사용할 수 있습니다. 간단한 라우팅 : 페이지 간의 탐색은 간단한 라우팅 구성을 통해 관리 할 수 ​​있습니다. SEO 최적화 : 각 페이지에는 자체 URL이있어 SEO가 도움이됩니다.

Vue가 이전 페이지로 돌아 오는 방법 Vue가 이전 페이지로 돌아 오는 방법 Apr 07, 2025 pm 11:30 PM

vue.js는 이전 페이지로 돌아갈 수있는 네 가지 방법이 있습니다. $ router.go (-1) $ router.back () 사용 & lt; router-link to = & quot;/quot; Component Window.history.back () 및 메소드 선택은 장면에 따라 다릅니다.

VUE 버전을 쿼리하는 방법 VUE 버전을 쿼리하는 방법 Apr 07, 2025 pm 11:24 PM

Vue DevTools를 사용하여 브라우저 콘솔에서 vue 탭을 보면 VUE 버전을 쿼리 할 수 ​​있습니다. npm을 사용하여 "npm list -g vue"명령을 실행하십시오. package.json 파일의 "종속성"객체에서 vue 항목을 찾으십시오. Vue Cli 프로젝트의 경우 "vue -version"명령을 실행하십시오. & lt; script & gt에서 버전 정보를 확인하십시오. vue 파일을 나타내는 html 파일의 태그.

See all articles