一路繁花似锦绣前程
失败的越多,成功才越有价值

导航

 

vue-typescript-element-template使用总结

一、请求
1、定义接口
import request from '@/utils/request'

export const 方法 = (params: params类型, data: data类型) =>
  request({
    url: '地址',
    method: 'get/post/put/delete',
    params,
    data
  })
2、请求拦截器
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 5000
})

// Request interceptors
service.interceptors.request.use(
  (config) => {
    config.headers['token'] = 'token'

    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// Response interceptors
service.interceptors.response.use(
  (response) => {
    return response
  },
  (error) => {
    return Promise.reject(error)
  }
)

interface IResult<T> {
  code: number
  data: T
  message: string
}

export default function <T>(config: AxiosRequestConfig) {
  return service(config).then((value: AxiosResponse): IResult<T> => {
    return value.data
  })
}
二、组件
1、Component
import { Component, Vue } from 'vue-property-decorator'

@Component({
  name: 'name'
})
export default class extends Vue {
  // 可在模板(template)中使用
  private 属性: 属性类型 = 值;

  // 可在模板(template)中使用
  private 方法(参数: 参数类型): 返回值类型 {
    // 可以使用this
    return 返回值;
  }

  // 生命周期
  created() {
    // 可以使用this
  }
}
2、watch
import { Component, Vue, Watch } from 'vue-property-decorator'

@Component({
  name: 'name'
})
export default class extends Vue {
  @Watch('监听属性')
  private 方法(监听属性: 属性类型) {
    // 可以使用this
  }
}
3、prop
import { Component, Prop, Vue } from 'vue-property-decorator'

@Component({
  name: 'name'
})
export default class extends Vue {

  // !表示非null和非undefined的断言,否则属性的类型后面需要加上undefined类型
  @Prop({ 
    type: Boolean,
    required: true,
    default: false,
    validator(value: any): boolean {
      return !!value
    }
  })
  private 属性!: 类型   
}
4、$emit
import { Component, Vue } from 'vue-property-decorator'

@Component({
  name: 'name'
})
export default class extends Vue {
  private 方法() {
    this.$emit('事件', 参数)
  }
}
5、$route和$router
import { Component, Vue } from 'vue-property-decorator'

@Component({
  name: 'name'
})
export default class extends Vue {
  private 方法() {
    console.log(this.$route)
    this.$router.push(路径)
  }
}
6、computed和store
import { Component, Vue } from 'vue-property-decorator'
import { TestModule } from '@/store/modules/test'

@Component({
  name: 'name'
})
export default class extends Vue {
  get 计算属性() {
    return TestModule
  }
}
7、filters
import { Component, Vue } from 'vue-property-decorator'

@Component({
  name: 'name',
  filters: {
    过滤器() {
      return '返回值'
    }
  }
})
export default class extends Vue {}
三、路由
1、路由配置
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  // 默认'hash'
  // mode: 'history',
  // 滚动行为(前进后退页面记录滚动值)
  scrollBehavior: (to, from, savedPosition) => {
    if (savedPosition) {
      return savedPosition
    } else {
      return { x: 0, y: 0 }
    }
  },
  // 实操,未出结果
  base: 路径,
  routes: [
    {
      path: 路径,
      component: 组件,
      redirect: 重定向路径,
      children: [
        {
          // 组件<keep-alive>时一定要配置,且与组件name一致,且唯一
          name: 'name',
          path: 路径(前面不加/:父路径/子路径),
          component: () => import(组件路径),
          meta: {
            hidden: true,
            title: 'title',
            icon: 'icon',
            affix: true,
            // 与<keep-alive>配合使用
            noCache: true
          }
        }
      ]
    }
  ]
})
2、路由守卫
import router from './router'
import { Route } from 'vue-router'

/**
 * next用法:
 *   next({ path: '/' })
 *   next({ ...to, replace: true })
 *   next(`/login?redirect=${to.path}`)
 *   next()
 */
router.beforeEach(async(to: Route, from: Route, next: any) => {
  next()
})

router.afterEach((to: Route) => {
})
3、main.js
import Vue from 'vue'
import router from '@/router'
import '@/permission'
import App from '@/App.vue'

new Vue({
  router,
  render: (h) => h(App)
}).$mount('#app')
4、嵌套路由记录scrollTop(vue3)
<template>
  <div ref="scrollRef" class="layout-container">
    <div>layout-container</div>
    <router-view v-slot="props">
      <!-- keep-alive不会缓存节点的scrollTop -->
      <keep-alive>
        <component :is="props.Component"></component>
      </keep-alive>
    </router-view>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { onBeforeRouteUpdate } from "vue-router";

/**
 * @type {import("vue").Ref<HTMLDivElement>}
 */
const scrollRef = ref(null);
onBeforeRouteUpdate((to, from) => {
  // matched是匹配的嵌套路由各层级节点组成的数组
  from.matched[1].savedPosition = {
    left: 0,
    top: scrollRef.value.scrollTop,
  };
  // 如果因为keep-alive的max原因组件销毁,可在组件的onUnmounted生命周期中将savedPosition置为null
  if (to.matched[1].savedPosition && to.matched[1].meta.keepAlive) {
    setTimeout(() => {
      scrollRef.value.scrollTop = to.matched[1].savedPosition.top;
    });
  } else {
    scrollRef.value.scrollTop = 0;
  }
});
</script>

<style scoped>
.layout-container {
  height: 100%;
  overflow-y: auto;
}
</style>
四、存储
1、store
import Vue from 'vue'
import Vuex from 'vuex'
import { IAppState } from './modules/app'

Vue.use(Vuex)

export interface IRootState {
  app: IAppState
}

export default new Vuex.Store<IRootState>({})
2、modules
import { VuexModule, Module, Mutation, Action, getModule } from 'vuex-module-decorators'
import store from '@/store'

export interface IAppState {
  bool: boolean
}

@Module({ dynamic: true, store, name: 'app' })
class App extends VuexModule implements IAppState {
  public bool = false
  
  // getter
  get getBool(): boolean {
    return this.bool
  }

  @Mutation
  private SET_BOOL(bool: boolean) {
    this.bool = bool
  }

  @Action
  public setBool(bool: boolean) {
    this.SET_BOOL(bool)
  }
}

export const AppModule = getModule(App)
3、main.js
import Vue from 'vue'
import store from '@/store'
import App from '@/App.vue'

new Vue({
  store,
  render: (h) => h(App)
}).$mount('#app')
posted on 2021-08-16 10:13  一路繁花似锦绣前程  阅读(304)  评论(0)    收藏  举报