最近刚刚写好了网易云音乐(wymusic )的实例,那就总结总结吧~~~~
先感谢感谢前人的努力吧
因为Binaryify 大神对接口的不对更新才有了这篇文章,感谢感谢!
公共引用
main.js(以element ui的使用为例)
1 2 3 import Element from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(Element)
关于分类
将view文件统一放在 src/pages/ 下面
将component文件统一放在 src/components/ 下面
vue-router
router/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 mport Vue from 'vue' import Router from 'vue-router' import Recommend from '@/pages/Recommend' import LeaderBoards from '@/pages/LeaderBoards' Vue.use(Router) export default new Router({ routes: [ { path:'', redirect: '/recommend' }, { path: '/recommend', name: 'recommend', component: Recommend } ] })
src/app.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <template> <div id="app"> <router-view :key="key" /> </div> </template> <script> export default { name: 'app', data () { return {} }, methods: { }, computed:{ key() { return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date() } } } </script>
ps:我创建和编辑的页面使用的是同一个component,默认情况下当这两个页面切换时并不会触发vue的created或者mounted钩子,官方说你可以通过watch $route的变化来做处理,但其实说真的还是蛮麻烦的。后来发现其实可以简单的在 router-view上加上一个唯一的key,来保证路由切换时都会重新渲染触发钩子了。这样简单的多了。
组件引用
src/pages/Recommend.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <template> <div id="Recommend"> <BannerComponent></BannerComponent> </div> </template> <script> import BannerComponent from '@/components/BannerComponent' export default { name:"Recommend", components:{ BannerComponent, AlbumComponent, SingersComponent, MVComponent }, data () { return {}; } } </script>
组件之间通信
父子组件之间(props)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 //在父组件中注册子组件 //父组件(Recommend.vue): <template> <BannerComponent :toBanner="bannerJson.banners" title="recommend-banner"></BannerComponent> </template> .... //子组件(BannerComponent.vue): <template> <div id="BannerComponent" v-if="title === 'recommend-banner'"> <swiper :options="swiperOption"> <swiper-slide v-for="(item,index) in toBanner" :key="index"> <img :src="item.pic | filterImg"> </swiper-slide> <div class="swiper-pagination" slot="pagination"></div> <div class="swiper-button-prev" slot="button-prev"></div> <div class="swiper-button-next" slot="button-next"></div> </swiper> </div> </template> <script> export default{ name: 'BannerComponent', props:['toBanner','title'], data () { return {} } } </script>
ps: (:toBanner)代表值是动态获取的;(title)代表值是静态的
子父组件传值(emit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 //子组件: <template> <button @click="sendToParent">向父组件传值</buttoon> </template> <script> export default { methods: { sendToParent() { this.$emit("listenToChild","this message is from child"); } } } </script> ..... //父组件: <template> <child listenToChild="showMsgFromChild"></child> </template> <script> export default{ data(){ return {}; }, methods: { showMsgFromChild(data){ console.log(data); //this message is from child } } } </script>
vuex
封装axios
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //src/config.js import Vue from 'vue' import axios from 'axios' import qs from 'qs' Vue.prototype.$http = axios // 这样设置就可以在组件内用 this.$http 使用axios了 axios.defaults.baseURL = 'http://localhost:3000' export var axiosRq = async(type = 'POST', url = '', data = {}) => { let result type = type.toUpperCase() if (type === 'GET') { await axios.get(url, { params: data }) .then(res => { result = res.data }) } else if (type === 'POST') { await axios.post(url, qs.stringify(data)) .then(res => { result = res.data }) } return result }
使用
在src先新建store文件夹
store中目录包含 index.js 和 modules文件夹
在src/main.js中引用store
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 //src/store/index.js import Vue from "vue" import Vuex from 'vuex' import banner from './modules/banner' Vue.use(Vuex) export default new Vuex.Store({ modules: { banner } }) src/store/modules/banner.js import { axiosRq } from "../../config" export default { state: { banner:[] }, mutations: { GETBANNER (state, res) { state.banner = res; } }, actions: { async getBannerData ({commit}) { let res = await axiosRq('GET', 'banner') if(res) { commit('GETBANNER',res); } } } }
在view中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 //Recommend.vue <template> {{bannerJson}} </template> <script> import { mapState, mapMutations, mapActions } from 'vuex' export default { data () { return {} }, methods: { ...mapAction([ 'getBannerData' //相当于this.$store.dispatch('getBannerData') ]) }, computed: { ...mapState({ 'bannerJson': state = > state.banner.banner, //第一个banner是export的banner对象,第二个banner是banner.js state值 }) }, mounted() { this.getBannerData(); // 调用banner接口 } } </script>
公共js(filter.js为例) 将公共js部分写在src/filter.js内,在src/main.js中导入即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //filter.js import Vue from 'vue' Vue.filter('transformTime', (value)=>{ if(!value) return '' let date = new Date(value) let time if(date.getHours() === 0 ){ time= date.getMinutes() + ":" + date.getSeconds() }else{ time = date.getHours() +":"+ date.getMinutes() + ":" + date.getSeconds() } return time }) //引用(src/main.js) import "@/filter.js" //使用 {{ message | transformTime }}
sass
将公共变量写在 src/assets/css/variables.scss
将公共样式写在 src/assets/css/style.scss
在src/main.js 中引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //variables.scss $grey:#eee; $font-title-color:#333; $font-detail-color:#999; $font-color:#666; $red:#c20c0c; $white:#fff; $black:#242424; $blue:#0c73c2; $body-color:#f5f5f5; $font-size:14px; $border-area-color:#d3d3d3; //style.scss body { font-size:$font-size; color:$font-color; background-color:$body-color; }
1 2 3 //main.js import "@/assets/css/variables.scss" import "@/assets/css/style.scss"