vue-element-admin import(@/views/${sub_view})模板语法识别不了怎么办

yxyvkwin  于 22天前  发布在  其他
关注(0)|答案(7)|浏览(20)

附一个我完成的PHP的动态方案,主要代码

首先PHP要返回用户可访问的路由,期望的结果是菜单中可以有一个指向 /example/sample 的菜单和路由。

public function actionMenu()
    {
        $data =[
            [
                'path' => '/example',
                'component' => 'Layout',
                'redirect'=> '',
                'name'=> 'ExampleRoot',
                'meta'=> [
                    'title'=>'示例',
                    'icon'=>'table'
                ],
                'children'=>[
                    [
                        'path' => 'sample',
                        'component' => '/example/sample',
                        'name'=> 'ExampleSample',
                        'meta'=> [
                            'title'=>'example',
                            'icon'=>'table'
                        ],
                    ]
                ]
            ]
        ]
            
            ;

        return json_encode($data);
    }

然后修改 src/store/modules/permission.js

添加一个方法

function dataArrayToRoutes(data) {
  const res = []
  data.forEach(item => {
    const tmp = { ...item }
    if (tmp.component === 'Layout') {
      tmp.component = Layout
    } else {
      let sub_view = tmp.component
      sub_view = sub_view.replace(/^\/*/g, '')
      tmp.component = () => import(`@/views/${sub_view}`)  //这里很重要,把view动态加载进来,而且似乎我只找到这样的写法,用拼接不行,然后 views 后面没有斜杆也不行
    }
    if (tmp.children) {
      tmp.children = dataArrayToRoutes(tmp.children)
    }
    res.push(tmp)
  })
  return res
}

然后修改这个文件中的 actions

const actions = {
  generateRoutes({ commit, state }, { roles, menus }) {
    return new Promise(resolve => {
      let accessedRoutes
      // if (roles.includes('admin')) {
      //   accessedRoutes = asyncRoutes || []
      // } else {
      //   accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      // }
      // commit('SET_ROUTES', accessedRoutes)

      accessedRoutes = dataArrayToRoutes(menus)

      commit('SET_ROUTES', accessedRoutes)

      resolve(accessedRoutes)
    })
  }
}

然后新增一个 user/getMenus 的 Vuex 的 action

const state = {
  token: getToken(),
  name: '',
  avatar: '',
  introduction: '',
  roles: [],
  menus: [] //这个是我新增的
}

const 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
  },
  SET_MENUS: (state, menus) => { //这里是新增的
    state.menus = menus
  }
}

const actions = {
    getMenus({ commit, state }) { //这个是新增的action
    return new Promise((resolve, reject) => {
      getMenus(state.token).then(response => {  //这里的getMenus是调用request方法从服务端获得路由菜单数据的Promise,类似getInfo
        const { data } = response
        console.log(data)

        if (!data) {
          reject('Verification failed, please Login again.')
        }

        const menus = data

        // roles must be a non-empty array
        if (!menus || menus.length <= 0) {
          reject('getMenus: menus must be a non-null array!')
        }

        commit('SET_MENUS', menus)
        resolve(menus)
      }).catch(error => {
        reject(error)
      })
    })
  },
}

还有一个文件是 src/permission.js
要在 store.dispatch('permission/generateRoutes') 代码附近要改一下,原先从本地配置+roles获得用户路由,现在改从服务端获得之后再 addRoutes

const menus = await store.dispatch('user/getMenus')
          // generate accessible routes map based on roles
          const accessRoutes = await store.dispatch('permission/generateRoutes', { menus })
          // dynamically add accessible routes
          router.addRoutes(accessRoutes)

亲测可行……

Originally posted by @amoydavid in #293 (comment)

czfnxgou

czfnxgou1#

Uncaught Error: Module build failed (from ./node_modules/eslint-loader/index.js):
TypeError: Cannot read property 'range' of null
Occurred while linting E:\project\base-vue\src\store\modules\permission.js:24
at SourceCode.getTokenBefore (E:\project\base-vue\node_modules\eslint\lib\source-code\token-store\index.js:298:18)
at checkSpacingBefore (E:\project\base-vue\node_modules\eslint\lib\rules\template-curly-spacing.js:60:42)
at TemplateElement (E:\project\base-vue\node_modules\eslint\lib\rules\template-curly-spacing.js:119:17)
at E:\project\base-vue\node_modules\eslint\lib\linter\safe-emitter.js:45:58
at Array.forEach ()
at Object.emit (E:\project\base-vue\node_modules\eslint\lib\linter\safe-emitter.js:45:38)
at NodeEventGenerator.applySelector (E:\project\base-vue\node_modules\eslint\lib\linter\node-event-generator.js:254:26)
at NodeEventGenerator.applySelectors (E:\project\base-vue\node_modules\eslint\lib\linter\node-event-generator.js:283:22)
at NodeEventGenerator.enterNode (E:\project\base-vue\node_modules\eslint\lib\linter\node-event-generator.js:297:14)
at CodePathAnalyzer.enterNode (E:\project\base-vue\node_modules\eslint\lib\linter\code-path-analysis\code-path-analyzer.js:634:23)
at E:\project\base-vue\node_modules\eslint\lib\linter\linter.js:936:32
at Array.forEach ()
at runRules (E:\project\base-vue\node_modules\eslint\lib\linter\linter.js:931:15)
at Linter._verifyWithoutProcessors (E:\project\base-vue\node_modules\eslint\lib\linter\linter.js:1157:31)
at Linter._verifyWithConfigArray (E:\project\base-vue\node_modules\eslint\lib\linter\linter.js:1255:21)
at Linter.verify (E:\project\base-vue\node_modules\eslint\lib\linter\linter.js:1210:25)
at eval (webpack-internal:///./src/store/modules/permission.js:1:7)
at Object../src/store/modules/permission.js ( http://localhost:9527/static/js/app.js:4193:1 )
at webpack_require ( http://localhost:9527/static/js/app.js:849:30 )
at fn ( http://localhost:9527/static/js/app.js:151:20 )
at webpackContext (eval at ./src/store/modules sync recursive .js$ ( http://localhost:9527/static/js/app.js:4158:1 ), :13:9)
at eval (webpack-internal:///./src/store/index.js:36:15)
at Array.reduce ()
at eval (webpack-internal:///./src/store/index.js:33:35)
at Object../src/store/index.js ( http://localhost:9527/static/js/app.js:4147:1 )
at webpack_require ( http://localhost:9527/static/js/app.js:849:30 )

dvtswwa3

dvtswwa32#

用的是最新的4.4.0

8iwquhpp

8iwquhpp3#

https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/lazy-loading.html#%E6%96%B0%E6%96%B9%E6%A1%88
这里的解决方案

mmvthczy

mmvthczy4#

import { constantRoutes } from '@/router'
import Layout from '@/layout'
import storeUtils from '@/utils/storeUtils'

function filterAsyncRoutes(routers) {
const accessedRouters = routers.filter(route => {
if (route.component) {
if (route.component === 'Layout') { // Layout组件特殊处理
route.component = Layout
} else {
debugger
route.component = _import(route.component)
}
}
if (route.children && route.children.length) {
route.children = filterAsyncRoutes(route.children)
}
return true
})
return accessedRouters
}
export const _import = file => {
debugger
return () => import( @/views/${file}.vue )
// return (resolve) => require([ @/views/${file}.vue ], resolve)
}

const state = {
addRoutes: storeUtils.getStorageS(storeUtils.CONST.addRoutes) || [],
routers: [],
permission: storeUtils.getStorageS(storeUtils.CONST.permission) || []
}

const mutations = {
SET_ROUTERS: (state, routes) => {
state.addRoutes = routes
state.routers = constantRoutes.concat(routes)
storeUtils.setStorageS(storeUtils.CONST.addRoutes, state.addRoutes)
},
SET_PERMISSION: (state, permission) => {
state.permission = permission
storeUtils.setStorageS(storeUtils.CONST.permission, state.permission)
}
}
const actions = {
generateRoutes({ commit, state }) {
return new Promise(resolve => {
console.log('过滤前传过来的', state.addRoutes)
var accessedRoutes = filterAsyncRoutes(state.addRoutes)
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
console.log('过滤后', accessedRoutes)
commit('SET_ROUTERS', accessedRoutes)
resolve(accessedRoutes)
})
}
}

export default {
namespaced: true,
state,
mutations,
actions
}
这是改造的代码

0dxa2lsx

0dxa2lsx5#

  1. import(( @/views/${sub_view} ))
  2. let imUrl = @/views/${sub_view}
    import(imUrl )

这两种方法也不行吗?

lzfw57am

lzfw57am6#

同遇到此问题,一直卡在这
Cannot read property 'range' of null

mwkjh3gx

mwkjh3gx7#

附一个我完成的PHP的动态方案,主要代码

首先PHP要返回用户可访问的路由,期望的结果是菜单中可以有一个指向 /example/sample 的菜单和路由。

公共 功能 actionMenu()
    {
        $ data = [
            [
                'path' => '/ example',
                 'component' => 'Layout',
                 'redirect' => ``,
                 'name' => 'ExampleRoot',
                 'meta' => [
                     'title' => '示例',
                     'icon' => 'table'
                ],
                '儿童' => [
                    [
                        'path' => 'sample',
                         'component' => '/ example / sample',
                         'name' => 'ExampleSample',
                         'meta' => [
                             'title' => 'example',
                             'icon' => '桌子'
                        ],
                    ]
                ]
            ]
        ]
            
            ;

        返回 json_encode($ data);
    }

然后修改 src/store/modules/permission.js

添加一个方法

function dataArrayToRoutes(data) {
  const res = []
  data.forEach(item => {
    const tmp = { ...item }
    if (tmp.component === 'Layout') {
      tmp.component = Layout
    } else {
      let sub_view = tmp.component
      sub_view = sub_view.replace(/^\/*/g, '')
      tmp.component = () => import(`@/views/${sub_view}`)  //这里很重要,把view动态加载进来,而且似乎我只找到这样的写法,用拼接不行,然后 views 后面没有斜杆也不行
    }
    if (tmp.children) {
      tmp.children = dataArrayToRoutes(tmp.children)
    }
    res.push(tmp)
  })
  return res
}

