删除的api
- o n , on, on,off,$once
$on,$off,$once被删除实例方法。应用程序实例不再实现事件发射器接口
vue2.X版本
eventBus.js
const eventHub = new Vue()
export default eventHub
childComponent.vue
// ChildComponent.vue
import eventHub from './eventHub'
export default {
mounted() {
// adding eventHub listener
eventHub.$on('custom-event', () => {
console.log('Custom event triggered!')
})
},
beforeDestroy() {
// removing eventHub listener
eventHub.$off('custom-event')
}
}
parentComponent.vue
import eventHub from './eventHub'
export default {
methods: {
callGlobalCustomEvent() {
eventHub.$emit('custom-event') // if ChildComponent is mounted, we will have a message in the console
}
}
}
vue3.0版本
我们删除$on,$off,$once从完全的实例方法。$emit仍然是现有API的一部分,因为它用于触发由父组件声明式附加的事件处理程序
- 过滤器
过滤器已从Vue 3.0中删除,不再受支持
vue2.X语法
<template>
<h1>Bank Account Balance</h1>
<p>{{ accountBalance | currencyUSD }}</p>
</template>
<script>
export default {
props: {
accountBalance: {
type: Number,
required: true
}
},
filters: {
currencyUSD(value) {
return '$' + value
}
}
}
</script>
vue3.X语法
在3.x中,过滤器已删除,不再受支持。相反,我们建议将它们替换为方法调用或计算的属性
<template>
<h1>Bank Account Balance</h1>
<p>{{ accountInUSD }}</p>
</template>
<script>
export default {
props: {
accountBalance: {
type: Number,
required: true
}
},
computed: {
accountInUSD() {
return '$' + this.accountBalance
}
}
}
</script>
- 多根节点
vue2.X语法
在2.x中,不支持多根组件,并且在用户意外创建组件时会发出警告。结果,许多组件被包装在一个
中,以解决此错误。
<template>
<div>
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
</template>
vue3.X语法
<!-- Layout.vue -->
<template>
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
</template>
- setup(vue3.X语法)
<template>
<div>{{count}}: {{double}}</div>
<button @click="increment">+1</button>
</template>
<script>
import { ref, computed } from 'vue'
export default {
setup() {
let count = ref('abc')
let double = computed(() => count.value + 'de')
function increment() {
count.value = count.value + 'f';
}
return {
count,
double,
increment
}
}
}
</script>
- 代码复用
useCount.js
import { ref, computed } from 'vue'
function useCount() {
let count = ref(0)
let double = computed(() => count.value * 2)
function increment() {
count.value++
}
return {
count,
double,
increment
}
}
export default useCount
app.vue
import useCount from './useCount.js'
export default {
setup() {
let { count, double, increment } = useCount()
return {
count,
double,
increment
}
}
}
- 生命周期(vue3.0语法)
App.vue
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3.0 + Vite" @count="fnCount">
<div>我是slots1</div>
<div>我是slots2</div>
<div>我是slots3</div>
<div>我是slots4</div>
<div>我是slots5</div>
</HelloWorld>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
setup(props,context){
function fnCount(count){
console.log(count); // 1,2,3,4,5...
}
return {
fnCount
}
},
components: {
HelloWorld
}
}
</script>
HelloWorld.vue
<template>
<div>props值:{{msgProps}}</div>
<div>{{count}}: {{double}}</div>
<button @click="increment">改变count</button>
<slot></slot>
</template>
<script>
import useCount from './useCount.js'
import { ref, computed, onMounted } from 'vue'
export default {
props: {
msg: {
type: String,
defalut: ''
}
},
setup(props,context) {
let { count, double, increment, msgProps } = useCount(props, context)
onMounted(() => {
console.log(context.slots.default()); //获取到父级slot插槽中内容
})
return {
count,
double,
increment,
msgProps
}
}
}
</script>
- reactive(vue3.0语法)
链接:https://v3.vuejs.org/api/basic-reactivity.html#reactive
HelloWorld.vue
<template>
<div>props值:{{msgProps}}</div>
<div>{{count}}: {{double}}</div>
<button @click="increment">改变count</button>
<!-- 点击fnChange改变,我是改变后的title -->
{{state.title}}
<button @click="fnChange">改变title</button>
<slot></slot>
</template>
<script>
import useCount from './useCount.js'
import { ref, computed, onMounted, reactive } from 'vue'
export default {
props: {
msg: {
type: String,
defalut: ''
}
},
setup(props,context) {
let { count, double, increment, msgProps } = useCount(props, context)
const state = reactive({ title: '原title' })
function fnChange(){
state.title = '我是改变后的title'
}
onMounted(() => {
console.log(context.slots.default())
})
return {
count,
double,
increment,
msgProps,
fnChange,
state
}
}
}
</script>
- 渲染函数(vue3.0)
import { h, ref, reactive } from 'vue'
export default {
setup() {
const readersNumber = ref(0)
const book = reactive({ title: 'Vue 3 Guide' })
// Please note that we need to explicitly expose ref value here
return () => h('div', [readersNumber.value, book.title])
}
}
- provide & inject(vue3.0)
类似于vue2中provide与inject, vue3提供了对应的provide与inject API,实现组件传参。
provide 函数允许你通过两个参数定义 property:
- property 的 name ( 类型)
- property 的 value
myMap.vue
<script>
import {provide} from 'vue'
import myMarker from './myMarker.vue'
export default {
name: "myMap",
components:{
myMarker
},
setup(){
provide('location', 'North Pole')
provide('geolocation', {
longitude: 90,
latitude: 135
})
}
}
</script>
myMarker.vue
<template>
{{userLocation}} {{userGeolocation.longitude}}
</template>
<script>
import { inject } from 'vue'
export default {
setup() {
const userLocation = inject('location', 'The Universe')
const userGeolocation = inject('geolocation')
return {
userLocation,
userGeolocation
}
}
}
</script>
<style scoped>
</style>
- watch & computed(vue3.0语法)
watch:侦听器,接受三个参数
- 一个响应式引用或我们想要侦听的 getter 函数
- 一个回调
- 可选的配置选项
import { ref, watch } from 'vue'
export default {
setup() {
const counter = ref(0)
watch(counter, (newValue, oldValue) => {
console.log('The new counter value is: ' + counter.value)
})
},
// setup中的相当于以下
data() {
return {
counter: 0
}
},
watch: {
counter(newValue, oldValue) {
console.log('The new counter value is: ' + this.counter)
}
}
}
或者如下代码:
<template>
{{obj.a}}
{{count}}
<button @click="fnChangeCount">改变count</button>
<!-- <myMarker/>-->
</template>
<script>
import {provide, watch, ref, reactive} from 'vue'
// import myMarker from './myMarker.vue'
export default {
name: "myMap",
// components:{
// myMarker
// },
setup(){
let count = ref(0);
let obj = ref({a: 1})
function fnChangeCount(){
count.value++;
obj['value']['a'] = 2;
}
function getProxy(obj) {
return new Proxy(obj, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
}
watch(count, (newVal, oldVal) => {
console.log(newVal,oldVal)
})
watch(obj, (newVal, oldVal) => {
console.log(getProxy(newVal).a, getProxy(oldVal).a)
},{
deep: true, // 深度监听
lazy: true, // vue中的immediate,默认挂载后执行
flush: '', // 三个值:'post'(默认), 'pre', 'sync'
// 'pre': 表示在状态更新时同步调用
// 'sync':表示在组件更新之前调用
onTrack(){}, // 在reactive属性或ref被追踪为依赖时调用。
onTrigger(){
} // 在watcher的回调因依赖改变而触发时调用。
})
return {
obj,
count,
fnChangeCount
}
// provide('location', 'North Pole')
// provide('geolocation', {
// longitude: 90,
// latitude: 135
// })
}
}
</script>
<style scoped>
</style>
watch第三个参数:
{
deep: true, // 深度监听
lazy: true, // vue中的immediate,默认挂载后执行
flush: '', // 三个值:'post'(默认), 'pre', 'sync'
// 'pre': 表示在状态更新时同步调用
// 'sync':表示在组件更新之前调用
onTrack(){}, // 在reactive属性或ref被追踪为依赖时调用。
onTrigger(){} // 在watcher的回调因依赖改变而触发时调用。
}
- computed
与vue2中computed功能一致,它接收一个函数并返回一个value为getter返回值的不可改变的响应式ref对象。
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // 错误,computed不可改变
// 同样支持set和get属性
onst count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => { count.value = val - 1 }
})
plusOne.value = 1
console.log(count.value) // 0