[Vue psutil模块、echars的使用、与后端交互的三种方式、计算属性、Mixins、dom和diff算法、全局组件、局部组件、父传子、子传父、ref属性、事件总线]
[Vue psutil模块、echars的使用、与后端交互的三种方式、计算属性、Mixins、dom和diff算法、全局组件、局部组件、父传子、子传父、ref属性、事件总线]
psutil模块
简介
psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息.
它主要用来做系统监控,性能分析,进程管理。
它实现了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、ionice、iostat、iotop、uptime、pidof、tty、taskset、pmap等。目前支持32位和64位的Linux、Windows、OS X、FreeBSD和Sun Solaris等操作系统.
安装psutil模块
pip3 install psutil
获取系统基本信息的使用
CPU信息
cpu_times() 获取CPU完整信息
print(psutil.cpu_times())
# scputimes(user=89295.53125, system=77180.578125, idle=649627.59375, interrupt=4747.625, dpc=2285.203125)
获取单个数据,如用户的cpu时
print(psutil.cpu_times().user)
# 89388.45312499999
cpu_count() 获取cpu逻辑和物理个数,默认logical值为True
#CPU逻辑个数
print(psutil.cpu_count())
# 4
#CPU物理个数
print(psutil.cpu_count(logical=False))
# 2
cpu_percent() 获取cpu的使用率
print(psutil.cpu_percent(1,percpu=True))
# [20.0, 18.5, 12.3, 13.8]
print(psutil.cpu_percent(percpu=True))
# [0.0, 0.0, 0.0, 0.0]
print(psutil.cpu_percent(1))
# 33.7
print(psutil.cpu_percent(percpu=True))
# [36.4, 29.2, 35.4, 33.8]
内存信息
virtual_memory() 获取内存信息,swap使用就用swap_memory()方法
print(psutil.virtual_memory())
# svmem(total=8425320448, available=2924511232, percent=65.3, used=5500809216, free=2924511232)
print(psutil.swap_memory())
# sswap(total=14599335936, used=7110447104, free=7488888832, percent=48.7, sin=0, sout=0)
percent表示实际已经使用的内存占比,即(1047543808-717537280)/1047543808*100% 。
available表示还可以使用的内存。
磁盘信息
磁盘信息主要有两部分,一个是磁盘的利用率,一个是io,他们分别可以通过disk_usage和disk_io_counters方法获取。
如下先获取分区信息,然后看下根分区的使用情况:
print(psutil.disk_partitions())
# [sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed', maxfile=255, maxpath=260), sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed', maxfile=255, maxpath=260)]
print(psutil.disk_usage('/'))
# sdiskusage(total=170147328000, used=75902009344, free=94245318656, percent=44.6)
默认disk_io_counters方法获取的是硬盘总的io数和读写信息,如果需要获取单个分区的io和读写信息加上"perdisk=True"参数。
print(psutil.disk_io_counters())
# sdiskio(read_count=1843048, write_count=2572395, read_bytes=58439621120, write_bytes=95755351040, read_time=1508, write_time=1301)
print(psutil.disk_io_counters(perdisk=True))
# {'PhysicalDrive0': sdiskio(read_count=1843051, write_count=2572627, read_bytes=58439633408, write_bytes=95769238528, read_time=1508, write_time=1301)}
网络信息
网络io和磁盘io使用方法差不多,主要使用net_io_counters方法,如果需要获取单个网卡的io信息,加上pernic=True参数。
#获取网络总的io情况
print(psutil.net_io_counters())
# snetio(bytes_sent=4323296995, bytes_recv=85900285374, packets_sent=20948831, packets_recv=744999, errin=0, errout=0, dropin=0, dropout=0)
#获取网卡的io情况
print(psutil.net_io_counters(pernic=True))
# {'WLAN': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), '本地连接* 1': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), '本地连接* 2': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), '以太网': snetio(bytes_sent=4323296251, bytes_recv=85900304865, packets_sent=20947000, packets_recv=745126, errin=0, errout=0, dropin=0, dropout=0), 'VMware Network Adapter VMnet1': snetio(bytes_sent=588, bytes_recv=8, packets_sent=588, packets_recv=8, errin=0, errout=0, dropin=0, dropout=0), 'VMware Network Adapter VMnet8': snetio(bytes_sent=1275, bytes_recv=8, packets_sent=1275, packets_recv=8, errin=0, errout=0, dropin=0, dropout=0), 'Loopback Pseudo-Interface 1': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0)}
其他系统信息
获取开机时间
# 以linux时间格式返回,可以使用时间戳转换
print(psutil.boot_time())
# 1625977244.9221938
# 转换成自然时间格式
print(datetime.datetime.fromtimestamp(psutil.boot_time ()).strftime("%Y-%m-%d %H: %M: %S"))
# 2021-07-11 12: 20: 44
查看系统全部进程
print(psutil.pids())
# [0, 4, 100, 108, 120, 392, 532, 604, 720, 792, 812, 892, 928, 956, 1016, 1056, 1120, 1168, 1236, 1268, 1296, 1412, 1448, 1576, 1604, 1632, 1724, 1736, 1764, 1788, 1800, 1848, 1884, 1908, 1972, 2024, 2036, 2044, 2076, 2100, 2172, 2236, 2240, 2268, 2316, 2328, 2428, 2468, 2508, 2560, 2588, 2592, 2604, 2620, 2628, 2716, 2828, 2836, 2956, 2980, 2992, 3024, 3088, 3156, 3180, 3192, 3200, 3204, 3216, 3240, 3320, 3396, 3404, 3452, 3468, 3548, 3624, 3672, 3832, 3840, 3852, 3860, 3872, 3880, 3896, 3920, 3972, 4004, 4024, 4032, 4052, 4104, 4112, 4272, 4560, 4608, 4616, 4792, 4900, 4924, 5232, 5368, 5628, 5648, 5700, 6088, 6096, 6148, 6236, 6308, 6312, 6336, 6644, 6772, 6928, 7296, 7340, 7364, 7376, 7632, 7732, 7984, 7996, 8020, 8044, 8384, 8720, 8764, 8912, 9008, 9068, 9152, 9272, 9344, 9384, 9444, 9504, 9512, 9520, 9708, 9716, 9880, 10012, 10432, 10480, 10640, 10712, 10816, 10980, 11024, 11088, 11484, 11496, 11512, 11580, 11604, 11684, 11720, 11880, 11912, 11936, 12100, 12272, 12280, 12736, 13108, 13280, 13436, 13480, 13488, 13548, 13556, 13632, 13652, 13728, 13836, 14188, 14396, 14412, 14468, 14480, 14740, 15000, 15032]
查看单个进程
p = psutil.Process(16031)
p.name() #进程名
p.exe() #进程的bin路径
p.cwd() #进程的工作目录绝对路径
p.status() #进程状态
p.create_time() #进程创建时间
p.uids() #进程uid信息
p.gids() #进程的gid信息
p.cpu_times() #进程的cpu时间信息,包括user,system两个cpu信息
p.cpu_affinity() #get进程cpu亲和度,如果要设置cpu亲和度,将cpu号作为参考就好
p.memory_percent() #进程内存利用率
p.memory_info() #进程内存rss,vms信息
p.io_counters() #进程的IO信息,包括读写IO数字及参数
p.connectios() #返回进程列表
p.num_threads() #进程开启的线程数
听过psutil的Popen方法启动应用程序,可以跟踪程序的相关信息
from subprocess import PIPE
p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"],stdout=PIPE)
p.name()
p.username()
查看系统硬件脚本
#!/usr/bin/env python
#coding:utf-8
import psutil
import datetime
import time
# 当前时间
now_time = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
print(now_time)
# 查看cpu物理个数的信息
print(u"物理CPU个数: %s" % psutil.cpu_count(logical=False))
#CPU的使用率
cpu = (str(psutil.cpu_percent(1))) + '%'
print(u"cup使用率: %s" % cpu)
#查看内存信息,剩余内存.free 总共.total
#round()函数方法为返回浮点数x的四舍五入值。
free = str(round(psutil.virtual_memory().free / (1024.0 * 1024.0 * 1024.0), 2))
total = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0 * 1024.0), 2))
memory = int(psutil.virtual_memory().total - psutil.virtual_memory().free) / float(psutil.virtual_memory().total)
print(u"物理内存: %s G" % total)
print(u"剩余物理内存: %s G" % free)
print(u"物理内存使用率: %s %%" % int(memory * 100))
# 系统启动时间
print(u"系统启动时间: %s" % datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S"))
# 系统用户
users_count = len(psutil.users())
#
# >>> for u in psutil.users():
# ... print(u)
# ...
# suser(name='root', terminal='pts/0', host='61.135.18.162', started=1505483904.0)
# suser(name='root', terminal='pts/5', host='61.135.18.162', started=1505469056.0)
# >>> u.name
# 'root'
# >>> u.terminal
# 'pts/5'
# >>> u.host
# '61.135.18.162'
# >>> u.started
# 1505469056.0
# >>>
users_list = ",".join([u.name for u in psutil.users()])
print(u"当前有%s个用户,分别是 %s" % (users_count, users_list))
#网卡,可以得到网卡属性,连接数,当前流量等信息
net = psutil.net_io_counters()
bytes_sent = '{0:.2f} Mb'.format(net.bytes_recv / 1024 / 1024)
bytes_rcvd = '{0:.2f} Mb'.format(net.bytes_sent / 1024 / 1024)
print(u"网卡接收流量 %s 网卡发送流量 %s" % (bytes_rcvd, bytes_sent))
io = psutil.disk_partitions()
# print(io)
# print("io[-1]为",io[-1])
#del io[-1]
print('-----------------------------磁盘信息---------------------------------------')
print("系统磁盘信息:" + str(io))
for i in io:
o = psutil.disk_usage(i.device)
print("总容量:" + str(int(o.total / (1024.0 * 1024.0 * 1024.0))) + "G")
print("已用容量:" + str(int(o.used / (1024.0 * 1024.0 * 1024.0))) + "G")
print("可用容量:" + str(int(o.free / (1024.0 * 1024.0 * 1024.0))) + "G")
print('-----------------------------进程信息-------------------------------------')
# 查看系统全部进程
for pnum in psutil.pids():
p = psutil.Process(pnum)
print(u"进程名 %-20s 内存利用率 %-18s 进程状态 %-10s 创建时间 %-10s " \
% (p.name(), p.memory_percent(), p.status(), p.create_time()))
echars的使用
详情点击官网查看 ←
导入cdn或者文件
# cnd
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.1.2/echarts.min.js"></script>
# 或者文件
<script src="./js/echarts.min.js"></script>
使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="./js/vue.js"></script>
<script src="./js/echarts.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.1.2/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 100%;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 展示'
},
tooltip: {},
legend: {
data: ['智商']
},
xAxis: {
data: ["刘鹏飞", "刘鹏飞啊飞", "老胡", "火神", "老郑", "左大",'颜值担当','刘浩杰']
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [112, 105, 110, 100, 102, 103,130,125]
}]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>

