Full Code of zzy0202/FinanceMobileWeb-Vue for AI

main d18096edf395 cached
32 files
36.0 KB
11.6k tokens
3 symbols
1 requests
Download .txt
Repository: zzy0202/FinanceMobileWeb-Vue
Branch: main
Commit: d18096edf395
Files: 32
Total size: 36.0 KB

Directory structure:
gitextract_ldjd61d0/

├── .gitignore
├── README.md
├── babel.config.js
├── package.json
├── public/
│   └── index.html
├── src/
│   ├── App.vue
│   ├── api/
│   │   ├── articleApi.js
│   │   ├── fundApi.js
│   │   ├── homeApi.js
│   │   ├── index.js
│   │   ├── loginApi.js
│   │   └── stockApi.js
│   ├── assets/
│   │   └── iconfont.css
│   ├── components/
│   │   ├── Article/
│   │   │   └── Comment.vue
│   │   ├── Home/
│   │   │   ├── Article.vue
│   │   │   ├── BottomNav.vue
│   │   │   ├── HeaderNav.vue
│   │   │   ├── HotSpot.vue
│   │   │   └── NaviList.vue
│   │   └── Me/
│   │       ├── MeContent.vue
│   │       └── MeHeader.vue
│   ├── main.js
│   ├── router/
│   │   └── index.js
│   ├── store/
│   │   └── index.js
│   ├── utils/
│   │   └── rem.js
│   └── views/
│       ├── ArticlePage.vue
│       ├── Fund.vue
│       ├── Home.vue
│       ├── Login.vue
│       ├── Me.vue
│       └── Stock.vue
└── vue.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?


================================================
FILE: README.md
================================================
# vue-finance mobile web 
这是一个基于Vue2开发的移动端财经网站

## Project setup
```
npm install
```

### Compiles and hot-reloads for development
```
npm run serve
```

