- vue3.x,中支持定义多个根节点,省略了包裹容器
<template>
<h1>vue3</h1>
<h2>vue3</h2>
</template>
vue3x生命周期钩子:
1.2 vue3x:setup() 替代了Vue2x中的beforeCreate和created生命周期函数,成为程序的入口
//挂载
1.3 vue3x: beforeMount => onBeforeMount
1.4 vue3x: mounted => onMounted
// 更新
1.5 vue3x: updated => onUpdated
// 卸载
1.6 vue3x: beforeUnmount => onBeforeUnmount
1.7 vue3x: unmounted => onUnmounted
//捕获子孙组件的错误
1.8 vue3x: errorCaptured => onErrorCaptured
import {
ref /**定义变量 */,
watchEffect /**监听 */,
getCurrentInstance /**组件实例 */,
onBeforeMount,
onMounted /**生命周期挂载钩子 */,
onErrorCaptured /**捕获子孙组件在内的错误 */,
onRenderTracked /**追踪render行为 */,
onRenderTriggered /**监听触发render行为 */,
} from "vue";
export default {
name: "MyApp",
components: {
HelloWorld,
},
setup(props, ctx) {
console.log("setup");
// 组件实例 及vue2x中 this
const instance = getCurrentInstance();
onBeforeMount(() => {
console.log("onBeforeMount");
});
//生命周期挂载钩子
onMounted(() => {
console.log("onMounted");
});
watchEffect(() => {
// do something
console.log("watchEffect");
},{
flush: "post",
onTriggered(e){},
onTrack(e){},
}
);
onErrorCaptured((e)=>{
console.log('e', e)
})
onRenderTracked((e) => {
debugger;
});
onRenderTriggered((e) => {
debugger;
});
},
};
组合式API
在vue3项目中,最显眼的变化就是setup的出现了,在vue文档中有这样的说明:
通过创建 Vue 组件,我们可以将界面中重复的部分连同其功能一起提取为可重用的代码段。仅此一项就可以使我们的应用在可维护性和灵活性方面走得相当远。然而,我们的经验已经证明,光靠这一点可能并不够,尤其是当你的应用变得非常大的时候——想想几百个组件。处理这样的大型应用时,共享和重用代码变得尤为重要。
如果能够将同一个逻辑关注点相关代码收集在一起会更好。而这正是组合式 API 使我们能够做到的
既然我们知道了为什么,我们就可以知道怎么做。为了开始使用组合式 API,我们首先需要一个可以实际使用它的地方。在 Vue 组件中,我们将此位置称为 setup。
setup函数是组合API的入口函数。
setup它会在beforeCreate钩子之前被调用。
setup由于在执行时候,还没有执行created生命周期方法,所以在setup函数中,无法使用data和methods。
setup它接收props和context两个参数。
setup函数中定义的变量和方法最后都是需要 return 出去的,不然无法在模板中使用。
全局 API
在测试期间,全局配置很容易意外地污染其他测试用例。用户需要仔细存储原始全局配置,并在每次测试后恢复 (例如重置 Vue.config.errorHandler)。有些 API 像 Vue.use 以及 Vue.mixin 甚至连恢复效果的方法都没有,这使得涉及插件的测试特别棘手。
为了避免这些问题,在 Vue 3 中我们引入一个全新的全局API createApp
// vue2
import Vue from "vue";
Vue.prototype.$moment = moment;
// vue3
import { createApp } from 'vue'
const app = createApp(App)
app.config.globalProperties.$moment = moment;
watch
watch API 与选项式 API this.$watch (以及相应的 watch 选项) 完全等效。watch 需要侦听特定的数据源,并在单独的回调函数中执行副作用。默认情况下,它也是惰性的——即回调仅在侦听源发生更改时被调用。
let count = 0
// vue2
watch: {
count: (res) => {
/* res */
}
}
// vue3
watch(() => count,
(newValues) => {
/* newValues */
}
)
// vue3监听多个
watch(() => [count1, count2],
(newValues1, newValues2) => {
/* newValues1 */
/* newValues2 */
}
)
keep-alive
<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
主要用于保留组件状态或避免重新渲染。
// vue2
<keep-alive>
<router-view />
</keep-alive>
// vue3
// keepAliveList需要缓存的组件列表
<router-view v-slot="{ Component }">
<keep-alive :include="keepAliveList">
<Component :is="Component"></Component>
</keep-alive>
</router-view>
vue2
<template lang="pug">
.layout-container
.layout-head
span {{count}}
// ...
.layout-page
keep-alive
router-view
</template>
<script>
export default {
name: "layout",
data() {
count: 0,
// ...
},
watch: {
count: (res) => {
// ...
}
},
created(){
// ...
},
mounted: () => {
// ...
},
methods: {
initPage() {
// ...
}
}
}
</script>
vue3
<template lang="pug">
.layout-container
.layout-head
span {{count}}
// ...
.layout-page
router-view(v-slot="{ Component }")
keep-alive(:include="keepAliveList")
Component(:is="Component")
</template>
<script lang="ts">
import { defineComponent, reactive, onMounted, watch } from 'vue'
export default defineComponent({
name: 'layout',
setup() {
const state:any = reactive({
count: 0,
// ...
})
watch(() => count,
(newValues) => {
// ...
}
)
onMounted(() => {
// ...
})
const initPage:Function = () => {
// ...
}
return {
...toRefs(state),
initPage
}
}
})
</script>
2.非vue3特性:
script节点中 name节点的为当前 组件定义一个名称
//Swiper.vue组件
<script>
export defailt {
//name 属性指向的是当前组件的名称(建议:每个单词首字母大写)
name: ’MyApp‘
}
</script>
在使用Vue-devtools进行调试是,自定义的组件名称可以清晰区分每个组件
3.使用name节点定义的组件名称注册组件:
import{createApp} from 'vue'
//导入需要注册的组件
import Swiper from './components/01.globalReg/Swiper.vue'
//调用 createApp函数 创建SPA应用实例
const app = createApp(App);
//调用app.component() 方法 全局注册组件
app.component(Swiper.name, Swiper)
4.class与style以数组
方式动态绑定:
<template>
<h2>vue3.X</h2>
<h3 :class="[isItalic ? 'italic' : '', isDelete ? 'delete' : '']">
{{ name }}
</h3>
</template>
<script>
export default {
data() {
return {
name: "Vue3.0 vite",
isDelete: true,
isItalic: true,
};
},
};
</script>
<style lang="less">
.thin {
font-size: 200;
}
.italic {
font-style: italic;
}
.delete {
text-decoration: lightblue;
color: red;
}
</style>
5.class与style以对象
方式动态绑定:
<template>
<h3 :class="classObj">
{{ name }}
</h3>
</template>
<script>
export default {
name: "MyApp",
data() {
return {
name: "Vue3.0 vite",
classObj: {
italic: true,
delete: true,
},
};
},
};
</script>
<style lang="less">
.thin {
font-size: 200;
}
.italic {
font-style: italic;
}
.delete {
text-decoration: lightblue;
color: blue;
}
</style>
6。内联样式动态绑定
<template>
<h3 :class="{color: active, fontSize: fsize + 'px','background-color': bgcolor}">
{{ name }}
</h3>
</template>
<script>
export default {
name: "MyApp",
data() {
return {
active: "red",
fsize: 30,
bgcolor: "pink",
name: "Vue3.0 vite",
};
},
};
</script>
<style lang="less">
.thin {
font-size: 200;
}
.italic {
font-style: italic;
}
.delete {
text-decoration: lightblue;
color: blue;
}
</style>
7.prop指定多个可能的类型:
exportdefault {
props: {
// propA属性的值可以使“字符串”或“数字”
propA: [String,Number]
}
}