vue2和vue3的路由、axios、vuex的配置和使用

vue3使用router

import Cookies from 'js-cookie';
import {
  createRouter,
  createWebHistory,
  RouteRecordRaw,
  Router,
} from 'vue-router'
import store from '../store';
import { getAdminInfoApi } from '../request/api'
import { ElMessage } from 'element-plus'

const routes: Array<RouteRecordRaw> = [
  {
    path: "/login",
    name: "Login",
    component: () =>
      import(/* webpackChunkName: "About" */ "../views/login/Login.vue"),
  },
  // {
  //   path: "/ums",
  //   name: "ums",
  //   component: () =>
  //     import(/* webpackChunkName: "About" */ "../views/index/Index.vue"),
  //   children: [
  //     {
  //       path: "admin",
  //       name: "Admin",
  //       component: () => import(/* webpackChunkName: "cart" */ "../views/admin/admin.vue"),
  //     },
  //   ],
  // },

];

const router: Router = createRouter({
  history: createWebHistory(),
  routes,
});

// 封装动态添加路由
const getRouter = ()=>{
  store.dispatch('getAdminInfo').then(() => {
    const menus = store.getters.getNewMenus
    for (let k in menus) {
      const newRoute: RouteRecordRaw = {
        path: "/" + menus[k].name,
        name: menus[k].name,
        component: () =>import(/* webpackChunkName: "About" */ "../views/index/homepage.vue"),
        redirect:"/"+ menus[k].name+'/'+menus[k].children[0].name,
        children: []
      }
      for (let i = 0; i < menus[k].children.length; i++) {
        newRoute.children?.push({
          path: menus[k].children[i].name,
          name: menus[k].children[i].name,
          component: () =>
            import(/* webpackChunkName: "About" */ `../views/${menus[k].name}/${menus[k].children[i].name}.vue`),
        })
      }
      router.addRoute(newRoute)
    }
    router.addRoute({
      path: "/",
      name: "homepage",
      component: () =>import("../views/index/homepage.vue"),
      redirect:"/index",
      children: [
        {
          path: "index",
          name: "Index",
          component: () => import(/* webpackChunkName: "cart" */ "../views/index/index.vue"),
        },
      ],
    })
  })
}


// 前置导航守卫
router.beforeEach((to, from, next) => {
  const token = Cookies.get('token')
 // 判断是否有token
  if (token && store.state.menus.length === 0) {
    // console.log('menus为空');
    getAdminInfoApi().then(res => {
      // console.log(res);
      // store.commit('updataments', res.data.menus)
      getRouter()

      next(to.path)
    })

  }else if(token && store.state.menus.length !== 0 && from.path ==='/login' && to.path==='/home'){
    getRouter();
    next('/index')
  }else if(token && to.path==='/login'){
    ElMessage.error('你已经登录了')
    next(from)
  } else if(!token && to.path !=='/login'){
    ElMessage.error('你还没有登录哦,正在跳转登录页')
    next('/login')
  } else {
    next()
  }

})

export default router;


使用

import { useRouter } from 'vue-router'

let router = useRouter()
router.push('/home')

vue3使用store(vuex)

import { createStore } from "vuex";
import { App } from "vue";
import { getAdminInfoApi} from '../request/api'


interface state{
    menus:Menobj[]
    username:String
}

interface Menobj{
    parentId:number;
    id:number;
    children?:Menobj[]
}

interface NewMenus {
    [key:number]:Menobj
}

const store =createStore<state>({
    state(){
        return{
            menus:[],
            username:""
        }
    },
    getters:{
        getNewMenus(state){
            const newMenus:NewMenus = {}
            const menus = state.menus

            for(let i=0;i<menus.length;i++){
                if(menus[i].parentId===0){
                    newMenus[menus[i].id] = {...menus[i],children:newMenus[menus[i].id]?.children || []}
                }else {
                    let parentId = menus[i].parentId;
                    newMenus[parentId] = newMenus[parentId] || {};
                    newMenus[parentId].children = newMenus[parentId].children || [];
                    newMenus[parentId].children?.push(menus[i])

                }
            }
            return newMenus
        }

    },
    mutations:{
        updataments(state,menus){
            state.menus = menus
        },
        upNewName(state,username){
            state.username = username
        }
    },
    actions:{
        getAdminInfo({commit}){
            return new Promise((resolve,reject)=>{
                getAdminInfoApi().then(res=>{
                    if(res.code===200){
                        commit('updataments',res.data.menus)
                        commit('upNewName',res.data.username)
                        resolve(res.data)
                    }else{
                        reject(res)
                    }
                })
            })
        }
    },
    modules:{}
})