与后端交互的几种方式
jquery的ajax(不推荐使用)
fetch(不是所有浏览器都支持,谷歌浏览器支持)
axios(基本都是用它)
jquery-ajax 与后端交互
前端
<div id="test">
<button @click="onefunc">按钮一个</button>
</div>
<script>
var vm = new Vue({
el: '#test',
data: {
shuju: 'asdf',
},
methods: {
onefunc() {
$.ajax({
url: 'http://127.0.0.1:5000/',
type: 'get',
dataType: 'json',# 不写这个后端返回的json格式不会自动反序列化,也就是字符串
success: args => {
console.log(args)
console.log(typeof args)
let args = JSON.parse(args) # 也可以前端手动反序列化
}
})
}
}
})
</script>
后端
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def index():
with open('./data.json','r',encoding='utf-8') as f:
res=f.read()
# res = {
# "liupengfei": {"name": "liupengfei", "age": 20},
# "liuhaojie": {"name": "liuhaojie", "age": 21},
# "laohu": {"name": "laohu", "age": 22},
# }
# 响应头中加入key-value:Access-Control-Allow-Origin
# 允许跨域,任意的前端都可以向我发送请求
resp = make_response(res)
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp
if __name__ == '__main__':
app.run()


fetch:(原生的)与后端交互
<script>
var vm = new Vue({
el: '#test',
data: {
shuju: 'asdf',
},
methods: {
onefunc() {
fetch('http://127.0.0.1:5000/').then(res => res.json()).then(res => {
console.log(typeof res)
console.log(res)
})
}
}
})
</script>
如果没有.then(res => res.json())返回的是个Response


