uni - app 开发
开发环境搭建
1.下载HbiuderX 下载插件

创建项目:

https://uniapp.dcloud.net.cn/ 官网
运行到雷电模拟器

安卓真机调试




微信小程序调试

支付宝小程序配置
https://opendocs.alipay.com/mini/ide/download



一、开发准备阶段
uni-app 目录结构

1.引入官方css样式库
新建项目
复制项目文件到自己的项目中

再复制文件static下的uni.ttf文件到自己的static目录下

2.引入自定义图标库

找到这两个文件

将css文件复制到common目录并改名为icon.css

修改文件:修改后的样子

引入样式

打开图标库html

引入图标
<template>
<view>
<text class="iconfont icon-shouye1" style="font-size: 100rpx; color: red;"></text>
</view>
</template>
示例:

3.引入css动画库
官网:Animate.css | A cross-browser library of CSS animations.
CSS下载网址:https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css
把下载的文件放入目录

引入样式App.vue
<style>
/*每个页面公共css */
/* 官方CSS库 */
@import url('common/uni.css');
/* 自定义图标库 */
@import url('common/icon.css');
/* 引入动画css库 */
@import url('common/animate.min.css');
</style>
动画的使用 animate__animated CSS固定的前缀,
animate__shakeY 动画效果,去官网复制
<!-- 动画使用 -->
<view class="animate__animated " hover-class="animate__shakeY" style="border: 1rpx solid black; padding: 20rpx;">
<view class="animate__animated " hover-class="animate__heartBeat" style="border: 1rpx solid black; padding: 20rpx;">
点击效果
</view>
</view>
<!-- 动画使用方式2 v-if-->
<!-- 动画使用方式3 列表渲染-->

4.设置全局属性globalStyle
App.vue: 可以检测更新,网络监听,初始化数据
pages.json 页面配置:路由,选项卡,导航的配置
**pages:**pages数组中第一项表示应用启动页
**globalStyle:**全局配置 属性地址:pages.json 页面路由 | uni-app官网 (dcloud.net.cn)
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
// "navigationBarTitleText": "uni-app"//首页标题
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",//标题颜色
"navigationBarTitleText": "社区交友",//标题
"navigationBarBackgroundColor": "#FFFFFF",//导航栏-状态栏的颜色
"backgroundColor": "#FFFFFF"//窗口背景色
},
示例效果:

二、基础知识学习 uni -app
1.底部导航开发
pages.json 配置: tabBar属性:
如果应用是一个多 tab 应用,可以通过 tabBar 配置项指定一级导航栏,以及 tab 切换时显示的对应页。
在 pages.json 中提供 tabBar 配置,不仅仅是为了方便快速开发导航,更重要的是在App和小程序端提升性能。在这两个平台,底层原生引擎在启动时无需等待js引擎初始化,即可直接读取 pages.json 中配置的 tabBar 信息,渲染原生tab。
Tips
当设置 position 为 top 时,将不会显示 icon
tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
tabbar 切换第一次加载时可能渲染不及时,可以在每个tabbar页面的onLoad生命周期里先弹出一个等待雪花(hello uni-app使用了此方式)
tabbar 的页面展现过一次后就保留在内存中,再次切换 tabbar 页面,只会触发每个页面的onShow,不会再触发onLoad。
顶部的 tabbar 目前仅微信小程序上支持。需要用到顶部选项卡的话,建议不使用 tabbar 的顶部设置,而是自己做顶部选项卡,可参考 hello uni-app->模板->顶部选项卡。
"tabBar": {
"color": "#323232",//颜色
"selectedColor": "#ED6384",//选中状态的颜色
"backgroundColor": "#FFFFFF",//背景颜色
"borderStyle": "black",//上边线颜色
"list": [
{
"pagePath": "pages/index/index",//路径
"text": "首页",//文字
"iconPath": "static/tabbar/index.png",//图标路径
"selectedIconPath": "static/tabbar/indexed.png"//选中的图标路径最后不能有逗号
},
{
"pagePath": "pages/news/news",//路径
"text": "动态",//文字
"iconPath": "static/tabbar/news.png",//图标路径
"selectedIconPath": "static/tabbar/newsed.png"//选中的图标路径
},
{
"pagePath": "pages/msg/msg",//路径
"text": "消息",//文字
"iconPath": "static/tabbar/paper.png",//图标路径
"selectedIconPath": "static/tabbar/papered.png"//选中的图标路径
},
{
"pagePath": "pages/my/my",//路径
"text": "我的",//文字
"iconPath": "static/tabbar/home.png",//图标路径
"selectedIconPath": "static/tabbar/homeed.png"//选中的图标路径
}
]//选项卡配置数组中有多少选项,则就对应多少页面
},
2.view和text组件和动画使用
**view:**视图组件,相当于div
hover配置:点击变色
<view class="view-box" hover-class="view-box-hover"> 第一个view </view>css
.view-box{ width: 200rpx; height: 100rpx; background-color: blue; color: #FFFFFF; margin: 50rpx; } .view-box-hover{ background: red; }使用动画(目前发现只支持手机APP)
<view class="view-box animate__animated" hover-class="view-box-hover animate__shakeY"> 第一个view </view>设置延时(消耗性能)
<view class="view-box animate__animated" hover-class="view-box-hover animate__shakeY" hover-stay-time="800"> 第一个view </view>
**text:**文本组件,相当于p
文档:text | uni-app官网 (dcloud.net.cn)
文本换行
<text>这是text \n 这是text</text>文本可选
<text :selectable="true">这是text \n 这是text</text>
3.uni-app的css3选择器
文档:CSS 支持 | uni-app官网 (dcloud.net.cn)
目前支持的选择器有:
| 选择器 | 样例 | 样例描述 |
|---|---|---|
| .class | .intro | 选择所有拥有 class="intro" 的组件 |
| #id | #firstname | 选择拥有 id="firstname" 的组件 |
| element | view | 选择所有 view 组件 |
| element, element | view, checkbox | 选择所有文档的 view 组件和所有的 checkbox 组件 |
| ::after | view::after | 在 view 组件后边插入内容,仅 vue 页面生效 |
| ::before | view::before | 在 view 组件前边插入内容,仅 vue 页面生效 |
CSS3选择器
- nth-of-type
<view class="box">
<text>112</text>
<view>1</view>
<view>2</view>
<view>3</view>
</view>
#view2,text{
background-color: yellow;
}
.box{
width: 300upx;
height: 300upx;
background-color: blue;
color: #FFFFFF;
margin: 100upx;
padding: 50upx;
}
.box view{
font-size: 30rpx;
}
.box>view:nth-of-type(1){
font-size: 30rpx;
background: green;
}
.box>view:nth-of-type(2){
background-color: red;
font-size: 30rpx;
}
.box>view:nth-of-type(3){
background-color: pink;
font-size: 30rpx;
}

- first-child/last-child
<view class="box">
<view>1</view>
<view>2</view>
<view>3</view>
<view>4</view>
</view>
.box view{
font-size: 30rpx;
}
.box>view:first-child{
font-size: 30rpx;
background: green;
}
.box>view:last-child{
background-color: red;
font-size: 30rpx;
}