export const initStore = (app:App<Element>)=>{
    app.use(store)
}

export default store

使用

import { useStore } from 'vuex'

let store = useStore()
store.state.menus

vue3存储cookies

https://www.npmjs.com/package/js-cookie

下载

npm i js-cookie
import Cookies from 'js-cookie'

//存储
 Cookies.set('token', res.data.tokenHead + res.data.token, { expires: 7 })
//获取
 Cookies.get('token')

vue3使用request

api.ts

import request from './request'
import qs from 'qs'

interface AdminLoginData {
    password: string
    username: string
}

type ProminseRes<T> = Promise<ManageResult<T>>

interface ManageResult<T = {}> {
    code?: number;
    data: T
    message?: string
    errno?: number
}

//登录返回token
interface AdminLoginRes {
    token: string;
    tokenHead: string;
}

// 当前用户信息
interface AdminInfoRes{
    menus:[],
    username:String
}
// 用户列表
interface AdminListRes{
    list:[{
        status:number | undefined;
        id:number | undefined
    }],
    total:number,
    totalPage:number
}
interface AdminListData {
    keyword:string
    pageNum: number
    pageSize: number
}
// 修改账号状态


// 推荐品牌
interface HomeBrandList{
    brandName?:string
    pageNum: number
    pageSize: number
    recommendStatus?:number
}




// 登录功能
export const LoginApi = (data: AdminLoginData):ProminseRes<AdminLoginRes> => request.post('/admin/login', data)
// 获取用户信息
export const getAdminInfoApi = ():ProminseRes<AdminInfoRes>=>request.get('/admin/info')
// 根据用户名或姓名分页获取用户列表
// export const getAdminlistApi = (data:AdminListData):ProminseRes<AdminListRes>=>request.get(`/admin/list?pageNum=${data.pageNum}&pageSize=${data.pageSize}`)
export const getAdminlistApi = (data:AdminListData):ProminseRes<AdminListRes>=>request.get('/admin/list',{params:data})

// 修改指定用户信息
export const AdminUpdateApi = (data: AdminObjInfo):ProminseRes<number> => request.post(`/admin/update/${data.id}`, data)
// 修改帐号状态
export const AdminupdateStatusApi = (id:number,status:number):ProminseRes<number> => request.post(`/admin/updateStatus/${id}/?status=${status}`)
// 添加用户
export const AdminregisterApi = (data: AdminObjInfo):ProminseRes<object> => request.post('/admin/register', data)
// 获取所有角色
export const rolelistAllApi = ():ProminseRes<[]>=>request.get('/role/listAll')
// 获取当前角色
export const roleApi = (adminId:number|undefined):ProminseRes<[{id:number}]>=>request.get(`/admin/role/${adminId}`)
// 给用户分配角色
export const  roleupdateApi= (data:{adminId:number;roleIds:string}):ProminseRes<object>=>request.post('/admin/role/update',null,{params:data})


// 分页查询推荐品牌
export const  HomeBrandList= (data:HomeBrandList):ProminseRes<AdminListRes>=>request.get('/home/brand/list',{params:data})

request.ts

import axios from "axios";
import Cookies from 'js-cookie'

let instance = axios.create({
    baseURL: "http://120.24.64.5:8088/mall-admin",
    timeout: 5000
});
instance.interceptors.request.use(function (config) {
  let token =Cookies.get('token')
  if(token){
    //添加请求头
    config.headers = config.headers || {}
    config.headers.Authorization = token
  }

    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response.data;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });
  
  export default instance

vue2使用router


import Vue from 'vue'
import VueRouter from 'vue-router'

import {wechatUsers} from '../request/httpApi'
import store from '../store'
import bus from "../components/bus"


Vue.use(VueRouter)

const routes = [
  {
    path: '/index',
    name: 'index',
    component: () => import(/* webpackChunkName: "index" */ '../views/index.vue')
  },
  {
    path: '/goods',
    name: 'goods',
    component: () => import(/* webpackChunkName: "goods" */ '../components/Goods.vue')
  },
  // {
  //   path: '/user',
  //   name: 'user',
  //   component: () => import(/* webpackChunkName: "user" */ '../views/User.vue')
  // },
  {
    path: '/user',
    name: 'user',
    redirect:'/user/cart',
    component: () => import(/* webpackChunkName: "user" */ '../components/User.vue'),
    children:[
  {
    path: 'cart',
    name: 'cart',
    component: () => import(/* webpackChunkName: "cart" */ '../components/Cart.vue')
  },
    ]
  },
  {
    path: '/detail/:pid',
    name: 'Detail',
    component: () => import(/* webpackChunkName: "user" */ '../views/Detail.vue')
  },
//   {
//     path: '/about',
//     name: 'About',
//     // route level code-splitting
//     // this generates a separate chunk (about.[hash].js) for this route
//     // which is lazy-loaded when the route is visited.
//     component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
//   }
 ]

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