axios与后端交互(用的最多)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
# 需要导入cdn 或者下载到本地导入
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<div v-for="data in data_list">
<h3>{{data.name}}</h3>
<img :src="data.poster" alt="">
<h5>导演:{{data.director}}</h5>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
data_list: []
},
methods: {
get_data() {
//发送请求
// axios.get('http://127.0.0.1:5000/').then(res => {
// // res.data才是真正后端返回的响应体中的内容
// console.log(res.status)
// this.data_list = res.data.data.films
//
// })
axios({
url: 'http://127.0.0.1:5000/',
methods: 'get',
}).then(res => {
// res.data才是真正后端返回的响应体中的内容
console.log(res.status)
this.data_list = res.data.data.films
})
}
},
mounted() {
this.get_data()
},
})
</script>
</html>

计算属性
计算属性的特点:只要返回的结果没有发生变化,那么计算属性就只会被执行一次
计算属性的应用场景:由于计算属性会将返回的结果缓存起来,所以如果返回的数据不经常发生变化
那么使用计算属性的性能就会比使用函数的性能高
计算属性优点 computed :{}
1、在同一个页面中使用多次计算属性,不会多次执行
2、不需要加括号,直接使用
<div id="app01">
<p>自动运行的方法 {{funcone()}} </p>
<p>自动运行的方法 {{funcone()}} </p>
<p>自动运行的属性 {{functwo}} </p>
<p>自动运行的属性 {{functwo}} </p>
</div>
<script>
var vm = new Vue({
el: '#app01',
data: {
func: '方法',
shuxing: '属性',
},
methods: {
funcone() {
console.log('执行了方法,打印:', this.func)
}
},
computed: {
functwo() {
console.log('执行了计算属性,打印:', this.shuxing)
return this.shuxing
}
}
})
</script>
只要有变动,方法就都会每个执行一遍,而计算属性,只会执行一次方法。

