Skip to content

import(@/views/${sub_view})模板语法识别不了怎么办 #3326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
zxx370455951 opened this issue Jul 18, 2020 · 7 comments
Open

import(@/views/${sub_view})模板语法识别不了怎么办 #3326

zxx370455951 opened this issue Jul 18, 2020 · 7 comments

Comments

@zxx370455951
Copy link

附一个我完成的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)

@zxx370455951
Copy link
Author

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)

@zxx370455951
Copy link
Author

用的是最新的4.4.0

@zxx370455951
Copy link
Author

@zxx370455951
Copy link
Author

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
}
这是改造的代码

@ocweai
Copy link

ocweai commented Jul 21, 2020

  1. import((@/views/${sub_view}))

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

这两种方法也不行吗?

@aboutZZ
Copy link

aboutZZ commented Nov 12, 2020

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

@Spring456
Copy link

附一个我完成的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)
你好,我按照你的方法,路由打印出来了,但是没有跳转,一直在循环打印中。这是怎么回事呢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants