Vue的生命周期指的是Vue实例在页面中创建到销毁整个过程。Vue提供了在各个生命周期的钩子,钩子也叫Vue生命周期函数。这些生命周期函数是伴随着Vue实例创建、销毁的过程中自动触发的(不需要人为手动触发)。Vue实例生命周期有三个阶段:
<template>
<div>
<p id="op" ref="myp">{{num}}</p>
<button id="obtn" @click="btnClick">按钮</button>
</div>
</template>
<script>
export default {
data() {
return {
num:20
};
},
methods:{
fn(){
return 999
},
btnClick(){
this.num++
}
},
beforeCreate() {
console.log("1.1---------------beforeCreate");
console.log(1.1, this.num, this.fn, document.getElementById("op"));
},
created() {
console.log("1.2-------------created");
console.log(1.2, this.num, this.fn, document.getElementById("op"));
},
beforeMount() {
console.log("2.1---------------beforeMount");
console.log(2.1, this.num, this.fn, document.getElementById("op"));
},
mounted() {
console.log("2.2-------------mounted");
console.log(2.2, this.num, this.fn, document.getElementById("op"));
},
beforeUpdate(){ //视图跟新之前
console.log("3.1-------------beforeUpdate");
console.log(3.1, this.num, this.$refs.myp.innerHTML);
},
updated(){ //视图跟新之后
console.log("3.2-------------updated");
console.log(3.2, this.num, this.$refs.myp.innerHTML);
},
beforeDestory(){
},
destoryed(){
}
};
</script>
在初始化阶段有两个生命周期函数:
data
和 methods
属性。这个函数执行时,仅仅完成自身内部事件的生命周期函数的注入。
data
和methods
已经创建好,此时还没有开始编译模板,这个函数执行时,完成自身内部事件和生命周期函数的注入,包括自定义的data、methods、computed等属性注入和校验工作。
data
的数据可以访问和修改,而且此时的模板已经编译好了,还没有更新到页面中
data
中的数据是最新,但是界面上显示的还是旧的,因为此时还没有开始重新渲染DOM节点。 此时修改输入框的内容,data
中的数据已经更新了,但是页面上显示的还是旧数据。
data
中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了。此时 data
的内容已经更新,页面显示的也是最新的数据。
EcmaScript 6.x简称ES6。
在ES5之前,我们都是使用var
生命变量,在ES6中,提供了两个新的关键字,推荐使用这两个关键字来声明变量:
使用var
声明的变量中存在作用范围混淆的问题。
在使用匿名函数时,可以使用ES6中的箭头函数(参数)=>{函数体}
,一般用于匿名函数作为参数的时候使用。
注意:
()
。()
可以省略不写。{}
可以省略不写。新增了模板字符串——反引号**``**,用来拼接html字符串。
在ES5中定义对象,无论对象的属性名和变量名是否一致,都需要写两遍。
let id = 21;
let name = "XiaoLin";
let age = 23;
const emp = {id:id,name:name,age:age}
在ES6中,如果对象属性名和变量名一致的话,写一个即可。
let id = 21;
let name = "XiaoLin";
let age = 23;
const emp = {id,name,age}
Vue推荐的开发方式是SPA(Single Page Application),单页面应用。单页面应用指的是项目只有一张页面。
Vue推荐的开发方式是一应用中只能存在一个Vue实例。
使用现有手段严格遵循SPA会存在的问题?
为了严格遵循SPA开发方式,Vue提供了Vue组件Compoent。日后你可以为你的每个业务功能去划分一个个组件,抽取出来,变成一个个组件,当你需要使用到哪个组件,直接加载哪个组件即可。使用组件的好处:
面对复杂问题的处理方式,把问题拆解成很多个能处理的小问题,再将其放在整体中,会发现大的问题也会迎刃而解。而组件化的思想也类似:
组件化开发的优势:
组件化是Vue重要的思想
组件化思想的应用开发:
通过Vue.component('组件名称', {})
,通过这个方法注册的都是全局组件,也就是他们再注册之后可以用在任何新创建的Vue
实例挂载的区域内。他有两个参数:
使用组件时,直接使用组件名来用即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--登录-->
<login></login>
<!--注册-->
<register></register>
</div>
</body>
</html>
<script>
//1.定义一个全局组件 参数1:组件名称 参数2: 组件的配置对象
Vue.component('login', {
template: `用户登录 `,//用来书写该组件的html代码
});
Vue.component('register', {
template: `用户注册 `
});
const app = new Vue({
el: "#app",
data: {
msg: "Vue 中组件使用"
},
methods: {},
computed: {},
});
</script>
在
...
外的组件 my-con
没有替换成组件真正的页面结构,是因为 new Vue()
挂载在 id=app
的节点上,不在这个节点上标签,不会受到Vue的影响。
通过 Vue.component
方式注册的组件,称之为全局组件。任何地方都可以使用。全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
于是就有了局部组件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--用户添加-->
<add></add>
</div>
</body>
</html>
<script>
const app = new Vue({
el: "#app",
data: {
msg: "Vue 中组件使用"
},
methods: {},
computed: {},
components: { //注册局部组件
add: { //添加局部组件
template: `用户添加 `
}
}
});
</script>
我们可以把组件抽取出来,在外部定义配置对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--用户添加-->
<add></add>
</div>
</body>
</html>
<script>
const login = { //把login组件抽出来
template:`用户登录`
}
const app = new Vue({
el:"#app",
data:{
msg:"Vue的组件中定义组件 Data methods Computed等"
},
methods:{},
computed:{},
components:{ //用来定义局部组件
login, // 在ES6中如果变量名等于属性名的话,可以只写一遍,这里也等于 login:login,
}
});
</script>
我们还可以给当前组件定义属于组件自己的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<login></login>
</div>
</body>
</html>
<script>
const login = { //把login组件抽出来
template:`用户登录`,
data:{
}
}
const app = new Vue({
el:"#app",
data:{
msg:"Vue的组件中定义组件 Data methods Computed等"
},
methods:{},
computed:{},
components:{ //用来定义局部组件
login, // 在ES6中如果变量名等于属性名的话,可以只写一遍,这里也等于 login:login,
}
});
</script>
data必须是一个函数,且是一个有返回值的函数。要是改为这样,依然会报错,因为我没有返回一个object对象。
const login = { //把login组件抽出来
template:`用户登录`,
data(){
}
}
所以要添加返回值对象即可。
const login = { //把login组件抽出来
template:`用户登录`,
data(){
return{
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<login></login>
<login></login>
</div>
</body>
</html>
<script>
const login = { //把login组件抽出来
template:`用户登录{{counter}}`,
data(){
return{
counter:0,
}
}
}
const app = new Vue({
el:"#app",
data:{
msg:"Vue的组件中定义组件 Data methods Computed等"
},
methods:{},
computed:{},
components:{ //用来定义局部组件
login, // 在ES6中如果变量名等于属性名的话,可以只写一遍,这里也等于 login:login,
}
});
</script>
在组件中还有msg
这个属性,如果在外面Vue实例中也有msg
这个属性,那么在组件中会优先使用组件中的msg
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<login></login>
<login></login>
</div>
</body>
</html>
<script>
const login = { //把login组件抽出来
template:`用户登录{{counter}}----{{msg}}`,
data(){
return{
counter:0,
msg:"我是组件中的msg",
}
}
}
const app = new Vue({
el:"#app",
data:{
msg:"Vue的组件中定义组件 Data methods Computed等"
},
methods:{},
computed:{},
components:{ //用来定义局部组件
login, // 在ES6中如果变量名等于属性名的话,可以只写一遍,这里也等于 login:login,
}
});
</script>
为了给组件自己定义一些列的方法,比如便于实现点击事件,组件中还有methods
属性,用来定义一系列方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<login></login>
</div>
</body>
</html>
<script>
const login = { //把login组件抽出来
template:`用户登录{{counter}}----{{msg}}
点我counter++
`,
data(){
return{
counter:0,
msg:"我是组件中的msg",
}
},
methods:{ //用来给组件自己定义一些列方法
test(count){
this.counter+=count;
}
},
}
const app = new Vue({
el:"#app",
data:{
msg:"Vue的组件中定义组件 Data methods Computed等"
},
methods:{},
computed:{},
components:{ //用来定义局部组件
login, // 在ES6中如果变量名等于属性名的话,可以只写一遍,这里也等于 login:login,
}
});
</script>
当然,如果多处地方都需要调用计算结果,我们还可以使用computed
这个属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<login></login>
</div>
</body>
</html>
<script>
const login = { //把login组件抽出来
template:`用户登录{{counter}}----{{msg}}-------{{counterSqrt}}
点我counter++
`,
data(){
return{
counter:0,
msg:"我是组件中的msg",
}
},
methods:{ //用来给组件自己定义一些列方法
test(count){
this.counter+=count;
}
},
computed:{ //用来给组件自己定义一些列计算方法
counterSqrt(){
return this.counter*this.counter;
}
},
}
const app = new Vue({
el:"#app",
data:{
msg:"Vue的组件中定义组件 Data methods Computed等"
},
methods:{},
computed:{},
components:{ //用来定义局部组件
login, // 在ES6中如果变量名等于属性名的话,可以只写一遍,这里也等于 login:login,
}
});
</script>
组件中也有生命周期的各种函数,组件也有生命周期。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<login></login>
</div>
</body>
</html>
<script>
const login = { //把login组件抽出来
template:`用户登录{{counter}}----{{msg}}-------{{counterSqrt}}
点我counter++
`,
data(){
return{
counter:0,
msg:"我是组件中的msg",
}
},
methods:{ //用来给组件自己定义一些列方法
test(count){
this.counter+=count;
}
},
computed:{ //用来给组件自己定义一些列计算方法
counterSqrt(){
return this.counter*this.counter;
}
},
//初始化阶段
beforeCreate(){
console.log("beforeCreate:",this.msg);},
created(){
console.log("created:",this.msg);
},
beforeMount(){ //此时组件中template还是模板还没有渲染
console.log(this);
//console.log("beforeMount:",this.$el.innerHTML);
},
mounted(){ // 此时组件中页面的数据已经和data中数据一致
console.log("mounted:",document.getElementById("aa").innerHTML);
},
//运行阶段
beforeUpdate(){// 此时data中数据变化了 页面数据还是原始数据
console.log("beforeUpdate:",this.counter);
console.log("beforeUpdate:",document.getElementById("aa").innerHTML);
},
updated(){ //此时data 页面数据一致
console.log("updated:",this.counter);
console.log("updated:",document.getElementById("aa").innerHTML);
},
//销毁阶段
beforeDestroy(){},
destroyed(){},
}
const app = new Vue({
el:"#app",
data:{
msg:"Vue的组件中定义组件 Data methods Computed等"
},
methods:{},
computed:{},
components:{ //用来定义局部组件
login, // 在ES6中如果变量名等于属性名的话,可以只写一遍,这里也等于 login:login,
}
});
</script>