计算属性几个问题
页面渲染问题
页面当开始渲染的时候,应该是先找data里面的属性,然后找 computed 计算属性,最后找methods,找不到嗝屁。
事件触发问题
<p @click="funcone">点我</p>
funcone 会去找方法,如果只写计算属性方法,只会刷新页面的时候执行一次计算属性里面的方法,后面点击也不会执行计算属性方法,方法 funcone 作为属性的时候只能找 methods 里面的方法。
<p @click="funcone()">点我</p>
这种情况下,如果只写了计算机属性方法,执行完计算机属性方法之后,会一直报错。
当然,如果写了方法,事件触发的对应函数带不带括号无关紧要。
插值语法放方法
只写了方法:
<p>自动运行的方法 {{funcone()}} </p>
页面 :自动运行的方法
<p>自动运行的方法 {{funcone}} </p>
页面显示 :自动运行的方法 function () { [native code] }
只写了计算属性:
<p>自动运行的方法 {{funcone}} </p>
<p>自动运行的方法 {{funcone()}} </p>
页面 : 空白
插值语法放入方法,带上括号直接刷新页面的时候就已经执行,会去方法里面找,在这之前会经过计算属性,然后触发计算属性的方法, 再报错 ,因为找不到methods里面的方法。

关于方法和计算属性需要注意的一个点
不要 funcone 计算属性里面的方法和 methods 里面的方法一样。
# 因为会报错
Mixins
混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。
混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
虚拟dom和diff算法
Vue2.0 v-for 中 :key 有什么用呢?
其实呢不只是vue,react中在执行列表渲染时也会要求给每个组件添加key这个属性。
key简单点来说就是唯一标识,就像ID一样唯一性
要知道,vue和react都实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法。
只做同层级的对比
按照key值比较,出现新的key就插入
通组件对比
虚拟DOM的diff算法
参考 :https://segmentfault.com/a/1190000020170310


