Vue.js异步操作完成后如何访问DOM元素progresstitle?
问题解决思路与方案
你的代码里progresstitle出现undefined,核心原因是异步请求getProjects还未完成、依赖content的DOM元素还没渲染时,你就去查询并操作DOM了,另外直接给this.data赋值会和组件的data选项冲突,属于不规范写法。下面是具体的解决方法:
方法一:等待异步请求完成后处理DOM
先等接口数据返回、DOM更新完毕,再去查询元素并执行逻辑:
export default { data() { return { content: {}, domRefs: {} // 用单独变量存DOM引用,避免和组件data冲突 } }, async created() { await this.getProjects(); // 等待异步请求完成 this.init(); }, methods: { async init() { await this.$nextTick(); // 确保DOM已完成更新 this.domRefs.progresstitles = document.querySelectorAll('[data-title="progress"]'); this.titles(); }, async getProjects() { const content = await this.$prismic.client.getSingle('identifier'); this.content = content.data; }, titles() { this.domRefs.progresstitles.forEach(item => { // 直接用item即可,无需通过index重复获取 console.log(item); }); } } }
方法二:通过watch监听数据变化
监听content的变化,当数据更新后自动触发DOM操作:
export default { data() { return { content: {}, domRefs: {} } }, created() { this.getProjects(); }, watch: { content: { async handler() { await this.$nextTick(); // 等待DOM渲染完成 this.domRefs.progresstitles = document.querySelectorAll('[data-title="progress"]'); this.titles(); }, deep: true // 监听对象内部属性的变化 } }, methods: { async getProjects() { const content = await this.$prismic.client.getSingle('identifier'); this.content = content.data; }, titles() { this.domRefs.progresstitles.forEach(item => { console.log(item); }); } } }
方法三:使用Vue的ref(推荐)
避免直接操作DOM,用Vue官方提供的ref来获取元素,更符合Vue响应式思想:
模板修改
<template> <div ref="progresstitle" data-title="progress"></div> <div ref="progresstitle" data-title="progress"></div> <div ref="progresstitle" data-title="progress"></div> </template>
脚本修改
export default { data() { return { content: {} } }, async created() { await this.getProjects(); await this.$nextTick(); // 等待基于content渲染的DOM生成 this.titles(); }, methods: { async getProjects() { const content = await this.$prismic.client.getSingle('identifier'); this.content = content.data; }, titles() { // $refs.progresstitle是包含所有目标元素的数组 this.$refs.progresstitle.forEach(item => { console.log(item); }); } } }
为什么原来的代码会出问题
mounted钩子执行时,getProjects的异步请求还没结束,依赖content的DOM元素还未渲染,querySelectorAll只能拿到空集合;- 直接给
this.data赋值会覆盖组件data选项返回的响应式对象,破坏Vue的响应式机制。
内容的提问来源于stack exchange,提问作者user20047355
相关产品推荐
相关产品推荐

