一,Vuex的使用
1 import Vue from ‘vue‘ 2 import Vuex from ‘vuex‘ 3 import MsgModules from ‘./MsgModules‘ 4 Vue.use(Vuex) 5 export default new Vuex.Store({ 6 modules: { 7 msg: MsgModules 8 } 9 })
1 export default{ 2 state: { 3 CheckedMenu: ‘‘, //菜单选中变量 4 CheckedLottoryHistory: [] //彩票历史变量 5 }, 6 mutations: { 7 setCheckedMenu (state, index) { 8 state.CheckedMenu = index 9 }, 10 setHistory (state, arr) { 11 state.CheckedLottoryHistory = arr 12 } 13 }, 14 getters: { 15 }, 16 actions: { 17 } 18 }
state中声明各种状态变量,使用方法this.$store.state.msg.xx
mutations中对state中状态做同步修改this.$store.commit("xx",obj),只能有一个obj参数
getters中为获取状态变量的方法this.$store.getters.xx
actions中可以支持异步操作状态变量this.$store.dispatch("xx",obj)
vuex.store使用modules可以统筹多个状态管理文件,使业务分离,便于维护
二,Vue核心,组件的编写
1 <template> 2 <div> 3 <div class="nav"> 4 <div class="channel"> 5 <ul> 6 <li v-for="(menu,index) in menulist" :key="index"> 7 <LinkBtn :title="menu.DESCR" :index="index"></LinkBtn> 8 </li> 9 </ul> 10 </div> 11 </div> 12 <ul class="newsContent" v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10"> 13 <li class="section" v-for="(item, index) in types" :key="index"> 14 <LastIssueItem :code="item" :name="categorys.CAI[item].DESCR"></LastIssueItem> 15 </li> 16 </ul> 17 </div> 18 </template> 19 20 <script> 21 import { Indicator } from ‘mint-ui‘ 22 import LinkBtn from ‘@/components/LinkBtn‘ 23 import LastIssueItem from ‘@/components/LastIssueItem‘ 24 export default { 25 data () { 26 return { 27 busy: false, 28 categorys: {}, 29 menulist: [], 30 types: [] 31 } 32 }, 33 mounted () { 34 this.$myaxios.get(‘http://misc.opencai.net/consts/lotts.json‘) // 使用自定义的axios来做ajax操作 35 .then((response) => { 36 if (response.data) { 37 this.categorys = response.data 38 this.menulist = response.data.GRP.C // 菜单数据 39 let firstKey = Object.keys(this.menulist)[0] // 第一个菜单的关键字 40 this.$store.commit(‘setCheckedMenu‘, firstKey) // 设置第一个菜单被选中,状态提交至vuex的状态管理器中 41 this.types = this.menulist[firstKey].CODES // 第一个菜单下的各类彩票编码集合 42 } 43 }) 44 }, 45 watch: { 46 CheckedMenu: { /* 监听菜单是否切换 */ 47 handler (newValue, oldValue) { 48 let self = this 49 self.busy = true 50 setTimeout(() => { 51 if (self && !self._isDestroyed) { 52 // 菜单发生切换之后,从集合中获取新的大类下的彩票类别10条 53 self.types = self.menulist[newValue].CODES.slice(0, 10) 54 self.busy = false 55 } 56 }, 500) 57 }, 58 deep: true 59 }, 60 busy (newValue, oldValue) { 61 if (newValue) { 62 Indicator.open({text: ‘加载中...‘, spinnerType: ‘fading-circle‘}) 63 } else { 64 Indicator.close() 65 } 66 } 67 }, 68 components: { 69 LinkBtn, 70 LastIssueItem 71 }, 72 computed: { 73 CheckedMenu () { 74 scrollTo(0, 0) 75 // 获取Vuex状态管理器中的选中菜单,如果状态管理器中菜单值发生改变,此处的计算属性也会发生改变 76 return this.$store.state.msg.CheckedMenu 77 } 78 }, 79 methods: { 80 loadMore () { 81 let i = this.types.length 82 if (i > 0) { 83 // 加载更多时,从某大类下获取所有彩票类型编码 84 let childs = this.menulist[this.CheckedMenu].CODES 85 // 如果大类下的彩票编码数量大于当前彩票编码数量则可以加载更多 86 if (childs.length > i) { 87 this.busy = true 88 // 从大类下的彩票编码集合中截取更多10条加入当前彩票编码集合 89 let array = childs.slice(i, i + 10) 90 for (var j = 0; j < array.length; j++) { 91 this.types.push(array[j]) 92 } 93 this.busy = false 94 } 95 } 96 } 97 } 98 } 99 </script> 100 101 <style lang="css" scoped> 102 .nav { 103 width: 100%; 104 height: .96rem; 105 background-color: #f4f5f6; 106 display: flex; 107 position: fixed; 108 z-index: 99; 109 } 110 .channel { 111 display: inline-block; 112 flex: 1; 113 white-space: nowrap; 114 display: flex; 115 align-items: center; 116 overflow-x: scroll; 117 font-size: .30rem; 118 color: #4b4949; 119 } 120 .channel::-webkit-scrollbar { 121 height: 0; 122 } 123 .channel ul li { 124 display: inline-block; 125 } 126 .newsContent { 127 padding-top: 0.96rem; 128 } 129 .section { 130 width: 100%; 131 height: 2.24rem; 132 border-bottom:1px solid #ccc; 133 } 134 </style>
可以看到组件中引入了两个自定义的组件,横向大类菜单和纵向各类彩票最新一期的信息。使用了Mint-UI中的Infinite scroll来做无限滚动加载,Indicator来做loading。唯一的操作“菜单切换”使用vuex来做状态管理。最终效果如下图
列表的子项组件,当传入某彩票编码时,获取彩票的数据
1 <template lang="html"> 2 <div class="news" @click="toDetail"> 3 <div class="p"> 4 <span class="s1">{{name}}</span> 5 <span class="s2">第{{Detail&&Detail.expect||""}}期</span> 6 <span class="s3"> 7 <span style=" color:grey;">开奖:</span> 8 <span v-if="Detail.hasOwnProperty(‘opentime‘)&&Detail.opentime"> 9 {{(new Date(Detail.opentime)).toLocaleDateString()}} 10 </span> 11 </span> 12 </div> 13 <div class="p"> 14 <span v-for="(value, index) in RedBall" class="ball1" :key="‘Red‘+index"> 15 <span class="word"> 16 {{value}} 17 </span> 18 </span> 19 <span v-for="(value, index) in BlueBall" class="ball2" :key="‘Blue‘+index"> 20 <span class="word"> 21 {{value}} 22 </span> 23 </span> 24 </div> 25 </div> 26 </template> 27 28 <script> 29 export default { 30 data () { 31 return { 32 List: [], 33 Detail: {}, 34 RedBall: [], 35 BlueBall: [] 36 } 37 }, 38 props: [‘code‘, ‘name‘], 39 mounted () { 40 // 此处根据传过来的彩票代码获取彩票最新的数据 41 this.$myaxios.get(‘/api/‘ + this.code + ‘-20.json‘) 42 .then((response) => { 43 if (response.data.rows > 0) { 44 // 某类彩票的最近20条数据 45 this.List = response.data.data 46 // 某类彩票的最近一条数据 47 this.Detail = response.data.data[0] 48 // 彩票数据的数字码 49 if (this.Detail.hasOwnProperty(‘opencode‘) && this.Detail.opencode) { 50 let arr = this.Detail.opencode.split(‘+‘) 51 if (arr.length > 0) { 52 if (arr[0]) { 53 this.RedBall = arr[0].split(‘,‘) 54 } 55 if (arr[1]) { 56 this.BlueBall = arr[1].split(‘,‘) 57 } 58 } else { 59 this.RedBall = this.Detail.opencode.split(‘,‘) 60 } 61 } 62 } 63 }) 64 }, 65 methods: { 66 toDetail () { 67 // 点击时,将某彩票的历史数据传递给Vuex的状态管理器。然后在历史页中直接获取这些历史数据并呈现 68 this.$store.commit(‘setHistory‘, this.List) 69 this.$router.push({path: ‘/history‘, query: { name: this.name }}) 70 } 71 }, 72 computed: { 73 } 74 } 75 </script> 76 77 <style lang="css" scoped> 78 .news { 79 height: 2.24rem; 80 box-sizing: border-box; 81 width: 100%; 82 padding: 0.01rem; 83 } 84 .p{ 85 height: 1.12rem; 86 line-height: 1.12rem; 87 padding-left: .1rem; 88 padding-right: .1rem; 89 vertical-align:middle; 90 width: 100%; 91 display:inline-block; 92 } 93 .s1{ 94 color:blue; 95 width: 30%; 96 padding:2px; 97 } 98 .s2{ 99 padding-left:2px; 100 padding-right: 2px; 101 } 102 .ball1{ 103 border-radius: 50%; 104 height: 20px; 105 width: 20px; 106 display: inline-block; 107 background: #f54646; 108 vertical-align: top; 109 } 110 .ball2{ 111 border-radius: 50%; 112 height: 20px; 113 width: 20px; 114 display: inline-block; 115 background: #39f; 116 vertical-align: top; 117 } 118 .word{ 119 display: block; 120 color: #FFFFFF; 121 height: 20px; 122 line-height: 20px; 123 text-align:center; 124 } 125 </style>
三,路由设置
1 import Vue from ‘vue‘ 2 import Router from ‘vue-router‘ 3 import index from ‘@/pages/index‘ 4 import history from ‘@/pages/history‘ 5 6 Vue.use(Router) 7 8 export default new Router({ 9 mode: ‘history‘, 10 routes: [ 11 { 12 path: ‘/‘, 13 component: index 14 }, 15 { 16 path: ‘/history‘, 17 component: history 18 } 19 ], 20 scrollBehavior (to, from, savedPosition) { 21 return { x: 0, y: 0 } 22 } 23 })
四,工程的入口main.js,引入各种包和声明全局变量
1 import Vue from ‘vue‘ 2 import App from ‘./App‘ 3 import axios from ‘axios‘ 4 import router from ‘./router‘ 5 import store from ‘./store/‘ 6 import MintUI from ‘mint-ui‘ 7 import ‘mint-ui/lib/style.css‘ 8 Vue.use(MintUI) 9 10 Vue.config.productionTip = false 11 axios.default.timeout = 5000 12 Vue.prototype.$myaxios = axios 13 14 /* eslint-disable no-new */ 15 let vm = new Vue({ 16 el: ‘#app‘, 17 router, 18 store, 19 template: ‘<App/>‘, 20 components: { App } 21 }) 22 console.log(vm)
原文地址:https://www.cnblogs.com/shi2310/p/8618483.html
时间: 2024-10-06 22:42:10