基础片段
安装uView
把 uview-ui 目录放入工程的 uni_modules 目录下
配置uView
- main.js
import Vue from 'vue'
Vue.config.productionTip = false
App.mpType = 'app'
import uView from 'uni_modules/uview-ui';
Vue.use(uView);
const app = new Vue({
...App
})
app.$mount()
- uni.scss
@import "uni_modules/uview-ui/theme.scss";
- App.vue
<style lang="scss">
@import "uni_modules/uview-ui/index.scss";
</style>
- pages.json:
"easycom": {
"^u-(.*)": "uni_modules/uview-ui/components/u-$1/u-$1.vue"
},
跳转到某个页面
-
方式1: 使用 uni-app 的组件 navigator
<navigator url="/pages/menu/menu" hover-class="navigator-hover"> 跳转到新页面 </navigator>注: 其中的 url 也可以用相对路径: "../menu/menu"
-
方式2: 使用uni-app 的api 方法 navigateTo
template中
<u-button type="primary" @click="go">跳转</u-button>script 中
go(){ uni.navigateTo({ url: '/pages/menu/menu' }) }
发出 request 请求
-
使用 uni-app 的 api
-
script 中:
data() {
return {
title: 'Hello',
list:[]
}
},
onLoad() {
uni.request({
url: 'http://simbajs.com:7890/list',
success: ({data}) => {
this.list = data ;
}
})
- template中:
<view v-for="(item,index) in list" :key="index">
{{item}}
</view>
使用 tabBar
- pages.json 中:
"tabBar": {
"color": "#dbdbdb",
"selectedColor": "#d81e06",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/images/home_grey.png",
"selectedIconPath": "static/home.png",
"text": "首页"
}, {
"pagePath": "pages/menu/menu",
"iconPath": "static/images/menu_grey.png",
"selectedIconPath": "static/menu.png",
"text": "菜单"
}]
}
-
注: 需要提前准备好 icon, 可以从 iconfont.cn 下载
-
注: color 和 selectedColor 一般需要和 icon 的颜色一致
跳转到tabBar
-
普通页面跳转, 可以使用navigator 组件或 navigatorTo 方法; 但如果要跳转到 tabBar , 只能用 switchTab 跳转。 此时需要在 navigator 组件中 加入属性 open-type=”switchTab“ 来表明跳转到 tabBar; 或者在javascript中使用 switchTo方法.
-
代码修改:
- 如果是使用 navigator 组件跳转, 则修改后的 navigator 组件, 使用方法如下, 加入了 open-type
<navigator open-type="switchTab" url="/pages/menu/menu" hover-class="navigator-hover"> 跳转到新页面 </navigator>- 如果是使用uni API跳转, 则修改后的 javascript 代码如下:
go(){ // 跳转到 tabBar 页面用 switchTab uni.switchTab({ url: '/pages/menu/menu' }) // 跳转到 普通页面用 navigatorTo // uni.navigateTo({ // url: '/pages/menu/menu' // }) }
使用 轮播图 swipera
- template 中:
<swiper class="swiper" indicator-dots circular autoplay
indicator-color="#eee"
indicator-active-color="#c0133c" >
<swiper-item>
<view class="swiper-item uni-bg-red">A</view>
</swiper-item>
<swiper-item>
<view class="swiper-item uni-bg-green">B</view>
</swiper-item>
<swiper-item>
<view class="swiper-item uni-bg-blue">C</view>
</swiper-item>
</swiper>
- style 中:
.swiper {
width:690rpx;
width: 100%;;
height: 300rpx;
}
.swiper-item {
display: block;
height: 300rpx;
line-height: 300rpx;
text-align: center;
}
.uni-bg-red{
background:#F76260; color:#FFF;
}
.uni-bg-green{
background:#09BB07; color:#FFF;
}
.uni-bg-blue{
background:#007AFF; color:#FFF;
}
轮播图中填入宫格
- template 中:
<swiper class="swiper" indicator-dots circular autoplay
indicator-color="#eee"
indicator-active-color="#c0133c">
<swiper-item>
<u-grid :col="3">
<template v-for="_ in 2">
<u-grid-item
v-for="(item, index) in baseList"
:key="index">
<u-icon :name="item.name" size="22" ></u-icon>
<text>{{item.title}}</text>
</u-grid-item>
</template>
</u-grid>
</swiper-item>
</swiper>
- script 中:
data() {
return {
baseList: [
{
name: 'photo',
title: '图片'
},
{
name: 'lock',
title: '锁头'
},
{
name: 'star',
title: '星星'
},
]
}
}
轮播图中加入图片
- template 中:
<swiper indicator-dots indicator-color="#eee" indicator-active-color="#c0133c" circular autoplay>
<swiper-item>
<image mode="aspectFill" src="http://p1.music.126.net/jKqekReDA3Q4l26sweNMcQ==/109951166925476325.jpg?imageView&quality=89"></image>
</swiper-item>
<swiper-item>
<image mode="aspectFill" src="http://p1.music.126.net/r6aplDsvEDiL8-UJi5eVdw==/109951166925482617.jpg?imageView&quality=89"></image>
</swiper-item>
<swiper-item>
<image mode="aspectFill" src="http://p1.music.126.net/qlBlZF_iHFWv_wcHix15Bw==/109951166923907526.jpg?imageView&quality=89"></image>
</swiper-item>
</swiper>
- style 中:
swiper {
width: 100%;
height: 400rpx;
image {
width: 100%;
height: 100%;
}
}
轮播图封装化为Banner组件( 示例组件封装和props使用)
-
新建文件 components/Banner/Banner.vue
<template> <view> <swiper :indicator-dots="dots" indicator-color="#eee" indicator-active-color="#c0133c" circular :autoplay="autoplay"> <swiper-item v-for='item in info'> <image mode="aspectFill" :src="item.img"></image> </swiper-item> </swiper> </view> </template> <script> export default { name:"Banner", props: { dots: { type: Boolean, default: false, required: false }, autoplay: { type: Boolean, default: false, required: false }, images: { type: Array, // 返回数组(构造缺省数据) default: ()=> [ { img: 'http://p1.music.126.net/jKqekReDA3Q4l26sweNMcQ==/109951166925476325.jpg?imageView&quality=89', }, { img: 'http://p1.music.126.net/r6aplDsvEDiL8-UJi5eVdw==/109951166925482617.jpg?imageView&quality=89', }, { img: 'http://p1.music.126.net/jKqekReDA3Q4l26sweNMcQ==/109951166925476325.jpg?imageView&quality=89', }, ] , required: false } }, data() { return { info: this.images }; } } </script> <style lang="scss" scoped> swiper { width: 100%; height: 400rpx; image { width: 100%; height: 100%; } } </style>注意: 当传入的参数时数组时, props 的default要使用构造函数 ()=>{} 方式. 而不能直接赋值.
其他使用此组件的页面 template 中, 如下使用
<Banner dots autoplay />若不需要 标志器 和 autoplay, 则可以不用写
dots和autoplayuni-app 的 特殊点记录
- style标签中, 不需要手动加 scoped , 框架会自动隔离
- 组件只要规范化命名, 就不需要手动引入, 即
@/components/<MyComponent>/<MyComponent.vue>, 其他页面即可直接使用<MyComponent></MyComponent> - 路由配置在pages.json中, pages数组的第一项就是首页
- 全局对象叫uni ,如请求数据, uni.request()
- 新增响应式样式单位 rpx, 在750px宽的屏幕上, 1rpx = 1px
- swiper有默认高度, 需要手动调整它, 否则图片会被盖住
CSS: 使用flex:1
-
flex-grow, 拉伸因子, 当flex元素宽度的未定义或未达到容器宽度时, 各元素会进行拉伸. 语法为:flex-grow: n;, n有三种取值: 0, 整数, inherit, 0表示不拉伸, 整数 表示拉伸时所占份数, inherit 表示继承上一级设置html 片段
<div class='box' > <div id='box1'></div> <div id='box2'></div> </div>css 片段:
<style> .box { height: 200px; width: 800px; display: flex; } #box1 { background: pink; flex-grw: 1; } #box2 { background: yellow; flex-grow: 3; } </style>以上代码, 一个box中套了两个box, 父box设置为
flex, 则意味着两个子 box 将遵循flex布局规则, 一般是横向排列. 它们的flex-grow分别是1,3, 则代表着横向100%空间, 由两个子box按照 1:3 的比例拉伸占满. -
flex-shrink, 收缩规则, 当flex元素宽度的和超过容器宽度时, 各元素会进行收缩. 语法:flex-shrink: n, n有三种取值: 0, 整数, inherit, 0表示不收缩, 整数 表示收缩时所占份数, inherit 表示继承上一级设置html 片段:
<div class="box"> <div id="box1"></div> <div id="box2"></div> </div>css 片段:
<style lang="scss"> .box { width: 500px; display: flex; } #box1 { width: 400px; background: #c5c5c5; flex-shrink: 1; } #box2 { width: 400px; background: red; flex-shrink: 3; } </style>由于box1和box2的宽度和为800px>500px, 因此子盒子会进行收缩,以满足总宽度500px的要求; 其中box1、box2本身宽度为0(没有内容撑开宽度), 则剩余空间500px将按照1:3 本分配给 box1和box2, 即325px和175px;
-
flex-basis: 元素的初始大小, 可以是一个数值+单位, 也可以是相对于父节点的百分比. 默认为auto
html片段:
<div class="box"> <div id="box1">box1</div> <div id="box2">box2</div> </div>css片段:
<style> .box { height: 200px; display: flex; } #box1 { background-color: lightcoral; flex-basis: 80%; } #box2 { background-color: lightpink; flex-basis: 100px; } </style>box1是占主轴宽度的80%, box2是占100px, 假设主轴宽982px, 则982px*80% -=788.8px, 此时box1和box2的宽度总和为888.8px.
-
flex:1是flex: 1 1数值+单位 的简写方式, 即拉伸/收缩的因子均是1;html片段:
<div class="box"> <div id="box1">box1</div> <div id="box2">box2</div> <div id="box3">box3</div> </div>css片段:
<style> .box { height: 200px; display: flex; } #box1 { background-color: lightpink; flex: 1; } #box2 { background-color: lightsalmon; flex: 1; } #box3 { background-color: lightslategray; flex: 3; } </style>主轴宽度按 box1,box2,box3的 1:1:3 进行自适应伸缩.
CSS: 使用letter-spacing 调整字符间隔
letter-spacing: 2rpx; 此样式设置字符间间隔比一般默认情况下多2rpx, 即会稍稍宽一点;
CSS: 利用div+CSS制作左右布局的导航
html片段:
<view class="container flex">
<view class="menu ">
<view class='item' v-for="(item,index) in menus"
@click='activeIndex=index'
:class='{highLight:index===activeIndex}' >
{{item}}
</view>
</view>
<view class='content'>
<view v-for='item in 10'>
{{item}}
</view>
</view>
</view>
css片段:
.container{
flex: 1;
.menu {
width: 200rpx;
background: #eee;
text-align: center;
.item{
padding: 10rpx;
letter-spacing: 2rpx;
&.highLight {
background:#fff;
font-weight: bold;
border-left: 5rpx solid $main-color;
color: $main-color;
}
}
}
.content {
flex: 1;
}
}
script片段:
data() {
return {
activeIndex: 1,
menus: [
"服装",
"食品",
"饰品",
"家具"
]
};
}
-
其中
view即为div, 顶层div设置为container flex, 代表其孩子节点走flex布局,两个孩子节点左右平铺,分别是menu和content; -
在menu里面
-
通过v-for循环生成菜单选项;
-
通过
class='item'设置样式为item, item样式中padding: 10rpx加大菜单项竖向间隔,letter-spacing:2rpx加大菜单项字符间的间隔 -
通过
:class={highLight===activeIndex}来设置一个条件样式, 即只有item===activeIndex条件成立时,highLight样式才生效. -
highLight样式定义为, 改变背景颜色和字体颜色, 并加重字体, 设置左边框竖线.-
&.highLight { background:#fff; font-weight: bold; border-left: 5rpx solid $main-color; color: $main-color; }
-
-
通过
@click='activeIndex=item'来切换当前选中项 -
备注: 在item 样式里, 有
border-left: 5rpx solid transparent;这是为了让每个 item 都有边框(透明色), 这样选中的item有红色左边框时, 就不会显得和别的菜单项左边对不齐;
-
url字符串含有v-for内容怎么办?
-
场景: 一个 v-for 列表, 每个item有不同的id, 点击其中一个item后, 跳转到item对应页面, 对应页面 url 为 /xxx/xxx/xxx?cate_id=nnn 这种形式, 其中nnn即为每个item的id. 此时可以使用 反引号 "`" 来做字符串拼接, 如下:
<u-grid-item v-for="item in 11"> <navigator :url='`/pages/goods-list/goods-list?cate_id=${item}`'> <image src="/static/good.png"</image> <view class='grid-text'>膨化食品-{{item}}</view> </navigator> </u-grid-item>
在多个页面间跳转时传递参数
-
触发方:
<u-grid-item v-for="item in 11"> <navigator :url='`/pages/goods-list/goods-list?cate_id=${item.id}&cate_name=${item.name}`'> <image src="/static/good.png"</image> <view class='grid-text'>膨化食品-{{item}}</view> </navigator> </u-grid-item>传递了两个参数, 一个是 cate_id, 一个是 cate_name
-
接收方:
onLoad({cate_id, cate_name}) { // option为object, 序列化上个页面传递的参数 uni.setNavigationBarTitle({ title: cate_name }) },
模拟网络请求延迟
- 有时需要模拟一次响应比较慢的网络请求, 比如请求后台数据列表. 纯前台可以用
setTimeout来模拟.
getGoodsList(){
uni.showLoading({ title: '加载中'});
// 模拟ajax请求
setTimeout(()=>{
uni.hideLoading();
this.goodslist = [+new Date]
}, 1000);
}
设置100vh时出现竖向滚动条的处理
-
当有顶部Navigator和底部tabBar时, 在内容区域设置 100vh 将会出现竖向滚动条. 在uni-app中, 顶部Navigator和底部tabBar的高度是固定的, 分别是44px和50px. 因此采用如下方式可以消除滚动条:
-
由于在H5端和APP端, 100vh的表现不同(App端100vh即为不包括顶部导航栏和底部tabBar的高度, 此时不需要减去 44px和 50px), 对此使用条件编译的方式,
.page-body { /*#ifdef APP-PLUS */ height: 100vh; /*#endif*/ /*#ifdef H5*/ height: calc(100vh - 44px); /*#endif*/ } .page-body-tab { /*#ifdef APP-PLUS */ height: 100vh; /*#endif*/ /*#ifdef H5*/ height: calc(100vh - 44px - 50px); /*#endif*/ }
文字显示两行,超出部分显示为省略号的CSS
-
如下情况, 当 item.name 内容很长时, 如何让它显示两行, 超过两行的部分, 自动使用省略号.
-
实现方法有两种, 一种是CSS控制, 一种是使用JS把长字符串截断, 然后后面拼接省略号. 第二种方法对中文和英文混排效果较差, 因为中英文宽度不同. 下面介绍CSS方法.
html片段:
<image src="1.png"></image> <view class="flex flex-col j-s info"> <view> <view class="title bold font16">{{ item.name }}</view> <view class="desc c-desc">销量 55 收藏 22 人气 3456</view> </view> <view class="price bold font16 c-m">¥ 456</view> </view>css片段: 重点看其中的 .title 样式
.info { flex: 1; padding: 0 16rpx; .title { line-height: 20px; max-height: 40px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; word-break: break-all; } .desc { padding: 10rpx 0; } .price { font-size: 36rpx; } }
手机端(APP)和H5端非全屏时, 对顶部状态栏的处理
-
在H5端, 顶部无状态栏, 但是在手机端, 顶部有手机的状态栏, 此时如果不预留这部分位置, 则内容会覆盖手机状态栏. uni-app 提供了一个变量 status-bar-height 来标记此位置的高度, 这个变量在不同的终端值不同, 在手机端有值, 在H5端为0. 具体过程如下
-
Step 1: 定义一个StatusBar组件, 在components目录下新增此组件, 内容如下:
<template> <view> <view class="status_bar"><!-- 状态栏 --></view> </view> </template> <script> export default { name:"StatusBar", } </script> <style lang="scss"> .status_bar { height: var(--status-bar-height); width: 100%; } </style> -
Step 2: 在全屏页面中使用这个组件占位
全屏页面即顶部没有导航栏的页面(一般是主动设置为隐藏), 此类页面, 在顶部首先使用 StatusBar
template片段:
<template> <view> <StatusBar></StatusBar> <!-- 此处放置其他代码 --> </view> </template>
-
JS语法: 解构
-
场景, swiper控件change事件中, 传入的参数event是个复杂对象, 内部有个成员 detail.current , 代表当前swiper item序号, 如下方式可以直接解构出这个current变量
/* handleSwiperChange(e) { console.log(e); this.currendImgIdx = e.detail.current; } */ // 两级解构写法 handleSwiperChange( { detail: {current}} ) { console.log(current); this.currendImgIdx = current; }
使用父子两层相对定位_+ 绝对定位 把子节点固定在父节点某个位置
-
html片段:
<view class="adv relative"> <swiper> <swiper-item v-for='item in info'> <image mode="aspectFill" :src="item.img"></image> </swiper-item> </swiper> <view class="indicator absolute flex a-c"> {{currendImgIdx}} <view class='split'>/</view> {{imgCount}} </view> </view> -
scss片段
.relative { position: relative; } .absolute: { position: absolute; } .adv { swiper { width: 100%; height: 400rpx; image { width: 100%; height: 100%; } } .indicator { bottom: 10rpx; right: 10rpx; padding: 5rpx 10rpx; font-size: 26rpx; border-radius: 6rpx; background: rgba(0, 0, 0, 0.2); color: #fff; .split { padding: 0 6rpx; } } }以上代码把 第二个 div 'indicator' 固定在父div 'adv'的右下角位置
使用 fixed 定位把div固定在底部
-
场景: 底部 购物车/付款 等按钮一直固定且浮动在页面上面
html片段:
<view> <view class="foot-bar"> </view> </view>scss 片段:
.foot-bar { height: 100rpx; width: 100vw; background: red; position: fixed; bottom: 0rpx; }注意: fixed 之后, 就不会有自动100%宽度了, 因此宽度是需要指定的.
使用Flex布局横向铺满
-
场景: 底部foot bar区域, 横向分为三部分, 购物车图标、加入购物车、立即购买, 比例为1:3:3。 使用Flex布局如下
html片段:
<view class="foot-bar fixed flex j-c"> <view class='cart'>1</view> <view class='add2cart flex flex-c'>加入购物车</view> <view class='pay flex flex-c'>立即购买</view> </view>scss片段:
.fixed { position: fixed; } .j-c { justify-content: center; } .a-c { align-items: center; } .flex { display: flex; flex-wrap: wrap; } .flex-c { align-items: center; justify-content: center; } .foot-bar { height: 100rpx; width: 100%; background: red; bottom: 0rpx; .cart { flex: 1; background: #eee; } .add2cart { flex: 3; color: #fff; background: $main-color; } .pay { flex: 3; color: #fff; background: orangered; } }
uni-app使用iconfont图标
- 使用iconfont, 在H5正常, 手机端不现实图标, 此时需要使用base64方式的图标来解决此问题.
- 如果图标的css文件太大超过64K时, 也需拆成两个文件分别导入;
过程如下:
-
把图标加入到 "资源管理/我的项目"
-
在"我的项目"中, 选择"项目设置", 在"字体格式"后只勾选"Base64"
-
在"我的项目"中, 选择"下载至本地", 解压缩zip包, 把其中的"iconfont.css"放置工程的目录
assets/font/下 -
在App.vue 中引入 此css文件:
<script> export default { } </script> <style lang="scss"> @import "uni_modules/uview-ui/index.scss"; @import "assets/font/iconfont.css"; </style> -
此时, 即可在页面上使用iconfont图标了]
template 片段
<view class='cart flex flex-col a-c'> <view class="iconfont icon-gouwuche"></view> <view class='text'>购物车</view> </view> -
还可以使用css对图标进行调整(颜色/大小等)
scss片段
.cart { flex: 1; background: #eee; color: #666; .iconfont { font-size: 42rpx; } .text { font-size: 24rpx; padding: 3rpx 0; } }
图片上放置回退/收藏/转发图标的布局
-
场景: 商城的商品详情页, 商品图片左边是返回图标, 右边是收藏和转发图标
-
实现上依然采用父div相对布局, 子div绝对布局来实现三个图标的放置
template 片段:
<view class="adv relative"> <swiper indicator-color="#eee" indicator-active-color="#c0133c" circular> <swiper-item v-for='item in info.imgList'> <image mode="aspectFill" :src="item"></image> </swiper-item> </swiper> <u-icon class="icon back absolute flex-c" name="arrow-left" color="#eee" size="18" bold></u-icon> <u-icon class="icon collect absolute flex-c" @click="info.hasCollected=!info.hasCollected" :name="info.hasCollected?'star-fill':'star'" :color="info.hasCollected?'#f00':'#eee'" size="18" bold></u-icon> <u-icon class="icon share absolute flex-c" name="share" color="#eee" size="18" bold></u-icon> </view>注: 其中通过三元运算符, 切换收藏图标点击后的显示样式
还可以通和计算属性, 使得html部分代码更为简洁
<u-icon class="icon collect absolute flex-c" @click="info.hasCollected=!info.hasCollected" :name="collectIconName" :color="collectIconColor" size="18" bold></u-icon>computed: { collectIconName() { return this.info.hasCollected? 'star-fill': 'star' } collectIconColor() { return this.info.hasCollected? '#f00' : '#eee' } }scss 片段
.relative { position: relative; } .absolute { position: absolute; } .adv { swiper { width: 100%; height: 400rpx; image { width: 100%; height: 100%; } } .icon { top: 30rpx; width: 60rpx; height: 60rpx; border-radius: 50%; background: rgba(0,0,0,0.3); &.back { left: 30rpx; } &.collect { right: 120rpx; } &.share { right: 30rpx; } } }注: 通过绝对定位
javascript片段:
data() { return { info: { hasCollected: false, imgList: [ '1.png', '2.png', ] } }; },
如何实现navigator的返回: uni.navigateBack()
-
当使用 navigator 进入某一页后, 点击返回时返回来的页面
template 片段:
<u-icon class="icon back absolute flex-c" @click="handleBack" name="arrow-left" color="#eee" size="18" bold></u-icon>javascript 片段:
methods: { handleBack() { uni.navigateBack() } }
如何通过图片边缘模糊, 实现边缘上的按钮更醒目
-
场景: 商品图片上面往往浮动一些icon, 若左上角的返回, 右上角的 收藏/分享, 右下角的图片滑动角标; 有时候由于图片颜色较深, 导致这些icon不明显.
-
实现: 通过图片边缘模糊, 让图片边缘浅色化, 使得icon显性化 template 片段:
<view class="adv relative"> <swiper> <swiper-item v-for='item in info.imgList'> <image mode="aspectFill" :src="item"></image> </swiper-item> </swiper> <view class="indicator absolute flex a-c"> {{currendImgIdx}} <view class='split'>/</view> {{imgCount}} </view> <!-- 左上角 "返回" --> <u-icon class="icon back absolute flex-c" @click="handleBack" name="arrow-left" color="#eee" size="18" bold> </u-icon> <!-- 右上角 "收藏" --> <u-icon class="icon collect absolute flex-c" @click="info.hasCollected=!info.hasCollected" :name="info.hasCollected?'star-fill':'star'" :color="info.hasCollected?'#f00':'#eee'" size="18" bold> </u-icon> <!-- 右上角 "分享" --> <u-icon class="icon share absolute flex-c" @click="handleShare" name="share" color="#eee" size="18" bold> </u-icon> </view>scss片段:
image { width: 100%; height: 100%; } image:after { position: absolute; content: ''; width: 100%; height: 100%; top: 0; left: 0; box-shadow: 0 0 50px 10px #fff inset; }注1: 直接为外层DIV添加边缘阴影是看不到效果的, 因为阴影会被DIV中的图片遮住. 因此, 必须通过一个绝度定位的伪元素 image:after 添加阴影.
文字和控件左右靠边对齐
-
效果: 文字在左边, 比如"购买信息", 控件在右边, 例如"步进器"
template片段:
<view class="flex j-s"> <view>购买数量</view> <u-number-box v-model="buyNumber" ></u-number-box> </view>scss片段:
.flex { display: flex; flex-wrap: wrap; } .j-s { justify-content: space-between; }如果不加flex样式, 则文字"购买数量"和步进器控件u-number-box 会处于两行. 通过在其父节点增加 class="flex j-s"使得它们在一行上.其中的
j-s确保两者横向两端对齐.
使用样式交集复用并部分改写原样式
-
场景: 已有样式 foot-bar , 想在本div中复用既有 foot-bar 样式, 但修改其中的部分属性
-
方式: 通过设置本div的样式为
class ="sku foot-bar ",并且在 scss 中取两个样式交集template 片段:
<view class="sku foot-bar fixed flex j-c font16"> <view class='add2cart flex flex-c' >加入购物车</view> <view class='pay flex flex-c' >立即购买</view> </view>注: 其中的foot-bar, add2cart, pay 三者都是已经存在且定义的css样式
scss片段:
.sku.foot-bar { border-radius: 50rpx; overflow: hidden; bottom: 10rpx; width: 90%; left: 0; right: 0; margin: 0 auto; .add2cart, .pay { flex: 1; } }- 使用
.sku.foot-bar交集写法 - 新覆盖了原来
.add2cart,.pay中的flex:n的设置值, 重新设置为flex:1; - div改为圆角:
border-radius: 50rpx; overflow: hidden;其中overflow把圆角以外的隐藏不显示 - div居中: 使用了
width:90%; left:0; right:0; margin:0 auto;联合, 整个div居中
- 使用
使用 scroll-view 达到popup中部分内容滚动的效果
-
场景: 在popup 底部弹出的div中, 其最下面 foot-bar 区域的 "加入购物车"和"立即购买" 两个按钮不滚动, 但上面的商品规格介绍区域需滚动,
-
方式: 可以把商品高规格介绍区域放入 scrolll-view 进行滚动, 然后把 foot-bar 区域相对于popup 层绝对定位在底部
template片段:
<u-popup :show="showSKU" :round="10" mode="bottom"> <!-- 滚动区域, 设置高度为700rpx , 超出部分沿y轴滚动--> <scroll-view class="u-popup" scroll-y="true" style="height:700rpx"> <!-- 内容区域略 --> </scroll-view> <!-- 非滚动区域, 使用 absolute 定位 --> <view class="sku foot-bar absolute flex font16"> <view class='add2cart flex flex-c' @click="add2Cart" >加入购物车</view> <view class='pay flex flex-c' @click="buy">立即购买</view> </view> </u-popup>scss 片段:
.u-popup{ padding: 20rpx; } .sku.foot-bar { // 底部按钮区域, 居中圆角效果 width: 90%; border-radius: 50rpx; overflow: hidden; bottom: 10rpx; left: 0; right: 0; margin: 0 auto; }
使用 mixin 制作Vue插件
-
场景: 大量的方法, 是否可以通过 mixin 混入到 Vue 对象上, 并简化其使用方式? 类似 uView 被 Vue对象use. 这样调用时就可以使用
this.xxx直接调用 -
方式: 使用 Vue.mixin() 方法
-
step1: 在项目目录下新建 plugins 目录, 下面新建 mixin.js 内容如下
// 导出一个函数, 函数需传入一个参数 Vue, 这个Vue 就是插件调用本方法时传入的Vue // export default function(Vue) { // // } export default Vue=>{ Vue.mixin({ data(){ return { } }, methods:{ $go(url, isTab=false) { if(isTab) { uni.switchTab({url}) }else{ uni.navigateTo({url}) } }, __msg__(type, message, desc) { this.$notification[type]({ message, desc, duration: 2, }) }, $ms(message="操作成功", desc="稍后将为您呈现最新效果") { this.__msg__('success', message, desc) }, $me(message="操作失败", desc="请刷新页面后重试") { this.__msg__('error', message, desc) } } }) )备注: 主要是对Vue的方法进行混入(mixin). 此处是混入 go 方法
-
step2: 在项目目录 plugins 目录下面新建 index.js, 内容如下
// 此文件负责 // import installMixins from './mixin' // import installDirectives from './directive' // import installFilters from './filter' // import extendVuew from './vue-extend' // import registerComponents from './component' // 导入 mixin 函数, 便于调用它把go 方法注册到全局Vue对象 // install(Vue) 是缺省被回调的函数, 当main.js调用 Vue.use(xxx)时, 就会调用此方法 import installMixins from "./mixin" export default { install(Vue) { installMixins(Vue) // installDirectives(Vue) // installFilters(Vue) // registerComponents(Vue) // registerComponents(Vue) } }备注: 插件的写法是必须安装Vue, 然后使用方法
-
step3: 在main.js中增加如下代码, 把插件挂接到 Vue 上
import Vue from 'vue' // 新增的两行如下 import naviPlugin from "./plugins" Vue.use(naviPlugin) const app = new Vue({ ...App }) app.$mount() -
step4: 使用插件, 通过 this.go() 可以直接使用此插件
this.$go('/pages/shop-cart/shop-cart', false)
-