装置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.xGlobal | 3.xGlobal |
---|---|
Vue.config | app.config |
Vue.config.productionTip | 破除 |
Vue.config.ignoredElements | app.config.isCustomElement |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.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'],})###