一.$ref获取子组件的实例化对象
代码:
App.Vue
<template>
<div class="">
<One ref="xxx"></One>
</div>
</template>
<script>
import One from "@/components/One.vue";
export default {
name: "",
components: {
One,
},
mounted() {
console.log(this.$refs.xxx);
},
methods: {},
};
</script>
<style scoped></style>
One.vue
<template>
<div class="">
<h1>张123</h1>
</div>
</template>
<script>
export default {
data() {
return {
name: "不分手的恋爱",
};
},
name: "",
methods: {
fn() {
},
},
};
</script>
<style scoped></style>
打印之后的结果:
调用变量:
mounted() {
console.log(this.$refs.xxx.name);
},
调用函数:
mounted() {
console.log(this.$refs.xxx.fn());
},
如果是在一个标签上呢?
代码:
<template>
<div class="">
<h1 ref="xxx">没有你以后我灵魂失控</h1>
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$refs.xxx);
},
name: "",
methods: {},
};
</script>
<style scoped></style>
获取到的是一个真实Dom:
总结:
1.如果在组件上加ref获取到是这个组件的实例化对象,可以使用组件的变量和方法
2.如果加在一个标签上获取的是这个标签的真实Dom
二.$parent获取父组件的实例化对象
父组件:
<template>
<div class="">
<One></One>
<h1>{
{ name }}</h1>
</div>
</template>
<script>
import One from "@/components/One.vue";
export default {
data() {
return {
name: "你要的全拿走",
};
},
components: {
One,
},
name: "",
methods: {},
};
</script>
<style scoped></style>
子组件:
<template>
<div class="">
<button @click="fn">获取父组件的实力对象</button>
</div>
</template>
<script>
export default {
name: "",
methods: {
fn() {
console.log(this.$parent.name);
},
},
};
</script>
<style scoped></style>
打印的结果:
说明已经获取到了。
三.在开发中的应用
如:
<template>
<div class="setting">
<el-card>
<el-tabs>
<el-tab-pane label="角色管理" lazy>
<el-button
type="primary"
size="small"
@click="addClick"
>+新增角色</el-button>
<el-table :data="list">
<!-- 数据绑定data -->
<!-- label表示标题 -->
<!-- prop='对应的字段名' -->
<!-- 自定义列 -->
<!-- <template>
<div v-slot="{$index:索引}:row:当前行数据">
</div>
</template> -->
<el-table-column label="序号" type="index">
<template v-slot="{ $index }">
<div>
{
{ (page.page - 1) * page.pagesize + $index + 1 }}
</div>
</template>
</el-table-column>
<el-table-column label="角色名" prop="name" />
<el-table-column label="描述" prop="description" />
<el-table-column label="操作">
<!-- row当前行的数据 -->
<template v-slot="{ row }">
<div>
<el-button type="text">分配权限</el-button>
<!-- 1.打开弹窗 -->
<!-- 2.回显数据 -->
<!-- 当前行数据 包含所有数据 只需要传过去-->
<!-- 3.定义变量区分场景 -->
<!-- 1.标题 -->
<!-- 2.表单验证 -->
<!-- 3.分场景调用接口 -->
<!-- 定义编辑api -->
<!-- 导入 -->
<el-button type="text" @click="edit(row)">修改</el-button>
<el-button type="text" @click="del(row)">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="page">
<!-- current-page当前页 -->
<!-- page-sizes 页容量 默认页容量一定要在页容量中存在-->
<!-- layout布局 -->
<el-pagination
style="text-align: right"
:current-page="page.page"
:page-sizes="[1, 10, 100, 200, 300, 400]"
:page-size="page.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-tab-pane>
<el-tab-pane label="公司信息" lazy>
<Info />
</el-tab-pane>
</el-tabs>
</el-card>
<Add ref="add" />
</div>
</template>
<script>
import { sysRole, sysRoleDelete } from '@/api/setting.js'
import Add from './components/add.vue'
export default {
name: '',
components: {
Info: () => import('./components/info.vue'),
Add
},
data() {
return {
list: [],
page: {
page: 1, // 默认页码
pagesize: 10, // 每页条数
total: 100
}
}
},
created() {
this.getData()
},
methods: {
// 页码改变
handleSizeChange(size) {
this.page.pagesize = size
// 页容量回到第一页
this.page.page = 1
this.getData()
console.log(size)
},
// 页容量改变
handleCurrentChange(page) {
this.page.page = page
this.getData()
console.log(page)
},
// 获取列表
async getData() {
const res = await sysRole(this.page)
// 存储分页总数
this.page.total = res.data.total
// 存储列表数据
this.list = res.data.rows
console.log(res.data.rows, '返回的数据')
},
// 新增按钮的点击
addClick() {
// 打开弹窗
this.$refs.add.isShow = true
this.$refs.add.mode = 'add'
},
// 删除事件
del(row) {
console.log(row)
this.$confirm('你确定要删除该角吗?', '提示')
.then(async() => {
await sysRoleDelete(row.id)
// 提示信息
this.$message.success('删除成功')
// 刷新列表数据回到第一页
this.handleCurrentChange(1)
})
.catch(() => {})
},
// 修改
edit(row) {
this.$refs.add.isShow = true
// 回显数据
this.$refs.add.form = JSON.parse(JSON.stringify(row))
this.$refs.add.mode = 'edit'
}
}
}
</script>
<style scoped></style>
在这里通过获取到子组件的实例化对象,来控制弹窗的显示和隐藏。
Add.vue
<template>
<div class="">
<el-dialog
:visible="isShow"
:title="{ add: '新增角色', edit: '编辑角色' }[mode]"
@close="closeEvent"
>
<el-form ref="form" label-width="100px" :rules="rules" :model="form">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="角色描述" prop="description">
<el-input v-model="form.description" />
</el-form-item>
</el-form>
<template>
<div style="text-align: center">
<el-button @click="closeEvent">取消</el-button>
<el-button type="primary" @click="submit">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import { sysRolePost, sysRolePut } from '@/api/setting'
export default {
name: '',
model: {
prop: 'isShow'
},
// props: {
// isShow: {
// type: Boolean,
// default: false
// }
// },
data() {
return {
mode: 'add', // 默认 新增 edit 编辑
isShow: false,
form: {
name: '', // 角色名称
description: '' // 角色描述
},
rules: {
name: [{ required: true, message: '必填', trigger: 'blur' }],
description: [{ required: true, message: '必填', trigger: 'blur' }]
}
}
},
methods: {
closeEvent() {
// 子传递父值,将其变为false
this.isShow = false
// 重置表单
this.$refs.form.resetFields
this.form = {
name: '',
description: ' '
}
},
// 确定按钮
submit() {
this.$refs.form.validate(async(result) => {
if (result) {
if (this.mode === 'add') {
await sysRolePost(this.form)
// 关闭页面
this.$message.success('新增成功')
} else {
await sysRolePut(this.form)
this.$message.success('编辑成功')
}
this.closeEvent()
// 刷新父级列表的数据
// 组件的ref拿到的是add组件的实例对象
}
})
}
}
}
</script>
<style scoped></style>
四.总结
$ref:
1.如果是标签,则获取到的是DOM
2.如果是在组件上,则获取的是组件的实例化对象。
$parent
能够获取父组件的实例化对象(最近的父组件)。