【心无旁骛】vue-ts-daily

匿名 (未验证) 提交于 2019-12-02 23:52:01

这是一个非常有意思的项目,我们先来看看效果

这个项目所用的技术也比较有意思,它的技术栈为vue2.5 + Typescript + vuex + vue-router
放下博主的项目地址吧,https://github.com/xiaomuzhu/vue-ts-daily
接下来我们一起看项目代码吧,也一起研究ts怎么在vue中进行使用
首先是入口文件main.ts

//main.ts // 本质上和写js一样 import Vue from 'vue'; // 解决300ms点击延迟问题 import FastClick from 'fastclick'; // 引用图标字体组件 import VueIconFont from 'vue-icon-font-pro'; // 日历组件 import vueEventCalendar from 'vue-event-calendar-pro'; // Vue.js 2.0 组件级懒加载方案:Vue Lazy Component import VueLazyComponent from '@xunlei/vue-lazy-component'; //骨架loading import VueSkeletonLoading from 'vue-skeleton-loading'; // Normalize.css是一种CSS reset的替代方案 import 'normalize.css'; // 动画 import 'vue2-animate/dist/vue2-animate.min.css'; import 'vue-event-calendar-pro/dist/style.css';  import App from './App.vue'; import router from './router'; import store from './store'; import './registerServiceWorker'; import '@/assets/iconfont.js';  // 兼容毒瘤ios的300ms延迟问题 if ('addEventListener' in document) {   document.addEventListener(     'DOMContentLoaded',     () => {       (FastClick as any).attach(document.body);     },     false,   ); }  Vue.use(VueLazyComponent); Vue.use(VueSkeletonLoading); Vue.use(vueEventCalendar, { locale: 'zh', weekStartOn: 1 }); Vue.use(VueIconFont);  Vue.config.productionTip = false;  new Vue({   router,   store,   render: (h) => h(App), }).$mount('#app');

App.vue引入两个组件

<template>   <main id="app">     <div v-if="$route.meta.main">       <Header></Header>         <router-view />         <Footer></Footer>     </div>     <div v-if="!$route.meta.main">     <router-view />     </div>   </main> </template>  <script lang="ts"> // 引入组件 import { Component, Prop, Vue } from 'vue-property-decorator'; // 引入头部和底部 import Header from './components/Header.vue'; import Footer from './components/Footer.vue'; @Component({   components: {     Header,     Footer,   }, }) export default class App extends Vue {} </script>  <style lang="scss" scoped> @import './style/mixin'; #app {   font-family: 'Avenir', Helvetica, Arial, sans-serif;   -webkit-font-smoothing: antialiased;   -moz-osx-font-smoothing: grayscale;   color: $font;   display: flex;   text-align: center;   flex-direction: column;   justify-content: space-between;   max-width: 100vw;   height: 100vh; } #nav {   padding: 30px;   a {     font-weight: bold;     color: $font;     &.router-link-exact-active {       color: #42b983;     }   } } .fade-enter-active, .fade-leave-active {   transition: opacity 0.5s; } .fade-enter,   .fade-leave-to   /* .fade-leave-active below version 2.1.8 */  {   opacity: 0; } </style>

接下来我们看里面引入的HeaderIcon.ts

//src\components\common\Icon\HeaderIcon.ts import { Component, Prop, Vue } from 'vue-property-decorator'; import template from './Icon.vue';  @Component({   name: 'HeaderIcon',   mixins: [template], }) // 使用ts封装的src\components\common\Icon\HeaderIcon.ts组 export default class FooterIcon extends Vue {   @Prop() private name!: string;   @Prop() private path!: string;    private data() {     return {       isTouched: false,     };   } } 

我们来看一下FooterIcon.ts

//src\components\common\Icon\FooterIcon.ts import { Component, Prop, Vue, Emit } from 'vue-property-decorator'; import { Mutation } from 'vuex-class';  import { PageInfo } from '@/store/state'; import template from './Icon.vue';  @Component({   name: 'FooterIcon',   mixins: [template], }) // 使用ts封装的src\components\common\Icon\FooterIcon.ts组件 export default class FooterIcon extends Vue {   @Prop() private name!: object;   @Prop() private path!: string;   @Prop() private id!: number;   @Prop() private isActived!: boolean;   @Prop() private tagName!: string;   @Mutation private getActivePage!: (pageName: number) => void;   @Mutation private changeHeaderState!: (pageName: number) => void;    private changeActivePage() {     const id = this.id;      if (!this.isActived) {       this.getActivePage(id);       this.changeHeaderState(id);     }   } }

对icon也做的封装

//src\components\common\Icon\Icon.vue <template>     <section>         <router-link v-if="!!path" :to="path">             <span @click="changeActivePage">                         <icon :name="!isActived ? name.defaultName : name.activedName" style="width: 2rem; height:2rem"></icon>                         <p :class="{active: isActived}">{{tagName}}</p>                     </span>         </router-link>         <div v-else class="headerIcon">             <icon :name="name" style="width: 1.6rem; height:1.8rem">             </icon>         </div>     </section> </template>  <style src="./style.scss" lang="scss" scoped> </style>

footer.vue中也是对footer进行了封装,感觉和封装普通的组件差别不大,不过在使用vuex,state之类的属性的时候就难起来

//src\components\Footer.vue <template>     <footer>         <Icon v-for="item in activePage" :key="item.id" :tagName="item.tagName" :isActived="item.isActived" :id="item.id" :name="item.name" :path="item.path" >         </Icon>     </footer> </template>  <script lang="ts"> import { Component, Prop, Vue, Watch } from 'vue-property-decorator'; import { State } from 'vuex-class';  import { PageInfo } from '@/store/state'; import Icon from './common/Icon/FooterIcon';  @Component({   components: {     Icon,   }, }) export default class Footer extends Vue {   @State private activePage!: PageInfo[]; } </script>  <style lang="scss" scoped> @import '../style/mixin';  footer {   width: 100%;   height: 3.5rem;   min-height: 8%;   background-color: $grey;   display: flex;   align-items: center;   justify-content: space-around;   div {     display: flex;     flex-direction: column;     justify-content: space-around;     align-items: center;     font-size: 60%;     svg {       margin-bottom: 0.4rem;     }   } } </style>

封装的骨架

//src\components\common\Skeleton\SkeletonList.vue <template>         <skeleton-loading>             <row                     v-for="i in num"                     :key="i"                     :gutter="{top: '10px', bottom: '10px'}"             >                 <column :span="23" :gutter="10">                         <square-skeleton                              :count="2"                             :boxProperties="{                                 bottom: '15px',                                 width: '250px',                                 height: '15px'                             }"                         >                         </square-skeleton>                 </column>             </row>         </skeleton-loading> </template>  <script lang="ts"> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component({}) export default class Skeleton extends Vue {   @Prop() private num!: number; } </script>  <style lang="scss" scoped> @import '../../../style/mixin';  </style>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!