vue-element-admin development log

vue-element-admin

The integrated solution is highly recommended.

Although the official website recommends the use of basic templates, add functions as needed from the integrated solution. Because some functions of the integration scheme are not available, redundant codes will be formed.

However, using the basic template is really very basic, and there are no many functions, such as tab navigation. The basic template only has breadcrumb navigation. At this time, if you want to add the function of tabs, people like me who are not familiar with the source code. I really can't find what to copy over.

Therefore, the integration scheme, redundancy is redundant, deleting code is always easier than copying code.

 

The previous work was all standing on the shoulders of giants. According to the business needs, the framework was remodeled by the big guys in the industry, and they were used directly, basically only worrying about the business code. Therefore, although this framework has not been used, it is not difficult to develop.

Now, a new project, starting from the beginning, needs to use this framework again. It is really starting to develop by downloading the framework source code from github, so many details need to be summarized and recorded.

 

text

Login: Parameters required for login in addition to user name and password, such as verification code code

src/store/modules/user.js

login({ commit }, userInfo) {

        const { username, password, code, codeId } = userInfo

        return new Promise((resolve, reject) => {

            login({ username: username.trim(), password: password, code: code.trim(), codeId: codeId }).then(response => {

                const { data } = response

                commit('SET_TOKEN', data.token)

                setToken (data.token)

                    // commit('SET_TOKEN', data.token)

                    // setToken (data.token)

                resolve()

            }).catch(error => {

                reject(error)

            })

        })

    },

 

Modify token

src/utils/request.js

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.headersekenen'X-Token '] = getToken ()

        config.headers['auth-token'] ='userToken:' + getToken() // Let each request carry a custom token, please modify it according to the actual situation

 }

 

Request timeout modification

src/utils/request.js

timeout: 10000

 

Modify routing: If the routing does not require redirection, such as the forgotten password on the login page.

src/permission.js

const whiteList = ['/login', '/auth-redirect', '/forgetPwd'] // no redirect whitelist

 

Permission routing: refer to permission related pages permission

src/router/index.js

export const asyncRoutes = [{}];

 

The route is hidden in the navigation menu: hidden: true

src/router/index.js

{

        path: '/forgetPwd',

        name: 'ForgetPwd',

        component: () =>

            import ('@/views/user/forgetPwd'),

        hidden: true

    },

 

Settings: Set to open the logo display above the menu by default

src/store/modules/settings.js

src/setting.js

/**

   * @type {boolean} true | false

   * @description Whether need tagsView

   */

  tagsView: true,

 

Property visible must be accessed with $ or _ are not proxied in the Vue instance

src/permission.js 中修改 Message.error(error) 为 Message.error(error.message)

 

catch (error) {

            // remove token and go to login page to re-login

            await store.dispatch('user/resetToken')

            Message.error(error.message)

            next(`/login?redirect=${to.path}`)

            NProgress.done()

}

Regarding permission control, the framework supports page-level and button-level permission control.

The permission control in routing is at the page level.

src/router/index.js

{

    path: '/permission',

    component: Layout,

    redirect: '/permission/page',

    alwaysShow: true, // will always show the root menu

    name: 'Permission',

    meta: {

      title: 'Permission',

      icon: 'lock',

      roles: ['admin', 'editor'] // you can set roles in root nav

    },

    children: [

      {

        path: 'page',

        component: () => import('@/views/permission/page'),

        name: 'PagePermission',

        meta: {

          title: 'Page Permission',

          roles: ['admin'] // or you can only set roles in sub nav

        }

      },

      {

        path: 'directive',

        component: () => import('@/views/permission/directive'),

        name: 'DirectivePermission',

        meta: {

          title: 'Directive Permission'

          // if do not set roles, means: this page does not require permission

        }

      },

      {

        path: 'role',

        component: () => import('@/views/permission/role'),

        name: 'RolePermission',

        meta: {

          title: 'Role Permission',

          roles: ['admin']

        }

      }

    ]

  },

 

The permission control in the page is at the button level.

Key method

v-if="checkPermission(['admin','editor'])"

v-permission="['admin','editor']"

 

Front-end and back-end parameter interaction: about response codes and response messages

The backend requests to obtain the status code and x-api-message in the header as the response code and error message.

Decode the message (base64)

decodeURIComponent (window.atob ('dG9rZW4lRTQlQjglOEQlRTglODMlQkQlRTQlQjglQkElRTclQTklQkElRUYlQkMlODE ='))

Request interceptor

src/utils/request.js

The problem with the following is that when the Status Code is 403 or 404, it cannot be obtained by using res.status. You need to use error.response.status to get it in the error handling function.

// response interceptor

service.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

     */

    response => {

        //const res = response.data

        const res = response

        // if the custom code is not 200, it is judged as an error.

        // Get response status Status Code information

        if (res.status != 200) {

            Message({

                message: res.msg ||'Request failed',

                type: 'error',

                duration: 5 * 1000

            })

 

            if (res.status == 401) {

                // to re-login

                MessageBox.confirm('Login failed, please log in again!','OK', {

                    confirmButtonText:'Login again',

                    cancelButtonText:'Cancel',

                    type: 'warning'

                }).then(() => {

                    store.dispatch('user/resetToken').then(() => {

                        location.reload()

                    })

                })

            }

            return Promise.reject(new Error(res.msg ||'Request failed'))

        } else {

            return res

        }

    },

    error => {

        Message({

            message: error.message,

            type: 'error',

            duration: 5 * 1000

        })

        return Promise.reject(error)

    }

)

