Vue.js中Read More组件props更新后不重新渲染的问题排查
Vue.js “阅读更多”组件无法随props更新内容的解决方案
我在Vue.js中实现了一个“阅读更多”组件,但当通过props传递的text内容发生变化时,组件不会重新渲染展示新内容。以下是组件代码:
Vue.component('readmore', { template: ` <span> {{ part1 }}<span v-if="leia.mais">... <span class="text-info ml-2" style="cursor:pointer;" v-on:click="readMore"> Leia mais</span> </span><span v-if="!leia.mais">{{ part2 }} <span class="text-info ml-2" style="cursor:pointer;" v-if="leia.menos" v-on:click="readLess">Leia menos</span> </span> </span> `, data: function () { return { part1: '', part2: '', leia: {}, defaultMaxChr: 200 } }, props: ['maxchr', 'text'], created: function () { var text = this.text; var maxchr = this.maxchr ? this.maxchr : this.defaultMaxChr; if ((undefined === text) || (0 === text.length)) { console.warn('COMPONENTE LEIA MAIS: Parâmetro text indefinido ou foi passada uma string vazia.'); return; } if (text.length <= maxchr) { this.part1 = text; this.part2 = ''; this.leia = {mais: false, menos: false}; } else { this.part1 = text.substr(0, maxchr); this.part2 = text.substr(maxchr); this.leia = {mais: true, menos: false}; } }, methods: { readMore: function() { this.leia.mais = false; this.leia.menos = true; }, readLess: function() { this.leia.mais = true; this.leia.menos = false; }, }, });
当我在父组件中用输入框绑定text数据,并将其传递给该组件时,修改输入框内容后组件毫无反应:
<input v-model="text"> <readmore v-bind:text="text" v-bind:maxchr="100" ></readmore>
问题原因
组件的created钩子只会在组件首次初始化时执行一次,当父组件传递的text或maxchr props发生变化时,created不会重新触发,导致组件内部的part1、part2和leia状态无法更新,自然不会重新渲染。
修复方案
添加watch监听器来监听text和maxchr的变化,同时把文本分割逻辑封装成独立方法,在组件创建和props变化时都调用该方法:
Vue.component('readmore', { template: ` <span> {{ part1 }}<span v-if="leia.mais">... <span class="text-info ml-2" style="cursor:pointer;" v-on:click="readMore"> 阅读更多</span> </span><span v-if="!leia.mais">{{ part2 }} <span class="text-info ml-2" style="cursor:pointer;" v-if="leia.menos" v-on:click="readLess">收起</span> </span> </span> `, data: function () { return { part1: '', part2: '', leia: {}, defaultMaxChr: 200 } }, props: ['maxchr', 'text'], created: function () { this.splitText(); }, // 监听props变化,重新分割文本 watch: { text() { this.splitText(); }, maxchr() { this.splitText(); } }, methods: { // 提取文本分割逻辑为独立方法 splitText() { const text = this.text; const maxchr = this.maxchr ?? this.defaultMaxChr; if (!text?.length) { console.warn('阅读更多组件:text参数未定义或传入空字符串。'); return; } if (text.length <= maxchr) { this.part1 = text; this.part2 = ''; this.leia = {mais: false, menos: false}; } else { this.part1 = text.substr(0, maxchr); this.part2 = text.substr(maxchr); this.leia = {mais: true, menos: false}; } }, readMore() { this.leia.mais = false; this.leia.menos = true; }, readLess() { this.leia.mais = true; this.leia.menos = false; }, }, });
修改说明
- 将原
created中的文本分割逻辑提取为splitText方法,便于复用 - 添加
watch监听器,当text或maxchr变化时自动调用splitText更新状态 - 优化了参数判断逻辑(使用可选链和空值合并运算符)
- 把葡萄牙语按钮文本替换为中文(可根据需求改回原语言)
内容的提问来源于stack exchange,提问作者Ederson Santos
相关产品推荐
相关产品推荐

