683 vue3的動態元件,keep-alive,快取元件的生命週期,非同步元件和Suspense,$refs,$parent和$root,生命週期,元件的v-model
阿新 • • 發佈:2021-06-12
切換元件案例
v-if顯示不同的元件
動態元件的實現
動態元件的傳值
認識keep-alive
keep-alive屬性
快取元件的生命週期
App.vue
<template> <div> <button v-for="item in tabs" :key="item" @click="itemClick(item)" :class="{ active: currentTab === item }" > {{ item }} </button> <!-- 2.動態元件 --> <keep-alive include="home,about"> <component :is="currentTab" name="coderwhy" :age="18" @pageClick="pageClick" > </component> </keep-alive> <!-- 1.v-if的判斷實現 --> <!-- <template v-if="currentTab === 'home'"> <home></home> </template> <template v-else-if="currentTab === 'about'"> <about></about> </template> <template v-else> <category></category> </template> --> </div> </template> <script> import Home from "./pages/Home.vue"; import About from "./pages/About.vue"; import Category from "./pages/Category.vue"; export default { components: { Home, About, Category, }, data() { return { tabs: ["home", "about", "category"], currentTab: "home", }; }, methods: { itemClick(item) { this.currentTab = item; }, pageClick() { console.log("page內部發生了點選"); }, }, }; </script> <style scoped> .active { color: red; } </style>
Home.vue
<template> <div @click="divClick"> Home元件: {{name}} - {{age}} </div> </template> <script> export default { name: "home", // home是字串 props: { name: { type: String, default: "" }, age: { type: Number, default: 0 } }, emits: ["pageClick"], methods: { divClick() { this.$emit("pageClick"); } } } </script> <style scoped></style>
About.vue
<template> <div> <div>About元件</div> <button @click="counter++">{{ counter }}</button> </div> </template> <script> export default { name: "about", data() { return { counter: 0, }; }, created() { console.log("about created"); }, unmounted() { console.log("about unmounted"); }, activated() { console.log("about activated"); }, deactivated() { console.log("about deactivated"); }, }; </script> <style scoped></style>
Category.vue
<template>
<div>
<div>Category元件</div>
<button @click="counter++">{{ counter }}</button>
</div>
</template>
<script>
export default {
name: "category",
data() {
return {
counter: 0,
};
},
};
</script>
<style scoped></style>
Webpack的程式碼分包
Vue中實現非同步元件
非同步元件的寫法二
非同步元件和Suspense
App.vue
<template>
<div>
App元件
<home></home>
<suspense>
<template #default>
<async-category></async-category>
</template>
<template #fallback>
<loading></loading>
</template>
</suspense>
</div>
</template>
<script>
import { defineAsyncComponent } from "vue";
import Home from "./Home.vue";
import Loading from "./Loading.vue";
// import AsyncCategory from './AsyncCategory.vue';
const AsyncCategory = defineAsyncComponent(() =>
import("./AsyncCategory.vue")
);
const AsyncCategory = defineAsyncComponent({
loader: () => import("./AsyncCategory.vue"),
loadingComponent: Loading,
// errorComponent,
// 在顯示loadingComponent元件之前, 等待多長時間
delay: 2000,
/**
* err: 錯誤資訊,
* retry: 函式, 呼叫retry嘗試重新載入
* attempts: 記錄嘗試的次數
*/
onError: function(err, retry, attempts) {},
});
export default {
components: {
Home,
AsyncCategory,
Loading,
},
};
</script>
<style scoped></style>
Home.vue
<template>
<div>
Home元件
</div>
</template>
<script>
export default {};
</script>
<style scoped></style>
Loading.vue
<template>
<div>
Loading
</div>
</template>
<script>
export default {};
</script>
<style scoped></style>
AsyncCategory.vue
<template>
<div>
<h2>{{ message }}</h2>
</div>
</template>
<script>
export default {
data() {
return {
message: "Hello Category",
};
},
};
</script>
<style scoped></style>
$refs的使用
$parent和$root
App.vue
<template>
<div>
<!-- 繫結到一個元素上 -->
<h2 ref="title">哈哈哈</h2>
<!-- 繫結到一個元件例項上 -->
<nav-bar ref="navBar"></nav-bar>
<button @click="btnClick">獲取元素</button>
</div>
</template>
<script>
import NavBar from "./NavBar.vue";
export default {
components: {
NavBar,
},
data() {
return {
names: ["abc", "cba"],
};
},
methods: {
btnClick() {
console.log(this.$refs.title);
console.log(this.$refs.navBar.message);
this.$refs.navBar.sayHello();
// $el
console.log(this.$refs.navBar.$el);
},
},
};
</script>
<style scoped></style>
NavBar.vue
<template>
<div>
<h2>NavBar</h2>
<button @click="getParentAndRoot">獲取父元件和根元件</button>
</div>
</template>
<script>
export default {
data() {
return {
message: "我是NavBar中的message",
};
},
methods: {
sayHello() {
console.log("Hello NavBar");
},
getParentAndRoot() {
console.log(this.$parent);
console.log(this.$root);
},
},
};
</script>
<style scoped></style>
認識生命週期
生命週期的流程
App.vue
<template>
<div>
<button @click="isShow = !isShow">切換</button>
<template v-if="isShow">
<home></home>
</template>
</div>
</template>
<script>
import Home from "./Home.vue";
export default {
components: {
Home,
},
data() {
return {
isShow: true,
};
},
};
</script>
<style scoped></style>
Home.vue
<template>
<div>
<h2 ref="title">{{ message }}</h2>
<button @click="changeMessage">修改message</button>
</div>
</template>
<script>
export default {
data() {
return {
message: "Hello Home",
};
},
methods: {
changeMessage() {
this.message = "你好啊, 哈哈";
},
},
beforeCreate() {
console.log("home beforeCreate");
},
created() {
console.log("home created");
},
beforeMount() {
console.log("home beforeMount");
},
mounted() {
console.log("home mounted");
},
beforeUnmount() {
console.log("home beforeUnmount");
},
unmounted() {
console.log("home unmounted");
},
beforeUpdate() {
console.log(this.$refs.title.innerHTML);
console.log("home beforeUpdate");
},
updated() {
console.log(this.$refs.title.innerHTML);
console.log("home updated");
},
};
</script>
<style scoped></style>