装置vite

npx create-vite-app myvue3-app
npm install
npm run dev

composition api

composition api 为vue代码提供更好的逻辑复用和代码组织

<template><div>    <h1>{{ msg }}</h1>    <button @click="count++">count is: {{ count }}</button>    <p>Edit <code>components/HelloWorld.vue</code> to test hot module replacement.</p>    <p>{{counter}}</p>    <p>{{doubleCounter}}</p>    <p>{{msg2}}</p>    <div ref="desc"></div></div></template><script>import {    reactive,    ref,    toRefs,    computed,    watch,    onMounted,    onUnmounted} from 'vue'export default {    name: 'HelloWorld',    props: {        msg: String    },    setup(props) {        const {            counter,            doubleCounter        } = useCounter();        const msg2 = ref('message');        // 应用元素援用        const desc = ref(null);        watch(counter, (val, oldVal) => {            const p = desc.value;            p.textContent = `counter change from ${oldVal} to ${val}`        })        return {            counter,            doubleCounter,            msg2,            desc        }    }}function useCounter() {    // counter相干    const data = reactive({        counter: 1,        doubleCounter: computed(() => data.counter * 2)    })    let timer    onMounted(() => {        timer = setInterval(() => {            data.counter++        }, 1000)    })    onUnmounted(() => {        clearInterval(timer)    })    return toRefs(data)}</script>

Teleport

传送门组件提供一种简洁的形式能够指定它外面内容的父元素

<template><div>    <button @click="modaleOpen = true">弹出一个模态窗口</button>    <teleport to="body">        <div v-if="modaleOpen" class="modal">            <div>                这是一个弹窗, 父元素是body                <button @click="modaleOpen = false">敞开</button>            </div>        </div>    </teleport></div></template><script>export default {    data() {        return {            modaleOpen: false        }    },}</script><style scoped>.modal {    position: absolute;    top: 0;    right: 0;    bottom: 0;    left: 0;    background-color: rgba(0, 0, 0, .5);    display: flex;    flex-direction: column;    align-items: center;    justify-content: center;}.modal div {    display: flex;    flex-direction: column;    align-items: center;    justify-content: center;    background-color: white;    width: 300px;    height: 300px;    padding: 5px;}</style>

Fragments

vue3中组件能够领有多个根

<template> <header>...</header> <main v-bind="$attrs">...</main> <footer>...</footer></template>

Emits Component Options

vue3中组件发送的自定义事件须要定义在emits选项中:

  • 原生事件会触发两次, 比方click
  • 更好的批示组件的工作形式

Global Api改为应用程序实例调用

vue2中有很多全局api能够扭转vue的行为,比方Vue.component

  • vue2没有app概念, new Vue()失去的根实例被作为app, 这样的话所有创立的根实例是共享雷同的全局配置,
  • 全局配置也导致没有方法在单页面创立不同全局配置的多个app实例

vue3中应用createApp返回app实例, 由它裸露一系列全局api

import { createApp, h } from 'vue'import App from './App.vue'import './index.css'createApp(App).component('comp', {    render() {        return h('div', 'weqew')    },}).mount('#app')
2.xGlobal3.xGlobal
Vue.configapp.config
Vue.config.productionTip破除
Vue.config.ignoredElementsapp.config.isCustomElement
Vue.componentapp.component
Vue.directiveapp.directive
Vue.mixinapp.mixin
Vue.useapp.use
Vue.filter破除

Global and internal APIS重构为可做摇树优化

vue2中不少global api是作为动态函数间接挂在构造函数上的, 例如Vue.nextTick(), 如果咱们从未在代码中用过它们,就会造成所谓的dead code, 这类global-api造成的dead code无奈应用webpack的tree-shaking排除掉

例如在vue2中

import Vue from 'vue'Vue.nextTick(() => {    // do something}) 

vue3.0做了相应的变动. 将它们抽取成为独立函数, 这样打包工具的摇树优化能够将这些dead code排除掉

import {nextTick} from 'vue'nextTick(()=>{    // do something})

受影响api:

  • Vue.nextTick()
  • Vue.observable
  • Vue.version
  • Vue.compile
  • Vue.set
  • Vue.delete

model选项和v-bind的sync修饰符被移除,对立为v-model参数模式

<div id="app"> <h3>{{data}}</h3>  <comp v-model="data"></comp></div>
app.component('comp', { template: ` <div @click="$emit('update:modelValue', 'new value')"> i am comp, {{modelValue}} </div>`, props: ['modelValue'],})###