Expand learning: http://www.axios-js.com/zh-cn/docs/#%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86

Error handling

axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

Summary: Let's use the regular parameter interaction, and what do those moths do. Later, I consulted other people, and the above writing still has functional problems. When using other protocols for transmission, some protocols do not have header messages. In addition, the back-end return value is encrypted as a whole, and the message and status code are more convenient to write together with other return values.

{

 "code": "200",

 "msg": "成功",

 "data": [{...},{...}]

}

 

设置的路由,跳出框架显示。

The reason is that component: Layout is not set

src/router/index.js

{

        path: '/user',

        component: Layout,

        children: [{

            path: 'center',

            name: 'Center',

            component: () =>

                import ('@/views/user/center/index'),

                hidden: true,

            meta: {title:'Personal Center'}

        }]

}

 

elementUI form reset Cannot read property'form' of undefined"

excluded 

The form needs to have ref, and the name of formName must be consistent.

You need to complete the el-form and form-item components and configure props. If you execute this method without configuration, the input box value will not be reset.

Reason for error: Note that it is refs, not ref.

resetForm(formName){

      this.$refs[formName].resetFields();

}

 

Switch the English display of the paging component to Chinese

I didn't realize that it was a language problem at first, and I couldn't find Go to in full text search.

Later I learned that it was a language problem.

src/main.js

In the default setting, English is used.

Direct comment, because the default is Chinese. Note that the following Vue.use Element should also be annotated.

//import enLang from'element-ui/lib/locale/lang/en'// If you use the Chinese language pack, please support it by default, no additional import is required, please delete the dependency

 

Vue.use(Element, {

  size: Cookies.get('size') || 'medium', // set element-ui default size

  //locale: enLang // If you use Chinese, no need to set, please delete

})

 

Close current page

this.$store.dispatch('tagsView/delView', this.$route)

 

It does not take effect if it is written, it may be written in a wrong place. For example, in the following example, the closing method error is written in the article component (article).

 

Application examples

Article management list page (index) == (click to add, jump to) == "New article page (add) == (sub component) == "article component (article) == (fill in the content and click submit) ==》Add successfully, trigger the parent component (add) to close the current page and return to the list page event.

Article management list page (index) == (click to edit, carry article id through routing, jump to) == "Article edit page (edit) == (sub-component) == "article component (article) == fill in After the content, click Submit==》Edit is successful, and trigger the event of the parent component (edit) to close the current page and return to the list page.

Remarks:

1. Stay on the edit page (edit) and directly click the refresh of the browser. Refresh will lose the article id. When refreshing, other pages are automatically closed, and only the current page is kept.

2. Add and edit, mainly adding. After returning to the list page, the list page needs to get data again. In the list page, write the method of page initialization in activated.

      activated() {

          this.getTableData()

      }

 

Article new page

<template>

  <article-detail :is-edit="false" @close="closeSelectedTag" />

</template>

<script>

import ArticleDetail from './components/ArticleDetail'

export default {

  name: 'ManageModuleNewsAdd',

  components: { ArticleDetail },

  methods: {

    closeSelectedTag() {

      // Close the current page

      this.$store.dispatch('tagsView/delView', this.$route)

      this.$router.push({

        name: 'ManageModuleNews'

      })

    }

  }

}

</script>

 

Article edit page

<template>

  <article-detail :is-edit="true" @close="closeSelectedTag" />

</template>

<script>

import ArticleDetail from './components/ArticleDetail'

export default {

  name: 'ManageModuleNewsEdit',

  components: { ArticleDetail },

  methods: {

    closeSelectedTag() {

      // Close the current page

      this.$store.dispatch('tagsView/delView', this.$route)

      this.$router.push({

        name: 'ManageModuleNews'

      })

    }

  }

}

</script>

 

Article component

created() {

    if (this.isEdit) { // 编辑 isEdit=true

      const id = this.$route.params.id

      if (!id) {

        // Refresh will lose id. When refreshing, other pages are automatically closed, and only the current page is kept.

        this.$message({

          message:'The information id is lost, please close this page and re-enter! ',

          type: 'warning'

        })

      } else {

        // Query article details based on id

        this.fetchData(id)

      }

    } else {

      // add

      this.newsForm = this.defaultNews

      this.fileObj.fileUrl = ''

    }

  },

 methods: {

   handleSubmit() {

      if (this.isEdit) {

        this.updateNews(this.newsForm)

      } else {

        this.addNews(this.newsForm)

      }

    },

 

    async addNews(row) {

      const res = await addNews(row)

      if (res.code === 200) {

        this.$message({

          message:'Added successfully! ',

          type: 'success'

        })

        // Trigger the parent component, close the current page, jump to the list page

        this.$emit('close')

      }

    },

 

    async updateNews(row) {

      const res = await updateNews(row)

      if (res.code === 200) {

        this.$message({

          message:'Save successfully! ',

          type: 'success'

        })

        // Trigger the parent component, close the current page, jump to the list page

        this.$emit('close')

      }

    },

}

 

 

======

To be continued

Guess you like

Origin blog.csdn.net/Irene1991/article/details/110957592