1.$options
概念:用于当前 Vue 实例的初始化选项。需要在选项中包含自定义 property 时会有用处:
用处示例:
①获取,调用data外定义的属性
<script>
export default {
data() {
return {
};
},
//在data外面定义的属性和方法通过$options可以获取和调用
name: "options_test",
age: 18,
testOptionsMethod() {
console.log("hello options");
},
created() {
console.log(this.$options.name); // options_test
console.log(this.$options.age); // 18
this.$options.testOptionsMethod(); // hello options
},
</script>
②复用过滤器filters中的方法
//常用于在表达式的尾部
<div>{{ text | filterText }}</div>
export default {
data() {
return {
text: 'hello'
}
},
filters: {
filterText: function (value) {
if (!value) return ''
return value
}
},
methods:{
getTextFn(){
let filterText = this.$options.filters.filterText
this.text = filterText('Hi')
},
},
}
③一键搞定之重置data中的数据
<script>
export default {
data() {
return {
// 表单
searchForm: {
input: ''
}
}
},
methods: {
retset() {
//重置某一个表单数据
this.searchForm = this.$options.data().searchForm;
//重置整个$data
this.$data = this.$options.data();
}
},
}
</script>
2.$parent
$parent:子组件获取父组件的数据、调用父组件的方法
父组件:
<template>
<div class="parent">
<h3>父组件</h3>
<div class="view-contain-box">
<child-one />
<child-two />
</div>
</div>
</template>
<script>
import ChildOne from '../components/child-one.vue'
import ChildTwo from '../components/child-two.vue'
export default {
components: {
ChildOne, ChildTwo
},
data () {
return {
text: 'hello'
}
},
methods: {
test () {
return 123
}
}
}
/************************************************/
子组件:
<template>
<div class="view-contain-one">
<button @click="getParentData">获取父组件数据并调用其内部方法</button>
</div>
</template>
<script>
export default {
data () {
return {
message: 123
}
},
methods: {
getParentData () {
const val = this.$parent.text
const val1 = this.$parent.test()
}
}
}
</script>
3.$children
$children:父组件获取子组件的数据、调用子组件的方法
<template>
<div class="parent">
<h3>父组件</h3>
<div @click="getChild1Value" class="operate">获取子组件1data里的数据并执行对应的方法</div>
<div @click="getChild2Value" class="operate">获取子组件2data里的数据并执行对应的方法</div>
<div class="view-contain-box">
<child-one />
<child-two />
</div>
</div>
</template>
<script>
import ChildOne from '../components/child-one.vue'
import ChildTwo from '../components/child-two.vue'
export default {
components: {
ChildOne, ChildTwo
},
data () {
return {
text: 'hello'
}
},
methods: {
getChild1Value () {
const val = this.$children[0].message || ''
const val1 = this.$children[0].test()
},
getChild2Value () {
const val = this.$children[1].message || ''
const val1 = this.$children[1].test()
}
}
}
</script>
4.$root
$root:获取当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。通过 $root,可以实现组件之间的跨级通信
父组件:
<template>
<div>
<div class="view-contain-box">
<child-one />
<child-two />
</div>
</div>
</template>
<script>
import ChildOne from '../components/child-one.vue'
import ChildTwo from '../components/child-two.vue'
export default {
components: {
ChildOne, ChildTwo
},
data () {
return {
text: 'hello'
}
},
methods: {
}
}
</script>
<style scoped>
.view-contain-box {
display: flex;
justify-content: center;
align-items: center;
}
</style>
/************************************************************************/
子组件1:
<template>
<div class="view-contain-one">
<p>我是子组件1</p>
<button @click="changeData">改变son2数据</button>
</div>
</template>
<script>
export default {
data () {
return {
message: 123
}
},
methods: {
// 点击按钮后需要改变Child2组件的数据。
// 我们可以通过在Child1组件的methods中使用$root属性来访问和操作Child2组件的数据:
changeData () {
this.$root.$emit('changeChild2Data', 456)
}
}
}
</script>
<style scoped>
.view-contain-one {
height: 300px;
width: 500px;
border: 1px solid #ccc;
}
</style>
/************************************************************************/
子组件2:
<template>
<div class="view-contain-two">
<p>我是子组件2</p>
<p>{{ child2Data }}</p>
</div>
</template>
<script>
export default {
data () {
return {
child2Data: 123
}
},
methods: {},
created () {
this.$root.$on('changeChild2Data', data => {
this.child2Data = data // 更新组件数据
})
}
}
</script>
<style scoped>
.view-contain-two {
height: 300px;
width: 500px;
border: 1px solid #ccc;
}
</style>
5.$refs
$refs:我们通常会将 refs 绑定在子组件上,从而获取子组件实例
<template>
<div class="parent">
<h3>父组件</h3>
<button @click="getChildData">获取子组件1data里的数据并执行methods对应的方法</button>
<div class="view-contain-box">
<child-one ref="childOne" />
</div>
</div>
</template>
<script>
import ChildOne from './components/child-one.vue'
export default {
components: {
ChildOne
},
data () {
return {
text: 'hello'
}
},
methods: {
getChildData () {
const message = this.$refs.childOne.message
console.log('message==', message)
const data = this.$refs.childOne.changeData()
console.log('data==', data)
// 需要注意下拾贝云框架中的refs嵌套问题
// this.$refs.DataTable.$refs.tableRef[0].clearSelection()
// const selection = this.$refs.DataTable.$refs.DataTable.getSelectionData();
const sonMessage = this.$refs.childOne.$refs.sonOne.message
console.log('sonMessage==', sonMessage)
// $refs引用将指向子组件的实例
// 在使用$refs时,需要确保在组件渲染完成后再去访问它们,例如在mounted生命周期钩子中,
// 这样可以确保ref注册的元素或组件已经被正确地创建和挂载,从而避免出现访问不到的情况
// if(this?.$refs?.DataTable) {}
}
}
}
</script>
6.$attrs和$listeners
父子组件的通信可以使用props和$emit的方式,但是如果进行父子组件和孙子组件的通讯使用props和$emit的话就比较复杂了,需要层层传递。
而$attrs和$listeners就减少了子组件的代码。它打通了父组件和孙组件之间的阻碍。
// 父组件
<template>
<div class="app">
<h3>我是父组件</h3>
<child-one :data1="data1" :data2="data2" :data3="data3" @fun1="fun1" @fun2="fun2"></child-one>
</div>
</template>
<script>
import childOne from './components/child-one.vue'
export default {
name: 'App',
components: {
childOne
},
data () {
return {
data1: '11',
data2: '22',
data3: '33'
}
},
methods: {
fun1 (val) {
console.log('通过子组件触发', val)
},
fun2 (val) {
console.log('通过子组件触发', val)
}
}
}
</script>
// 子组件
<template>
<div class="parent">
<h3>我是子组件</h3>
<Son v-bind="$attrs" v-on="$listeners"></Son>
</div>
</template>
<script>
import Son from './son-one.vue'
export default {
name: 'ChildOne',
props: {
data1: {
type: String,
default: ''
}
},
components: {
Son
},
created () {
console.log('this.$attrs==', this.$attrs) // data2: "数据2", data3: "数据3"
console.log('this.$listeners==', this.$listeners) // fun1, fun2
}
}
</script>
// 孙组件
<template>
<div class="son">
<h3>我是孙组件</h3>
这是爷爷的数据=={{data2}} <br>
这是自己的数据=={{message}}<br>
<button @click="toParent">传递数据给父组件</button>
</div>
</template>
<script>
export default {
name: 'Son',
props: {
// 接收父组件的数据
data2: {
type: String,
default: ''
},
data3: {
type: String,
default: ''
}
},
data () {
return {
message: 123
}
},
created () {
console.log(this.data2, this.data3, '$attrs')
},
methods: {
toParent () {
// 触发父组件的方法
this.$emit('fun1', '我是孙组件数据')
}
}
}
</script>
7.$slots
$slots:用来访问被插槽分发的内容。在使用渲染函数书写一个组件时,访问 vm.$slots 最有帮助。
// 父组件
<template>
<div class="parent">
<div class="view-contain-box">
<child-one :tableData="tableData">
<div>123</div>
<div>456</div>
<div slot="header">slot: header</div>
<div slot="footer">slot: footer</div>
</child-one>
</div>
</div>
</template>
<script>
import ChildOne from './components/child-one.vue'
export default {
components: {
ChildOne
},
data () {
return {
tableData: [
{ name: 111 },
{ name: 222 },
{ name: 333 }
]
}
},
methods: {
}
}
</script>
// 子组件
<script>
export default {
props: {
tableData: {
type: Array,
default () {
return []
}
}
},
data () {
return {
}
},
mounted () {
console.log('this.$slots==', this.$slots) // { default:[VNode, VNode], footer: [VNode], header:[VNode] }
console.log('this.$slots.default==', this.$slots.default) // undefind
},
render (h, vm) {
return (
<ul>
{
this.tableData.map(item => (
<li>{this.$slots.default || item.name}</li>
// <li>{this.$slots.header || item.name}</li>
))
}
</ul>
)
}
}
</script>
8.$scopedSlots
用来访问作用域插槽。vm.$scopedSlots 在使用渲染函数开发一个组件时特别有用。
// 父组件
<template>
<div class="parent">
<div class="view-contain-box">
<child-one :tableData="tableData">
<!-- 无论怎么修改,页面显示的列表项都是一样的,因为我们的default插槽是一样的。 -->
<!-- <span>{{tableData[0].name}} ===> vm.$slots的使用</span> -->
<span slot-scope="scope">{{scope.name}} ===> vm.scopedSlots的使用</span>
</child-one>
</div>
</div>
</template>
<script>
import ChildOne from './components/child-one.vue'
export default {
components: {
ChildOne
},
data () {
return {
tableData: [
{ name: 111 },
{ name: 222 },
{ name: 333 }
]
}
},
methods: {
}
}
</script>
// 子组件
<script>
export default {
props: {
tableData: {
type: Array,
default () {
return []
}
}
},
data () {
return {
}
},
mounted () {
// 作用域插槽允许子组件向父组件传递数据
console.log('this.$scopedSlots.default==', this.$scopedSlots.default)
},
render (h, vm) {
return (
<ul>
{
this.tableData.map(item => (
// <li>{this.$slots.default || item.name}</li>
<li>{this.$scopedSlots.default(item)}</li>
))
}
</ul>
)
}
}
</script>