<template>
|
<div class="stock_list flex-center">
|
<van-row class="markets_head">
|
<van-col span="14" class="flex-start head_item">{{ $t("Name") }}</van-col>
|
<van-col span="4" class="flex-start head_item">{{ $t("Price") }}</van-col>
|
<van-col span="6" class="flex-end head_item">{{ $t("Change") }}</van-col>
|
</van-row>
|
|
<van-list v-model="loading" :finished="finished" :finished-text="$t('沒有更多了')" :loading-text="$t('加载中')"
|
style="height: 50vh;width: 100%;" @load="onLoad">
|
<van-row class="markets_item" v-for="item in stockList" :key="item.id" @click="toDetails(item)">
|
<van-col span="14" class="item_n">
|
<div class="flex-start">
|
<span class="i_icon">{{ item.stock_type }}</span>
|
<span class="i_hint">{{ item.spell }}</span>
|
</div>
|
<div class="i_name">{{ item.name }}</div>
|
</van-col>
|
<van-col span="4" class="flex-start item_n">
|
{{ (Number(item.nowPrice)).toFixed(3) }}
|
</van-col>
|
|
<van-col span="6" class="item_n flex-end">
|
<div class="flex-end" :class="{ green: item.hcrate < 0, red: item.hcrate > 0 }">
|
{{ item.hcrateP }}
|
</div>
|
</van-col>
|
|
<div class="edit flex-end" v-show="editorShow" @click.stop="deleteStock(item)">
|
<span>{{ $t("移除") }}</span>
|
</div>
|
</van-row>
|
</van-list>
|
|
<van-skeleton :row="7" v-if="stockList.length == 0" style="margin-top: 1em;" />
|
</div>
|
</template>
|
|
<script>
|
import * as api from "@/axios/api";
|
import { Toast } from "vant";
|
import { WhrWebSocket } from "@/utils/WhrWebSocket";
|
export default {
|
name: "stock_list",
|
components: {},
|
data() {
|
return {
|
pageNum: 1,
|
pageSize: 20,
|
total: 1,
|
stockList: [],
|
loading: false,
|
finished: false
|
};
|
},
|
props: {
|
propOption: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
listApi: {
|
default: () => {
|
return api.getStockByType;
|
}
|
},
|
// 编辑状态
|
editorShow: {
|
type: Boolean,
|
default: false
|
}
|
},
|
watch: {},
|
mounted() {
|
this.init();
|
this.initWebSocket();
|
},
|
methods: {
|
init() {
|
this.pageNum = 1;
|
this.stockList = [];
|
this.getStockList();
|
},
|
// 获取数据
|
async getStockList() {
|
let opt = {
|
pageNum: this.pageNum,
|
pageSize: this.pageSize,
|
stockPlate: "",
|
keyWords: "",
|
orderBy: ""
|
};
|
|
opt = { ...opt, ...this.propOption };
|
|
let data = await this.listApi(opt);
|
if (data.status == 0) {
|
this.stockList = [...this.stockList, ...data.data.list];
|
// this.total = data.data.total || 1;
|
// 加载状态结束
|
this.loading = false;
|
|
if (data.data.list.length <= 0) {
|
this.finished = true;
|
}
|
}
|
},
|
// 点击进入详情
|
toDetails(item) {
|
const obj = {
|
pid: item.code || "",
|
type: item.stock_type || ""
|
};
|
window.localStorage.setItem("kLine", JSON.stringify(obj));
|
|
this.$router.push({
|
path: "/kline",
|
query: {
|
code: item.code,
|
type: item.stock_type
|
}
|
});
|
},
|
// 删除自选股
|
async deleteStock(item) {
|
let opt = {
|
code: item.code
|
};
|
let data = await api.delOption(opt);
|
if (data.status === 0) {
|
this.$emit("update:editorShow", false);
|
Toast.success(data.msg);
|
this.getStockList();
|
} else {
|
Toast.fail(data.msg);
|
}
|
},
|
// 连接ws实时监控变动
|
initWebSocket() {
|
console.log("initWebSocket");
|
this.Trade = new WhrWebSocket({
|
path: `wss://usws.yanshiz.com/websocket-server `,
|
onmessage: this.getTradeMessage
|
});
|
|
this.Trade.init();
|
},
|
getTradeMessage({ data }) {
|
let result = JSON.parse(data);
|
let pid = result.pid;
|
let userToUpdate = this.stockList.find(item => item.code == pid);
|
if (userToUpdate) {
|
// 更新对象数据
|
userToUpdate.nowPrice = result.last;
|
userToUpdate.hcrateP = result.pcp;
|
}
|
},
|
onLoad() {
|
console.log("dddddddd");
|
|
this.pageNum++;
|
this.getStockList();
|
}
|
},
|
beforeDestroy() {
|
if (this.Trade) {
|
this.Trade.close();
|
console.log("WebSocket disconnected");
|
}
|
}
|
};
|
</script>
|
|
<style lang="less">
|
@green2: #f0f0f0;
|
@dark_green: #07c160;
|
@red: #ee0a24;
|
|
#app {
|
padding-bottom: 1.4rem;
|
}
|
|
.stock_list {
|
flex-direction: column;
|
|
.markets_head {
|
// background-color: @green2;
|
margin-top: 0.25em;
|
height: 1em;
|
width: 100%;
|
padding: 0 0.25em;
|
|
.head_item {
|
font-size: 0.3em;
|
height: 100%;
|
font-weight: 300;
|
color: #898a8e;
|
}
|
}
|
|
.markets_item {
|
padding: 0.5em 0.25em 0.25em;
|
border-bottom: rgba(#fff, 0.2) solid 0.01em;
|
position: relative;
|
|
.item_n {
|
font-size: 0.3em;
|
min-height: 2em;
|
font-weight: 300;
|
|
.i_icon {
|
border-radius: 0 26em 26em 0;
|
background: @dark_green;
|
color: #fff;
|
padding: 0.1em 0.5em 0.1em 0.4em;
|
margin-right: 0.3em;
|
font-size: 0.8em;
|
}
|
|
.i_name {
|
margin-top: 0.3em;
|
color: #777777;
|
font-size: 0.8em;
|
}
|
}
|
|
.up {
|
color: @dark_green;
|
}
|
|
.down {
|
color: @red;
|
}
|
|
.edit {
|
width: 100%;
|
height: 100%;
|
position: absolute;
|
top: 0;
|
left: 0;
|
background: linear-gradient(to right,
|
rgba(0, 0, 0, 0),
|
rgba(0, 0, 0, 0.8));
|
text-align: end;
|
color: @red;
|
padding-right: 0.25em;
|
|
span {
|
font-size: 0.55em;
|
}
|
}
|
}
|
}
|
</style>
|