2018-09-23
今天呢,学习的是组件的最后一个部分了,也就是非父子传值。首先,要了解生命周期
的 运行结构了。他呢,核心部分就是Mounted
,下面就是他的图解:


看完图解后,我们就来给核心部分举个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='app'>{{msg}}</div>
<script src='js/vue.js'></script>
<script>
new Vue({
el: '#app'
, data: {
msg: 'hello Vue'
}
, beforeCreate: function () {
alert('beforeCreate');
}
, created: function () {
alert('created')
}
, beforeMount: function () {
alert('beforeMount')
}
, mounted: function () {
alert('mounted')
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='app'>{{msg}}</div>
<script src='js/vue.js'></script>
<script>
new Vue({
el: '#app'
, data: {
msg: 'hello Vue'
}
, created: function () {
alert('created')
}
, mounted: function () {
alert('mounted')
}
, beforeCreate: function () {
alert('beforeCreate');
}
, beforeMount: function () {
alert('beforeMount')
}
})
</script>
</body>
</html>
效果图:
生命周期.png
因此,足以证明Mounted时才是在页面上正常显示的部分
。
前一篇我们谈过这个问题,在上一篇中我们是在main.js中定义空的bus
.大家如果自己写个简单的demo是可以实现的,但是在项目中如果有路由存在的话,则会失效!那么在有路由的情况下如何在非父子组件中传值呢?
也就是说 非父子组件之间的通信,必须要有公共的实例(可以是空的)
,才能使用 $emit
获取 $on
的数据参数,实现组件通信
那么接下来我们可以创建一个公共实例文件bus.js:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='app'>
<chat></chat>
</div>
<script src='js/vue.js'></script>
<script>
Vue.component('chat', {
template: `
<div>
<ul>
<li v-for="value in arr">{{value}}</li>
</ul>
<user @send='rcvMsg' userName='jack'></user>
<user @send='rcvMsg' userName='rose'></user>
</div>
`
, data: function () {
return {
arr: []
}
}
, methods: {
rcvMsg: function (txt) {
this.arr.push(txt)
}
}
})
Vue.component('user', {
props: ['userName']
, template: `
<div>
<label>{{userName}}</label>
<input type='text' v-model='inputVal'>
<button @click='sendMsg'>发送</button>
</div>
`
, data: function () {
return {
inputVal: ''
}
}
, methods: {
sendMsg: function () {
this.$emit('send', this.userName + ':' + this.inputVal)
}
}
})
new Vue({
el: '#app'
})
</script>
</body>
</html>
效果图:


下面就是非父子传值的实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id='app'>
<child></child>
<son></son>
</div>
<script src='js/vue.js'></script>
<script>
var bus = new Vue();
Vue.component('child', { //A
template: `
<div>
<h1>我是child组件</h1>
<button @click='sendMsg'>发送数据给son</button>
</div>
`
, data: function () {
return {
msg: 'hello vue'
}
}
, methods: {
sendMsg: function () {
bus.$emit('send', this.msg)
}
}
})
Vue.component('son', { //B
template: `
<div>
<h1>我是son组件</h1>
<a href=''>{{mess}}</a>
</div>
`
, data: function () {
return {
mess: ''
}
}
, mounted: function () {
bus.$on('send', msg => { //箭头函数
console.log(this);
this.mess = msg
})
}
})
new Vue({
el: '#app'
}) < /body> < /html>


这个例子的核心就是箭头函数
==>>
this 指向问题是入坑前端必须了解知识点,现在迎来了ES6时代,因为箭头函数的出现,所以感觉有必要对 this 问题梳理一下,遂有此文
在非箭头函数下, this 指向调用其所在函数的对象,而且是离谁近就是指向谁(此对于常规对象,原型链, getter & setter等都适用);构造函数下,this与被创建的新对象绑定;DOM事件,this指向触发事件的元素;内联事件分两种情况,bind绑定, call & apply 方法等, 容以下一步一步讨论。箭头函数也会穿插其中进行讨论。
全局环境下
在全局环境下,this 始终指向全局对象(window), 无论是否严格模式
;
函数直接调用。
函数上下文调用
普通函数内部的this分两种情况,严格模式和非严格模式。
非严格模式下,this 默认指向全局对象window。
而严格模式下, this为undefined
。
对象中的this
对象中的this
对象内部方法的this指向调用这些方法的对象,
函数的定义位置不影响其this指向,this指向只和调用函数的对象有关。
多层嵌套的对象,内部方法的this指向离被调用函数最近的对象(window也是对象,其内部对象调用方法的this指向内部对象, 而非window)。
箭头函数中的 this
由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值
,
所以 call() / apply() / bind() 方法对于箭头函数来说只是传入参数
,对它的 this 毫无影响。
考虑到 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。(可以忽略是否在严格模式下的影响)
因为箭头函数可以捕获其所在上下文的this值 所以
function Person() {
this.age = 0;
setInterval(() => {
// 回调里面的 `this` 变量就指向了期望的那个对象了
this.age++;
}, 3000);
}
var p = new Person();
以上代码可以得到我们所以希望的值,下图可以看到,在setTimeout中的this指向了构造函数新生成的对象,而普通函数指向了全局window对象。
组件今天就学到这里了,我们下期见!!!
网友评论