vue项目token放在哪里_关于vue动态菜单的那点事

vue-element-admin4.0国内节点访问地址:https://panjiachen.gitee.io/vue-element-admin-site/zh/

本此使用的是https://github.com/PanJiaChen/vue-element-admin/tree/i18n 国际化分支的版本。说是除了国际化其他都一样。

本文主要介绍前台动态的使用资源权限。

  • 后台使用springboot2搭建项目就不说了,百度一下一大堆。
  • 前台开发前需要安装一下nodejs,这里注意一下nodejs和npm的版本要相互匹配,否则在编译的时候会报错。

打开项目后需要安装一下依赖的模块。

npm install

  • 1、全局请求配置的修改。

src/utils/request.js 当然也有用src/utils/request-axios.js的 修改方式大同小异zhe'li

import axios from 'axios'// import { MessageBox, Message } from 'element-ui'import { MessageBox, Message } from 'element-ui'import store from '@/store'import { getToken, removeToken } from '@/utils/auth' const qs = require('querystring') create an axios instanceconst service =    axios.create({  baseURL: process.env.VUE_APP_BASE_API,                  url = base url + request url                  withCredentials: true,                  send cookies when cross-domain requests  timeout: 5000,                  request timeout  jsonData: false}) request interceptorservice.interceptors.request.use(    config => {        if (store.getters.token) {          let each request carry token            ['X-Token'] is a custom headers key           please modify it according to the actual situation            config.headers['X-Token'] = getToken()    }         if (config.method.toLowerCase() === 'get') {            config.params = config.data    }    else if (config.method.toLowerCase() === 'post') {            if (config.jsonData) {               config.headers['Content-Type'] = 'application/json;charset=UTF-8'                config.data = JSON.stringify(config.data)      }       else {               config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'               config.data = qs.stringify(config.data)      }       }       console.log(config) // for debug        return config  },  error => {          // do something with request error         console.log(error)       // for debug          return Promise.reject(error)  }) // response interceptorservice.interceptors.response.use(    /**   * If you want to get http information such as headers or status   *  Please return  response => response   */    /**   * Determine the request status by custom code   * Here is just an example     * You can also judge the status by HTTP Status Code   */  r  esponse => {    const res = response.data    // code==2000是业务逻辑成功,其他的返回code都是业务逻辑错误    if (res.code === 5002) {      // to re-login      // token过期或者密码被修改了都需要重新获取token      MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {        confirmButtonText: 'Re-Login',        cancelButtonText: 'Cancel',        type: 'warning'      }).then(() => {        store.dispatch('user/resetToken').then(() => {          location.reload()        })      })    } else {      return res    }  },  error => {    // console.log('err' + error) // for debug    Message({      message: error.message,      type: 'error',      duration: 5 * 1000    })    removeToken()    if (error.response && error.response.status === 403) {      this.$router.push(`/login?redirect=${this.$route.fullPath}`)    }    return Promise.reject(error)  }) export default service

这个文件修改的主要是get、post请求传递参数的设置。

get使用params传递参数。post就data

还有就是form数据需要转化,使用qs.stringify来转换。转化成A=1&B=2&c=3这样的形式。

  • 2、后台接口路径的配置。

api请求都放在一个文件下面,这样以后维护比较方便

b4ffbbe4e973874fa2264a3d30ab75ee.png
1d4cddc9a448ec8038b264d1390fa07e.png

至于请求后台方法每个界面一个方法,例如这样

a3d18be25ccca604f6eb81f400f84024.png

页面调用方法需要引用,类似这种