### Compiles and minifies for production
```
npm run build
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).


================================================
FILE: babel.config.js
================================================
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}


================================================
FILE: package.json
================================================
{
  "name": "vue-finance",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  },
  "dependencies": {
    "axios": "^0.26.1",
    "core-js": "^3.6.5",
    "vant": "^2.12.47",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.13",
    "@vue/cli-plugin-router": "~4.5.13",
    "@vue/cli-plugin-vuex": "~4.5.13",
    "@vue/cli-service": "~4.5.13",
    "babel-plugin-import": "^1.13.5",
    "less": "^3.0.4",
    "less-loader": "^5.0.0",
    "vue-template-compiler": "^2.6.11"
  }
}


================================================
FILE: public/index.html
================================================
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>


================================================
FILE: src/App.vue
================================================
<template>
  <div id="app">
    <keep-alive>
      <router-view>
      </router-view>
    </keep-alive>
    <BottomNav></BottomNav>
  </div>
</template>

<script>
  import Home from "@/views/Home";
  import BottomNav from "@/components/Home/BottomNav";
  import Stock from "@/views/Stock";
  import Me from "@/views/Me";
  import Login from "@/views/Login";
  export default {
    name:"App",
    data() {
      return {
        active:null,
      }
    },
    components:{
      Home,BottomNav,Stock,Me,Login,
    }
  }
</script>
<style lang="less">
* {
  padding: 0;
  margin: 0;
}
html {
  background-color: rgb(245, 247, 249);
}
</style>


================================================
FILE: src/api/articleApi.js
================================================
import request from "@/api/index";

let getComment = (params) => {
	return request({
		url: '/article/comments',
		method:"GET",
		params,
	})
}

export {
	getComment,
}


================================================
FILE: src/api/fundApi.js
================================================
import request from "@/api/index";

//获取基金轮播图
let getFund = () => {
	return request({
		url: '/fund/banner',
		method: "GET",
	})
}

let getFundTabList = () => {
	return request({
		url:'/fund/tablist',
		method:"GET",
	})
}

export {
	getFund,getFundTabList
}


================================================
FILE: src/api/homeApi.js
================================================
import request from "@/api/index";

let getHotspot = () => {
	return request({
		method:'GET',
		url:'/quote',
	})
}

let getArticle = (params) => {
	return request({
		method:"GET",
		url:'/articles',
		params,
	})
}

export {
	getHotspot,getArticle,
}


================================================
FILE: src/api/index.js
================================================
import axios from "axios";
import store from '@/store/index'

const request = axios.create({
	baseURL: 'http://api.cpengx.cn/finance/api',
})

request.interceptors.request.use(function (config) {
	if(store.state.user&&store.state.user.token) {
		config.headers.Authorization = 'Bearer '+store.state.user.token;
	}
	return config;
}, function (error) {
	return Promise.reject(error);
})

request.interceptors.response.use(function (response) {
	if(response.status===200) {			//代表拦截到的回应没问题
		return response.data;					//返回数据
	}else {
		return response;							//返回数据有问题
	}
},function (error) {
	return Promise.reject(error);		//出错了,显示错误
})

export default request;


================================================
FILE: src/api/loginApi.js
================================================
import request from "@/api/index";

let getLogin = (data) => {
	return request({
		url: '/login',
		method: "POST",
		data,
	})
}
let getVerifyCode = (params) => {
	return request({
		url: '/code',
		method: "GET",
		params,
	})
}
export {
	getLogin,getVerifyCode
}


================================================
FILE: src/api/stockApi.js
================================================
import request from "@/api/index";

let getStockRank = (params) => {
	return request({
		url: '/stocks',
		method: "GET",
		params,
	})
}

export {
	getStockRank,
}


================================================
FILE: src/assets/iconfont.css
================================================
@font-face {
    font-family: "iconfont"; /* Project id 3336648 */
    src: url('//at.alicdn.com/t/font_3336648_zc9svdlbwz.woff2?t=1650537850371') format('woff2'),
    url('//at.alicdn.com/t/font_3336648_zc9svdlbwz.woff?t=1650537850371') format('woff'),
    url('//at.alicdn.com/t/font_3336648_zc9svdlbwz.ttf?t=1650537850371') format('truetype');
}

.iconfont {
    font-family: "iconfont" !important;
    font-size: 16px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.icon-comment:before {
    content: "\e667";
}

.icon-star:before {
    content: "\e7df";
}

.icon-like:before {
    content: "\e707";
}

.icon-youxiang1:before {
    content: "\e664";
}

.icon-gerenzhongxin:before {
    content: "\e61d";
}


================================================
FILE: src/components/Article/Comment.vue
================================================
<template>
  <div class="comment"  style="z-index: 99">
    <h4>评论</h4>
    <div class="commentUnit" v-for="(item,i) in commentArr.comments" :key="i">
      <div class="header" style="margin-top: 0.1rem;">
        <img :src="item.user.photo_domain+item.user.profile_image_url.split(',')[0]">
        <span style="margin-left: 0.1rem;">{{item.user.screen_name}}</span>
      </div>
      <p v-html="item.text"></p>
      <div class="comment"></div>
    </div>
    <div style="font-size: 0.14rem;text-align:center; margin-top: 0.09rem;">因为后台服务限制,目前暂不支持发表评论</div>
  </div>
</template>

<script>
export default {
  name: "Comment",
  props:['commentArr'],
  mounted() {
    console.log(this.commentArr);
  },
  methods:{
    alert(hello) {
      alert('ksksks');
    }
  }
}
</script>

<style scoped lang="less">
.commentUnit {
  background-color: #efefef;
  display: flex;
  flex-direction: column;
  margin: 0.08rem 0.1rem 0;
  height: 1.2rem;
  .header {
    display: flex;
    align-items: center;
    justify-content: start;
  }
  img {
    width: 0.3rem;
    height: 0.3rem;
    border-radius: 0.3rem;
  }
  span {
    font-size: 0.14rem;
  }
  p {
    margin-top: 0.2rem;
    font-size: 0.14rem;
  }
}

h4 {
  font-size: 0.2rem;
  margin: 0.15rem 0.1rem;
}
</style>


================================================
FILE: src/components/Home/Article.vue
================================================
<template>
  <div class="article">
    <van-icon name="back-top" class="back" size="0.32rem" @click="returnTop"/>
    <div class="articleUnit" @load="getArticleList" v-for="(item,i) in articleArr" v-if="item!==undefined" :key="i" @click="jump(item.original_status.id,item)">
      <div class="header">
        <img
            :src="item.original_status.user.photo_domain+item.original_status.user.profile_image_url.split(',')[0]"
            alt="">
        <div style="margin-left: 0.1rem;">
          <div class="name">{{ item.original_status.user.screen_name }}</div>
          <div class="publishDate">{{ item.original_status.timeBefore }}</div>
        </div>
      </div>
      <div class="content" style="margin: 0 0.05rem 0 0.03rem">
        <p v-html="item.original_status.description"></p>
      </div>
      <div class="footer">
        <van-icon name="share-o" size="0.2rem" style="margin-left: 0.05rem;"/>
        <span>{{ item.original_status.retweet_count }}</span>
        <van-icon name="good-job-o" size="0.2rem"/>
        <span>{{ item.original_status.like_count }}</span>
        <van-icon name="chat-o" size="0.2rem"/>
        <span>{{ item.original_status.reply_count }}</span>
      </div>
    </div>
    <div class="bottom" v-if="loading">正在加载中</div>
    <div class="bottom" v-if="end">你到了世界的尽头</div>
  </div>
</template>

<script>
import {getArticle} from "@/api/homeApi";

export default {
  name: "Article",
  data() {
    return {
      articleArr: [],
      page: 1,
      end: false,
      loading: false,
    }
  },
  methods: {
    async getArticleList() {
      if (!this.end) {
        this.loading = true;
        let res = await getArticle({page: this.page});
        if (res.result && res.result.indexOf('已加载完') !== -1) {
          this.end = true;
          this.loading = false;
        }
        this.page++;
        this.articleArr = this.articleArr.concat(res.items);
      }
    },
    returnTop() {
      cancelAnimationFrame(timer);
      let speed = document.documentElement.scrollTop / 60;
      let timer = requestAnimationFrame(function fn() {
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if (oTop > 0) {
          document.documentElement.scrollTop -= speed;
          timer = requestAnimationFrame(fn);
        } else {
          cancelAnimationFrame(timer);
        }
      });
    },
    debounce(fn, delay) {
      let timer = null;
      return function () {
        if (!timer) {
          timer = setTimeout(fn, delay);
        } else {
          clearTimeout(timer);
          timer = setTimeout(fn, delay);
        }
      }
    },
    show() {
      console.log('loading');
    },
    jump(articleId,params) {
      this.$router.push({name:'Article',params});
    }
  },
  mounted() {
    this.getArticleList();
    let timer = null;
    window.addEventListener('scroll', this.debounce(() => {
      let scrollTop = document.documentElement.scrollTop;
      let scrollHeight = document.documentElement.scrollHeight;
      let innerHeight = window.innerHeight;
      if (scrollHeight - scrollTop - innerHeight < 50) {
        this.getArticleList();
      }
    }, 250));
  }
}
</script>

<style scoped lang="less">
.back {
  position: fixed;
  right: 0;
  top: 50%;
  border-radius: 0.25rem;
  background-color: #f8f6f6;
}

.articleUnit {
  span, div {
    font-size: 0.15rem;
  }

  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 3.68rem;
  border-radius: 0.1rem;
  margin: 0.1rem auto;
  background-color: white;
  box-shadow: 0.01rem 0.01rem 0.01rem #dcdcdc;
  .header {
    margin: 0.12rem 0 0.06rem 0.05rem;
    display: flex;
    justify-content: start;
    align-items: center;
    img {
      width: 0.3rem;
      height: 0.3rem;
      border-radius: 0.3rem;
    }

    div {
      font-size: 0.08rem;
      color: darkgrey;
    }
  }

  .content {
    margin: 0.12rem 0;

    p {
      font-size: 0.12rem;
      line-height: 0.25rem;
    }
  }

  .footer {
    margin: 0.06rem 0 0.12rem;
    display: flex;
    align-items: center;
    justify-content: start;

    span {
      margin: 0 0.2rem 0 0.07rem;
      font-size: 0.12rem;
    }
  }
}

.bottom {
  font-size: 0.12rem;
  color: darkgray;
  text-align: center;
  margin-bottom: 0.1rem;
}
</style>


================================================
FILE: src/components/Home/BottomNav.vue
================================================
<template>
  <div class="bottomNav">
    <van-tabbar v-model="active" v-show="show">
      <van-tabbar-item icon="wap-home-o" to="/">首页</van-tabbar-item>
      <van-tabbar-item icon="chart-trending-o" to="/stock">股票</van-tabbar-item>
      <van-tabbar-item icon="after-sale" to="/fund">基金</van-tabbar-item>
      <van-tabbar-item icon="contact" to="/me">我的</van-tabbar-item>
    </van-tabbar>
  </div>
</template>

<script>
export default {
  name: "BottomNav",
  data() {
    return {
      active:null,
      show:true,
      showNavPath : ['/','/stock','/fund','/me'],
    }
  },
  watch:{
    $route:{
      handler(newRoute,OldRoute) {
        this.show = this.showNavPath.indexOf(newRoute.path) !== -1;
        if(this.show) {
          this.active = this.showNavPath.indexOf(newRoute.path);
        }
      },
      immediate:true,
    },
  }
}
</script>

<style scoped>
.bottomNav {
  margin-top: 0.65rem;
}
</style>


================================================
FILE: src/components/Home/HeaderNav.vue
================================================
<template>
  <div class="headerNav" >
    <van-nav-bar :fixed="true">
      <template #left>
        <span class="iconfont icon-gerenzhongxin"></span>
      </template>
      <template #title>
        <van-search
            v-model="value"
            shape="round"
            placeholder="请输入搜索关键词"
        />
      </template>
      <template #right>
        <span class="icon-youxiang1 iconfont" style="font-size: 0.26rem"></span>
      </template>
    </van-nav-bar>
  </div>
</template>

<script>
export default {
  name: "HeaderNav",
  data() {
    return {
      value:"",
      show:false,
    }
  },
  mounted() {
    window.addEventListener('scroll',()=>{
      if(document.documentElement.scrollTop<40) {
        this.show = false;
      }
      else {
        this.show = true;
      }
    })
  }
}
</script>

<style scoped lang="less">
.iconfont {
  font-size: 0.22rem;
}
::v-deep .van-nav-bar__title {
  max-width: 100%;
  width: 2.5rem;
}
</style>


================================================
FILE: src/components/Home/HotSpot.vue
================================================
<template>
  <div class="hotspot">
    <h5 class="title">今日市场</h5>
    <van-swipe class="my-swipe" :autoplay="3000" indicator-color="skyblue">
      <van-swipe-item v-for="i in 3" >
        <van-grid :column-num="3" :border="false">
          <van-grid-item v-for="item in hotspotData.slice((i-1)*3,(i-1)*3+3)" >
            <h5>{{ item.quote.name }}</h5>
            <h5 :class="parseFloat(item.quote.chg)>0?'red':'green'">{{ item.quote.chg }}%</h5>
            <h5 :class="parseFloat(item.quote.chg)>0?'red':'green'">{{ item.quote.current }}</h5>
          </van-grid-item>
        </van-grid>
      </van-swipe-item>
    </van-swipe>
  </div>
</template>

<script>
import * as api from '@/api/homeApi'

export default {
  name: "HotSpot",
  data() {
    return {
      hotspotData: [],
    }
  },
  async mounted() {
    let res = await api.getHotspot();
    this.hotspotData = res.data.items;
  },
  computed: {
    hotLength() {
      return Math.ceil(this.hotspotData.length/3);
    }
  }
}
</script>

<style scoped lang="less">
h5 {
  font-size: 0.17rem;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  background-color: white;
  padding: 0.02rem;
}

.title {
  margin: auto auto;
  text-align: center;
}

::v-deep .van-grid-item {
  max-width: 33.33%;

  h5 {
    font-size: 0.15rem;
    margin: 0.02rem;
  }

  .green {
    color: forestgreen;
  }

  .red {
    color: orangered;
  }

  .bg {
    background-color: pink;
  }
}
::v-deep .van-swipe__indicators {
  bottom: 0;
  .van-swipe__indicator {
    background-color: grey;
  }
}
.test {
  width: 1.2rem;
  height: 10rem;
  background-color: pink;
}
</style>


================================================
FILE: src/components/Home/NaviList.vue
================================================
<template>
  <div class="naviList" style="margin-top: 0.5rem;">
    <van-grid direction="horizontal" :column-num="4" :border="false">
      <van-grid-item v-for="item in navListArr" :icon="item.imgSrc"  :text="item.title">
      </van-grid-item>
    </van-grid>
  </div>
</template>

<script>
export default {
  name: "NaviList",
  data() {
    return {
      navListArr: [
        {title:'大盘行情',imgSrc:'./imgs/nav1.png',linkTo:''},
        {title:'股票组合',imgSrc:'./imgs/nav2.png',linkTo:''},
        {title:'股票开户',imgSrc:'./imgs/nav3.png',linkTo:''},
        {title:'选股攻略',imgSrc:'./imgs/nav4.png',linkTo:''},
        {title:'指数选基',imgSrc:'./imgs/nav5.png',linkTo:''},
        {title:'基金组合',imgSrc:'./imgs/nav6.png',linkTo:''},
        {title:'私募基金',imgSrc:'./imgs/nav7.png',linkTo:''},
        {title:'基金必看',imgSrc:'./imgs/nav8.png',linkTo:''},
      ]
    }
  }
}
</script>

<style scoped lang="less">
::v-deep .van-grid-item__content--horizontal {
  flex-direction: column;
}
::v-deep .van-grid-item__content--horizontal .van-grid-item__icon+.van-grid-item__text {
  margin-top: 0.1rem;
}
</style>


================================================
FILE: src/components/Me/MeContent.vue
================================================
<template>
  <div class="meContent">
    <h5>服务</h5>
    <van-cell icon="edit" title="申请专栏" is-link />
    <van-cell icon="cash-back-record" title="创作者权益" is-link />
    <van-cell icon="comment-circle-o" title="建议反馈" is-link />

    <h5>其他</h5>
    <van-cell icon="service-o" title="帮助与客服" is-link />
    <van-cell icon="setting-o" title="设置" is-link />
  </div>
</template>

<script>
export default {
  name: "MeContent"
}
</script>

<style scoped lang="less">
h5 {
  font-size: 0.18rem;
  margin: 0.3rem 0.2rem 0.15rem 0.14rem;
}
::v-deep .van-cell__title {
  height: 0.24rem;
  line-height: 0.24rem;
}
</style>


================================================
FILE: src/components/Me/MeHeader.vue
================================================
<template>
  <div class="meHeader">
    <div class="bg" style="background-image:url('./imgs/meBg.png');"></div>
    <div class="content">
      <div class="upperInfo">
        <van-cell-group inset v-if="!user">
          <van-cell title="登录财经通" to="/login" is-link value="登录个人账号"/>
        </van-cell-group>

        <van-cell v-else style="border-radius: 0.07rem;border-bottom: 0.01rem solid #efefef;">
          <template #title>
            <div class="profile">
              <img :src="user.avatar">
              <span >{{user.nickname}}</span>
            </div>
          </template>
        </van-cell>
      </div>
      <div class="bottomInfo">
        <span class="bookmark">
          <img src="/imgs/me1.png">
          <div>收藏</div>
        </span>
        <span class="comment">
          <img src="/imgs/me2.png">
          <div>评论</div>
        </span>
        <span class="liked">
          <img src="/imgs/me3.png">
          <div>赞过</div>
        </span>
        <span class="history">
          <img src="/imgs/me4.png">
          <div>最近</div>
        </span>
      </div>
    </div>
  </div>
</template>

<script>
import {mapState} from 'vuex';

export default {
  name: "MeHeader",
  computed: {
    ...mapState({
      user: state => state.user,
    })
  },
  methods:{
  }
}
</script>

<style scoped lang="less">
.bg {
  height: 1.4rem;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

.meHeader {
  position: relative;
}

.content {
  width: 3.4rem;
  height: 1.8rem;
  background-color: white;
  margin: -1rem auto 0;
  border-radius: 0.1rem;
}

.bottomInfo {
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  margin-top: 0.2rem;

  span {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    div {
      font-size: 0.13rem;
      margin-top: 0.1rem;
    }

    img {
      width: 0.3rem;
      height: 0.3rem;
    }
  }
}
.profile {
  display: flex;
  justify-content: start;
  margin-left:0.04rem;
  border-radius: 0.3rem;
  img {
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 0.4rem;
  }
  span {
    margin-top: 0.05rem;
    margin-left: 0.1rem;
    line-height: 0.38rem;
  }
}
</style>


================================================
FILE: src/main.js
================================================
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './utils/rem'
import Vant from 'vant';
import 'vant/lib/index.css';
import '@/assets/iconfont.css';

Vue.use(Vant);
const bus = new Vue();
Vue.prototype.$bus = bus;
Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')


================================================
FILE: src/router/index.js
================================================
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import ArticlePage from "@/views/ArticlePage";
import Stock from "@/views/Stock";
import Fund from "@/views/Fund";
import Me from "@/views/Me";
import Login from "@/views/Login";

Vue.use(VueRouter)

const routes = [
	{
		path: '/',
		name: 'Home',
		component: Home
	},
	{
		path: '/article/:id',
		name: 'Article',
		props: route => ({ article: route.params }),
		component: ArticlePage
	},
	{
		path: '/stock',
		name: 'Stock',
		component: Stock,
	},
	{
		path:'/fund',
		name:'Fund',
		component: Fund,
	},
	{
		path: '/me',
		name: 'Me',
		component: Me,
	},
	{
		path: '/login',
		name:'Login',
		component: Login,
	}
]

const router = new VueRouter({
	mode: 'hash',
	base: process.env.BASE_URL,
	routes
})

export default router


================================================
FILE: src/store/index.js
================================================
import Vue from 'vue'
import Vuex from 'vuex'
import {getLogin} from "@/api/loginApi";
import {Toast} from "vant";
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    user:localStorage.user?JSON.parse(localStorage.user):null,
  },
  mutations: {
    setUser(state,payload){
      state.user = payload;
      console.log(state.user);
    }
  },
  actions: {
    async asyncLogin(context,payload) {
      let res =await getLogin(payload);
      console.log(res)
      if(res.msg ==='操作成功') {
        Toast.success('登录成功');
        context.commit('setUser',res.result);
        localStorage.user = JSON.stringify(res.result);
        return {user:res.result,successLogin:true};
      }
      else {
        Toast.fail(res.result);
        return {user:res,successLogin:false};
      }
    }
  },
  modules: {
  }
})


================================================
FILE: src/utils/rem.js
================================================
function setRem() {
	let width = document.documentElement.clientWidth;
	let htmlFontsize = width/3.75;
	document.documentElement.style.fontSize = htmlFontsize+'px';
}
window.addEventListener('resize',()=>{
	setRem();
})
setRem();


================================================
FILE: src/views/ArticlePage.vue
================================================
<template>
  <div class="articlePage">
    <div class="articleUnit">
      <van-nav-bar
          left-arrow
          left-text="返回"
          @click-left="quit"
          :fixed="true"
          :placeholder="true"
      />
      <div class="header">
        <img
            :src="articleDetails.original_status.user.photo_domain+articleDetails.original_status.user.profile_image_url.split(',')[0]"
            alt="">
        <div style="margin-left: 0.1rem;">
          <div class="name">{{ articleDetails.original_status.user.screen_name }}</div>
          <div class="publishDate">{{ articleDetails.original_status.timeBefore }}</div>
        </div>
      </div>
      <h5 class="title">{{ articleDetails.original_status.title }}</h5>
      <p class="content" v-html="articleDetails.original_status.text"></p>
    </div>
    <div class="position" ref="hook"></div>
    <Comment :commentArr="commentArr"></Comment>
    <div class="wrap" style="margin-top: 0.4rem;">
      <div class="bottomNav">
      <span class="operation" @click="like($event)">
        <div class="iconfont icon-like"></div>
        <div>{{ articleDetails.original_status.like_count }}</div>
      </span>
        <span class="operation" @click="star($event)">
        <div class="iconfont icon-star"></div>
        <div>{{ articleDetails.original_status.retweet_count }}</div>
      </span>
        <span class="operation" @click="moveComment">
        <div class="iconfont icon-comment"></div>
        <div>{{ commentArr.count }}</div>
      </span>
      </div>
    </div>
  </div>

</template>

<script>
import {getComment} from "@/api/articleApi";
import Comment from "@/components/Article/Comment";

export default {
  name: "ArticlePage",
  props: ['article'],
  data() {
    return {
      articleId: this.$route.params.id,
      commentArr: [],
      liked: false,
      stared: false,
      showComment: false,
    }
  },
  components: {
    Comment,
  },
  async mounted() {
    if (this.article && this.article.original_status) {
      console.log(this.articleId);
      sessionStorage[this.article.id] = JSON.stringify(this.article);
    }
    console.log(this.articleId);
    this.commentArr = await getComment({id: this.articleId.toString()});
  },
  updated() {
    if (this.article && this.article.original_status) {
      console.log(this.articleId);
      sessionStorage[this.article.id] = JSON.stringify(this.article);
    }
  },
  computed: {
    articleDetails() {
      document.documentElement.scrollTop = 0;
      return (this.article && this.article.original_status) ? this.article : JSON.parse(sessionStorage[this.articleId]);
    }
  },
  methods: {
    quit() {
      this.$router.go(-1);
    },
    like(event) {
      this.liked = !this.liked;
      event.currentTarget.style.color = this.liked ? 'red' : 'black';
      if (this.liked) {
        this.articleDetails.original_status.like_count++;
      } else {
        this.articleDetails.original_status.like_count--;
      }
      this.$forceUpdate();
    },
    star(event) {
      this.stared = !this.stared;
      event.currentTarget.style.color = this.stared ? 'orange' : 'black';
      if (this.stared) {
        this.articleDetails.original_status.retweet_count++;
      } else {
        this.articleDetails.original_status.retweet_count--;
      }
      this.$forceUpdate();
    },
    moveComment() {
      console.log(this.$refs.hook);
      document.documentElement.scrollTop = this.$refs.hook.offsetTop;
    }
  }
}
</script>

<style scoped lang="less">
.articlePage {
  height: 100%;
}

.articleUnit {
  span, div {
    font-size: 0.12rem;
  }

  h5 {
    font-size: 0.16rem;
    margin: 0.1rem 0.1rem;
  }

  display: flex;
  flex-direction: column;
  justify-content: center;
  margin: 0 auto;
  background-color: white;
  box-shadow: 0.01rem 0.01rem 0.01rem #dcdcdc;

  .header {
    margin: 0.12rem 0 0.06rem 0.05rem;
    display: flex;
    justify-content: start;
    align-items: center;

    img {
      width: 0.3rem;
      height: 0.3rem;
      border-radius: 0.3rem;
    }

    div {
      font-size: 0.08rem;
      color: darkgrey;
    }
  }

  .content {
    margin: 0.1rem 0.1rem;
    font-size: 0.135rem;
    line-height: 0.2rem;

    ::v-deep img {
      width: 3.4rem;
      display: block;
      margin: 0.08rem auto;
    }
  }
}

h5 {
  font-size: 0.17rem;
}

.bottomNav {
  width: 100%;
  background-color: white;
  display: flex;
  position: fixed;
  bottom: 0;
  right: 0;
  justify-content: end;
  border-top: 1px #e5e4e4 solid;

  .operation {
    height: 0.35rem;
    margin: 0 0.1rem 0.1rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-evenly;
  }

  .iconfont {
    margin: 0.08rem 0.05rem 0.05rem;
    font-size: 0.18rem;
    transition: 0.5s all ease;
  }

  span {
    font-size: 0.14rem;
    display: inline-block;
  }
;
}

.show-enter-active, .show-leave-active {
  transition: all 0.5s;
}

.show-enter, .show-leave-to /* .fade-leave-active below version 2.1.8 */ {
  transform: translateY(1rem);
}
</style>


================================================
FILE: src/views/Fund.vue
================================================
<template>
  <div class="fund">
    <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
      <van-swipe-item v-for="(item,i) in bannerArr">
        <van-image :src="item.icon_url" fit="fill"/>
      </van-swipe-item>
    </van-swipe>
    <van-tabs type="card" v-if="loadingEnd">
      <van-tab :title="item.tab_name" v-for="item in tabListArr">
        <div class="content">
          <div class="title">{{ item.comment }}</div>
          <div class="tips">{{ item.tips }}</div>
          <div class="box" style="margin: 0.1rem auto">
            <div class="data" v-for="(content) in item.items">
              <img :src="content.img_src">
              <span class="name">{{ content.name }}</span>
              <span class="pe">
              <span class="description">{{ content.content[0].desc }}</span>
              <span class="description">{{ content.content[0].value }}</span>
            </span>
              <span class="percentage">
              <span class="description">{{ content.content[1].desc }}</span>
              <span class="description">{{ content.content[1].value }}</span>
            </span>
            </div>
          </div>
        </div>
      </van-tab>
    </van-tabs>
    <div class="loading" style="margin: 0 auto" v-if="!loadingEnd">
      <van-loading style="text-align:center;"/>
    </div>
  </div>
</template>

<script>
import {getFund, getFundTabList} from "@/api/fundApi";

export default {
  name: "Fund",
  data() {
    return {
      bannerArr: [],
      tabListArr: [],
      loadingEnd:false,
    }
  },
  async mounted() {
    getFund().then(res => {
      this.bannerArr = res.data.items;
    });
    getFundTabList().then(res => {
      this.tabListArr = res.data.tab;
      console.log(this.tabListArr);
      this.loadingEnd = true;
    });
  }
}
</script>

<style scoped lang="less">
::v-deep .van-swipe__indicators {
  bottom: 0.32rem;
}

::v-deep .van-swipe__indicator {
  background-color: #666;
}
.box {
  background-color: white;
  width: 3.5rem;
  border-radius: 0.1rem;
}

.content {
  display: flex;
  justify-content: center;
  align-items: start;
  flex-direction: column;
  div {
    margin: 0.1rem 0.1rem 0.04rem 0.1rem;
    font-size: 0.14rem;
  }

  .title {
    color: orange;
    font-weight: 800;
    margin-top: 0.18rem;
  }

  .tips {
    color: grey;
    line-height: 0.20rem;
  }
  .data {
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    border-bottom: 0.02rem rgb(245,247,249) solid;
    div {
      font-size: 0.12rem;
    }
    img {
      width: 0.90rem;
      height: 0.90rem;
    }
    .name {
      flex: 2;
      text-align: center;
      line-height: 0.25rem;
    }
    .pe,.percentage {
      flex: 1.5;
      display: flex;
      text-align: center;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      span {
        margin-bottom: 0.11rem;
      };
    }
  }
}
</style>


================================================
FILE: src/views/Home.vue
================================================
<template>
  <div class="home">
    <!--    这个是Header导航栏-->
    <div style="margin-bottom: 0.3rem;">
      <HeaderNav></HeaderNav>
    </div>
    <!--    这个是导航列表-->
    <NaviList></NaviList>
    <!--    这是热度内容-->
    <HotSpot></HotSpot>
    <!--这是文章推荐列表-->
    <Article></Article>
  </div>
</template>

<script>
// @ is an alias to /src
import HeaderNav from "@/components/Home/HeaderNav";
import NaviList from "@/components/Home/NaviList";
import HotSpot from "@/components/Home/HotSpot";
import Article from "@/components/Home/Article";

export default {
  name: 'Home',
  components: {
    HeaderNav, NaviList, HotSpot, Article,
  },
  data() {
    return {}
  }
}
</script>


================================================
FILE: src/views/Login.vue
================================================
<template>
  <div class="login">
    <div class="header">
      <div style="flex: 1;">
        <img class="logo" src="/imgs/logo.png"><span class="name">熊熊财经通</span>
      </div>
      <div @click="$router.go(-1)" style="flex: 1">
        <img class="quit" src="/imgs/quit.png"><span style="line-height: 0.22rem">退出</span>
      </div>
    </div>
    <div class="content">
      <div class="logo">
        <img class="logoImg" src="/imgs/logo.png">
        <div>登录账户</div>
      </div>
      <div class="loginBox">
        <div class="choose">
          <span @click="move('left')">验证码登录</span>
          <span @click="move('right')">密码登录</span>
          <div ref="activeLine" class="activeLine"></div>
        </div>
        <transition :name="show" mode="out-in">
          <div class="input" style="margin-top: 0.1rem;" v-if="show==='right'" key="password">
            <input v-model="account" placeholder="账户名/手机号" class="phoneNumber">
            <input v-model="password" placeholder="密码" class="password">
          </div>
          <div class="input" style="margin-top: 0.1rem;position: relative" v-if="show==='left'" key="verifyCode">
            <input v-model="account" placeholder="手机号" class="phoneNumber">
            <input placeholder="验证码" class="password">
            <button class="verify" @click="getVerifyCode">获取验证码</button>
          </div>
        </transition>
      </div>
      <van-button @click="login" type="info" style="width: 3rem;border-radius: 0.06rem;margin-top: 0.2rem;">登录
      </van-button>
    </div>
  </div>
</template>

<script>
import {getVerifyCode} from "@/api/loginApi";
export default {
  name: "Login",
  data() {
    return {
      show: 'left',
      account: '',
      password: '',
    }
  },
  methods: {
    move(direction) {
      if (direction === 'right') {
        this.$refs.activeLine.style.left = '1.03rem'
        this.show = direction;
      } else {
        this.$refs.activeLine.style.left = '0';
        this.show = direction;
      }
    },
    async login() {
      let res =await this.$store.dispatch('asyncLogin', {account: this.account, password: this.password});
      if(res.successLogin) {    //登录成功,跳转回到/me
        this.$bus.$emit('hello',res.user);
        this.$router.go(-1);
      }
    },
    async getVerifyCode() {
      let res = await getVerifyCode({mobile:this.account});
      console.log(res);
    }
  }
}
</script>

<style scoped lang="less">
span {
  font-size: 0.16rem;
}

.login {
  background-color: white;
  width: 100%;
  position: absolute;
  bottom: 0;
  top: 0;
  height: 98vh;
  .header {
    margin-top: 0.1rem;
    height: 0.5rem;
    position: relative;
    border-bottom: 0.01rem lightgray solid;
    display: flex;
    align-items: center;
    justify-content: center;
    span, img {
      width: 0.40rem;
      height: 0.25rem;
      display: block;
      top: 0.09rem;
      right: 0.1rem;
      position: absolute;
      font-size: 0.16rem;
      color: grey;
    }

    .logo {
      left: 0.15rem;
      height: 0.3rem;
      width: 0.3rem;
      margin-bottom: 0.03rem;
      top: 0.07rem;
    }

    .quit {
      top: 0.1rem;
      right: 0.587rem;
      width: 0.2rem;
      height: 0.2rem;
    }

    .name {
      top: 0.12rem;
      left: 0.53rem;
      height: 0.2rem;
      width: 1rem;
    }
  }

  .content {
    width: 3.7rem;
    margin: 0.6rem auto;
    display: flex;
    flex-direction: column;
    align-items: center;

    .logo {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      margin-top: 0.2rem;

      img {
        width: 0.4rem;
        height: 0.4rem;
      }

      div {
        font-size: 0.28rem;
        margin-top: 0.2rem;
        font-weight: 400;
      }
    }

    .loginBox {
      display: flex;
      flex-direction: column;
      //align-items: center;
      justify-content: center;

      span {
        width: 0.9rem;
        margin: 0.1rem;
      }

      .choose {
        border-bottom: 1px solid lightgrey;
        height: 1.05rem;
        width: 3.0rem;
        position: relative;

        span {
          font-size: 0.14rem;
          margin: 0.2rem;
          text-align: center;
          width: 1.2rem;
        }

        .activeLine {
          position: absolute;
          height: 0.01rem;
          width: 1.1rem;
          background-color: blue;
          bottom: 0;
          left: 0;
          transition: all 0.5s ease;
        }
      }

      input {
        width: 3.0rem;
        height: 0.3rem;
        font-size: 0.14rem;
        margin: 0.24rem auto 0.3rem;
        display: block;
        border: none;
        border-bottom: 0.01rem solid darkgray;
      }

      .verify {
        font-size: 0.15rem;
        background-color: rgba(51, 137, 245);
        border: none;
        color: white;
        width: 1rem;
        height: 0.33rem;
        position: absolute;
        bottom: 0.38rem;
        right: 0;
        border-radius: 0.1rem;
      }
    }
  }
}


.left-enter-active, .left-leave-active {
  transition: all 0.3s;
}

.left-enter {
  opacity: 0;
  transform: translateX(-0.2rem);
}

.left-leave-to {
  opacity: 0;
  transform: translateX(0.2rem);
}

.right-enter-active, .right-leave-active {
  transition: all 0.3s;
}

.right-enter {
  opacity: 0;
  transform: translateX(0.2rem);
}

.right-leave-to {
  opacity: 0;
  transform: translateX(-0.2rem);
}
</style>


================================================
FILE: src/views/Me.vue
================================================
<template>
  <div class="me">
    <MeHeader></MeHeader>
    <me-content></me-content>
  </div>
</template>

<script>
import MeHeader from "@/components/Me/MeHeader";
import MeContent from "@/components/Me/MeContent";
export default {
  name: "Me",
  components:{
    MeHeader,MeContent
  }
}
</script>

<style scoped>

</style>


================================================
FILE: src/views/Stock.vue
================================================
<template>
  <div class="stock">
    <div class="title">
      <h5>股票榜单</h5>
    </div>
    <van-tabs v-model="active">
      <van-tab :title="item" v-for="(item,i) in stockType">
        <div class="rank">
          <div class="content" v-for="(item,index) in stockRanking[i]">
            <span class="number">{{ index + 1 }}</span>
            <span class="name">{{ item.name }}</span>
            <span class="arrow">
              <img src="/imgs/up.png" v-if="item.chg>0">
              <img src="/imgs/down.png" v-else>
            </span>
            <span class="current">{{ item.current }}</span>
          </div>
        </div>
      </van-tab>
    </van-tabs>
    <div class="loading" style="margin: 0 auto" v-if="!loadingEnd">
      <van-loading style="text-align:center;"/>
    </div>
  </div>
</template>

<script>
import {getStockRank} from "@/api/stockApi";

export default {
  name: "Stock",
  data() {
    return {
      active: null,
      stockRanking: [],
      stockType: ['全球', '沪深', '港股', '美股'],
      loadingEnd:false,
    }
  },
  async mounted() {
    for (let i = 0; i < 4; i++) {
      let res = await getStockRank({type: i});
      this.loadingEnd = true;
      this.stockRanking[i] = res.data.items;
      this.$forceUpdate();
    }
  }
}
</script>

<style scoped lang="less">
h5 {
  font-size: 0.15rem;
  margin: 0 0 0 0.1rem;
  line-height: 0.5rem;
  height: 0.5rem;
}

.title {
  background-color: white;
  border-bottom: 1px #e2e2e2 solid;
}

.rank {
  width: 3.5rem;
  background-color: white;
  margin: 0.15rem auto;
  border-radius: 0.1rem;
  overflow: hidden;
}

.content {
  display: flex;
  margin: 0.1rem 0.1rem 0.2rem;
  align-items: center;

  span {
    font-size: 0.14rem;
    line-height: 0.2rem;
    height: 0.2rem;
  }

  .name {
    flex: 7;
  }

  .number {
    flex: 1;
  }

  .current {
    flex: 2;
  }

  .arrow {
    flex: 1;
    margin-right: 0.08rem;
    img {
      width: 0.14rem;
      height: 0.14rem;
      margin: auto auto;
    }
  }
}
</style>


================================================
FILE: vue.config.js
================================================
module.exports = {
	publicPath: "./",
};
Download .txt
gitextract_ldjd61d0/

├── .gitignore
├── README.md
├── babel.config.js
├── package.json
├── public/
│   └── index.html
├── src/
│   ├── App.vue
│   ├── api/
│   │   ├── articleApi.js
│   │   ├── fundApi.js
│   │   ├── homeApi.js
│   │   ├── index.js
│   │   ├── loginApi.js
│   │   └── stockApi.js
│   ├── assets/
│   │   └── iconfont.css
│   ├── components/
│   │   ├── Article/
│   │   │   └── Comment.vue
│   │   ├── Home/
│   │   │   ├── Article.vue
│   │   │   ├── BottomNav.vue
│   │   │   ├── HeaderNav.vue
│   │   │   ├── HotSpot.vue
│   │   │   └── NaviList.vue
│   │   └── Me/
│   │       ├── MeContent.vue
│   │       └── MeHeader.vue
│   ├── main.js
│   ├── router/
│   │   └── index.js
│   ├── store/
│   │   └── index.js
│   ├── utils/
│   │   └── rem.js
│   └── views/
│       ├── ArticlePage.vue
│       ├── Fund.vue
│       ├── Home.vue
│       ├── Login.vue
│       ├── Me.vue
│       └── Stock.vue
└── vue.config.js
Download .txt
SYMBOL INDEX (3 symbols across 2 files)

FILE: src/store/index.js
  method setUser (line 12) | setUser(state,payload){
  method asyncLogin (line 18) | async asyncLogin(context,payload) {

FILE: src/utils/rem.js
  function setRem (line 1) | function setRem() {
Condensed preview — 32 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (42K chars).
[
  {
    "path": ".gitignore",
    "chars": 231,
    "preview": ".DS_Store\nnode_modules\n/dist\n\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyar"
  },
  {
    "path": "README.md",
    "chars": 308,
    "preview": "# vue-finance mobile web \n这是一个基于Vue2开发的移动端财经网站\n\n## Project setup\n```\nnpm install\n```\n\n### Compiles and hot-reloads for d"
  },
  {
    "path": "babel.config.js",
    "chars": 73,
    "preview": "module.exports = {\n  presets: [\n    '@vue/cli-plugin-babel/preset'\n  ]\n}\n"
  },
  {
    "path": "package.json",
    "chars": 644,
    "preview": "{\n  \"name\": \"vue-finance\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"serve\": \"vue-cli-service serve\","
  },
  {
    "path": "public/index.html",
    "chars": 611,
    "preview": "<!DOCTYPE html>\n<html lang=\"\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=ed"
  },
  {
    "path": "src/App.vue",
    "chars": 642,
    "preview": "<template>\n  <div id=\"app\">\n    <keep-alive>\n      <router-view>\n      </router-view>\n    </keep-alive>\n    <BottomNav><"
  },
  {
    "path": "src/api/articleApi.js",
    "chars": 170,
    "preview": "import request from \"@/api/index\";\n\nlet getComment = (params) => {\n\treturn request({\n\t\turl: '/article/comments',\n\t\tmetho"
  },
  {
    "path": "src/api/fundApi.js",
    "chars": 261,
    "preview": "import request from \"@/api/index\";\n\n//获取基金轮播图\nlet getFund = () => {\n\treturn request({\n\t\turl: '/fund/banner',\n\t\tmethod: \""
  },
  {
    "path": "src/api/homeApi.js",
    "chars": 254,
    "preview": "import request from \"@/api/index\";\n\nlet getHotspot = () => {\n\treturn request({\n\t\tmethod:'GET',\n\t\turl:'/quote',\n\t})\n}\n\nle"
  },
  {
    "path": "src/api/index.js",
    "chars": 662,
    "preview": "import axios from \"axios\";\nimport store from '@/store/index'\n\nconst request = axios.create({\n\tbaseURL: 'http://api.cpeng"
  },
  {
    "path": "src/api/loginApi.js",
    "chars": 266,
    "preview": "import request from \"@/api/index\";\n\nlet getLogin = (data) => {\n\treturn request({\n\t\turl: '/login',\n\t\tmethod: \"POST\",\n\t\tda"
  },
  {
    "path": "src/api/stockApi.js",
    "chars": 165,
    "preview": "import request from \"@/api/index\";\n\nlet getStockRank = (params) => {\n\treturn request({\n\t\turl: '/stocks',\n\t\tmethod: \"GET\""
  },
  {
    "path": "src/assets/iconfont.css",
    "chars": 772,
    "preview": "@font-face {\n    font-family: \"iconfont\"; /* Project id 3336648 */\n    src: url('//at.alicdn.com/t/font_3336648_zc9svdlb"
  },
  {
    "path": "src/components/Article/Comment.vue",
    "chars": 1269,
    "preview": "<template>\n  <div class=\"comment\"  style=\"z-index: 99\">\n    <h4>评论</h4>\n    <div class=\"commentUnit\" v-for=\"(item,i) in "
  },
  {
    "path": "src/components/Home/Article.vue",
    "chars": 4298,
    "preview": "<template>\n  <div class=\"article\">\n    <van-icon name=\"back-top\" class=\"back\" size=\"0.32rem\" @click=\"returnTop\"/>\n    <d"
  },
  {
    "path": "src/components/Home/BottomNav.vue",
    "chars": 925,
    "preview": "<template>\n  <div class=\"bottomNav\">\n    <van-tabbar v-model=\"active\" v-show=\"show\">\n      <van-tabbar-item icon=\"wap-ho"
  },
  {
    "path": "src/components/Home/HeaderNav.vue",
    "chars": 965,
    "preview": "<template>\n  <div class=\"headerNav\" >\n    <van-nav-bar :fixed=\"true\">\n      <template #left>\n        <span class=\"iconfo"
  },
  {
    "path": "src/components/Home/HotSpot.vue",
    "chars": 1646,
    "preview": "<template>\n  <div class=\"hotspot\">\n    <h5 class=\"title\">今日市场</h5>\n    <van-swipe class=\"my-swipe\" :autoplay=\"3000\" indi"
  },
  {
    "path": "src/components/Home/NaviList.vue",
    "chars": 1101,
    "preview": "<template>\n  <div class=\"naviList\" style=\"margin-top: 0.5rem;\">\n    <van-grid direction=\"horizontal\" :column-num=\"4\" :bo"
  },
  {
    "path": "src/components/Me/MeContent.vue",
    "chars": 614,
    "preview": "<template>\n  <div class=\"meContent\">\n    <h5>服务</h5>\n    <van-cell icon=\"edit\" title=\"申请专栏\" is-link />\n    <van-cell ico"
  },
  {
    "path": "src/components/Me/MeHeader.vue",
    "chars": 2227,
    "preview": "<template>\n  <div class=\"meHeader\">\n    <div class=\"bg\" style=\"background-image:url('./imgs/meBg.png');\"></div>\n    <div"
  },
  {
    "path": "src/main.js",
    "chars": 383,
    "preview": "import Vue from 'vue'\nimport App from './App.vue'\nimport router from './router'\nimport store from './store'\nimport './ut"
  },
  {
    "path": "src/router/index.js",
    "chars": 831,
    "preview": "import Vue from 'vue'\nimport VueRouter from 'vue-router'\nimport Home from '../views/Home.vue'\nimport ArticlePage from \"@"
  },
  {
    "path": "src/store/index.js",
    "chars": 823,
    "preview": "import Vue from 'vue'\nimport Vuex from 'vuex'\nimport {getLogin} from \"@/api/loginApi\";\nimport {Toast} from \"vant\";\nVue.u"
  },
  {
    "path": "src/utils/rem.js",
    "chars": 230,
    "preview": "function setRem() {\n\tlet width = document.documentElement.clientWidth;\n\tlet htmlFontsize = width/3.75;\n\tdocument.documen"
  },
  {
    "path": "src/views/ArticlePage.vue",
    "chars": 5066,
    "preview": "<template>\n  <div class=\"articlePage\">\n    <div class=\"articleUnit\">\n      <van-nav-bar\n          left-arrow\n          l"
  },
  {
    "path": "src/views/Fund.vue",
    "chars": 2956,
    "preview": "<template>\n  <div class=\"fund\">\n    <van-swipe class=\"my-swipe\" :autoplay=\"3000\" indicator-color=\"white\">\n      <van-swi"
  },
  {
    "path": "src/views/Home.vue",
    "chars": 678,
    "preview": "<template>\n  <div class=\"home\">\n    <!--    这个是Header导航栏-->\n    <div style=\"margin-bottom: 0.3rem;\">\n      <HeaderNav></"
  },
  {
    "path": "src/views/Login.vue",
    "chars": 5424,
    "preview": "<template>\n  <div class=\"login\">\n    <div class=\"header\">\n      <div style=\"flex: 1;\">\n        <img class=\"logo\" src=\"/i"
  },
  {
    "path": "src/views/Me.vue",
    "chars": 328,
    "preview": "<template>\n  <div class=\"me\">\n    <MeHeader></MeHeader>\n    <me-content></me-content>\n  </div>\n</template>\n\n<script>\nimp"
  },
  {
    "path": "src/views/Stock.vue",
    "chars": 2011,
    "preview": "<template>\n  <div class=\"stock\">\n    <div class=\"title\">\n      <h5>股票榜单</h5>\n    </div>\n    <van-tabs v-model=\"active\">\n"
  },
  {
    "path": "vue.config.js",
    "chars": 41,
    "preview": "module.exports = {\n\tpublicPath: \"./\",\n};\n"
  }
]

About this extraction

This page contains the full source code of the zzy0202/FinanceMobileWeb-Vue GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 32 files (36.0 KB), approximately 11.6k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!