然后修改这个文件中的 actions

const actions = {
  generateRoutes({ commit, state }, { roles, menus }) {
    return new Promise(resolve => {
      let accessedRoutes
      // if (roles.includes('admin')) {
      //   accessedRoutes = asyncRoutes || []
      // } else {
      //   accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      // }
      // commit('SET_ROUTES', accessedRoutes)

      accessedRoutes = dataArrayToRoutes(menus)

      commit('SET_ROUTES', accessedRoutes)

      resolve(accessedRoutes)
    })
  }
}

然后新增一个 user/getMenus 的 Vuex 的 action

const state = {
  token: getToken(),
  name: '',
  avatar: '',
  introduction: '',
  roles: [],
  menus: [] //这个是我新增的
}

const 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
  },
  SET_MENUS: (state, menus) => { //这里是新增的
    state.menus = menus
  }
}

const actions = {
    getMenus({ commit, state }) { //这个是新增的action
    return new Promise((resolve, reject) => {
      getMenus(state.token).then(response => {  //这里的getMenus是调用request方法从服务端获得路由菜单数据的Promise,类似getInfo
        const { data } = response
        console.log(data)

        if (!data) {
          reject('Verification failed, please Login again.')
        }

        const menus = data

        // roles must be a non-empty array
        if (!menus || menus.length <= 0) {
          reject('getMenus: menus must be a non-null array!')
        }

        commit('SET_MENUS', menus)
        resolve(menus)
      }).catch(error => {
        reject(error)
      })
    })
  },
}

还有一个文件是 src/permission.js
要在 store.dispatch('permission/generateRoutes') 代码附近要改一下,原先从本地配置+roles获得用户路由,现在改从服务端获得之后再 addRoutes

const menus = await store.dispatch('user/getMenus')
          // generate accessible routes map based on roles
          const accessRoutes = await store.dispatch('permission/generateRoutes', { menus })
          // dynamically add accessible routes
          router.addRoutes(accessRoutes)

亲测可行……

Originally posted by @amoydavid in #293 (comment)
你好,我按照你的方法,路由打印出来了,但是没有跳转,一直在循环打印中。这是怎么回事呢

相关问题