c614a7dd3f8788fb4e74c0054ddbe638.png
export default {  name: 'user-list',  components: { Pagination },  directives: { waves },  filters: {    statusFilter(status) {      const statusMap = {        published: 'success',        draft: 'info',        deleted: 'danger'      }      return statusMap[status]    },    typeFilter(type) {      return calendarTypeKeyValue[type]    }  },  data() {    return {      tableKey: 0,      list: null,      total: 0,      listLoading: true,      listQuery: {        page: 1,        limit: 20,        importance: undefined,        title: undefined,        type: undefined,        username: undefined,        deptname: undefined,        rolename: undefined      },      calendarTypeOptions,      showReviewer: false,      temp: {        id: undefined,        remark: '',        username: '',        rolename: '',        deptid: '',        roleid: '',        password: ''      },      dialogFormVisible: false,      dialogCzmmVisible: false,      dialogStatus: '',      textMap: {        update: '修改用户',        create: '新增用户'      },      pvData: [],      rules: {        username: [{ required: true, message: '必填项', trigger: 'change' }],        loginname: [{ required: true, message: '必填项', trigger: 'change' }],        deptid: [{ required: true, message: '必选项', trigger: 'change' }],        roleid: [{ required: true, message: '必选项', trigger: 'change' }],        password: [{ required: true, message: '必选项', trigger: 'change' }, { min: 6, max: 30, message: '长度在 6 到 30 个字符', trigger: 'change' }]      },      downloadLoading: false,      deptOptions: [],      roleOptions: []    }  },  created() {    this.getList()  },  methods: {    getList() {      this.listLoading = true      fetchList(this.listQuery).then(response => {        debugger        this.list = response.attributes.list.list        this.total = response.attributes.list.total        this.listLoading = false      })    },    handleFilter() {      this.listQuery.page = 1      this.getList()    },    resetTemp() {      this.temp = {        id: undefined,        remark: '',        username: '',        rolename: '',        deptid: '',        roleid: '',        password: ''      }    },    handleCreate() {      this.resetTemp()      this.dialogStatus = 'create'      this.dialogFormVisible = true      this.$nextTick(() => {        this.$refs['dataForm'].clearValidate()      })      fetchRoleOptions().then(response => {        this.roleOptions = response.attributes.list      })      var aa = {        code: 'dept'      }      fetchDicePropOptions(aa).then(response => {        this.deptOptions = response.attributes.list      })    },    createData() {      this.$refs['dataForm'].validate((valid) => {        if (valid) {          const tempData = Object.assign({}, this.temp)          saveSysUser(qs.stringify(tempData)).then(() => {            this.dialogFormVisible = false            this.$notify({              title: '提示',              message: '保存成功!',              type: 'success',              duration: 2000            })            this.getList()          })        }      })    },    handleUpdate(row) {      this.temp = Object.assign({}, row) // copy obj      this.temp.roleid = Number(this.temp.roleid)      this.temp.deptid = Number(this.temp.deptid)      this.dialogStatus = 'update'      this.dialogFormVisible = true      this.$nextTick(() => {        this.$refs['dataForm'].clearValidate()      })      fetchRoleOptions().then(response => {        this.roleOptions = response.attributes.list      })      var aa = {        code: 'dept'      }      fetchDicePropOptions(aa).then(response => {        this.deptOptions = response.attributes.list      })    },    updateData() {      this.$refs['dataForm'].validate((valid) => {        if (valid) {          const tempData = Object.assign({}, this.temp)          updateSysUser(qs.stringify(tempData)).then(() => {            this.dialogFormVisible = false            this.$notify({              title: '提示',              message: '保存成功!',              type: 'success',              duration: 2000            })            this.getList()          })        }      })    },    handleDelete(row, index) {      deleteSysUser(row.id).then(response => {        this.dialogFormVisible = false        this.$notify({          title: '提示',          message: '删除成功!',          type: 'success',          duration: 2000        })        this.getList()      })    },    handleReloadPassword() {      if (this.temp.password === '') {        this.$notify({          title: '提示',          message: '密码不能为空!',          type: 'error',          duration: 2000        })        return      }      var date = {        id: this.temp.id,        password: this.temp.password      }      reloadPassword(date).then(response => {        if (response.code > 0) {          this.dialogCzmmVisible = false          this.$notify({            title: '提示',            message: '重置密码成功!',            type: 'success',            duration: 2000          })        }      })    },    handleRefresh() {      this.listQuery.username = ''      this.listQuery.rolename = ''      this.listQuery.deptname = ''    },    formatJson(filterVal) {      return this.list.map(v => filterVal.map(j => {        if (j === 'timestamp') {          return parseTime(v[j])        } else {          return v[j]        }      }))    },    indexMethod(index) {      return index + 1    },    handleCz(row) {      this.resetTemp()      this.dialogCzmmVisible = true      this.temp.id = row.id      this.$nextTick(() => {        this.$refs['dataFormCx'].clearValidate()      })    }  }}import qs from 'qs'

方法调用就像这种这么做就可以

3 、 登录设置角色信息、过滤路由(根据角色动态的生成菜单)

  • store/user.js
import { loginByPwd, logout, getLoginUserInfo } from '@/api/user'import { getToken, setToken, removeToken } from '@/utils/auth'import router, { resetRouter } from '@/router' const state = {    token: getToken(),    name: '',  avatar: '',   introduction: '',    roles: []} c  onst mutations = {  SET_TOKEN: (state, token) => {    state.token = token  },  SET_INTRODUCTION: (state, introduction) => {    state.introduction = introduction  },  SET_NAME: (state, name) => {    state.name = name  },  SET_AVATAR: (state, avatar) => {    state.avatar = avatar  },  SET_ROLES: (state, roles) => {    state.roles = roles  }} const actions = {  // user login  loginByPwd({ commit }, userInfo) {    const { userName, passWord } = userInfo     return new Promise((resolve, reject) => {      loginByPwd({ userName: userName.trim(), passWord: passWord }).then(response => {        if (response.code === 2000) {          commit('SET_TOKEN', response.data)          setToken(response.data)        }        resolve(response)      }).catch(error => {        reject(error)      })    })  },   // get user info  getLoginUserInfo({ commit, state }) {    return new Promise((resolve, reject) => {      getLoginUserInfo(state.token).then(response => {        // const { data } = response         // console.log('getLoginUserInfo', response)         if (!response) {          reject('Verification failed, please Login again.')        }         if (response.resultFlag) {          commit('SET_ROLES', response.data.roleList)          commit('SET_NAME', response.data.likeName)          commit('SET_AVATAR', response.data.imgUrl)          commit('SET_INTRODUCTION', '我是一个超级管理员哦')          // 一个用户可能有多个角色,这里返回的是角色的集合信息          // let allRole = response.data.roleList           resolve(response)        } else {          console.error('获取当前登录用户信息出错了')        }      }).catch(error => {        reject(error)      })    })  },   // user logout  logout({ commit, state }) {    return new Promise((resolve, reject) => {      logout(state.token).then(() => {        commit('SET_TOKEN', '')        commit('SET_ROLES', [])        removeToken()        resetRouter()        resolve()        location.reload()      }).catch(error => {        reject(error)      })    })  },   // remove token  resetToken({ commit }) {    return new Promise(resolve => {      commit('SET_TOKEN', '')      commit('SET_ROLES', [])      removeToken()      resolve()    })  },   // dynamically modify permissions  changeRoles({ commit, dispatch }, role) {    return new Promise(async resolve => {      const token = role + '-token'       commit('SET_TOKEN', token)      setToken(token)       const { roles } = await dispatch('getInfo')       resetRouter()       // generate accessible routes map based on roles      const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })       // dynamically add accessible routes      router.addRoutes(accessRoutes)       // reset visited views and cached views      dispatch('tagsView/delAllViews', null, { root: true })       resolve()    })  }} export default {  // namespaced: true,  state,  mutations,  actions}

这个文件就是登录,成功后获取当前用户拥有的资源信息。

当然下载下来的这个文件菜单权限是写死的是直接使用roles来做的判断,就是在router.js文件中直接把菜单需要的角色设置在里边。

缺点是添加了角色就要修改代码打包发布。这简直是灾难。

所以这里面将原系统修改了一下实现动态菜单读取,就好多了

vue-element-admin-mastersrcouterindex.jsimport Vue from 'vue'import Router from 'vue-router'Vue.use(Router)/* Layout */import Layout from '@/layout'/* Router Modules */// import componentsRouter from './modules/components'// import chartsRouter from './modules/charts'// import tableRouter from './modules/table'// import nestedRouter from './modules/nested'export const constantRoutes = [  {    path: '/redirect',    component: Layout,    hidden: true,    children: [      {        path: '/redirect/:path*',        component: () => import('@/views/redirect/index')      }    ]  },  {    path: '/login',    component: () => import('@/views/login/index'),    hidden: true  },  {    path: '/auth-redirect',    component: () => import('@/views/login/auth-redirect'),    hidden: true  },  {    path: '/',    component: Layout,    redirect: '/dashboard',    children: [      {        path: 'dashboard',        component: () => import('@/views/dashboard/index'),        name: 'Dashboard',        meta: { title: 'dashboard', icon: 'dashboard', affix: true }      }    ]  }]/** * asyncRoutes * the routes that need to be dynamically loaded based on user roles */export const asyncRoutes = [  /** when your routing map is too long, you can split it into small modules **/  // componentsRouter,  // chartsRouter,  // nestedRouter,  // tableRouter,  // 404 page must be placed at the end !!!]const createRouter = () => new Router({  // mode: 'history', // require service support  mode: 'hash',  scrollBehavior: () => ({ y: 0 }),  routes: constantRoutes})const router = createRouter()// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465export function resetRouter() {  const newRouter = createRouter()  router.matcher = newRouter.matcher // reset router}export default router

首先先将静态路由调好,一些常用的不需要权限的先加上

然后找到srcpermission.js

import router, { resetRouter } from '@/router'import store from './store'import { Message } from 'element-ui'import NProgress from 'nprogress' // progress barimport 'nprogress/nprogress.css' // progress bar styleimport { getToken } from '@/utils/auth' // get token from cookieimport getPageTitle from '@/utils/get-page-title'NProgress.configure({ showSpinner: false }) // NProgress Configurationconst whiteList = ['/login', '/auth-redirect'] // no redirect whitelistlet add1 = falseconst matched1 = falserouter.beforeEach(async(to, from, next) => {  // start progress bar  NProgress.start()  // set page title  document.title = getPageTitle(to.meta.title)  // determine whether the user has logged in  const hasToken = getToken()  if (hasToken) {    if (to.path === '/login') {      // if is logged in, redirect to the home page      next({ path: '/' })      NProgress.done()    } else {      // determine whether the user has obtained his permission roles through getInfo      const hasRoles = store.getters.roles && store.getters.roles.length > 0      if (hasRoles) {        next()      } else {        try {          // get user info          // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']          // const { roles } = await store.dispatch('user/getInfo')          // generate accessible routes map based on roles          debugger          // const fromPath = GetUrlRelativePath(window.location.href)          if (!add1) {            //注意在这里,将后台拼装好的功能菜单添加到当前路由中,切记一定要加变量控制            //不然会死循环,如果谁有好的解决办法请回复我谢谢            // router.resetRouter()            let accessRoutes = []            accessRoutes = await store.dispatch('permission/getAuthMenu')             router.addRoutes(accessRoutes)            add1 = true            // hack method to ensure that addRoutes is complete            // set the replace: true, so the navigation will not leave a history record            next({ ...to, replace: true })          } else {            // debugger            // if (to.matched.length === 0) {            //   router.resetRouter()            //   let accessRoutes = []            //   accessRoutes = await store.dispatch('permission/getAuthMenu')            //   router.addRoutes(accessRoutes)            //   next({ ...to, replace: true })            // } else {              next()            // }          }        } catch (error) {          // remove token and go to login page to re-login          await store.dispatch('user/resetToken')          Message.error(error || 'Has Error')          next(`/login?redirect=${to.path}`)          NProgress.done()        }      }    }  } else {    /* has no token*/    if (whiteList.indexOf(to.path) !== -1) {      // in the free login whitelist, go directly      next()    } else {      // other pages that do not have permission to access are redirected to the login page.      next(`/login?redirect=${to.path}`)      NProgress.done()    }  }})export function GetUrlRelativePath(url) {  var arrUrl = url.split('//')  var start = arrUrl[1].indexOf('/')  var relUrl = arrUrl[1].substring(start)  if (relUrl.indexOf('?') !== -1) {    relUrl = relUrl.split('?')[0]  }  return relUrl}router.afterEach(() => {  // finish progress bar  NProgress.done()})
import { asyncRoutes, constantRoutes } from '@/router'const state = {  routes: [],  roles: [],  username: '',  addRoutes: [],  isChange: false}const mutations = {  isChange: (state, isChanged) => {    state.isChange = isChanged  },  SET_USER: (state, username) => {    state.username = username  },  SET_ROLES: (state, roles) => {    state.roles = roles  },  SET_ROUTES: (state, routes) => {    state.addRoutes = routes    state.routes = constantRoutes.concat(routes)  }}export function formatMenus(routes, data) {  data.forEach(item => {    const menu = {}    menu.path = '/' + item.path    menu.name = item.name    menu.component = Layout    menu.redirect = '/'    menu.meta = { title: item.title, icon: 'excel', noCache: false }    if (item.children.length > 0) {      menu.children = []      item.children.forEach(item1 => {              if (item1.name === 'examinationInfo') {          const menu1 = {}          menu1.path = 'detail'          menu1.component = resolve => require(['@/views/' + item1.component + '/' + item1.path + '.vue'], resolve)          menu1.name = 'examinationInfo'          menu1.meta = { title: item1.title, noCache: false, activeMenu: '@/views/Examination/examination' }          menu1.hidden = true          menu.children.push(menu1)        }        else {          const menu1 = {}          menu1.path = item1.path          menu1.component = resolve => require(['@/views/' + item1.component + '/' + item1.path + '.vue'], resolve)          menu1.name = item1.name          menu1.meta = { title: item1.title }          menu.children.push(menu1)        }      })    }    debugger    routes.push(menu)  })}const actions = {  getAuthMenu({ commit }) {    return new Promise(resolve => {      getAuthMenu({}).then(response => {        const data = response.attributes.menus        const roles = response.attributes.rolesgetAuthMenu        const username = response.attributes.username        formatMenus(asyncRoutes, data)        commit('SET_ROUTES', asyncRoutes)        commit('SET_ROLES', roles)        commit('SET_USER', username)        // const isChanged = true        // commit('isChange', isChanged)        asyncRoutes.push({ path: '*', redirect: '/404', hidden: true })        //注意404界面一定要加载最后,不然会报错        resolve(asyncRoutes)      })    })  }}export default {  namespaced: true,  state,  mutations,  actions}import Layout from '@/layout'import { getAuthMenu } from '@/api/user'

在请求头部如果需要添加cookie

f9c0827520b69f7017c71e9f070782b3.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453766.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习之 ROI Pooling

什么是ROI? ROI是 Region of interest 的简写,指的是 Faster R-CNN 结构中,经过 RPN 层后,产生的 proposal 对应的 box 框。 ROI Pooling 顾名思义,是 pooling 层的一种,而且是针对 ROIs 的 pooling。整个…

KD树小结

很久之前我就想过怎么快速在二维平面上查找一个区域的信息,思考许久无果,只能想到几种优秀一点的暴力。 KD树就是干上面那件事的。 别的不多说,赶紧把自己的理解写下来,免得凉了。 KD树的组成 以维护k维空间(x,y,……)内的KD树为例…

深度学习之 RPN(RegionProposal Network)- 区域候选网络

anchor boxes基本概念与作用: feature map 上的一个点可以映射回输入图片上的一个点,以特征图上这个点为中心,预先人为设定 k 个 boxes,这些 boxes 就称为在这个点上生成的 k 个 anchor boxes(所有anchor boxes的中心点坐标是一样…

workbench拓扑优化教程_优化技术在水泵水力设计的应用(上篇)

文章来源:安世亚太官方订阅号(搜索:Peraglobal)CFD技术在泵的内流数值模拟、研究泵内部流动规律和结构方面已广泛应用,取得了很多成果。但是初步设计的产品如果通过CFD仿真得到的性能曲线不能满足使用要求,…

深度学习之 TensorRT

1 简介 TensorRT是一个高性能的深度学习推理(Inference)优化器,可以为深度学习应用提供低延迟、高吞吐率的部署推理。TensorRT可用于对超大规模数据中心、嵌入式平台或自动驾驶平台进行推理加速。TensorRT现已能支持TensorFlow、Caffe、Mxne…

进制转换中dbho是什么意思_什么是网段?二进制十进制如何互相转换?看完这篇,你就全明白了...

之前的文章讲了ip,子网掩码,网关的关系,今天着重讲一下网段。我们用傻瓜交换机通讯时,一个网段的设备才能互相通讯,怎么能判断两个ip是同一个网段呢?今天就简单的说一下。(这篇文章用语音听可以起到催眠作用…

软件需求与问题解决

(一) 小满当上项目经理后不久,参与了一个大项目。当时市场签下来的时候,公司里面是欢天喜地的。项目做了一年多。到了交付的时候,用户却很不满意,当初说好的东西,好多都变了卦。用户是上帝&…

flex 换主轴后子元素占满_Chrome72 嵌套 flex 布局修改,你的网站可能会发生布局错乱...

起源2019 年 1 月 29 日,Chrome72 正式版(72.0.3626.81)发布,本次发布带来了一个改变,且没有在更新日志中提及,该改变导致某些网站发生了布局错乱。该改变主要针对的是嵌套的flex布局,下面我们一起看下是怎么回事。问题…

路由到另外一个页面_Nextjs使用解读一(项目搭建与路由系统)

文章说明:1. 之前想搭建个人博客,由于学习的是react技术栈,所以就到处搜罗资料学了nextjs,配合koa就把博客搭起来了。该系列文章基于我的学习笔记,重新整理了一遍,如果有错误之处,还请指正。2. …

微信获取token -1000

最终翻看微信开发api找到需要去配置IP白名单。只需要配置访问来源IP即可。 转载于:https://www.cnblogs.com/yangjinqiang/p/8184663.html

产品技术和管理

为啥纯粹为消费者传递体验的活动可以价格不菲,几为暴利?——谈客户体验作为客户价值提升之源 不论产品还是服务,如果能够为消费者传递有益的体验,其价值就可以在一般的产品服务之上得以体现;附加了体验的产品&#xff…

jquery ztree 设置勾选_047 JAVA-jQuery

jQuery操作元素属性的值表单:<body><input type"button" name"" id"but1" value"测试获得属性值" /><hr />账号&#xff1a;<input type"text" name"sxtzh" id"zhanghao" value&q…

Opencv undefined reference to `cv::imread() Ubuntu编译

Ubuntu下编译一个C文件&#xff0c;C源程序中使用了opencv&#xff0c;opencv的安装没有问题&#xff0c;但是在编译的过程中出现如下错误&#xff1a; undefined reference to cv::imread(std::string const&, int)undefined reference to cv::noArray()undefined referen…

深度学习目标检测之 YOLO v1

这是继 RCNN&#xff0c;fast-RCNN 和 faster-RCNN 之后&#xff0c;rbg&#xff08;RossGirshick&#xff09;针对DL目标检测速度问题提出的另外一种框架。YOLO V1 增强版本GPU中能跑45fps&#xff0c;简化版本155fps。 论文名&#xff1a; 《You Only Look Once&#xff1a;…

编程珠玑番外篇

1.Plan 9 的八卦 在 Windows 下喜欢用 FTP 的同学抱怨 Linux 下面没有如 LeapFTP 那样的方便的工具. 在苹果下面用惯了 Cyberduck 的同学可能也会抱怨 Linux 下面使用 FTP 和 SFTP 是一件麻烦的事情. 其实一点都不麻烦, 因为在 LINUX 系统上压根就不需要用 FTP. 为什么呢? 因…

BT下载原理分析

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 BitTorrent协议。 BT全名为BitTorrent,是一个p2p软件,你在下载download的同时&#xff0c;也在为其他用户提供上传upload&#xff0c;因为大家是“互相帮助”&#xff0c;所以不会随着用户数的增加而…

表格列求和_excel表格制作,Excel表格的基本操作,包含制作一个表格10方面的知识...

创建表格&#xff0c;插入与删除一行一列或多行多行&#xff0c;一次移动一行一列或多行多列&#xff0c;拆分与合并单元格&#xff0c;单元格内换行&#xff0c;表格求和与求平均值是Excel表格的基本操作&#xff1b;除此之外&#xff0c;Excel表格的基本操作还包括调整行高列…

深度学习之 FPN (Feature Pyramid Networks)

论文题目&#xff1a;Feature Pyramid Networks for Object Detection论文链接&#xff1a;https://arxiv.org/abs/1612.03144论文代码&#xff1a;Caffe版本 https://github.com/unsky/FPN 《Feature Pyramid Networks for Object Detection》这篇论文主要解决的问题是目标检…

ISLR—第二章 Statistical Learning

Statistical Learning Y 和X的关系why estimate f 用来预测 预测的时候可以将f^当成一个black box来用&#xff0c;目的主要是预测对应x时候的y而不关系它们之间的关系。用来推断 推断的时候&#xff0c;f^不能是一个black box&#xff0c;因为我们想知道predictor和response之…

提高编程思想

虚函数和抽象函数有什么区别 虚函数是有代码的并明确允许子类去覆盖&#xff0c;但子类也可不覆盖,就是说可以直接用&#xff0c;不用重写 抽象函数是没有代码&#xff0c;子类继承后一定要重写 ****************************************************************** 在一…