Fragment(片断)
好处: 减少标签层级, 减小内存占用
- 在 Vue2 中: 组件必须有一个根标签
- 在 Vue3 中: 组件可以没有根标签, 内部会将多个标签包含在一个 Fragment 虚拟元素中
不能使用的原因: 1.查看是否安装了Vetur插件 2.文件=>首选项=>设置 3.进入设置页搜索 eslint 把Vetur的验证模板,取消勾选Validate vue-html in using eslint-plugin-vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| // vue3 <template> <h2>aaaa</h2> <h2>aaaa</h2> </template>
// vue2 <template> <!-- 根标签 --> <div> <h2></h2> <h2></h2> </div> </template>
|
Teleport(瞬移)
Teleport 提供了一种干净的方法, 让组件的 html 在父组件界面外的特定标签(很可能是 body)下插入显示
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <h2>APP父级组件</h2> <modalOpen /> </template>
<script lang="ts"> import { defineComponent, ref } from "vue"; import modalOpen from "./ModalButton.vue"; export default defineComponent({ name: "", components: { modalOpen, }, setup(props, { attrs, emit, slots }) { return {}; }, }); </script>
|
ModalButton.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <template> <button @click="modalOpen = true">打开对话框</button> <!-- 对话框代码 --> <Teleport to="body"> <div v-if="modalOpen" class="modal"> <div> 这是对话框 <button @click="modalOpen = false">关闭对话框</button> </div> </div> </Teleport> </template>
<script lang="ts"> import { defineComponent, ref } from "vue"; export default defineComponent({ name: "", setup(props, { attrs, emit, slots }) { // 控制对话框显示隐藏 const modalOpen = ref(false); return { modalOpen, }; }, }); </script> <style scoped> .modal { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 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>
|
Suspense(不确定的)
它们允许我们的应用程序在等待异步组件时渲染一些后备内容,可以让我们创建一个平滑的用户体验
作用:在一个异步组件加载的过程中,显示其他内容,不使用长时间显示空白界面
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <template> <h2>App父级组件:Suspense</h2> <Suspense> <template #default> <!-- 放入一个异步组件 --> <!-- <Async></Async> --> <Async1></Async1> </template> <template v-slot:fallback> <!-- 准备的内容 --> <h2>Loading</h2> </template> </Suspense> </template>
<script lang="ts"> // 引入组件 :静态引入 和动态引入 // vue2的动态引入组件的写法:(在vue3中,这种写法不行) // const Async = () => import("./Async.vue") // vue3的动态引入组件的写法: // const Async = defineAsyncComponent(() => import("./Async.vue")); // 静态引入 // import Async from "./Async.vue" import Async1 from "./Async1.vue"
import { defineAsyncComponent, defineComponent, ref } from "vue"; export default defineComponent({ name: "", components: { // Async, Async1, }, setup(props, { attrs, emit, slots }) { return {}; }, }); </script>
|
Async.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <h2>Async子级组件</h2> <h3>{{msg}}</h3> </template>
<script lang="ts"> import { defineComponent, ref } from "vue"; export default defineComponent({ name: "", setup(props, { attrs, emit, slots }) { return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve({ msg:'123456789' }) },2000) }) // return {}; }, }); </script>
|
Async1.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <h2>Async1组件</h2> <h3>{{ data }}</h3> </template>
<script lang="ts"> import { defineComponent, ref } from "vue"; import axios from "axios"; export default defineComponent({ name: "", setup() { return axios.get('/data/address.json').then(response =>{ return { data:response.data } }).catch() }, // async setup() { // const result = await axios.get("/data/address.json"); // return { // data:result.data // } // }, }); </script>
|
public/data/address.json
1 2 3 4 5
| { "id":1, "address":"四川省成都市二仙桥", "distance":"200m" }
|
其他新的 API
1. 全新的全局 API
- createApp()
- defineProperty()
- defineAsyncComponent()
- nextTick()
2. 将原来的全局 API 转移到应用对象
- app.component()
- app.config()
- app.directive()
- app.mount()
- app.unmount()
- app.use()
3. 模板语法变化
- v-model 的本质变化
- prop:value -> modelValue;
- event:input -> update:modelValue;
- sync 修改符已移除, 由 v-model 代替
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
- v-if 优先 v-for 解析
对vue3的了解
- 2020年9月发布正式版
- vue3支持大多数vue2的特性
- vue3设计了一套强大的组合API代替vue2中的option API,复用性更强
- 更好的支持了Ts
- vue3使用了Proxy配合Reflect 代替了vue2中的Object.defineProperty()方式实现数据的响应式(数据代理)
- 重写了虚拟DOM,速度更快了
- 新的组件:Fragment(片段) / Teleport(瞬移) /Susperse(不确定)
- 设计了一个新的脚手架工具 vite