2023.04.06 - vue组件中动态指定监听的值

发布时间 2023-04-06 17:08:18作者: Yehuda

业务场景:高拍仪给出的视频信息API回调里会不断返回图像数据。因为有主副摄像图像信息,并且两个图像信息会二选一展示在DOM容器里。所以就是二对一的关系。

// 主摄像数据
let priPic:string = '';
// 副摄像数据
let subPic:string = '';
// 展示在容器的数据 = 主摄像数据||副摄像数据;
let showPic:string = '';
// 镜头
let lens:'主' | '副'= '主';

我的思路是,通过监听lens指定镜头的状态后,将选择的镜头数据不断进行赋值操作给showPic

这就意味着,主摄像和副摄像的数据我只要监听一条就可以实现了,多出来的监听就是冗余代码。

所以我想到了 动态制定监听对象的方法,并作了实现,下面是核心代码:

<script>
  watcher() {
    // 如过有监听,就注销
    if (this.unwatch) this.unwatch();
    // 没有制定监听的变量名,直接return
    if (!this.choosewatch) return;
    //vm.$watch 返回一个取消观察函数,用来停止触发回调:
    this.unwatch = this.$watch(this.choosewatch, (val) => {
      //TODO Someting:callback
      this.watchdata = `${this.choosewatch}: ${val}`;
    });
  }
</script>

相关实现方法参考vm-watch

完整案例

<template>
	<div id="app">
		<label for="pet-select">Choose a watch:</label>

		<select v-model="choosewatch" name="pets" id="pet-select">
			<option value="">--Please choose an option--</option>
			<option v-for="watch in watchList" :value="watch" :key="watch">{{ watch }}</option>
		</select>
		<p>
			监听watch1
			<input type="text" v-model="watch1" />
			<button
				@click="
					() => {
						watch1 = '';
					}
				"
			>
				清空
			</button>
		</p>
		<p>
			监听watch2
			<input type="text" v-model="watch2" />
			<button
				@click="
					() => {
						watch2 = '';
					}
				"
			>
				清空
			</button>
		</p>
		<p>{{ watchdata || 'watch:暂无数据' }}</p>

		<p>{{ choosewatchdata || 'choosewatch:暂无选择' }}</p>
	</div>
</template>

<script>
export default {
	data() {
		return {
			// 选择监听的属性
			choosewatch: '',
			// 监听的属性
			watch1: '',
			watch2: '',
			watchList: ['watch1', 'watch2'],
			// 监听的属性值
			watchdata: '',
			// 选择监听的属性值
			choosewatchdata: ''
		};
	},
	methods: {
		watcher() {
			if (this.unwatch) this.unwatch();
			if (!this.choosewatch) return;
			this.unwatch = this.$watch(this.choosewatch, (val) => {
				this.watchdata = `${this.choosewatch}: ${val}`;
			});
		}
	},
	watch: {
		choosewatch(val) {
			this.choosewatchdata = `choosewatch: ${val}`;
			this.watcher();
		}
	}
};
</script>