本篇要学习的是下面两种卡片的实现
照着做了一下,实在没什么好写的。
简单说一下思路,不同卡片图片是因为用了三种展示方式,为每一种展示方式写一组css,三种方式通过父组件传过来。子组件通过增加props来接收。
父组件 index.vue 其他内容省略了。
<template>
<view class="home">
<navbar></navbar>
<tab :list="tabList" @tab="tab_update"></tab>
<list-scroll>
<!-- <list-card v-for="item in 5"></list-card> -->
<list-card mode="base"></list-card>
<list-card mode="image"></list-card>
<list-card mode="column"></list-card>
</list-scroll>
</view>
</template>
子组件 list-card.vue
<template>
<view>
<!-- 基础卡片 --><!-- aspectFill 保持纵横比缩放图片 -->
<view v-if="mode === 'base'" class="listcard">
<view class="listcard-image">
<image src="/static/logo.png" mode="aspectFill"></image>
</view>
<view class="listcard-content">
<view class="listcard-content_title">
<text>
uni-app开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架
</text>
</view>
<view class="listcard-content_des">
<view class="listcard-content_des-label">
<view class="listcard-content_des-label-item">
前端
</view>
</view>
<view class="listcard-content_des-label-browse">
120浏览
</view>
</view>
</view>
</view>
<!-- 多图模式 -->
<view v-if="mode ==='column'" class="listcard mode-column">
<view class="listcard-content">
<view class="listcard-content_title">
<text>
uni-app开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架
</text>
<view class="listcard-image">
<view v-for="item in 3" :key="item" class="listcard-image_item">
<image src="/static/logo.png" mode="aspectFill"></image>
</view>
</view>
</view>
<view class="listcard-content_des">
<view class="listcard-content_des-label">
<view class="listcard-content_des-label-item">
前端
</view>
</view>
<view class="listcard-content_des-label-browse">
120浏览
</view>
</view>
</view>
</view>
<!-- 大图模式 -->
<view v-if="mode === 'image'" class="listcard mode-image">
<view class="listcard-image">
<image src="/static/logo.png" mode="aspectFill"></image>
</view>
<view class="listcard-content">
<view class="listcard-content_title">
<text>
uni-app开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架开发框架
</text>
</view>
<view class="listcard-content_des">
<view class="listcard-content_des-label">
<view class="listcard-content_des-label-item">
前端
</view>
</view>
<view class="listcard-content_des-label-browse">
120浏览
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
mode:{
type:String,
default:'base'
}
},
data() {
return {
};
}
}
</script>
<style lang="scss">
.listcard{
display: flex;
padding: 10px;
margin:10px;
border-radius: 5px;
box-shadow: 0 0 5px rgba($color: #000000, $alpha: 1.0);
box-sizing: border-box;
.listcard-image{
// 不让图片被挤压
flex-shrink: 0;
width:60px;
height: 60px;
border-radius: 5px;
overflow: hidden;
image{
width:100%;
height: 100%;
}
}
.listcard-content{
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 10px;
width:100%;
.listcard-content_title{
padding-right: 30px;
font-size: 14px;
color: #333;
font-weight: 400;
line-height: 1.2;
// 下面的text是做溢出隐藏
text{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp:2;
-webkit-box-orient:vertical;
}
}
.listcard-content_des{
display: flex;
justify-content: space-between;
font-size: 12px;
.listcard-content_des-label{
display: flex;
.listcard-content_des-label-item{
padding: 0 5px;
margin-right: 5px;
border-radius: 15px;
color: $mk-base-color;
border: 1px $mk-base-color solid;
}
}
.listcard-content_des-label-browse{
color: #999999;
line-height: 1.5;
}
}
}
&.mode-column{
.listcard-content{
width: 100%;
padding-left: 0;
}
.listcard-image{
display: flex;
margin-top: 10px;
width: 100%;
height: 70px;
.listcard-image_item{
margin-left: 10px;
width: 100%;
border-radius: 5px;
overflow: hidden;
&:first-child{
margin-left: 0;
}
image {
width: 100%;
height: 100%;
}
}
}
.listcard-content_des{
margin-top: 10px;
}
}
&.mode-image{
flex-direction: column;
.listcard-image{
width: 100%;
height: 100px;
}
.listcard-content{
padding-left: 0;
margin-top: 10px;
.listcard-content_des{
display: flex;
align-items: center;
margin-top: 10px;
}
}
}
}
</style>
效果图。
实现内容切换
由于这阶段大多数是css的调整,细节繁琐,所以不做笔记。只记录个别需要注意的地方。其他样式相关内容,直接贴代码领会。
前面记录过,这里在重复一下,如果组件名字和文件夹名字不一样,需要手动导入的。如下:
下面是零散的记录。
当滑动卡片,让选项卡也跟着变化,监听选项卡的当前indexid.用watch。下面是使用例子。注意demo和watch里面是一样的。
<template>
<div>
<el-input v-model="demo"></el-input>
{{value}}
</div>
</template>
<script>
export default {
name: 'index',
data() {
return {
demo: '',
value: ''
};
},
watch: {
demo(val) {
this.value = this.demo;
}
}
};
</script>
如果不想要云函数返回的数据库内容中的某项,可以通过下面方法过滤掉。
下面两种写法是一样的。
如何通过云函数查询云数据库中某个字段下面匹配某个字符串的一些数据?
具体意思,hbuilder会有注释。
懒加载: 原问题是第一种赋值的话,并不会马上刷新。所以用第二种形式。这里懒加载的意思是说如果滑动到上次滑动过的页面,那么就不刷新,否则刷新。
这个例子讲的很好,
遇到报错信息
vue.runtime.esm.js:619 [Vue warn]: Unknown custom element: <FormError> - did you register the component correctly? For recursive components, make sure to provide the “name” option.
可能原因:出现这种问题的原因我目前只遇到一种,那就是vue的组件使用错误,具体原因包括以下几种:
- import语句导入组件时from后面的路径写错
- 注册组件时括号内的组件名称写错,与import声明的不一致
- 注册组件关键字components写错导致无法使用
- 使用组件时名称写错,与注册组件的名字不一致
- 使用组件时没有使用 / 反斜杠结尾
上拉显示加载中,以及拉到底显示没有更多数据是下面组件。
对于加载中的传递是: list-scroll emit发送 -> list-item emit发送 -> list.vue 永远是子向父组件发送的方向。
图中是什么语法
扩展语法。对数组和对象而言,就是将运算符后面的变量里东西每一项拆下来。
收藏按钮实现
1.按钮的位置是与卡片中的title同级的。
2.收藏按钮需要用绝对定位固定到卡片的右上角。
问题:点击收藏图标的时候,卡片也被点击了。
解决办法:阻止冒泡,具体如下
云函数临时测试可以通过下面的方式,比如你想测试按照userid 查询
如何添加新收藏的文章编号到用户表的数据库中?
用addToSet 避免重复。
删除操作
很巧妙的“点击收藏,再点击取消”的效果
问题:当前我点击收藏了,当我刷新页面后,收藏状态消失了。
解决办法:添加字段is_like。保存。然后读取文章内容的时候,把这个字段的值读取出来,赋给收藏红心。
问题:希望在点击收藏后,显示个提示收藏成功的提示信息
解决办法: