ul列表事件($(this).data('value') 这个是什么意思?)

<ul class="am-dropdown-content " id="changeLanguage">
  <li data-value="zh-CN"><a >简体中文</a></li><--!data-value是自定义属性-->
  <li data-value="zh-TW"><a >繁體中文</a></li>
  <li data-value="en"><a >English</a></li>
</ul>
$("#changeLanguage").on('click', "li", function() {

        var language = $(this).data("value");//获取data-value的值
        console.log(language)
        getCookie("userLanguage", language, {
            expires : 30,
            path : '/'
        });
        location.reload();
        console.log(document.cookie)
    })

$(this).data('value')这个是什么意思?

获取元素data-value属性的值,等价于$(this).attr('data-value')

 

转载于:https://www.cnblogs.com/package-java/p/11598210.html

<think>我们面对的问题是在Vue项目中如何监听Map对象的变化,并在Map更新时将其value)提取出来组成数组传递给子组件。由于Vue2的响应式系统对ES6的Map支持有限,直接修改Map内容(如使用set、delete等方法)不会触发视图更新。因此,我们需要采取一些策略来实现监听。 ### 解决方案思路 1. **使用Vue的响应式原理扩展**:通过自定义方式让Map的变化可被Vue追踪。 2. **利用计算属性**:将Map的转换为数组,并确保在Map更新时计算属性重新计算。 3. **添加版本号触发更新**:通过一个额外的响应式数据(如版本号)来手动触发更新。 ### 具体实现步骤 #### 1. 定义响应式Map和版本号 在Vue实例或Vuex状态中,我们使用一个Map来存储数据,并添加一个版本号(作为响应式属性)来强制更新。 ```javascript data() { return { // 存储设备位置的Map deviceMap: new Map(), // 用于强制更新的版本号 mapVersion: 0 } } ``` #### 2. 更新Map时改变版本号 每次更新Map(添加、删除、修改)时,我们手动增加`mapVersion`,这样依赖`mapVersion`的计算属性就会重新计算。 ```javascript methods: { updateDeviceMap(deviceId, position) { // 更新Map this.deviceMap.set(deviceId, position); // 增加版本号,触发计算属性更新 this.mapVersion++; } } ``` #### 3. 创建计算属性将Map的转换为数组 使用计算属性将Map的(即每个设备的位置对象)提取出来组成数组。 ```javascript computed: { devicePositionsArray() { // 依赖mapVersion,确保Map更新时重新计算 this.mapVersion; return Array.from(this.deviceMap.values()); } } ``` #### 4. 将数组传递给子组件 在模板中,将计算属性`devicePositionsArray`传递给子组件。 ```html <template> <child-component :device-positions="devicePositionsArray" /> </template> ``` ### 完整示例代码 ```vue <template> <div> <device-list :positions="devicePositionsArray" /> </div> </template> <script> import DeviceList from './DeviceList.vue'; export default { components: { DeviceList }, data() { return { deviceMap: new Map(), // 存储设备位置信息 mapVersion: 0 // 用于强制更新 }; }, computed: { devicePositionsArray() { // 依赖mapVersion,当mapVersion变化时,重新计算 this.mapVersion; return Array.from(this.deviceMap.values()); } }, methods: { // 更新Map的方法 updateDeviceMap(deviceId, position) { this.deviceMap.set(deviceId, position); this.mapVersion++; }, // 模拟MQTT消息处理 initMqtt() { // 假设这是MQTT消息回调 mqttClient.on('message', (topic, message) => { const data = JSON.parse(message.toString()); // 调用更新方法 this.updateDeviceMap(data.deviceId, { longitude: parseFloat(data.longitude), latitude: parseFloat(data.latitude), speedKph: parseInt(data.speedKph) }); }); } }, mounted() { this.initMqtt(); } }; </script> ``` ### 子组件接收数组 子组件通过`props`接收数组,并可以遍历展示。 ```vue <template> <ul> <li v-for="(pos, index) in positions" :key="index"> 经度: {{ pos.longitude }}, 纬度: {{ pos.latitude }}, 速度: {{ pos.speedKph }} km/h </li> </ul> </template> <script> export default { props: { positions: { type: Array, default: () => [] } } }; </script> ``` ### 优化:使用Vue.set或Vue.delete(不适用Map) 注意:Vue.set和Vue.delete只适用于普通对象或数组,不适用于Map。因此我们采用版本号的方式。 ### 为什么需要版本号? 因为Vue2的响应式系统无法检测到Map内部的变化(如set、delete等操作)。通过引入一个额外的响应式属性(如`mapVersion`),并在Map更新时改变这个属性,我们可以让依赖这个属性的计算属性重新计算,从而触发视图更新。 ### 替代方案:使用Vue.observable 在Vue2中,我们可以使用`Vue.observable`来创建一个响应式的对象,但同样对Map的支持有限。因此,版本号方法是最简单可靠的。 ### 总结 1. **定义Map和版本号**:在data中定义Map和一个用于强制更新的版本号。 2. **更新Map时改变版本号**:每次更新Map后,增加版本号。 3. **计算属性转换Map为数组**:计算属性依赖版本号,返回Map的values数组。 4. **传递数组给子组件**:在模板中将计算属性传递给子组件。 这样,每次Map更新时,计算属性都会重新计算,子组件也会重新渲染。 §§相关问题§§ 1. Vue2中如何监听Set对象的变化? 2. Vue2中如何实现嵌套Map的响应式更新? 3. Vue3中如何使用Proxy监听Map的变化?</think>### Vue 项目中监听 Map 对象变化并传递给子组件 在 Vue 项目中监听 Map 对象变化并实时提取组成数组传递给子组件,可以通过以下方案实现: #### 解决方案(Vue2 环境) ```vue <template> <!-- 将转换后的数组传递给子组件 --> <child-component :device-positions="devicePositionsArray" /> </template> <script> import Vue from 'vue'; export default { data() { return { // 存储设备位置的 Map deviceMap: new Map(), // 用于强制更新的版本号 mapVersion: 0 }; }, computed: { // 将 Map 的转换为数组 devicePositionsArray() { // 依赖 mapVersion 确保 Map 更新时重新计算 this.mapVersion; return Array.from(this.deviceMap.values()); } }, methods: { // 更新 Map 的方法 updateDeviceMap(deviceId, position) { // 1. 更新 Map this.deviceMap.set(deviceId, position); // 2. 增加版本号触发计算属性更新 this.mapVersion++; }, // 监听 Map 变化(备选方案) initMapWatcher() { // 使用 Vue 的全局 API 监听 Map 变化 Vue.set(this, 'deviceMap', new Proxy(this.deviceMap, { set(target, property, value) { target[property] = value; this.mapVersion++; // 触发更新 return true; } })); } }, mounted() { // 模拟 MQTT 消息处理 setInterval(() => { const mockData = { deviceId: `device_${Math.floor(Math.random() * 100)}`, longitude: 116 + Math.random(), latitude: 39 + Math.random(), speedKph: Math.floor(Math.random() * 100) }; this.updateDeviceMap(mockData.deviceId, mockData); }, 2000); } }; </script> ``` #### 关键实现原理 1. **响应式更新机制**: - Vue2 无法直接检测 Map 内部变化,需要额外触发机制 - 使用 `mapVersion` 作为"依赖标记",修改时强制计算属性重新计算 - 每次 Map 更新后执行 `this.mapVersion++` 2. **Map 转数组**: ```javascript // 将 Map 的转换为数组 devicePositionsArray() { this.mapVersion; // 依赖标记 return Array.from(this.deviceMap.values()); } ``` 3. **子组件接收数据**: ```vue <!-- 子组件 --> <template> <ul> <li v-for="(pos, index) in devicePositions" :key="index"> 设备: {{ pos.deviceId }} - 速度: {{ pos.speedKph }}km/h </li> </ul> </template> <script> export default { props: { devicePositions: { type: Array, default: () => [] } } }; </script> ``` #### 优化方案(推荐) 对于更复杂的场景,建议使用 Vue.observable 创建响应式 Map: ```javascript // 在单独文件中创建响应式 Map import Vue from 'vue'; export const reactiveMap = Vue.observable({ data: new Map(), version: 0, set(key, value) { this.data.set(key, value); this.version++; }, getValuesArray() { return Array.from(this.data.values()); } }); // 在组件中使用 import { reactiveMap } from './reactiveMap'; export default { computed: { devicePositions() { reactiveMap.version; // 建立依赖 return reactiveMap.getValuesArray(); } }, methods: { handleMqttMessage(message) { const data = JSON.parse(message); reactiveMap.set(data.deviceId, { longitude: data.longitude, latitude: data.latitude, speedKph: data.speedKph }); } } } ``` #### Vue3 优化方案 Vue3 的响应式系统原生支持 Map: ```vue <script setup> import { ref, reactive, computed } from 'vue'; // 创建响应式 Map const deviceMap = reactive(new Map()); // 计算属性直接返回数组 const devicePositionsArray = computed(() => Array.from(deviceMap.values()) ); // 更新 Map 的方法 const updateDeviceMap = (deviceId, position) => { deviceMap.set(deviceId, position); }; </script> <template> <child-component :device-positions="devicePositionsArray" /> </template> ``` ### 总结 1. **Vue2 解决方案**: - 使用 `mapVersion` 作为依赖标记触发更新 - 通过计算属性将 Map 转换为数组 - 使用 Proxy 作为备选监听方案 2. **最佳实践**: ```javascript // 更新 Map this.deviceMap.set(key, value); this.mapVersion++; // 关键步骤:触发计算属性更新 // 计算属性 computed: { deviceArray() { this.mapVersion; // 建立依赖 return Array.from(this.deviceMap.values()); } } ``` 3. **性能考虑**: - 避免在计算属性中进行复杂操作 - 对于大型数据集,考虑使用虚拟滚动 - 定期清理不活跃设备防止内存泄漏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值