独书先生 Menu

Viewing all items for tag vue

Tree树形控件展示当前路径

问题

现有一个树形结构的菜单,支持无限的嵌套层级,需要根据用户点击的某个子菜单,获取到这个子菜单所在节点的路径,类似于面包屑效果。

一个合格的树形菜单数据结构

const menu = [{
          id:'1',
          label: '一级 1',
          children: [{
            id:'11',
            label: '二级 1-1',
            children: [{
              id:'111',
              label: '三级 1-1-1'
            }]
          }]
        }, {
          id:'2',
          label: '一级 2',
          children: [{
            id:'21',
            label: '二级 2-1',
            children: [{
              id:'211',
              label: '三级 2-1-1'
            }]
          }, {
            id:'22',
            label: '二级 2-2',
            children: [{
              id:'221',
              label: '三级 2-2-1'
            }]
          }]
        }, {
          id:'3',
          label: '一级 3',
          children: [{
            id:'31',
            label: '二级 3-1',
            children: [{
              id:'311',
              label: '三级 3-1-1'
            }]
          }, {
            id:'32',
            label: '二级 3-2',
            children: [{
              id:'321',
              label: '三级 3-2-1'
            }]
          }]
        }]

解决方案

思路:

递归整个树形菜单,记录下每次循环时候的当前路径名称,匹配到之后再把所有节点名称拼接起来。

其中有一个关键处理点是每次循环到同级数组,需要重新开始记录路径,否则会出现路径重复的情况

代码:

/**
 * @param {array[][]} data 整个菜单数组
 * @param {object[][]} v 当前节点对象
 * @return {string[]} 当前节点对象路径
 */

function findPath(data, v){
            var find = false; //找到id后标记,结束递归
            var paths = [];

            findId(data, v.id);

            return paths.join('/');

            function findId(root, vid) {

                var currentPathsLength = paths.length;

                root.forEach((ele, i, root) => {
                    // 后面不再循环找了
                    if (find) {
                        return
                    }

                    // 每次循环到同级数组,重新开始记录路径
                    paths = paths.slice(0,currentPathsLength);
                    paths.push(ele.label)


                    // 找到即返回
                    if (ele.id === vid) {
                        find = true;
                        return;
                    } else if (Array.isArray(ele.children) && ele.children.length > 0) { //有子节点继续寻找
                        return findId(ele.children, vid)
                    }

                });

            }
        }

在线演示:

See the Pen
zYKeVJe
by alex (@dushusir)
on CodePen.

vue no-parsing-error x-invalid-end-tag 报错

分类:vue

问题

vue + iview + eslint环境下开发,写一个<Input></Input>时报了错,提示如下:

Parsing error: x-invalid-end-tag.

原因

iView在标签渲染为原生html标签时候,因为这些标签是自闭合的,所以有end标签会报错

解决

vue cli2:

  1. 在根目录下找到.eslintrc.js – rules文件
  2. 在rules中添加一行,内容为:
  3. ‘vue/no-parsing-error’: [2, { ‘x-invalid-end-tag’: false }] // 关闭对iview end-tag 检查
  4. 重启启动服务 npm run serve / npm run dev。

vue cli3:

  1. 进入vue ui运行的http://localhost:8000管理界面
  2. 找到:配置-ESLint configuration-规则-vue/no-parsing-error, 改为关闭并保存修改
  3. 重新启动server

nuxt sass全局引入不起作用bug

问题

nuxt 全局引入sass时,官方例子有bug, github上已经有各种讨论,有很多方法是旧版本的解决方案,无法使用

解决方案

基于 nuxt 2.0.0版本的解决方案

步骤一

安装npm包

npm i -D @nuxtjs/style-resources sass-loader node-sass

步骤二

配置nuxt.config.js

module.exports = {
    // Other nuxt.config.js

    modules: ['@nuxtjs/style-resources'],
    styleResources: {
        scss: [
            'assets/css/global.scss',
            'assets/css/main.scss'
        ]
    }
}

扩展

附上2.0.0之前的旧版本的配置,可能有用,未尝试,但是 2.0.0 版本没有用

步骤一

安装npm包

npm i nuxt-sass-resources-loader

步骤二

配置nuxt.config.js

module.exports = {
    // Other nuxt.config.js

    modules: [
        [
            'nuxt-sass-resources-loader', 
            [
                'assets/css/global.scss',
                'assets/css/main.scss'
            ]åç
        ]
    ]
}

v-for id重复问题

vue中v-for 使用i 指定了唯一key,且v-for的组件内部又嵌套了v-for的组件,id会有重复的问题,

这里分享个小技巧,加前缀防止相同的id

<div v-for="(item, i) in items" :key="i"></div>

<div v-for="(item, i) in items2" :key="`A-${i}`"></div>

<div v-for="(item, i) in items3" :key="`B-${i}`"></div>

Uncaught TypeError: (intermediate value)(intermediate value).push is not a function

问题

vue cli3 + element-ui , 使用vue ui 界面工具打包(build) 项目,运行打包完成的项目时候控制台报错:

chunk-vendors.js:1 Uncaught TypeError: (intermediate value)(intermediate value).push is not a function at chunk-vendors.js:1 (anonymous) @ chunk-vendors.js:1

bootstrap:141 Uncaught TypeError: Cannot read property 'bind' of undefined at bootstrap:141 at bootstrap:151

分析

项目内通过静态资源目录(public)引入了另一个打包好的vue工程(1.这个工程是当前项目的前置依赖 2. 这个工程打包好的js是无chunks且不带hash值的,但是当前工程js是有chunks且带hash值的),把静态引入的工程去掉,就不会报那个错了,分析可能是静态工程和现有工程的打包方式冲突了.

百度一波没有解决方案,google一波省时省力,看到vue官方论坛有类似问题,参考

https://forum.vuejs.org/t/error-when-loading-vue-on-a-webpage-that-uses-webpack-3/48955

解决方案

vue.config.js中配置去除chunks即可暂时解决这个问题

chainWebpack: config => { 
  config.optimization.delete('splitChunks') 
}