//全局导航钩子
router.beforeEach((to,from ,next)=>{
  const token = localStorage.getItem('token')
  const userinfo = store.state.userInfo
  const code = to.query.code
  if(token && !userinfo){
    // getUserProfiles().then(res=>{
    //   if(res.code===0){
    //     store.commit('getUserInfo' ,res.data)
    //   }
    // })
    store.dispatch('getdatauserInfo')

    next()
  }else if(code && !token){
    wechatUsers({code}).then(res=>{
      if(res.code===0){
        localStorage.setItem("token", res["x-auth-token"]);

        store.dispatch('getdatauserInfo').then(res=>{
          //替换掉路径上的code参数
          router.replace(to.path)
        })
        next()
      }else if(res.code ===407){

        bus.$emit("loginFn", true);
        bus.$emit("uuid", res.uuid);
      }
    })
  
  }else{
    next()
  }

})

export default router

要在main.js中全局引入

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'reset-css'

import toast from './components/Toast'

import SlideVerify from 'vue-monoplasty-slide-verify';
Vue.use(SlideVerify);

Vue.config.productionTip = false

Vue.prototype.$toast = toast

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

使用

//路由跳转
this.$router.push
//获取参数
this.$route.params   带/的地址或者是push跳转
this.$route.query    带?的地址

vue2使用store(vuex)

import Vue from 'vue'
import Vuex from 'vuex'

import {getUserProfiles} from '../request/httpApi'
import store from '../store'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    userInfo:null

  },
  mutations: {
    getUserInfo(state,userInfo){
      state.userInfo = userInfo
    }

  },
  actions: {
    getdatauserInfo({commit}){
      return new Promise((resolve,reject)=>{
        getUserProfiles().then(res=>{
          if(res.code===0){
           commit('getUserInfo' ,res.data)
            resolve(res.data)
          }else{
            reject(res.message)
          }
        })
      })

    }
  },
  modules: {
  },
  getters:{

  },
  getters:{

  }
})

要在main.js中全局引入

使用

//拿vuex中的数据
this.$store.state.userInfo

//修改vuex中的数据
//mutations进行修改
 this.$store.commit('getUserInfo' , res.data)

//使用actions的方法
this.$store.dispatch("getdatauserInfo").then((res) => {
     this.cancelFn();
    });

vue2使用localStorage本地存储

//存入
localStorage.setItem("token", res["x-auth-token"]);

//获取
localStorage.getItem('token')

//清除
localStorage.removeItem("token");

vue2使用bus

bus.js

import Vue from 'vue'

export default new Vue()

引入

//传参
bus.$emit("loginFn", true);

//接收
    bus.$on("loginFn", (data) => {
      this.showData = data;
      console.log("222");
    });

微信扫码登录

微信扫码布局与配置

public/index.htmlhead 中:

<script src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>

在登录框中代码中添加一个div,这个div是用来存放微信二维码所在的iframe的:

<div id="weixin"></div>

api.js 中:

// 微信登录(这个接口必须用qs对数据进行格式化)
export const WeixinLoginApi = (params) => request.post(`/wechatUsers/PCLogin`, qs.stringify(params));

在切换到 微信扫码登录 的事件中:

// 点击了微信扫码登录
weixinClickFn() {
    let _this = this;
    new WxLogin({
        id: "weixin",
        appid: "wx67cfaf9e3ad31a0d",  // 这个appid要填死
        scope: "snsapi_login",
        // 扫码成功后重定向的接口
        redirect_uri: "https://sc.wolfcode.cn/cms/wechatUsers/shop/PC",
        // state填写编码后的url
        state: encodeURIComponent(window.btoa(process.env.VUE_APP_STATE_URL + _this.$route.path)),
        // 调用样式文件  base64格式
        href: "",
    });
},

#* 环境变量 (不一定要进行)

上面的process.env.VUE_APP_STATE_URL是环境变量。书写方式:

在项目根目录新建 .env.prod.env.dev

# .env.dev
NODE_ENV=development
VUE_APP_BASE_URL=/
VUE_APP_STATE_URL=http://127.0.0.1:8080

# .env.prod
NODE_ENV = production
VUE_APP_BASE_URL = 'http://codesohigh.com/store-pc/#'
VUE_APP_STATE_URL = 'http://codesohigh.com/store-pc/#'
 
        Copied!
    