组件介绍,全局组件,局部组件
组件的作用
扩展 HTML 元素,封装可重用的代码,目的是复用
-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
-组件把js,css,html放到一起,有逻辑,有样式,有html
组件分类:局部组件和全局组件
组件注册方式
1、全局组件
Vue.component('myall', {
})
2、局部组件
Vue.component('myheader', {
components:{
child:{}
}
})
全局组件
<div id="app01">
<mydiv></mydiv>
</div>
<script>
# 没有代码提示,语法检查,目前这么用
# 后面会使用webpack打包,直接定义成 xx.vue文件,通过webpack打包
# 定义一个全局组件
# 组件可以有data,methods,computed....,但是data 必须是一个函数,其他和原来Vue使用一样
Vue.component('mydiv', {
template: `
<div>
<h1 style="font-size: 80px;background-color: deepskyblue">我是全局组件</h1>
<button @click="func">这是一个弹出按钮</button>
</div>
`,
data() {
return {
name: '颜值担当'
}
},
methods: {
func() {
alert('弹出了一个框')
}
}
})
var vm = new Vue({
el: '#app01',
data: {
func: '方法',
shuxing: '属性',
},
})
</script>

局部组件
<div id="app01">
<mydiv></mydiv>
</div>
<script>
Vue.component('mydiv', {
# 如果有局部组件全局组件使用,需要在template注册局部组件标签。
template: `
<div>
<h1 style="font-size: 80px;background-color: deepskyblue">我是全局组件</h1>
<button @click="func">这是局部组件召唤按钮</button>
<child v-show="isshowa"></child>
</div>
`,
data() {
return {
name: '颜值担当',
isshowa:false
}
},
methods: {
func() {
this.isshowa = !this.isshowa
}
},
components: {
child: {
template: `
<div>
<p>我只是个简简单单的{{name}}罢了</p>
<p>我只是个简简单单的{{name}}罢了</p>
</div>
`,
data() {
return {name: '局部组件'}
}
}
}
})
var vm = new Vue({
el: '#app01',
data: {
func: '方法',
shuxing: '属性',
},
})
</script>

组件通信
1、父子组件传值 (props down, events up)
2、父传子之属性验证props:{name:Number}Number,String,Boolean,Array,Object,Function,null(不限制类型)
3、事件机制a.使用 $on(eventName) 监听事件b.使用 $emit(eventName) 触发事件
4、Ref<input ref="mytext"/> this.$refs.mytext
5、事件总线var bus = new Vue();* mounted生命周期中进行监听
组件通信之父传子(通过自定义属性的方式)
父中:<myheader :myname="name" :myshow="false"></myheader>
子中:props:['myname','myshow']
# 子中:props:{myname:类型,myshow:类型]}
示例
<div id="app">
<myheader :Vm_name="liuhaojie"></myheader>
</div>
</body>
<script>
Vue.component('myheader', {
template: `
<div>
<h1 style="background-color: greenyellow">我是全局组件:{{Vm_name}}</h1>
</div>
`,
props:['Vm_name',]
// 属性验证
// props:{
// myname:String,
// myshow:Boolean
// }
})
var vm = new Vue({
el: '#app',
data: {
liuhaojie:'颜值担当'
},
})
</script>

示例
<div id="app">
<myheader :Vm_name="liuhaojie"></myheader>
</div>
</body>
<script>
Vue.component('myheader', {
template: `
<div>
<h1 style="background-color: greenyellow">我是全局组件:{{Vm_name}}</h1>
<erzi :inner="Vm_name"></erzi>
</div>
`,
props: ['Vm_name',],
components: {
erzi: {
template: `
<div>
<span>这是局部的{{ inner }}</span>
</div>
`,
props: ['inner',],
}
}
})
var vm = new Vue({
el: '#app',
data: {
liuhaojie: '颜值担当'
},
})
</script>

