共计 3015 个字符,预计需要花费 8 分钟才能阅读完成。
装置 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'],
})
###
正文完