前言 自从vue3
请大家在真正进行项目迁移前务必先看下官方迁移的文档,以下内容尽量讲vue官方文档中比较难找到或者没有讲过的内容。
vue2迁移vue3官网文档介绍
以下内容和示例统一使用的是 vue3 composition api
开发准备 首先如果你是用的是vscode进行vue2的开发,我相信你一定会安装vetur这个拓展插件,我们要做的第一件事是安装一个新的拓展插件 volar , volar 是官方的一个vue3代码提示插件。
单文件组件
响应式变量声明
vue2写法
<!-- vue2写法 -->
<template>
<div>
{{ a }}
{{ b.c }}{{ b.d }}
</div>
</template>
<script>
export default {
data() {
return {
a: "我是oil",
b: {
c: "我是张三",
d: "我是赵四",
},
}
},
}
</script>
<!-- vue3写法 -->
<template>
<div>
{{ a }}
{{ b.c }}{{ b.d }}
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue"
const a = ref("我是oil")
const b = reactive({
c: "我是张三",
d: "我是赵四",
})
</script>
<style lang="scss" scoped></style>
在vue3中响应式变量用 ref 和 reactive 两个api来定义,reactive用来定义对象,ref用来定义除了对象的其他数据类型。
watch,computed及生命周期
vue2写法
<!-- vue2写法 -->
<template>
<div>
{{ a }}
<!-- 我是oil -->
{{ computedA }}
<!-- 其实我是oil -->
</div>
</template>
<script>
export default {
data() {
return {
a: "我是oil",
}
},
watch: {
a: {
handler() {
console.log(this.a)
},
immediate: true,
deep: true,
},
},
computed: {
computedA() {
return "其实" + this.a
},
},
mounted() {
this.a = "我不是oi"
},
}
</script>
<!-- vue3写法 -->
<template>
<div>
{{ a }}
<!-- 我是oil -->
{{ computedA }}
<!-- 其实我是oil -->
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, computed } from "vue"
const a = ref("我是oil")
watch(
() => a.value,
() => {
console.log(a.value)
},
{ immediate: true }
)
const computedA = computed(() => "其实" + a.value)
onMounted(() => {
a.value = "我不是oil"
})
</script>
在vue3中,生命周期,computed 和 watch 都是通过传入回调方法进行方法声明的。具体的使用方法可以看上面的示例和官方的介绍
父组件向子组件传值
vue2写法
子组件
<!-- vue2子组件 -->
<template>
<div>
{{ a }}
<!-- 我是oil -->
{{ computedA }}
<!-- 其实我是oil -->
</div>
</template>
<script>
export default {
props: {
a: {
type: String,
},
},
}
</script>
父组件
<!-- vue2父组件 -->
<template>
<div>
<vue2-child></vue2-child>
<!-- 我是oil -->
</div>
</template>
<script>
import Vue2Child from "./vue2-child.vue"
export default {
data() {
return {
a: "我是oil",
}
},
components: {
Vue2Child,
},
}
</script>
vue3写法
子组件
<!-- vue3子组件 -->
<template>
<div>
{{ a }}
<!-- 我是oil -->
</div>
</template>
<script setup lang="ts">
import { onMounted, defineProps } from "vue"
const props = defineProps({
a: String,
})
onMounted(() => {
console.log(props.a)
})
</script>
父组件
<!-- vue3父组件 -->
<template>
<div>
<vue3-child :a="a"></vue3-child>
<!-- 我是oil -->
</div>
</template>
<script setup lang="ts">
import vue3Child from "./vue3-child.vue"
import { ref } from "vue"
const a = ref("我是oil")
</script>
首先展示的是最传统的通过props传值的写法,在vue3中的变化为通过defineProps这个api来定义参数值,且组件的引入无需局部注册,可以直接使用
通过ref实现子组件向父组件传值
vue2 写法
子组件
<!-- vue2子组件 -->
<template>
<div>
{{ a }}
<!-- 我是oil -->
{{ computedA }}
<!-- 其实我是oil -->
</div>
</template>
<script>
export default {
props: {
a: {
type: String,
},
},
data() {
return {
b: "这个是我想给父组件的值",
}
},
}
</script>
父组件
<!-- vue2父组件 -->
<template>
<div>
<vue2-child ref="childRef"></vue2-child>
<!-- 我是oil -->
</div>
</template>
<script>
import Vue2Child from "./vue2-child.vue"
export default {
data() {
return {
a: "我是oil",
}
},
components: {
Vue2Child,
},
mounted() {
console.log(this.$refs.childRef.b)
},
}
</script>
vue3 写法
子组件
<!-- vue3子组件 -->
<template>
<div>
{{ a }}
<!-- 我是oil -->
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, defineProps, defineExpose } from "vue"
const props = defineProps({
a: String,
})
const b = ref("这个是我想给父组件的值")
onMounted(() => {
console.log(props.a)
})
defineExpose({
b,
})
</script>
父组件
<!-- vue3父组件 -->
<template>
<div>
<vue3-child :ref="childRef" :a="a"></vue3-child>
<!-- 我是oil -->
</div>
</template>
<script setup lang="ts">
import vue3Child from "./vue3-child.vue"
import { ref, onMounted } from "vue"
const childRef = ref()
const a = ref("我是oil")
onMounted(() => {
console.log(childRef.value.b) // "这个是我想给父组件的值"
})
</script>
通过以上例子的对比,在vue2中如果父组件想要拿到子组件的值可以通过$ref 被来给元素或子组件注册引用信息,通过childRef指向引用组件实例,这样我们可以获取到子组件上的属性。
在vue3中,使用