1. vm.$refs
- 定义:被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例;
- 定义MyRef组件,分别展示引用指向DOM元素和组件两种情况
- 其中Inner组件就是即将用来被引用的组件
- 组件包括一个button按钮(DOM元素),一个引入的Inner组件,两个分贝绑定show1、show2事件的button按钮(主要用来点击展示获取的DOM元素和组件的结果)
<template>
<div class="box">
<h2>MyRef</h2>
<button ref="btn1" @click="doClick">按钮</button>
<!-- 原生事件绑定在根元素 -->
<Inner ref="comp1" @click.native="doClick"/>
<button @click="show1">展示效果(获取DOM元素)</button>
<button @click="show2">展示效果(获取组件)</button>
</div>
</template>
<script>
import Inner from './01_Inner.vue'
export default {
components:{
Inner
},
methods:{
show1(){
console.dir(this.$refs.btn1)
},
show2(){
console.dir(this.$refs.comp1)
console.dir(this.$refs.comp1.getData())
},
doClick(){
alert('点击了')
}
}
}
</script>
- 定义Inner组件
- 组件很简单,组件只包含一个getData()方法
<template>
<div>Inner</div>
</template>
<script>
export default {
methods:{
getData(){
return 999;
}
}
}
</script>
- 引用指向的就是 DOM 元素和引用就指向组件实例的结果展示
- 引用指向的就是 DOM 元素
- 引用就指向组件实例
补充知识点
在MyRef组件的<Inner ref="comp1" @click.native="doClick"/>代码,向组件绑定事件时,需要加上标识.native(比如click事件就是@click.native),就可以实现点击整个组件执行对应的事件代码;
2. watch/ computed监视属性
2.1 watch属性
- watch的监听变量必须是data中的;
- 无法监听数组值为基本数据类型时的值的变化;
- 可以设置属性deep: true,来实现深度监听;
<template>
<div class="box">
<h2>02Watch</h2>
<input v-model="name">
{{ name }}
<hr />
<input v-model="obj.name">
{{ obj.name }}
<hr />
{{ arr }}
<button @click="arr[1] = 99">改变数组元素</button>}
</div>
</template>
<script>
export default {
// 1.watch的监听变量必须是data中的
data() {
return {
name: 'Green',
obj: {
name: 'green'
},
// 无法监听数组值为基本数据类型时的值的变化
arr: [1, 2, 3]
}
},
methods: {
loadData() {
console.log('初始化数据...');
}
},
watch: {
name(newV, oldV) {
console.log('值:', newV, oldV)
},
obj: {
deep: true,
handler(newV, oldV) {
console.log('深度监视:', newV, oldV);
// 保证初始 调用一次 , 后续变更, 继续调用
this.loadData();
}
},
arr: {
deep: true,
handler(newV, oldV) {
console.log('深度监视2:', newV, oldV)
}
},
}
}
</script>
- 初始界面
- 当输入值变化时
这里要注意
- 点击改变数组元素按钮,页面数组值没有发生变化。证明无法监听数组值为基本数据类型时的值的变化;
- 如果对象中有__ob__属性,证明该元素实现了监视,没有证明该元素没有被监视;
- 可以使用与deep属性同级的immediate属性,设置为 true可以实现初始 调用一次的效果 , 而且后续变更, 继续调用;
补充知识,动态添加watch属性
点击按钮给指定input组件动态添加watch属性
<button @click="addWatch">动态加入watch</button>
<hr />
<input v-model="text">
{{ text }}
在methods中定义addWatch方法(注意定义方法的代码格式)
addWatch() {
this.$watch('text', function (newV) {
console.log('text变化了', newV)
});
}
2.2 computed监视属性
- 必须只有this.xxx相关的属性变更才会被监视,触发计算属性
<template>
<div class="box">
<h2>03_Computed</h2>
<input type="text" v-model="n1"> +
<input type="text" v-model="n2"> +
<input type="text" v-model="n3">
= {{ calc }}
</div>
</template>
computed: {
calc() {
return parseInt(this.n1)
+ parseInt(this.n2)
+ parseInt(this.n3)
}
}
效果如下图
- 使用computed属性实现多选框选择功能,具体功能描述:
- 全选: 选中的话,子项都选中,反之,都不选中,子项每次勾选或取消, 同步全选状态;
- 全选变更同步子项,子项变更计算有一项不为true,全选就不勾;
<template>
<div class="box">
<h2>03_Computed</h2>
<input type="checkbox" v-model="calcSelectAll">全选
<ul>
<li v-for="(item, i) in arr">
<input type="checkbox" v-model="item.checked"> {{ item }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
arr: [
{ checked: true, text: "小木" },
{ checked: true, text: "小明" },
{ checked: true, text: "小红" },
]
}
},
computed: {
calcSelectAll: {
// checkbox v-model勾选后触发的函数
set(val) {
console.log(val);
this.arr.forEach(ele => {
ele.checked = val;
});
},
get() {// 获取:全选的checkbox使用every
return this.arr.every(ele => {
return ele.checked
})
}
}
}
</script>
- 功能设计中用到every,总结some和every的用法:
- some宽泛有1个true就true;
- every找到一个flase就false;
- 计算属性可以存在 set/get:
- set : v-model="计算属性" , 参数就是用户的输入;
- get: v-model="计算属性" , 对元素的输出, [checked或者value属性等];
总结一下computed和methods的不同
- computed 优先走缓存, 多次渲染时使用 首先从计算一次, 后续从缓存中获取,直到数据改变触发再次执行计算;
- methods不存在缓存情况,每次调用都会重新计算;