一.Vue生命周期阶段:
vue生命周期分为四个阶段
第一阶段(创建阶段):beforeCreate,created
第二阶段(挂载阶段):beforeMount(render),mounted
第三阶段(更新阶段):beforeUpdate,updated
第四阶段(销毁阶段):beforeDestroy,destroyed
二.生命周期钩子函数:
1.创建阶段:
beforeCreate:
实例刚刚被创建,数据观测和事件配置尚未开始
created:
实例创建完成,数据观测已经完成,可以访问数据和计算属性,但是尚未挂载DOM,可以进行初始化操作,如发送ajax请求,向后台拿取数据。
2.挂载阶段:
beforeMount:
在挂载之前被调用,'render'首次调用
mounted:
实例挂载后被调用,此时可以访问DOM
3.更新阶段:
beforeUpdate:
数据更新时调用,发生在虚拟DOM重新渲染之前
updated:
数据更新之后调用,发生在DOM重新渲染之后
4.销毁阶段:
beforeDestroy:
实例销毁之前,可以做一些清除操作。
destroyed:
实例被销毁后调用。
三.组件化编程:
组件化编程就是将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,我们管理和维护时只需要处理指定的功能模块就行了。
组件(Component):
定义: 用于实现局部功能的代码和资源的集合
作用: 复用编码,简化项目编程.提高运行效率
1.组件分类:
组件可以分为:非单文件组件和单文件组件
非单文件组件:
一个文件中包含n个组件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style type="text/css">
</style>
<script src="./js/vue.global.js"></script>
</head>
<body>
<div id="box">
<!--3.使用组件 -->
<person></person>
<hr/>
<job></job>
</div>
<script type="text/javascript" >
const {createApp} = Vue
//1,定义组件
const person = {
data(){
return {
name:'张三',
age:21
}
},
template:`<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>`,
}
const job = {
data(){
return {
name:'java程序员',
salary: 8000
}
},
template:`<p>岗位:{{name}}</p>
<p>薪水:{{salary}}</p>`,
}
var app = createApp({
//2.注册组件(局部)
components:{
person : person,
job : job,
},
data(){
return {}
},
}).mount("#box");
</script>
</body>
</html>
缺点:
-
模板编写没有提示
-
没有构建过程, 无法将 ES6 转换成 ES5
-
不支持组件的 CSS
-
真正开发中几乎不用
组件注意事项:
-
组件名称
一个单词组成
第一种写法: 首字母小写: person
第二种写法: 首字母大写: Person
多个单词组成
第一种写法(kebab-case命名):my-person
第二种写法:大驼峰命名法: MyPerson (需要vue脚手架支持)
2.关于标签名
双标签:
<person></person>
单标签:
<person/>
(需要vue脚手架支持)注意: 不使用脚手架时,
<person/>
会导致后续组件不能渲染
单文件组件:
定义: 一个文件中包含1个组件
实际开发使用一般使用单文件组件
-
单文件组件的后缀名为.vue
-
.vue文件无法直接在浏览器使用,需要借助vue的脚手架
-
一个.vue的文件结构:
<template>
<!--组件的结构-->
</template>
<script>
//组件交互相关的js代码
</script>
<style>
/*组件的样式 */
</style>
2.使用Vue脚手架:
1.安装nodejs环境:
官网下载nodejs: Node.js — Download Node.js®
2.全局安装@vue/cli
进入VS coded 命令终端:
执行:npm install -g @vue/cli
切换到你需要创建项目的目录,然后使用命令创建项目
<br class="Apple-interchange-newline"><div></div>
vue create 项目名
选择默认
启动项目
npm run serve
如果下载缓慢,可以配置npm淘宝镜像:
npm config set registry https://registry.npm.taobao.org
项目结构如下:
在开发过程中,我们先关闭ES的语法检查:
在vue.config.js文件中添加如下配置:
lintOnSave:false,//关闭语法检查
重启项目
但是现在官方推荐使用 create-vue 来创建基于 Vite 的新项目
官方文档:https://cn.vitejs.dev/guide/
3.单文件组件SFC
<template>
<!--组件的结构-->
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
</template>
<script>
//组件交互相关的js代码
export default{
name:'Person',
data(){
return {
name:'张三',
age:21
}
},
}
</script>
<style>
/*组件的样式 */
p{
color:red;
}
</style>
在src/App.vue组件中注册Person组件,并使用Person组件,这个App.vue是我们的根组件。
<template>
<div>
<Person></Person>
</div>
</template>
<script>
import Person from './Person.vue'
export default {
name:'App',
data() {
return {
};
},
components:{
Person,
},
};
</script>
<style lang="scss" scoped>
</style>
3.ref特殊属性:
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 ref
属性:
ref
是一个特殊的 attribute,和 v-for
章节中提到的 key
类似。它允许我们在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用。
访问引用:
<template>
<div ref="app">
<Person></Person>
</div>
</template>
<script>
import Person from './components/Person.vue'
export default {
name:'App',
data() {
return {
};
},
components:{
Person,
},
mounted(){
console.log(this.$refs.app);
}
};
</script>
<style lang="scss" scoped>
</style>
组件上的 ref
ref引用也可以被用在一个子组件上。这种情况下引用中获得的值是组件实例:
<template>
<div ref="app">
<Person ref="p"></Person>
</div>
</template>
<script>
import Person from './components/Person.vue'
export default {
name:'App',
data() {
return {
};
},
components:{
Person,
},
mounted(){
console.log(this.$refs.p.name);
}
};
</script>
<style lang="scss" scoped>
</style>
4.组件间通信:
-
父组件传递给子组件:通过props属性;
-
子组件传递给父组件:通过$emit触发事件;
1.父组件传递给子组件:
什么是Props呢?
-
Props是你可以在组件上注册一些自定义的attribute;
-
父组件给这些attribute赋值,子组件通过attribute的名称获取到对应的值;
Props有两种常见的用法:
-
方式一:字符串数组,数组中的字符串就是attribute的名称;
-
方式二:对象类型,对象类型我们可以在指定attribute名称的同时,指定它需要传递的类型、是否是必须的、默认值等等;
Props的数组用法
子组件:
<template>
<!--组件的结构-->
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
</template>
<script>
//组件交互相关的js代码
export default{
name:'Person',
props:["name","age"],
data(){
return {
}
},
}
</script>
<style>
/*组件的样式 */
p{
color:red;
}
</style>
父组件:
<template>
<div>
<Person name="张三" age="21"/>
<hr/>
<Person name="李四" age="20"/>
</div>
</template>
<script>
import Person from './components/Person.vue'
export default {
name:'App',
data() {
return {
};
},
components:{
Person,
},
};
</script>
<style lang="scss" scoped>
</style>
注意:props中的属性名一定要引号引起
Props的对象用法
当使用对象语法的时候,我们可以对传入的内容限制更多:
比如指定传入的attribute的类型
比如指定传入的attribute是否是必传的
比如指定没有传入时,attribute的默认值
props:{
name:{
type:String,
required:true,
default:'无名氏'
},
age:{
type:Number,
required:true,
},
},
type的类型:String Number Boolean Array Object Date Function Symbol
Prop 名字格式:如果一个 prop 的名字很长,应使用 camelCase 形式
上面我们传递值都是静态的:
如果想动态传值可以使用v-bind
或缩写 :
来进行动态绑定的 props:
单向数据流:
所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。
另外,每次父组件更新后,所有的子组件中的 props 都会被更新到最新值,这意味着你不应该在子组件中去更改一个 prop。若你这么做了,Vue 会在控制台上向你抛出警告:
2.子组件传递给父组件
什么情况下子组件需要传递内容到父组件呢?
-
当子组件有一些事件发生的时候,比如在组件中发生了点击,父组件需要切换内容
-
子组件有一些内容想要传递给父组件的时候
我们如何完成上面的操作呢?
-
首先,我们需要在子组件中定义好在某些情况下触发的事件名称; 自定义事件
-
其次,在父组件中以v-on的方式传入要监听的事件名称,并且绑定到对应的方法中
-
最后,在子组件中发生某个事件的时候,根据事件名称触发对应的事件
子组件:
<template>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
</template>
<script>
export default {
name: 'CodeCounterOperation',
//用于声明由组件触发的自定义事件。
emits:['addOne','subOne'],
data() {
return {
};
},
mounted() {
},
methods: {
increment(){
//自定义事件
//通过this.$emit(事件名[,参数列表]) 发出事件
this.$emit('addOne')
},
decrement(){
this.$emit('subOne')
}
},
};
</script>
<style lang="scss" scoped>
</style>
父组件:
<template>
<div>
<h2>当前计数:{{count}}</h2>
<!--在子组件绑定自定义事件-->
<Counter-Operation @addOne="add" @subOne="sub"/>
</div>
</template>
<script>
import CounterOperation from './components/CounterOperation.vue'
export default {
name:'App',
data() {
return {
count : 0,
};
},
components:{
CounterOperation,
},
methods:{
add(){
this.count++;
},
sub(){
this.count--;
}
}
};
</script>
<style lang="scss" scoped>
</style>
我们还可以使用this.$emit(事件名,参数列表)的形式给父组件传递参数 :