1. vue实例化方法改变
vue2通过new Vue(),手动生成。vue3通过createApp实例化
// vue2
import Vue from 'vue';
import App from './App.vue';
new Vue({
render: h => h(App)
}).$mount('#app')
// vue3
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
2、 全局API改变
vue2中全局API挂在Vue上,vue3挂在vue实例上 app;
比如定义全局组件:
// vue2
import Vue from 'vue';
Vue.component('loading', {})
// vue3
import { createApp } from 'vue'
let app = createApp(App);
app.component('loading', {})
vue官网:
3. 取消filter
在 3.x 中,过滤器已移除,且不再支持。取而代之的是,我们建议用方法调用或计算属性来替换它们。
4. v-model改变
// vue2
v-model = :value + @input
// vue3
// html组件
v-model = :value + @input
// 自定义组件
v-model = :modelValue + @update:modelValue
<ChildComponent v-model="pageTitle" />
// ChildComponent.vue
export default {
props: {
modelValue: String // 以前是`value:String`
},
emits: ['update:modelValue'],
methods: {
changePageTitle(title) {
this.$emit('update:modelValue', title) // 以前是 `this.$emit('input', title)`
}
}
}
5. 函数组件写法改变 - h
在 2.x 中,render 函数会自动接收 h 函数
// vue2
Vue.component('loading', {
render(h) {
return h('div', {title: 'ass'}, ['这是内容'])
},
})
在 3.x 中,h 函数现在是全局导入的,而不是作为参数自动传递。
// vue3
import { h } from 'vue'
app.component('loading', {
render(props, context) {
return h('div', {title: 'ass'}, ['这是内容'])
},
})
6. data统一写法
在 2.x 中,开发者可以通过 object 或者是 function 定义 data 选项。
在 3.x 中,data 选项已标准化为只接受返回 object 的 function。
7. 异步组件写法改变
// vue2
const asyncModal = () => import('./Modal.vue')
// vue3
import { defineAsyncComponent } from 'vue'
const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))
8. 事件简化
o
n
,
on,
on,off 和 $once 实例方法已被移除,组件实例不再实现事件触发接口。
$emit 仍然包含于现有的 API 中,因为它用于触发由父组件声明式添加的事件处理函数
9. 自定义指令
vue3新增
1. composition API
出现的原因:
帮助更好的重用组件的特征。
vue2中将数据、方法、computed、watch等注入都一个组件中;组件中代码特别多、特别乱,重用比较麻烦。
composition组合式把(数据、方法、computed、生命周期函数…)注入组件一个地方-setup,方便重用。
执行时机:
setup是在组件创建的过程中执行。返回值会被注册到组件当中。
执行时机在beforeCreate与created之间执行。
beforeCreate,
setup
created
setup中this为undefined,所以不能在setup中使用组件的其他东西(data/computed/methods…),不要在setup使用this。
setup执行过程中,组件中其他东西都没被创建。
- 在 setup 中你应该避免使用 this,因为它不会找到组件实例。setup 的调用发生在 data property、computed property 或 methods 被解析之前,所以它们无法在 setup 中被获取。
- setup必须是同步的(不能有aynsc)。
export default {
setup() {
const a = 12;
const fn = () => {
console.log(a);
}
return {
a, // 数据放入data
fn // 方法放入methods
}
}
}
最后会把解析为:
export default {
data() {
return {
a: 12
}
},
methods: {
fn() {
console.log(this.a);
}
}
}
可响应数据
普通变量无法完成响应式(检测到数据变化,重新渲染组件)。
普通变量在setup时会出现数据更新,视图未更新。
<template>
<div>a = {{a}}</div>
<button @click="add">+</button>
</template>
<script>
export default {
setup() {
let a = 12
const add = () => {
a++
console.log('a:', a)
}
return {
a,
add
}
}
}
</script>
结果如下图:
解决响应式
reactive
reactive({}|[])
- 必须是对象或数组
- 如果是其他对象(Date、RegExp…),不能直接修改已有的数据,可以创建一个新的对象
<template>
<div>a = {{a.count}}</div>
<button @click="add">+</button>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const a = reactive({ count: 12 })
console.log(a); // Proxy {count: 12}
const add = () => {
a.count++
console.log('a:', a.count)
}
return {
a,
add
}
}
}
</script>
ref
可以直接封装基本类型数据
本质:reactive({value: xxx});
template里面使用ref不需要加.value,在js里需要
<template>
<div>a = {{a}}</div>
<button @click="add">+</button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const a = ref(12)
console.log(a); // {"_shallow":false,"__v_isRef":true,"_rawValue":12,"_value":12}
const add = () => {
a.value++
console.log('a:', a.value)
}
return {
a,
add
}
}
}
</script>