小白一枚,有错误的地方还请路过大佬指出,感谢
知识点
- uniapp路由与vue路由
- uniapp 的路由和 vue 中的路由有点不一样,uniapp 是通过一个 json 配置,写法和小程序的路由一样,而 vue 的路由是通过一个路由对象,区别如下
//以下是vue的路由写法
import Vue from "vue";
import Router from "vue-router";
import Hello from "@/components/Hello";
import Word from "@/components/Word";
Vue.use(Router);
export default new Router({
routes: [
{
path: "/",
component: Hello,
},
{
path: "/index",
component: Word,
},
],
});
// 这是uniapp的路由写法
{
"pages": [
{
"path": "pages/pc/index"
},
{
"path": "pages/auth/login"
},
{
"path": "pages/auth/register"
}
]
}
- 虽然路由的结构不同,但是传参方式是一样
- 不一样的是,vue 中封装的叫 router,uniapp 中叫 Router,并且 vue 需要在路由配置中声明传参像这样
{
path:'router1/:id',//这里的id是参数
component:Router1
}
- uniapp 中不需要额外的声明就可以直接这样传参
- 绑定样式及类名
- 绑定样式
- 需要注意的是 : 是 v-bind 的缩写,{}中可以写 js 比如简单的三元运算,样式名称需要用驼峰命名代替短杠-如,border-radius 写成 borderRadius
<view
class="progress-left"
:style="{
width: `${rate}%`,
borderRadius:
rate === 100 ? '0.15rem 0.15rem 0.15rem 0.15rem !important' : ''
}"
></view>
- 绑定类名
- 推荐三元运算符
<div :class="[isActive ? activeClass : '', errorClass]"></div>
data() {
return {
isActive:false
}
}
- 组件封装
- 对于一个项目很多地方都需要用的结构可以单独拿出来写成一个组件
- 封装组件要全面,比如不同页面中用到这个组件的样式不一样,那么就需要需要给组件结构动态绑定类名来实现不同样式的切换,可以去看一点 elementui 的源码,比如 button 组件的封装,相信你一定会有收获的
- 关于功能,在我现阶段的开发中,我做的不是很好,同事给我指出了很多错误的地方。什么是组件,很多地方要用到,不仅仅说是样式,还有功能。我之前的错误做法是很多方法 function 定义在了父组件中,导致父组件很臃肿,但是正确做法应该是组件该有的功能必须在这个组件中实现,而不是写到父组件里然后传递给子组件,这样的话,组件就是去了它脱离出来的目的
- v-for
- 写页面的时候遇到三个或者三个以上相同的结构,请一定使用 v-for,因为会简便很多,尤其是需要通过数据来渲染页面时,v-for 能解决你很多困扰,方便对数据进行操作
- 示例
- 切换每一个 tab 都要进行数据请求,这时就可以把结构设计为对象数组
<ul class="choices-ul">
<li
class="choices-li choice-underline"
v-for="(item, index) in typeValues"
:key="index"
@click="currentChange(index)"
>
{{ item.text }}
</li>
</ul>
data() {
return {
currentType:0,
typeValues: [
{
value: "current",
text: "在期合约"
},
{
value: "history",
text: "历史合约"
},
{
value: "review",
text: "我的审核"
}
]
}
},
watch:{
currentType: async function() {
this.getList();
}
},
methods:{
currentChange(index) {
this.currentType = index;
},
async getList() {
let data = await this.loadMyContract({//异步请求
type: this.typeValues[this.currentType].value,
page: this.page,
limit: this.limit
});
}
}
- 监听索引,发生点击事件,索引发生改变,watch 监听到之后执行函数,重新请求数据
- async await
- 如果你需要接收异步请求的返回值,那么可以把函数定义为异步函数 async,并使用 await 来等待请求结束以接收返回值
async loadOneContract() {
let data = await this.loadIndexContract({//这是个请求数据的函数
symbol: this.symbol,
type: this.type,
status: this.typeValues[this.currentType].value
});
this.onshowData = this.formatData(data);
}
- 如果不使用 await 的话,这里接收到的就会是一个 promise,而不是一个 json 对象。await 和 async 是一家的,用了 await 当然不能少了 async
- 重置 elementui 组件样式
-
很多地方我们需要引入别的框架组件库,这里以 element 组件为例,但是它原有的样式可能不是我们想要的,这时候需要修改它的样式,并且需要设置为全局的样式,否则不生效。好像 less 写的样式可以通过/deep/ 这样的操作把样式生效,感兴趣可自行百度。
-
重置样式步骤
- 将组件的示例代码复制过来,引入组件后给这组件最外层或者说就这个元素加上一个类名,这个目的是方便写在全局样式中的样式不会混乱,因为你可能不止一个地方需要用到这个组件并且都需要设置不同的样式,如果不额外加一个类名给这个组件的话,容易污染样式
- 到页面上查看现在的样式是怎么样的,同时对比设计稿上的样式
- F12 打开开发者工具,用鼠标选中组件
- 选中后在开发者工具中直接给组件加样式,看哪些样式会有改变,
- 确定会改变后,复制类名写到全局样式中,并在其前面加上之前自己加的类名,添加注释说明修改的是哪里的样式
- 接着就是慢慢调试,选中结构,在对应的类名修改样式,直到调试成我们需要的样式
-
以分页组件为例
<!-- 下面这个class就是自己添加的类名 -->
<el-pagination
v-if="myContract"
class="userpersonal-pagination"
hide-on-single-page
background
prev-text="上一页"
next-text="下一页"
layout="prev, pager, next"
:total="myContract.total"
@current-change="pageChange"
:page-size="limit"
></el-pagination>
/* 这个是写在全局样式中的 */
/** 个人中心的分页组件-自定义样式 */
.userpersonal-pagination {
display: flex;
align-items: center;
justify-content: center;
}
.userpersonal-pagination .btn-prev,
.userpersonal-pagination .btn-next {
width: 0.71rem !important;
height: 0.28rem !important;
line-height: 0.28rem !important;
background: #787ffc !important;
border-radius: 0.09rem !important;
font-size: 0.14rem !important;
font-weight: 400 !important;
color: #ffffff !important;
border: none !important;
}
.el-pagination uni-button,
.el-pagination span:not([class*="suffix"]) {
line-height: 0.28rem !important;
font-size: 0.14rem !important;
}
.userpersonal-pagination .el-pager .number {
background: none !important;
}
.userpersonal-pagination .el-pager .el-icon-more {
background: none !important;
}
- try catch
- 先上代码
async loginByPassword() {
// 接收状态判断是否为第一次登录
// 1.第一次登录
// dialog弹框使用验证码登录
// 根据用户名接收返回的手机号mobile
// 2.不是第一次登录,使用账号密码登录,调账号密码登录的接口
try {
// 这里的表单验证用的是GraceUI
this.validate(this.form, {
username: {
type: "string",
required: true,
message: "用户名不能为空"
},
password: {
type: "string",
required: true,
message: "密码不能为空"
}
});
this.form.address = this.dappWalletAddress;
// 下面这个是请求登录接口的函数
const data = await this.login(this.form);
} catch (e) {
console.log("错误", e);
if (e.response.data.code == "401") {
// 接收后端返回的手机号
this.mobile = e.response.data.mobile;
}
}
}
- 以前没有真正的写过项目,都是自己弄着玩,所以以前根本就没用过 try,catch 这个东西,但是这次写项目时遇到个问题刚好需要用到这个,所以加上了
- 遇到的问题:场景是这样的,用户注册账号后的第一次登录如果是用户名登录,登录请求时会报错提示你为了安全起见,第一次必须使用电话号码加验证码登录,在这个过程中,后端通过请求的用户名找到该用户的电话号码并返回,但不是正常地用一个变量接收,会抛出异常,而是会在响应体中接收到请求的结果。这时用 try 包裹发起请求的这个函数,然后在 catch 中就可以捕获异常,在这个异常中就是后端返回的结果,手机号就在里面,拿到手机号后就弹框给用户发验证码
- 分页组件
<el-pagination
v-if="myContract"
class="userpersonal-pagination"
hide-on-single-page
background
prev-text="上一页"
next-text="下一页"
layout="prev, pager, next"
:total="myContract.total"
@current-change="pageChange"
:page-size="limit"
></el-pagination>
- 使用的是 elementui 的分页组件,配置项可以看文档,实现分页功能主要是点击上一页下一页以及点击页码时的点击事件,而这三个点击事件都被绑定在@current-change 这个属性,这个属性绑定一个函数,最重要的是这个函数可以接收一个参数,这个参数就是点击后的页码,可以使用这个参数做些需要做的事
methods:{
pageChange(page) {
this.page = page;
// 这个getList函数在第5点出现过
this.getList();
}
}
- echarts
- 新手,只了解九牛一毛,这里只是把我写好的部分分享,有看到需要的属性可以去试试,更多的还是看官方文档,网上也有很多教程
// 引入基本模板
let echarts = require("echarts/lib/echarts");
// 引入柱状图组件
require("echarts/lib/chart/line");
// 引入提示框和title组件
require("echarts/lib/component/tooltip");
require("echarts/lib/component/grid");
require("echarts/lib/component/legend");
require("echarts/lib/component/axis");
var drawLine = function () {
var option = {
title: {
// text: "合约资金及流水折线图",
// backgroundColor: "transparent",
},
axisTick: {},
grid: {
x: 35,
y: 35,
x2: 0,
y2: 20,
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "transparent",
},
},
},
legend: {
icon: "rect",
itemWidth: 10,
itemHeight: 1,
textStyle: {
fontSize: "0.12rem",
color: "#8C8C8C",
},
},
theme: {
// backgroundColor: "rgba(189,26,0,0.8)"
},
xAxis: {
type: "category",
boundaryGap: true,
axisTick: {
// 刻度和坐标值对齐
// inside: true,
alignWithLabel: true,
lineStyle: {
color: "#737589",
},
},
// 改变x轴颜色
axisLine: {
lineStyle: {
color: "#737589",
},
},
// 改变x轴字体颜色和大小
axisLabel: {
interval: 0,
textStyle: {
color: "#FFFFFF",
fontSize: "0.12rem",
},
},
splitLine: {
show: false,
// 改变轴线颜色
lineStyle: {},
},
data: ["9.23", "9.24", "9.25", "9.26", "9.27", "9.28", "9.29"],
},
yAxis: [
{
type: "value",
min: 0,
max: 1000,
interval: 250,
splitLine: {
// 改变轴线颜色
lineStyle: {
// 使用深浅的间隔色
color: "#737589",
},
},
// 隐藏y轴
axisLine: {
show: false,
},
// 去除y轴上的刻度线
axisTick: {
show: false,
},
axisLabel: {
textStyle: {
color: "#FFFFFF",
fontSize: "0.12rem",
},
},
},
],
series: [
{
type: "line",
name: "合约资金",
itemStyle: {
normal: {
color: "#5B8FF9",
lineStyle: {
color: "#5B8FF9",
},
},
},
data: [120, 900, 400, 900, 920, 370, 210],
},
{
type: "line",
name: "流水",
itemStyle: {
normal: {
color: "#5AD8A6",
lineStyle: {
color: "#5AD8A6",
},
},
},
data: [350, 750, 870, 658, 458, 257, 960],
},
],
};
let dom = document.getElementById("info-echarts");
if (dom) {
// 使用刚指定的配置项和数据显示图表。
var myChart = echarts.init(dom);
myChart.setOption(option);
}
};
export { drawLine };
- 打断点调试
- 以前从来没打过断点进行调试,但事实确实很多你找不到 bug 在哪的问题,通过打断点调试都可以解决
- 如何打断点