属性验证
对传过来的属性进行类型的验证,验证不成功会抛异常报错,但是一般情况下还是可以渲染出来。
<div id="app">
<myheader :Vm_name="liuhaojie"></myheader>
</div>
</body>
<script>
Vue.component('myheader', {
template: `
<div>
<h1 style="background-color: greenyellow">我是全局组件:{{Vm_name}}</h1>
<erzi :inner="Vm_name"></erzi>
</div>
`,
props: ['Vm_name',],
components: {
erzi: {
template: `
<div>
<span>这是局部的{{ inner }}</span>
</div>
`,
// props: ['inner',],
props:{
inner:String
}
}
}
})
var vm = new Vue({
el: '#app',
data: {
liuhaojie: 1
},
})

组件通信之子传父(通过自定义事件)
示例
<div id="test">
<myall @onefunc="funcone"></myall>
</div>
<script>
Vue.component('myall', {
template: `
<div>
<p>{{innerdata}}</p>
<button @click="buttonfunc">这是一个按钮啊</button>
</div>
`,
data(){
return {innerdata:'这是全局的组件'}
},
methods: {
buttonfunc(){
// 触发父组件中onefunc这个自定义事件对应的函数执行
this.$emit('onefunc',this.innerdata)
}
}
})
var vm = new Vue({
el: '#test',
methods:{
funcone(args){
console.log(args)
}
}
})
</script>

ref属性
ref放在标签上,拿到的是原生节点
ref放在组件上,拿到的是组件对象
通过这种方式实现子传父(this.$refs.mychild.text)
通过这种方式实现父传子(调用子组件方法传参数)
示例
------------------------------------ ref 属性展示 -------------------------------------
<div id="test">
<span ref="gen">这是根组件</span>
<myall ref="all"></myall>
<button @click="functwo">按钮</button>
</div>
<script>
Vue.component('myall', {
template: `
<div>
<p>{{innerdata}}</p>
</div>
`,
data(){
return {innerdata:'这是全局的组件'}
},
})
var vm = new Vue({
el: '#test',
methods:{
functwo(){
console.log(this.$refs)
}
}
})
</script>

示例
------ ref 也可以拿到组件对象的属性和方法 ----------------------------------------------
<div id="test">
<myall ref="all"></myall>
<button @click="functwo">按钮</button>
<span ref="gen">这是根组件拿到的全局组件数据:{{vmdata}}</span>
</div>
<script>
Vue.component('myall', {
template: `
<div>
<p>局部组件打印:{{innerdata}}</p>
</div>
`,
data() {
return {innerdata: '这是全局的组件的数据',}
},
methods:{
innerfunc(){
return this.innerdata
}
}
})
var vm = new Vue({
el: '#test',
data: {
vmdata: ''
},
methods: {
functwo() {
this.vmdata = this.$refs.all.innerfunc()
}
}
})
</script>

事件总线(不同层级的不同组件通信)
注意事项!!!
1、需要再 new 一个 Vue 对象 作为中央事件总线
2、bus.$emit()写在methods方法里面,但是 bus.$on()一定要写在 mounted()
3、根Vue需要放在组件最下面,否则异常
<div id="test">
<myallone></myallone>
<myalltwo></myalltwo>
</div>
<script>
// 借助事件总线,实现跨组件通信
// 定义一个事件总线
var bus = new Vue()
Vue.component('myallone', {
template: `
<div>
<p>全局组件one打印:{{innerdata}}</p>
<button @click="innerfuncone"> 全局组件one给two发信息 </button>
</div>
`,
data() {
return {innerdata: '这是全局的组件 1 的数据', msg1: '我是组件1啊'}
},
methods: {
innerfuncone() {
bus.$emit('ceshi', this.msg1)
}
}
})
Vue.component('myalltwo', {
template: `
<div>
<p>全局组件two打印:{{innerdata}}</p>
<p>全局组件two收到one的信息:{{msg2}}</p>
</div>
`,
data() {
return {innerdata: '这是全局的组件 2 的数据', msg2: ''}
},
mounted() {
bus.$on('ceshi', msg1 => {
this.msg2 = msg1
})
}
})
# 一定要放在最下面
var vm = new Vue({
el: '#test',
data: {
vmdata: ''
},
methods: {}
})
</script>


浙公网安备 33010602011771号