一、vue环境搭建
安装Vue官方脚手架以及创建项目
注意: 安装脚手架创建项目之前之前,我们的电脑上必须得安装Nodejs,推荐安装nodejs稳定版本
文档地址: https://v3.vuejs.org/guide/installation.html#cli
Vue-cli地址: https://cli.vuejs.org/
Vite地址: https://github.com/vitejs/vite
通过Vue-cli脚手架工具可以让我们快速的搭建vue项目,目前Vue官方给我们提供了2个脚手架,Vue-cli和Vite。
通过Vue-cli创建我们的项目
yarn global add @vue/cli # OR npm install -g @vue/cli # OR cnpm install -g @vue/cli
|
如果电脑上面没有安装过cnpm可以通过下面命令安装:
npm install -g cnpm --registry=https://registry.npm.taobao.org
|
如果电脑上面没有安装过yarn可以通过下面命令安装:
创建项目
vue create hello-vue3
yarn serve
|
通过Vite脚手架创建我们的项目
1. 使用npm创建
npm init vite-app <project-name> cd <project-name> npm install npm run dev
|
2. 使用yarn创建
yarn create vite-app <project-name> cd <project-name> yarn yarn dev
|
目录结构

开发工具以及插件配置

二、父组件给子组件传值、Props验证、单向数据流
父子组件介绍

父组件给子组件传值
父组件调用子组件的时候传值
<template> <v-header :title="title"></v-header> </template>
<script> import Header from './Header' export default { data() { return { title: "首页组件title" } }, components: { "v-header": Header } } </script>
|
子组件接收父组件传值
<template> <header>{{title}}</header> </template>
<script> export default { props: ["title"] } </script>
|
Props验证
我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助
props验证:
props: { propA: Number, propB: [String, Number], propC: { type: String, required: true }, propD: { type: Number, default: 100 }, propE: { type: Object, default: function() { return { message: 'hello' } } }, propF: { validator: function(value) { return ['success', 'warning', 'danger'].indexOf(value) !== -1 } }, propG: { type: Function, default: function() { return 'Default function' } }
|
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
另外,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
父组件主动获取子组件的数据和执行子组件方法
调用子组件的时候定义一个ref
<v-header ref="header"></v-header>
|
父组件主动获取子组件数据
父组件主动执行子组件方法
子组件主动获取父组件的数据和执行父组件方法
子组件主动获取父组件的数据
子组件主动获取父组件的数据
三、组件的生命周期函数、 this.$nextTick、动态组件 keep-alive
生命周期函数

| Vue2 |
Vue3 |
| beforeCreate |
❌setup(替代) |
| created |
❌setup(替代) |
| beforeMount |
onBeforeMount |
| mounted |
onMounted |
| beforeUpdate |
onBeforeUpdate |
| updated |
onUpdated |
| beforeDestroy |
onBeforeUnmount |
| destroyed |
onUnmounted |
| errorCaptured |
onErrorCaptured |
| - |
🎉onRenderTracked |
| - |
🎉onRenderTriggered |
setup中调用生命周期钩子
import { onBeforeMount,onMounted } from "vue"; export default { setup() { onBeforeMount(() => { console.log('Before Mount!') }) onMounted(() => { console.log('Before Mount!') }) }, };
|
动态组件 keep-alive
- 当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题,这个时候就用用
keep-alive
- 在不同路由切换的时候想保持组件的状态也可以使用
keep-alive
<keep-alive> <life-cycle v-if="isShow"></life-cycle> </keep-alive>
|
this.$nextTick
Vue中可以把获取Dom节点的代码放在mounted里面,但是如果要在渲染完成数据后获取DOM节点就需要用到this.$nextTick
mounted() { this.$nextTick(function () { }) },
|
mounted() { var oDiv1 = document.querySelector("#msg"); console.log("1-" + oDiv1.innerHTML); this.msg = "$nextTick演示"; var oDiv2 = document.querySelector("#msg"); console.log("2-" + oDiv2.innerHTML); this.$nextTick(() => { var oDiv3 = document.querySelector("#msg"); console.log("3-" + oDiv3.innerHTML); }) },
|
四、Mixin实现组件功能的复用
mixin介绍使用
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项
新建mixin/base.js
const baseMixin = { data() { return{ apiDomain: "http://www.itying.com" } }, methods: { success() { console.log('succss') }, error() { console.error('error') } } }
export default baseMixin;
|
使用mixin
<template> <div> 首页模板--{{apiDomain}} </div> </template>
<script> import BaseMixin from '../mixin/base' export default { mixins: [BaseMixin], data() { return {
} } } </script>
|
关于Mixin的选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”
1. 数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先
const myMixin = { data() { return { message: 'hello', foo: 'abc' } } }
const app = Vue.createApp({ mixins: [myMixin], data() { return { message: 'goodbye', bar: 'def' } }, created() { console.log(this.$data) } })
|
2. 同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用
const myMixin = { created() { console.log('mixin hook called') } }
const app = Vue.createApp({ mixins: [myMixin], created() { console.log('component hook called') } })
|
3. 值为对象的选项,例如 methods、components,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对
const myMixin = { methods: { foo() { console.log('foo') }, conflicting() { console.log('from mixin') } } }
const app = Vue.createApp({ mixins: [myMixin], methods: { bar() { console.log('bar') }, conflicting() { console.log('from self') } } })
const vm = app.mount('#mixins-basic')
vm.foo() vm.bar() vm.conflicting()
|
全局配置Mixin
你还可以为 Vue 应用程序全局应用 mixin
const app = Vue.createApp({ myOption: 'hello!' })
app.mixin({ created() { const myOption = this.$options.myOption if (myOption) { console.log(myOption) } } })
app.mount('#mixins-global')
|
import { createApp } from 'vue' import App from './App.vue' import BaseMixin from './mixin/base'
const app=createApp(App);
app.mixin(BaseMixin)
app.mount('#app');
|
五、使用Teleport自定义一个模态对话框的组件
Teleport
Vue3.x中的组件模板属于该组件,有时候我们想把模板的内容移动到当前组件之外的DOM 中,这个时候就可以使用 Teleport。
表示teleport内包含的内容显示到body中
<teleport to="body"> 内容 </teleport>
|
<teleport to="#app"> 内容 </teleport>
|
使用Teleport实现一个模态对话框的组件
Modal.vue
<template> <teleport to="body"> <div class="model-bg" v-show="visible"> <div class="modal-content"> <button class="close" @click="$emit('close-model')">X</button> <div class="model-title">{{title}}</div> <div class="model-body"> <slot> 第一个对话框 </slot> </div> </div> </div>
</teleport> </template>
<script> export default { props: ["title", "visible"] } </script>
<style lang="scss"> .model-bg { background: #000; opacity: 0.7; width: 100%; height: 100%; position: absolute; top: 0px; }
.modal-content { width: 600px; min-height: 300px; border: 1px solid #eee; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff;
.model-title { background: #eee; color: #000; height: 32px; line-height: 32px; text-align: center; }
.model-body { padding: 40px; }
.close { position: absolute; right: 10px; top: 5px; padding: 5px; border: none; cursor: pointer; }
} </style>
|
Home.vue使用model
<template> <div class="home"> <button @click="isVisible=true">弹出一个模态对话框</button> <modal :visible="isVisible" title="用户登录" @close-model="isVisible=false"></modal> </div> </template>
<script> import Modal from "./Modal" export default { data() { return { isVisible: false } }, components: { Modal }
} </script>
<style lang="scss"> .home { position: relative; } </style>
|