安装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'],
})
###
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。