路由传值获取参数 渲染数据
主页面
<template>
<div class="km">
<div v-for="item in items" :key="item.id">
<div class="title-km" >
<img :src="item.imageUrl" alt="Image" class="title-km-img">
<div class="title-km-text">
<h3 class="title-km-text-p">{{ item.title }}</h3>
<span class="title-km-text-span ">{{ item.content }}</span>
</div>
</div>
<button class="but" @click="but(item)">详情>></button>
<el-divider></el-divider>
</div>
</div>
</template>
<script>
export default {
// 当前页面的 父页面传过来的参数
props: ['contentArr'],
data(){
return{
// 定义变量
items: [],
// 定义传值的变量 // 新增数组用于存储
itemcontent: {
conten:[],
images:[]
},
}
},
created() {
// 把从当前页面的 父页面传过来的参数 进行赋值,赋值给items
this.items=this.contentArr
// // 然后,从 items 中提取 imageUrl 并更新 images///提取 content 并更新 conten
this.itemcontent.conten = this.items.map(item => item.content);
this.itemcontent.images = this.items.map(item => item.imageUrl );
// 将this.contentArr数组中的每个元素(item)通过map方法处理,返回一个新的数组,赋值给this.items。
this.items = this.contentArr.map(item => ({
// 使用对象展开语法复制当前item对象的所有属性。
...item,
// 对content属性进行特殊处理:
content: item.content
.replace(/ /g, ' ') // 首先,使用正则表达式将所有 字符(HTML中表示不间断空格的实体)替换为普通的空格字符。
// /g标志表示全局替换,即替换所有匹配的项,而不仅仅是第一个。
.replace(/<[^>]*>/g, '') // 然后,使用正则表达式剥离所有的HTML标签。
// 这个正则表达式匹配以<开头,以>结尾,中间不包含>的任意字符序列,即匹配一个完整的HTML标签,并将其替换为空字符串。
// 同样,/g标志表示全局替换。
}));
},
methods: {
but() {
// alert('内容')
// 通过路由把参数传给 当前页面的子页面
this.$router.push({
path: '/subcomponent/DetailPage', //路径 需要在 router 定义路由
query: {
// 传递的是一个对象 但是路由有限制 所以需要变化
itemcontent: JSON.stringify(this.itemcontent) // 将对象转换为字符串,因为 query 参数只能是字符串
// 传递一项 可以不用转换类型
// itemcontent: this.itemcontent.images
}
});
// 写法二
// this.$router.push({ path: '/subcomponent/DetailPage',this.itemcontent.images });
},
}
}
</script>
<style>
.km{
width: 43rem;
background-color: rgb(255 255 255);
flex-wrap: wrap;
gap: 1rem;
}
.title-km {
flex: 1 1 calc(33.333% - 1rem);
box-sizing: border-box;
padding: 1rem;
display: flex;
}
.title-km-img {
width: 10rem;
height: 8rem;
}
.title-km-text-p{
width: 13rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.title-km-text-span {
display: inline-block;
width: 25rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16px;
}
.but{
margin-left: 35rem;
margin-top: -2rem;
position: absolute;
}
.el-divider--horizontal {
display: block;
height: 1px;
width: 100%;
margin: 3px 0;
}
</style>
子页面
<template>
<!-- 组件的模板部分 -->
<div class="conten">
<!-- 使用v-for指令遍历images数组,为每个元素渲染一个img标签 -->
<!-- :key绑定唯一标识,这里使用index作为临时解决方案,但通常建议使用唯一ID -->
<img v-for="(image, index) in images" :key="index" :src="image" alt="Image">
<!-- 使用v-html指令将sanitizedConten的数据作为HTML插入到p标签中 -->
<!-- 注意:v-html会插入原始的HTML,因此要确保sanitizedConten是安全的,避免XSS攻击 -->
<p v-html="sanitizedConten"></p>
</div>
</template>
<script>
export default {
data() {
return {
// 定义响应式数据
images: [], // 存储图片的URL数组
contenRaw: '', // 存储从路由获取的原始HTML内容(未清理)
sanitizedConten: '' // 存储清理后的HTML内容,用于安全显示
};
},
computed: {
// 定义一个计算属性,用于从路由查询参数中获取itemcontent数据
itemcontent() {
// 使用this.$route.query访问路由查询参数
// 提供一个空对象字符串作为默认值,然后尝试解析为JSON
return this.$route.query.itemcontent || '{}';
}
},
mounted() {
// 组件挂载完成后执行的钩子函数
try {
// 解码URL编码的JSON字符串,并尝试解析为JavaScript对象
const parsedData = JSON.parse(decodeURIComponent(this.itemcontent));
// 确保this.images是一个数组,即使解析的数据中没有提供images也保持为数组
this.images = parsedData.images || [];
// 处理contenRaw,假设只需要显示第一个content元素(如果有的话)
this.contenRaw = parsedData.conten ? parsedData.conten[0] : '';
// 使用cleanHtml方法清理HTML内容,并将结果赋值给sanitizedConten
this.sanitizedConten = this.cleanHtml(this.contenRaw);
} catch (error) {
// 如果在解析或处理数据时发生错误,将错误信息打印到控制台
console.error('Error parsing itemcontent:', error);
}
},
methods: {
// 定义一个方法用于清理HTML内容
cleanHtml(html) {
// 使用正则表达式删除所有的HTML标签(包括自闭合标签)
// 同时将 实体替换为空格,并去除字符串两端的空白字符
return html.replace(/<\/?[^>]+(>|$)/g, '').replace(/ /g, ' ').trim();
}
}
};
</script>
<style scoped>
/* .conten{
padding: 7rem 20rem ;
} */
</style>