first-of-type/last-of-type
<view class="box"> <view>1</view> <view>2</view> <view>3</view> <view>4</view> </view>.box view{ font-size: 30rpx; } .box>view:first-of-type{ font-size: 30rpx; background: green; } .box>view:last-of-type{ background-color: red; font-size: 30rpx; }
奇偶选择器
<view class="box"> <view>1</view> <view>2</view> <view>3</view> <view>4</view> </view>.box view{ font-size: 30rpx; } .box>view:nth-of-type(2n-1){ font-size: 30rpx; background: green; } .box>view:nth-of-type(2n){ background-color: red; font-size: 30rpx; }
第二种写法
.box>view:nth-of-type(even){//偶数 font-size: 30rpx; background: green; } .box>view:nth-of-type(odd){//奇数 background-color: red; font-size: 30rpx; }
4.flex布局快速上手
文档 CSS 支持 | uni-app官网 (dcloud.net.cn)
教程:Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com)
<template>
<view>
<view class="box">
<view class="box-item">1</view>
<view class="box-item">2</view>
<view class="box-item">3</view>
<!-- <view class="box-item">4</view>
<view class="box-item">5</view>
<view class="box-item">6</view>
<view class="box-item">7</view>
<view class="box-item">8</view> -->
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
.box{
width: 100%;
border:1upx solid #CCCCCC;
height: 500upx;
display: flex;/*同一行显示*/
/* flex-wrap: wrap; /*超出换行*/
/*flex-wrap: wrap-reverse;/*倒叙向上填充 */
/* center居中 space-between两端对齐 start默认左对齐 flex-end 右对齐*/
/* justify-content: center; */
/* center 垂直居中 stretch 填充满(去掉高度) flex-end 到底部 */
/* align-items: center; */
/* 从上到下排列 */
/* flex-direction: column; */
}
.box-item{
background: #007AFF;
color: #FFFFFF;
height: 200upx;
/* width: 200upx; */
/* 平均分配 */
/* 1.宽度50% */
/* width: 50%; */
/* 2. flex 1 占几份*/
flex: 1;
line-height: 200upx;
font-size: 30upx;
font-weight: bold;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.box-item:nth-of-type(odd){/*奇数*/
background-color: green;
}
.box-item:nth-of-type(even){/*偶数*/
}
/* .box-item:nth-of-type(1){
/* 1 代表被压缩 0 代表不被压缩
flex-shrink: 0;
} */
.box-item:nth-of-type(1){
flex: 1;
}
.box-item:nth-of-type(2){
flex: 2;
/* 第二个元素放到最下面 */
align-self: flex-end;
}
.box-item:nth-of-type(3){
flex: 3;
}
</style>
5.数据渲染
修改样式/值绑定
<template>
<view>
<view :class="classname">
<view class="box-item">{{username}}</view>
<view class="box-item">{{userinfo.age}}2</view>
<view class="box-item">{{userinfo.gender}}</view>
</view>
<button type="primary" @tap='changeUsername("hahah")'> 修改名称</button>
<button type="primary" @tap='changeClassName()'> 修改样式</button>
</view>
</template>
<script>
export default {
data() {
return {
classname:"box",
username:"xiaoyan",
userinfo:{
age:18,
gender:"男"
}
}
},
methods: {
changeUsername:function(name){
this.username=name;
},
changeClassName:function(){
this.classname="box2";
}
}
}
</script>
<style>
.box{
width: 100%;
border:1upx solid #333333;
height: 500upx;
display: flex;/*同一行显示*/
}
.box2{
width: 100%;
border:1upx solid #333333;
height: 200rpx;
display: flex;/*同一行显示*/
}
.box>view{
background: #007AFF;
color: #FFF;
font-weight: bold;
font-size: 40upx;
flex: 1;
height: 500upx;
display: flex;
justify-content: center;
align-items: center;
border: 1upx solid #fff;
}
</style>

6.class和style绑定
<template>
<view>
<!-- 静态数组 -->
<view class="box" :class="['bor','fs']">
box
</view>
<!-- 动态数组 -->
<view class="box" :class="[class1,class2]">
box
</view>
<!-- 三元运算符 -->
<view class="box" :class="[is ? class1:'',class2]">
box
</view>
<!-- 条件判断 -->
<view class="box" :class="{'bor':is}">
box
</view>
<!-- style 支持语法 -->
<view class="box" :style="{'color': Color ,'font-size': Size+'px'}">
box
</view>
</view>
</template>
<script>
export default {
data() {
return {
class1:"bor",
class2:"fs",
is:false,
Color:"red",
Size:20
}
},
methods: {
}
}
</script>
<style>
.box{
background: green;
color: #FFFFFF;
width: 350upx;
height: 350upx;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 50upx;
}
.bor{
border: 10upx solid salmon;
}
.fs{
font-size: 80upx;
}
</style>

7.条件渲染
v-if (是否显示)
<template> <view> <!-- 条件渲染 --> <!-- v-if --> <view class="box" v-if="isShow" > box </view> <button type="default" @tap="changeShow()">显示/隐藏</button> <!-- v-if --> <view class="box" v-if="age>20" > {{age>30?'中年人':'年轻人'}} {{age}} </view> <button type="default" @tap="changeAge()">年龄+</button> <button type="default" @tap="changeAgem()">年龄-</button> </view> </template> <script> export default { data() { return { isShow:true, age:10 } }, methods: { changeShow:function(){ this.isShow=!this.isShow }, changeAge:function(){ this.age+=11 }, changeAgem:function(){ this.age-=11 } } } </script> <style> .box{ background: gray; color: aliceblue; font-size: 50upx; width: 350upx; height: 350upx; display: flex; justify-content: center; align-items: center; } </style>v-show
<template> <view> <!-- 条件渲染 --> <!-- v-show --> <view class="box" v-show="isShow" > box </view> <button type="default" @tap="changeShow()">显示/隐藏</button> <!-- v-show --> <view class="box" v-show="age>20" > {{age>30?'中年人':'年轻人'}} {{age}} </view> <button type="default" @tap="changeAge()">年龄+</button> <button type="default" @tap="changeAgem()">年龄-</button> </view> </template> <script> export default { data() { return { isShow:true, age:10 } }, methods: { changeShow:function(){ this.isShow=!this.isShow }, changeAge:function(){ this.age+=11 }, changeAgem:function(){ this.age-=11 } } } </script> <style> .box{ background: gray; color: aliceblue; font-size: 50upx; width: 350upx; height: 350upx; display: flex; justify-content: center; align-items: center; } </style>v-if和v-show的区别 v-if 1、v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 2、v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
v-show 1、v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
总结: 相同点:
1、v-if 与 v-show 都可以动态控制 DOM 元素的显示隐藏。 不同点:
1、v-if 有更高的切换开销,v-show 有更高的初始渲染开销 3、v-if 适合运营条件不大可能改变;v-show 适合频繁切换。 4、v-if 通过动态向DOM树增删DOM元素,v-show 设置display来进行隐藏 5、v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show 只是简单的基于 CSS 切换; 如果需要非常频繁地切换,则使用v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
官方推荐的渲染方式[ v-if v-else ]
<template> <view> <!-- 条件渲染 v-if v-else --> <template v-if="isShow"> <view class="box"> box </view> </template> <template v-else-if="age>15"> <view class="box"> {{age}} </view> </template> <template v-else> <view class="box"> {{age}} </view> </template> <button type="default" @tap="changeShow()">显示/隐藏</button> </view> </template> <script> export default { data() { return { isShow:true, age:10 } }, methods: { changeShow:function(){ this.isShow=!this.isShow this.age+=11 } } } </script> <style> .box{ background: gray; color: aliceblue; font-size: 50upx; width: 350upx; height: 350upx; display: flex; justify-content: center; align-items: center; } </style>
8.列表渲染
循环一维数组
<!-- 1. 循环一维数组 --> <view v-for="(item,index) in array1" :key="index"> {{index+1}}.{{item}} </view> <view v-for="(item,index) in array2" :key="index"> {{index+1}}-{{item.id}}-{{item.name}}--{{item.nameid}} </view>循环二维数组
<!-- 2. 循环二维数组 --> <view v-for="(item,index) in array3" :key="index"> {{index+1}}-{{item.id}}-{{item.name}} <view v-for="(list,li) in item.list" :key="li"> {{li+1}}.{{list}} </view> </view>循环对象
<view v-for="(item,index) in obj" :key="index"> {{index}}-{{item}} </view>官方推荐写法
<block v-for="(item,index) in array1" :key="index"> <view> {{index+1}}.{{item}} </view> </block>
9.事件处理器
@tap 建议用在手机端
<view class="box" @tap="clickevent()">按钮</view>点击事件遇到嵌套作用域时,默认会触发所有涵盖内的内容 设置stop属性
<view> <view class="box1" @tap.stop="box1event()"> 外面 <view class="box2" @tap.stop="box2event()">里面</view> </view> </view>
10.监听属性
监听事件
<view>
<view class="font">{{name}}</view>
<button type="default" @tap="update()">按钮</button>
</view>
<script>
export default {
data() {
return {
name: "我是一个名称"
}
},
//监听
watch: {
//监听属性
name(val) {
console.log(val)
}
},
methods: {
update() {
this.name = this.name + "1"
}
}
}
</script>
11.计算属性
计算属性computed
<template>
<view>
<view class="font">{{ZHweight}}</view>
</view>
</template>
<script>
export default {
data() {
return {
// 体重
weight: 1200
}
},
//计算属性
computed: {
//计算属性的方法,自动调用
ZHweight() {
return this.weight > 1000 ? (this.weight / 1000) + 'KG' : this.weight + 'g'
}
},
methods: {
}
}
</script>
<style>
.font {
font-size: 50upx;
}
</style>
三、开发阶段
1.page.json配置
官方文档:pages.json 页面路由 | uni-app官网 (dcloud.net.cn)
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index", //页面路径
"style": { //用于设置每个页面的状态栏、导航条、标题、窗口背景色等。
// "navigationBarTitleText": "uni-app"//首页标题
"app-plus": {
//配置导航栏
"titleNView": {
//搜索框配置
"searchInput": {
"align": "center", //居中
"backgroundColor": "#F5F4F2", //背景色
"borderRadius": "4px", //圆角
"disabled": true, //不可输入
"placeholder": "搜索帖子", //显示文本
"placeholderColor": "#6D6C67" //显示文本颜色
},
//顶部按钮配置
"buttons": [{
"color": "#333333", //颜色
"colorPressed": "#FD597C", //点击颜色
"float": "right", //浮动
"fontSize": "20px", //大小
"fontSrc": "/static/iconfont.ttf", //引入图标库
"text": "\ue668" //引入具体图标
}]
}
}
}
}, {
"path": "pages/news/news",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/msg/msg",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/my/my",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black", //标题颜色
"navigationBarTitleText": "社区交友", //标题
"navigationBarBackgroundColor": "#FFFFFF", //背景色
"backgroundColor": "#FFFFFF" //窗口背景色
},
"tabBar": {
"color": "#323232", //颜色
"selectedColor": "#ED6384", //选中状态的颜色
"backgroundColor": "#FFFFFF", //背景颜色
"borderStyle": "black", //上边线颜色
"list": [{
"pagePath": "pages/index/index", //路径
"text": "首页", //文字
"iconPath": "static/tabbar/index.png", //图标路径
"selectedIconPath": "static/tabbar/indexed.png" //选中的图标路径最后不能有逗号
},
{
"pagePath": "pages/news/news", //路径
"text": "动态", //文字
"iconPath": "static/tabbar/news.png", //图标路径
"selectedIconPath": "static/tabbar/newsed.png" //选中的图标路径
},
{
"pagePath": "pages/msg/msg", //路径
"text": "消息", //文字
"iconPath": "static/tabbar/paper.png", //图标路径
"selectedIconPath": "static/tabbar/papered.png" //选中的图标路径
},
{
"pagePath": "pages/my/my", //路径
"text": "我的", //文字
"iconPath": "static/tabbar/home.png", //图标路径
"selectedIconPath": "static/tabbar/homeed.png" //选中的图标路径
}
] //选项卡配置数组中有多少选项,则就对应多少页面
},
"uniIdRouter": {},
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "", //模式名称
"path": "", //启动页面,必选
"query": "" //启动参数,在页面的onLoad函数里面得到
}]
}
}
2.图文列表样式
补充知识点:把UI图放到ps中,修改宽度为750px 则可测量,比例与rpx相同
<template>
<view>
<!-- 列表样式 -->
<view class="p-2">
<!-- 头像昵称 | 关注按钮 -->
<view class="flex aline-center justify-between ">
<view class="flex aline-center">
<!-- 头像-->
<image class="runded-circle" src="../../static/default.jpg"
style="margin-right:20rpx; width: 65rpx; height: 65rpx;" lazy-load></image>
<!-- 昵称发布时间 -->
<view>
<view class="line-height1" style="font-size: 25rpx;">昵称</view>
<text class="line-height1" style="color: #9D9589; font-size: 20rpx;">2019-10-20 下午4点30分</text>
</view>
</view>
<!-- 按钮 -->
<view class="flex aline-center justify-content"
style="width:90rpx; height: 50rpx; border-radius: 5rpx;background-color:#FF4A6A ;color: #FFFFFF;">
关注
</view>
</view>
<!-- 标题 -->
<view style="font-size: 30rpx; margin: 10rpx 0;">
我是标题
</view>
<!-- 图片 -->
<image src="../../static/demo/datapic/11.jpg" style="height: 350rpx; width: 100%; border-radius: 5rpx;"
mode="widthFix">
</image>
<!-- 图标按钮 -->
<view class="flex aline-center">
<view class="flex aline-center justify-content flex-1">
<text class="iconfont icon-dianzan2" style="margin-right: 20rpx;"></text>
<text>赞</text>
</view>
<view class="flex aline-center justify-content flex-1">
<text class="iconfont icon-cai" style="margin-right: 20rpx;"></text>
<text>踩</text>
</view>
<view class="flex aline-center justify-content flex-1">
<text class="iconfont icon-pinglun2" style="margin-right: 20rpx;"></text>
<text>评论</text>
</view>
<view class="flex aline-center justify-content flex-1">
<text class="iconfont icon-fenxiang" style="margin-right: 20rpx;"></text>
<text>转发</text>
</view>
</view>
</view>
</view>
</template>
在APP.vue引入自己定义的CSS库 free.css
/* 引入自定义的CSS库 */
@import url('common/free.css');
3.封装列表样式组件
①自定义的组件进行封装 common-list.vue
<template>
<!-- 列表样式 -->
<view class="p-2">
<!-- 头像昵称 | 关注按钮 -->
<view class="flex aline-center justify-between ">
<view class="flex aline-center">
<!-- 头像-->
<image class="runded-circle mr-2" :src="item.userpic" style="width: 65rpx; height: 65rpx;" lazy-load>
</image>
<!-- 昵称发布时间 -->
<view>
<view class="line-height1 font">{{item.username}}</view>
<text class="line-height1 font-sm text-light-muted">{{item.newstime}}</text>
</view>
</view>
<!-- 按钮 -->
<view class="flex aline-center justify-center rounded bg-main text-white"
style="width:90rpx; height: 50rpx;">
关注
</view>
</view>
<!-- 标题 -->
<view class="font-md my-1">
{{item.title}}
</view>
<!-- 图片 -->
<image :src="item.titlepic" class="rounded w-100" style="height: 350rpx;" mode="widthFix">
</image>
<!-- 图标按钮 -->
<view class="flex aline-center">
<view class="flex aline-center justify-center flex-1">
<text class="iconfont icon-dianzan2 mr-2"></text>
<text>{{item.support.support_count}}</text>
</view>
<view class="flex aline-center justify-center flex-1">
<text class="iconfont icon-cai mr-2"></text>
<text>{{item.support.unsupport_count}}</text>
</view>
<view class="flex aline-center justify-center flex-1">
<text class="iconfont icon-pinglun2 mr-2"></text>
<text>{{item.comment_count}}</text>
</view>
<view class="flex aline-center justify-center flex-1">
<text class="iconfont icon-fenxiang mr-2"></text>
<text>{{item.share_num}}</text>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
item: Object,
index: Number
}
}
</script>
<style>
</style>引入组件
②引入组件
<template>
<view>
<block v-for="(item,index) in list" :key="index">
//组件使用
<common-list :item="item" :index="index"></common-list>
</block>
</view>
</template>
<script>
//组件导入
import commonList from '@/components/common/common-list.vue';
export default {
components: {
// 组件注册
commonList
},
data() {
return {
list: [{
username: "xiao闫",
userpic: "../../static/default.jpg",
newstime: "2019-10-20 下午4点30分",
isFollow: false,
title: "标题",
titlepic: "../../static/demo/datapic/11.jpg",
support: {
type: "support",
support_count: 1,
unsupport_count: 2
},
comment_count: 2,
share_num: 10
},
{
username: "xiao闫",
userpic: "../../static/default.jpg",
newstime: "2019-10-20 下午4点30分",
isFollow: false,
title: "标题",
titlepic: "../../static/demo/datapic/11.jpg",
support: {
type: "support",
support_count: 1,
unsupport_count: 2
},
comment_count: 2,
share_num: 10
}
]
}
},
onLoad() {
},
methods: {
}
}
</script>
<style>
</style>
4.全局分割线开发
① 每个地方都要使用全局分隔线,所以使用组件
<template>
<view style="height: 15rpx; background-color: #f5f5f4;"></view>
</template>
<script>
</script>
<style>
</style>
②在全局导入组件,就不用每个页面都导入一次 main.js
// 引入全局组件
import divider from './components/common/divider.vue';
Vue.component('divider', divider)
③直接使用这个分割线做全局组件
<template>
<view>
<block v-for="(item,index) in list" :key="index">
<!-- //组件使用 -->
<common-list :item="item" :index="index"></common-list>
<!-- 全局分割线 -->
<divider></divider>
</block>
</view>
</template>
5.优化列表组件的动画特效
给组件添加点击动画与点击事件
<template>
<!-- 列表样式 -->
<view class="p-2">
<!-- 头像昵称 | 关注按钮 -->
<view class="flex aline-center justify-between ">
<view class="flex aline-center">
<!-- 头像-->
<image class="runded-circle mr-2" :src="item.userpic" style="width: 65rpx; height: 65rpx;" lazy-load
@click="openSpace()">
</image>
<!-- 昵称发布时间 -->
<view>
<view class="line-height1 font">{{item.username}}</view>
<text class="line-height1 font-sm text-light-muted">{{item.newstime}}</text>
</view>
</view>
<!-- 按钮 -->
<view @click="follow()"
class="flex aline-center justify-center rounded bg-main text-white animate__animated animate__faster"
hover-class="animate__bounceIn" style="width:90rpx; height: 50rpx;">
关注
</view>
</view>
<!-- 标题 -->
<view class="font-md my-1">
{{item.title}}
</view>
<!-- 图片 -->
<image @click="openDtail()" v-if="item.titlepic" :src="item.titlepic" class="rounded w-100"
style="height: 350rpx;" mode="widthFix">
</image>
<!-- 图标按钮 -->
<view class="flex aline-center">
<view class="flex aline-center justify-center flex-1 animate__animated animate__faster"
hover-class="animate__bounceIn text-main" @click="doSupport('support')">
<text class="iconfont icon-dianzan2 mr-2"></text>
<text>{{item.support.support_count}}</text>
</view>
<view class="flex aline-center justify-center flex-1 animate__animated animate__faster"
hover-class="animate__bounceIn text-main" @click="doSupport('unsupport')">
<text class="iconfont icon-cai mr-2"></text>
<text>{{item.support.unsupport_count}}</text>
</view>
<view class="flex aline-center justify-center flex-1 animate__animated animate__faster"
hover-class="animate__bounceIn text-main" @click="openDtail()">
<text class="iconfont icon-pinglun2 mr-2"></text>
<text>{{item.comment_count}}</text>
</view>
<view class="flex aline-center justify-center flex-1 animate__animated animate__faster"
hover-class="animate__bounceIn text-main" @click="openDtail()">
<text class="iconfont icon-fenxiang mr-2 "></text>
<text>{{item.share_num}}</text>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
item: Object,
index: Number
},
methods: {
//点击头像跳转主页 打开个人空间
openSpace() {
console.log("打开个人空间")
},
//点击关注事件
follow() {
console.log("关注")
},
//点击打开帖子详情页面 分享-评论
openDtail() {
console.log("打开帖子详情1")
},
//顶 踩 操作
dSupport(type) {
console.log("顶")
}
}
}
</script>
<style>
</style>
6.优化列表组件-关注功能
① 组件通过this.$emit方法触发一个名为"follow"的自定义事件,并传递了this.index作为事件的参数
//点击关注事件
follow() {
//通知父组件
this.$emit('follow', this.index)
}
<!-- 按钮 -->
<view @click="follow()" v-if="!item.isFollow"
class="flex aline-center justify-center rounded bg-main text-white animate__animated animate__faster"
hover-class="animate__bounceIn" style="width:90rpx; height: 50rpx;">
关注
</view>
② 在使用组件的页进行接收
<common-list :item="item" :index="index" @follow='follow'></common-list>
并自定义方法进行处理
methods: {
// 接收方法
follow(e) { // e 通过this.$emit('follow', this.index) 传过来的参数
console.log("接收" + e)
this.list[e].isFollow = true
//提示消息
uni.showToast({
title: '关注成功'
})
}
}
知识点
//通知父组件
this.$emit('follow', this.index)
//提示消息
uni.showToast({
title: '关注成功'
})

