您的位置:首页 > Web前端 > Vue.js

vue的生命周期,钩子函数和组件传值

2019-03-21 14:14 549 查看

所有的生命周期钩子自动绑定this上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法,这是因为箭头函数绑定了父上下文,因此this与你期待的 Vue 实例不同。

 

 

生命周期

  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  5. beforeUpdate
  6. updated
  7. activated
  8. deactivated
  9. beforeDestroy
  10. destroyed

 

 

1、beforeCreate

       在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。

[code] beforeCreate() {
console.log(this.page); // undefined
console.log{this.showPage); // undefined
},
data() {
return {
page: 123
}
},
methods: {
showPage() {
console.log(this.page);
}
}

created

      实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
     这个时候可以操作vue实例中的数据和各种方法,但是还不能对"dom"节点进行操作; 

[code] created() {
console.log(this.page); // 123
console.log{this.showPage); // ...
$('select').select2(); // jQuery插件需要操作相关dom,不会起作用
},
data() {
return {
page: 123
}
},
methods: {
showPage() {
console.log(this.page);
}
}

3、beforeMounte

在挂载开始之前被调用:相关的 render 函数首次被调用。 

4、

mounted

el
被新创建的
vm.$el
替换,并挂载到实例上去之后调用该钩子。如果
root
实例挂载了一个文档内元素,当
mounted
被调用时
vm.$el
也在文档内。
挂载完毕,这时
dom
节点被渲染到文档内,一些需要
dom
的操作在此时才能正常进行

[code] mounted() {
$('select').select2(); // jQuery插件可以正常使用
},

 

5、beforeUpdate(更改已完成,但尚未准备好更新DOM)

在外部事件/用户输入beforeUpdate发生更改时,此钩子即 在反映原始DOM元素的更改之前被触发。

6、Updated(在DOM中呈现的更改)

然后,通过实际更新DOM对象并触发updated,屏幕上的变化得到呈现 。

7、beforeDestroy(对象准备死掉)

就在Vue对象被破坏并从内存中释放之前, deforeDestroy 钩子被触发,并允许我们在其中处理我们的自定义代码。

8、Destroyed(对象停止并从内存中删除)

该 destroyed 钩子被成功运行销毁对象上调用。

 

 

组件传值

组件:组件是可复用的 Vue 实例,且带有一个名字,每个组件必须只有一个根元素,data必须是一个函数。
因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

 

引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示:

1.父组件通过Prop向子组件传递数据

Prop 是你可以在组件上注册的一些自定义特性。当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性。可以用一个 props 选项将需要传递的数据包含在该组件可接受的 prop 列表中

[code]<!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>
</head>
<body>
<div id="app">
<counter :step1="2"></counter>
</div>
<script src="./lib/vue.js"></script>
<script>
Vue.component('counter',{
template:`<button @click="plusHandle">当前计数值: {{count}}</button>` ,
data(){
return {
count:1,
step:1
}
},
methods: {
plusHandle(){
this.count+=this.step1
}
},
props:['step1']
})
var app=new Vue({
el:'#app',
})
</script>
</body>
</html>

2.子组件向父组件传值 使用事件派发

在子组件内部使用this.$emit派发事件
在父组件中使用@(v-on)绑定事件

[code]<!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>
</head>
<body>
<div id="app">
<h5>当前计数器的值为:{{c}}</h5>
<counter @plusadd="plusAddHandle" :step1="2"></counter>
</div>
<script src="./lib/vue.js"></script>
<script>
Vue.component('counter',{
template:`<button @click="plusHandle">当前计数值: {{count}}</button>` ,
data(){
return {
count:0,
step:1
}
},
methods: {
plusHandle(){
this.count+=this.step1;
this.$emit('plusadd',this.count);
}
},
props:['step1']
})
var app=new Vue({
el:'#app',
data:{
c:0,
},
methods: {
plusAddHandle(params){
this.c=params;
}
}
})
</script>
</body>
</html>

3.非父子组件之间的数据传递

为了解决非父子组件之间的传值问题,引入事件总线(EventBus)
在vue中使用一个空白的Vue对象作为一个EventBus,用来做事件的监听和派发

[code]<!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>动态组件</title>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.nav {
background-color: deeppink;
padding: 1.5rem 1rem;
height: 60px;
}
.nav ul {
margin: 0;
padding: 0;
}
.nav ul li {
float: left;
margin: 1.5rem;
list-style: none;;
}
.nav a {
color: #fff;
cursor: pointer;
}
.nav a.cur {
color: greenyellow;
}
.product {
border-bottom: 1px solid #ccc;
padding: 0.2rem 0.5rem;
}
</style>
</head>
<body>
<div id="app">
<navbar @pagchange="changePageHandle"></navbar>
<component :is="currentPage"></component>
</div>
<script src="./lib/vue.js"></script>
<script>

// 事件总线
// 为了解决非父子组件之间的传值问题,引入事件总线
//  在vue中使用一个空白的Vue对象作为一个EventBus,用来做事件的监听和派发

const Nav = {
template:  `
<div class="nav">
<ul>
<li><a :class="this.selIndex==0? 'cur': ''" @click="navClick(0, 'Home')">首页</a></li>
<li><a :class="this.selIndex==1? 'cur': ''" @click="navClick(1, 'List')">商品列表页</a></li>
<li><a :class="this.selIndex==2? 'cur': ''" @click="navClick(2, 'Cart')">购物车【{{cartCount}}】</a></li>
<li><a :class="this.selIndex==3? 'cur': ''" @click="navClick(3, 'Us')">关于我们</a></li>
</ul>
</div>
`,
data() {
return {
selIndex: 0,
cartCount: 0
}
},
methods: {
navClick(index, page) {
this.$emit('pagchange', page); // 子组件传值到父组件
this.selIndex = index
}
},
created() {
this.$eventBus.$on('addToCartEvent', (id) => {
console.log(id);
console.log(this);
this.cartCount += 1;
})
}
}
const Home = {
template: `
<div>
<h1>我是首页</h1>
</div>
`
}
const List = {
template: `
<div>
<div v-for="item in products" class="product">
<h3>{{item.name}}</h3>
<p>{{item.price}}<button @click="addToShopCart(item.id)">加入购物车</button></p>
</div>
</div>
`,
data() {
return {
products: [{
id: 1,
name: 'iphone18',
price: 19999,
}, {
id: 2,
name: 'vivo 32',
price: 5200
}, {
id: 3,
name: 'redmi 10',
price: 3000,
}]
}
},
methods: {
addToShopCart(id) {
this.$eventBus.$emit('addToCartEvent', id); // 使用$eventBus对象派发一个事件
}
}
}
const Cart = {
template: `
<div>
<h1>我是购物车</h1>
</div>
`
}
const Us = {
template: `
<div>
<h1>关于我们</h1>
</div>
`
}
var $eventBus = new Vue(); // 使用一个空白的VUE实例作为中间媒介
Vue.prototype.$eventBus = $eventBus; // 此种定义的属性可以在实例中进行访问
var app = new Vue({
el: '#app',
components: {
navbar: Nav,
Home,
List,
Cart,
Us
},
data: {
currentPage: 'Home'
},
methods: {
changePageHandle(page) {
this.currentPage = page;
}
}
})
</script>
</body>
</html>

 

 

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: