利用Vuecli脚手架搭建一个Demo:
App.vue
<template> <div id="nav"> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view /> </template> <script> export default { name: "App", beforeCreate() { console.log("App beforeCreate", this.$data, this.$el); }, created() { console.log("App created", this.$data, this.$el); }, beforeMount() { console.log("App beforeMount", this.$data, this.$el); }, mounted() { console.log("App mounted", this.$data, this.$el); }, beforeUpdate() {}, updated() {}, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } #nav { padding: 30px; a { font-weight: bold; color: #2c3e50; &.router-link-exact-active { color: #42b983; } } } </style>
Home.vue
<template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Welcome to Your Vue.js App" proper="1" @custome="handler" :list="list" > <template v-slot:two="{ slottwo }"> {{ home }} - 子组件插槽的数据: {{ slottwo }} </template> </HelloWorld> </div> </template> <script> import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "Home", data() { return { home: "主页", list: [ { name: "马冬梅", age: 19, gender: "女" }, { name: "周冬雨", age: 23, gender: "女" }, { name: "周杰伦", age: 20, gender: "男" }, { name: "温兆伦", age: 22, gender: "男" }, ], }; }, components: { HelloWorld }, methods: { handler(args) { console.log("子组件传递的参数:", args); }, }, beforeCreate() { console.log("Home beforeCreate", this.$data, this.$el); }, created() { console.log("Home created", this.$data, this.$el); }, beforeMount() { console.log("Home beforeMount", this.$data, this.$el); }, mounted() { console.log("Home mounted", this.$data, this.$el); }, beforeUpdate() { console.log("Home beforeUpdate", this.$data, this.$el); }, updated() { console.log("Home updated", this.$data, this.$el); }, }; </script>
HelloWorld.vue
<template> <div> <h1>{{ msg }}</h1> <span>这里是插槽内容:</span> <slot slotone="01" name="one"></slot> <slot :slottwo="keyword" name="two"></slot> <hr /> <button @click="$emit('custome', '参数')">点击传递参数</button> <hr /> <p>输入姓名只显示相关信息</p> <input type="text" placeholder="请输入姓名" v-model="keyword" @keyup.delete="backspace" /> <button @click="sort(1)">正序排序</button> <button @click="sort(-1)">倒序排序</button> <button @click="sort(0)">恢复默认</button> <ul> <li v-for="(item, index) in infos" :key="index"> {{ item.name }}-{{ item.age }}-{{ item.gender }} </li> </ul> <hr /> 自定义指令: <p v-big>自定义指令</p> </div> </template> <script> export default { name: "HelloWorld", data() { return { keyword: "", infos: this.list, type: 0, }; }, props: { msg: String, list: Array, }, watch: { keyword(newVal, oldVal) { if (!newVal) { this.infos = this.list; } this.infos = this.infos.filter((item) => { return item.name.indexOf(newVal) !== -1; }); }, }, methods: { backspace() { this.infos = this.list; this.infos = this.infos.filter((item) => { return item.name.indexOf(this.keyword) !== -1; }); }, sort(type) { if (type === 0) { this.infos = this.list; } else if (type === 1) { this.infos = this.infos.sort(function (a, b) { return a.age - b.age; }); } else if (type === -1) { this.infos = this.infos.sort(function (a, b) { return b.age - a.age; }); } }, }, directives: { big(a, b) { // console.dir(b); }, }, // setup(props, context) { // console.log("props:", props); // console.log("context:", context); // const { attrs, slots, emit } = context; // console.log("attrs:", attrs); // console.log("slots:", slots); // console.log("emit:", emit); // }, beforeCreate() { console.log("HelloWorld beforeCreate", this.$data, this.$el); }, created() { console.log("HelloWorld created", this.$data, this.$el); }, beforeMount() { console.log("HelloWorld beforeMount", this.$data, this.$el); }, mounted() { console.log("HelloWorld mounted", this.$data, this.$el); }, beforeUpdate() { console.log("HelloWorld beforeUpdate", this.$data, this.$el); }, updated() { console.log("HelloWorld updated", this.$data, this.$el); }, }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped>
页面加载效果如上图,helloworld是Home的子组件,父子组件加载顺序是:
父组件(beforeCreate)->父组件(created)->父组件(beforeMount)->子组件(beforeCreate)->子组件(created)->子组件(beforeMount)->子组件(mounted)->父组件(mounted)
子组件的生命周期“插队”添加到了父组件挂载(mounted)之前。也就是说,父组件在挂载完成前会完成子组件的创建和挂载
另外,图示的箭头部分说明DOM的渲染是在挂载(mounted)部分完成的,蓝色和绿色框说明数据的“识别监测”是在(created)完成的。