然后修改 package.json 中:

{
    "scripts": {
        "serve": "vue-cli-service serve --mode dev",
        "build": "vue-cli-service build --mode prod"
    },
}
 
        Copied!
    

重跑项目即可。

当你还没写href的时候,会发现iframe样式是无法改变的,因此我们需要借助 node+css 来实现css转base64:

src 下新建 utils 文件夹,并且在其中新建: data-url.jswxlogin.css

/* wxlogin.css */
.impowerBox .title, .impowerBox .info{
    display: none;
}

.impowerBox .qrcode{
    margin-top: 20px;
}

然后控制台运行:

cd src/utils/
node data-url.js

得到一段base64转码字符串:

data:text/css;base64,LmltcG93ZXJCb3ggLnRpdGxlLCAuaW1wb3dlckJveCAuaW5mb3sNCiAgICBkaXNwbGF5OiBub25lOw0KfQ0KDQouaW1wb3dlckJveCAucXJjb2Rlew0KICAgIG1hcmdpbi10b3A6IDIwcHg7DQp9DQoNCg==

然后粘贴到 href 中。最终效果:

登录滑动拼图验证

插件参考:https://gitee.com/monoplasty/vue-monoplasty-slide-verify(opens new window)

#1、安装插件

npm install --save vue-monoplasty-slide-verify
# yarn安装方式
yarn add vue-monoplasty-slide-verify

#2、入口文件引入

import SlideVerify from 'vue-monoplasty-slide-verify' // 拼图验证码

Vue.use(SlideVerify)

#3、组件引用

<template>
	<slide-verify :l="42" :r="20" :w="362" :h="140" @success="onSuccess" @fail="onFail" @refresh="onRefresh" :style="{ width: '100%' }" class="slide-box" ref="slideBlock" :slider-text="msg"></slide-verify>
</template>

<script>
export default {
  data() {
    return {
      msg: "向右滑动"
    };
  },
  methods: {
    // 拼图成功
    onSuccess(times) {
      let ms = (times / 1000).toFixed(1);
      this.msg = "login success, 耗时 " + ms + "s";
    },
    // 拼图失败
    onFail() {
      this.onRefresh(); // 重新刷新拼图
    },
    // 拼图刷新
    onRefresh() {
      this.msg = "再试一次";
    },
    // 点击登录按钮
    submitFn(formName) {
      if (this.msg == "再试一次" || this.msg == "向右滑动") {
        console.log("请滑动拼图");
      } else {
        console.log("开始登录");
      }
    },
  },
};
</script>

<style lang="less" scoped>
/deep/.slide-box {
    width: 100%;
    position: relative;
    box-sizing: border-box;
    canvas {
        position: absolute;
        left: 0;
        top: -140px;
        display: none;
        width: 100%;
        box-sizing: border-box;
    }
    .slide-verify-block{
        width: 85px;
        height: 136px;
    }
    .slide-verify-refresh-icon {
        top: -140px;
        display: none;
    }
    &:hover {
        canvas {
            display: block;
        }
        .slide-verify-refresh-icon {
            display: block;
        }
    }
}
</style>
 

vue2解决跨域(代理配置)

//对 vue.config.js 进行配置:

module.exports = {
    devServer: {
        port: 3000,
        proxy: {
            '/api': {
                //要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理(简单来说:转发的目标服务器和端口)
                target: "http://kumanxuan1.f3322.net:8001/",
                //pathRewrite是使用proxy进行代理时,对请求路径进行重定向以匹配到正确的请求地址
                        //         '^/api': '/api'   // 这种接口配置出来     http://XX.XX.XX.XX:8083/api/login
                        //'^/api': '/' 这种接口配置出来     http://XX.XX.XX.XX:8083/login
                pathRewrite: {
                    '^/api': ''
                }
            }
        }
    }
}

vue2中ref和$refs

<div ref="testDom">11111</div>

 console.log(this.$refs.testDom)

//本页面获取dom元素
//获取子组件中的data
//调用子组件中的方法

//子组件调用父组件方法
this.$emit("refreshData");获取父组件的方法

this.$refs.hello.open();再调用子组件的方法 

vue2注册组件(局部)

//引入
import Header from './heard'
import Nav from './nav'

//注册
export default {
    //组件注册
    components:{
        Header,
        Nav,
        // Good
    }
}

//使用
    <Header></Header>
    <Nav></Nav>

vue3注册组件(局部)

//引入组件
import MyCom from './components/Mycom.vue'

//直接使用
<template>
<!-- 局部组件 -->
  <MyCom></MyCom>
</template>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值