本文主要内容是通过@vue/cli4创建一个基础的element项目,记录一下完整的创建过程

1.安装node.js

访问地址:Node官网,下载最新的LTS(长期支持版本),进行安装,安装过程使用默认安装方式就可以,但是注意一点,安装过程中出现如下选择,建议选择,虽然安装时间较长,但是会将node.js需要的一些工具安装好如python2等。

本人安装的版本如下,如果为了确保一致性,可以选择此版本安装(V12.16.1)

2.修改NPM镜像源

由于国内访问NPM有时候会比较慢,建议将镜像源更换成淘宝的镜像源

//永久修改本地npm的配置
npm config set registry https://registry.npm.taobao.org
//查看npm源地址有没有换成功
npm config get registry
//重置为官方源
npm config set registry https://registry.npmjs.org/

3.安装@vue/cli

按照Vue Cli官方给出的安装说明进行安装即可

//Vue CLI 的包名称由 vue-cli 改成了 @vue/cli。 
//如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先卸载 
npm uninstall vue-cli -g
//或者使用yarn
yarn global remove vue-cli


//卸载完成后使用如下命令进行安装
npm install -g @vue/cli
# OR
yarn global add @vue/cli


//安装完成后输入如下命令查看版本
vue --version

如下给出当前安装版本信息,用于一致性

4.通过VUE UI进行项目创建

相关的VUE UI说明可以通过VUE CLI官网了解

//首先新建一个对应的目录(本机在Win10上,如下是通过Win10的命令提示符运行)
//目录路径为D:\workspace\myjs在此目录当中执行如下命令
vue ui

启动之后会打开默认浏览器进入如下界面,界面开始是英文,稍等一下会自动切换为中文,由于之前已经创建过一个项目,如果是第一次打开,应该是一个完全空白的界面,点击创建进行新项目的创建

创建界面如下,找到对应的路径,点击在此创建新项目

进入如下页面创建项目,其余的配置选择默认就可以,点击下一步

选择默认就可以,后期可以在UI界面进行插件和依赖的安装,也可以在这里直接手动选择,点击创建项目,稍等片刻,项目创建成功

项目创建成功会弹出此界面,可能会是英文,会自动转换成中文

到此一个新项目创建成功,打开webstorm将新项目导入

执行yar serve,查看项目是否能够正常启动

打开浏览器查看,出现如下的界面说明启动成功

 

5.配置Element

找到Element官网快速上手当中的Element 插件,根据插件的Readme.md,进行Element安装,第一种是通过命令行安装

 

另一种是通过VUE UI进行安装,找到插件==》添加插件

搜索element,找到vue-cli-plugin-element进行安装

弹出如下界面,点击完成安装

弹出如下完成安装

这时打开webstorm对应项目会发现多了plugins文件夹,element相关已经被添加到element.js当中

重新启动项目yarn serve,打开浏览器发现界面当中多出了el-button说明安装成功

6.编写customtree.vue进行测试

这里是随机选择了Element组件当中的tree树形控件进行测试

在webstorm的components文件夹下添加elm/tree文件夹,在此文件夹当中新增customtree.vue

将element官方文档当中的tree树形控件当中的自定义节点内容的代码复制到template当中

//可以通过两种方法进行树节点内容的自定义:render-content和 scoped slot。
//使用render-content指定渲染函数,该函数返回需要的节点区内容即可。
//渲染函数的用法请参考 Vue 文档。使用 scoped slot 会传入两个参数node和data,
//分别表示当前节点的 Node 对象和当前节点的数据。注意:由于 jsfiddle 不支持 JSX 语法,
//所以render-content示例在 jsfiddle 中无法运行。
//但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。

<div class="custom-tree-container">
  <div class="block">
    <p>使用 render-content</p>
    <el-tree
      :data="data"
      show-checkbox
      node-key="id"
      default-expand-all
      :expand-on-click-node="false"
      :render-content="renderContent">
    </el-tree>
  </div>
  <div class="block">
    <p>使用 scoped slot</p>
    <el-tree
      :data="data"
      show-checkbox
      node-key="id"
      default-expand-all
      :expand-on-click-node="false">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <el-button
            type="text"
            size="mini"
            @click="() => append(data)">
            Append
          </el-button>
          <el-button
            type="text"
            size="mini"
            @click="() => remove(node, data)">
            Delete
          </el-button>
        </span>
      </span>
    </el-tree>
  </div>
</div>

<script>
  let id = 1000;

  export default {
    data() {
      const data = [{
        id: 1,
        label: '一级 1',
        children: [{
          id: 4,
          label: '二级 1-1',
          children: [{
            id: 9,
            label: '三级 1-1-1'
          }, {
            id: 10,
            label: '三级 1-1-2'
          }]
        }]
      }, {
        id: 2,
        label: '一级 2',
        children: [{
          id: 5,
          label: '二级 2-1'
        }, {
          id: 6,
          label: '二级 2-2'
        }]
      }, {
        id: 3,
        label: '一级 3',
        children: [{
          id: 7,
          label: '二级 3-1'
        }, {
          id: 8,
          label: '二级 3-2'
        }]
      }];
      return {
        data: JSON.parse(JSON.stringify(data)),
        data: JSON.parse(JSON.stringify(data))
      }
    },

    methods: {
      append(data) {
        const newChild = { id: id++, label: 'testtest', children: [] };
        if (!data.children) {
          this.$set(data, 'children', []);
        }
        data.children.push(newChild);
      },

      remove(node, data) {
        const parent = node.parent;
        const children = parent.data.children || parent.data;
        const index = children.findIndex(d => d.id === data.id);
        children.splice(index, 1);
      },

      renderContent(h, { node, data, store }) {
        return (
          <span class="custom-tree-node">
            <span>{node.label}</span>
            <span>
              <el-button size="mini" type="text" on-click={ () => this.append(data) }>Append</el-button>
              <el-button size="mini" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
            </span>
          </span>);
      }
    }
  };
</script>

<style>
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
</style>

复制到webstorm的customtree.vue当中的样子如下,会发现有多处报错

<template>
    <div class="custom-tree-container">
        <div class="block">
            <p>使用 render-content</p>
            <el-tree
                    :data="data"
                    show-checkbox
                    node-key="id"
                    default-expand-all
                    :expand-on-click-node="false"
                    :render-content="renderContent">
            </el-tree>
        </div>
        <div class="block">
            <p>使用 scoped slot</p>
            <el-tree
                    :data="data"
                    show-checkbox
                    node-key="id"
                    default-expand-all
                    :expand-on-click-node="false">
                <span class="custom-tree-node" slot-scope="{ node, data }">
                    <span>{{ node.label }}</span>
                    <span>
                        <el-button
                                type="text"
                                size="mini"
                                @click="() => append(data)">
                            Append
                        </el-button>
                        <el-button
                                type="text"
                                size="mini"
                                @click="() => remove(node, data)">
                            Delete
                        </el-button>
                    </span>
                </span>
            </el-tree>
        </div>
    </div>
</template>

<script>
    export default {
        name: "customtree",
        data() {
            const data = [{
                id: 1,
                label: '一级 1',
                children: [{
                    id: 4,
                    label: '二级 1-1',
                    children: [{
                        id: 9,
                        label: '三级 1-1-1'
                    }, {
                        id: 10,
                        label: '三级 1-1-2'
                    }]
                }]
            }, {
                id: 2,
                label: '一级 2',
                children: [{
                    id: 5,
                    label: '二级 2-1'
                }, {
                    id: 6,
                    label: '二级 2-2'
                }]
            }, {
                id: 3,
                label: '一级 3',
                children: [{
                    id: 7,
                    label: '二级 3-1'
                }, {
                    id: 8,
                    label: '二级 3-2'
                }]
            }];
            return {
                data: JSON.parse(JSON.stringify(data)),
                data: JSON.parse(JSON.stringify(data))
            }
        },

        methods: {
            append(data) {
                const newChild = {id: id++, label: 'test', children: []};
                if (!data.children) {
                    this.$set(data, 'children', []);
                }
                data.children.push(newChild);
            },

            remove(node, data) {
                const parent = node.parent;
                const children = parent.data.children || parent.data;
                const index = children.findIndex(d => d.id === data.id);
                children.splice(index, 1);
            },
            renderContent(h, {node, data}) {
                return (
                    <span class="custom-tree-node">
                    <span>{node.label}</span>
                    <span>
                    <el-button size="mini" type="text" on-click={() => this.append(data)}>Append</el-button>
                <el-button size="mini" type="text" on-click={() => this.remove(node, data)}>Delete</el-button>
                </span>
                </span>
            );
            }
        }
    }
</script>

<style scoped>
    .custom-tree-node {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        font-size: 14px;
        padding-right: 8px;
    }
</style>

第一处报错,是官方多了个data....,我们删除

第二处是JSX语法报错,我们看之前的说明,这里表明了我们的VUE需要添加JSX语法的支持

找到官方中对VUE使用JSX的说明,找到对应的Babel插件

我们可以通过如下方式进行安装,也可以通过vue ui进行安装

vue ui安装方式如下,找到依赖==》安装依赖

 

搜索@vue/babel-preset-jsx,进行安装

搜索@vue/babel-helper-vue-jsx-merge-props进行安装

查看是否都已经安装成功

打开babel.config.js:修改成如下

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
    '@vue/babel-preset-jsx'
  ]
}

修改后的customtree.vue如下

<template>
    <div class="custom-tree-container">
        <div class="block">
            <p>使用 render-content</p>
            <el-tree
                    :data="data"
                    show-checkbox
                    node-key="id"
                    default-expand-all
                    :expand-on-click-node="false"
                    :render-content="renderContent">
            </el-tree>
        </div>
        <div class="block">
            <p>使用 scoped slot</p>
            <el-tree
                    :data="data"
                    show-checkbox
                    node-key="id"
                    default-expand-all
                    :expand-on-click-node="false">
                <span class="custom-tree-node" slot-scope="{ node, data }">
                    <span>{{ node.label }}</span>
                    <span>
                        <el-button
                                type="text"
                                size="mini"
                                @click="() => append(data)">
                            Append
                        </el-button>
                        <el-button
                                type="text"
                                size="mini"
                                @click="() => remove(node, data)">
                            Delete
                        </el-button>
                    </span>
                </span>
            </el-tree>
        </div>
    </div>
</template>

<script>
    let id=1000;
    export default {
        name: "customtree",
        data() {
            const data = [{
                id: 1,
                label: '一级 1',
                children: [{
                    id: 4,
                    label: '二级 1-1',
                    children: [{
                        id: 9,
                        label: '三级 1-1-1'
                    }, {
                        id: 10,
                        label: '三级 1-1-2'
                    }]
                }]
            }, {
                id: 2,
                label: '一级 2',
                children: [{
                    id: 5,
                    label: '二级 2-1'
                }, {
                    id: 6,
                    label: '二级 2-2'
                }]
            }, {
                id: 3,
                label: '一级 3',
                children: [{
                    id: 7,
                    label: '二级 3-1'
                }, {
                    id: 8,
                    label: '二级 3-2'
                }]
            }];
            return {
                data: JSON.parse(JSON.stringify(data))
            }
        },

        methods: {
            append(data) {
                const newChild = {id: id++, label: 'test', children: []};
                if (!data.children) {
                    this.$set(data, 'children', []);
                }
                data.children.push(newChild);
            },

            remove(node, data) {
                const parent = node.parent;
                const children = parent.data.children || parent.data;
                const index = children.findIndex(d => d.id === data.id);
                children.splice(index, 1);
            },
            renderContent(h, {node, data}) {
                return (
                    <span class="custom-tree-node">
                    <span>{node.label}</span>
                    <span>
                    <el-button size="mini" type="text" on-click={() => this.append(data)}>Append</el-button>
                <el-button size="mini" type="text" on-click={() => this.remove(node, data)}>Delete</el-button>
                </span>
                </span>
            );
            }
        }
    }
</script>

<style scoped>
    .custom-tree-node {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        font-size: 14px;
        padding-right: 8px;
    }
</style>

此时依然在JSX语法下报错,这是由于webstorm的原因造成的,打开File==>settings==>Languages&Frameworks==>JavaScript

将ECMAScript6+修改成React JSX,此时等待webstorm运行完成,这里也就不再报错误了,目前只有这个方法能解决element当中的这个标红问题,虽然标红不影响正常运行,但是看着别扭,通过这种方式可解决,老版本的webstorm应该叫做JSX Harmony

这时JSX语法不再报错

修改App.vue如下

<template>
  <div id="app">
    <CustomTree></CustomTree>
  </div>
</template>

<script>
import CustomTree from "./components/elm/tree/customtree";
export default {
  name: 'app',
  components: {
    CustomTree
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

然后运行yarn serve,出现如下界面说明正常运行,但是这里又出现了个问题,第一种的reder-content方式Append Delete紧贴在节点后面,而官方的例子是正常的,这里经过查询主要原因是于<style scoped></style>造成的

修改customtree.vue如下,再次运行,结果正常

<template>
    <div class="custom-tree-container">
        <div class="block">
            <p>使用 render-content</p>
            <el-tree
                    :data="data"
                    show-checkbox
                    node-key="id"
                    default-expand-all
                    :expand-on-click-node="false"
                    :render-content="renderContent">
            </el-tree>
        </div>
        <div class="block">
            <p>使用 scoped slot</p>
            <el-tree
                    :data="data"
                    show-checkbox
                    node-key="id"
                    default-expand-all
                    :expand-on-click-node="false">
                <span class="custom-tree-node" slot-scope="{ node, data }">
                    <span>{{ node.label }}</span>
                    <span>
                        <el-button
                                type="text"
                                size="mini"
                                @click="() => append(data)">
                            Append
                        </el-button>
                        <el-button
                                type="text"
                                size="mini"
                                @click="() => remove(node, data)">
                            Delete
                        </el-button>
                    </span>
                </span>
            </el-tree>
        </div>
    </div>
</template>

<script>
    let id=1000;
    export default {
        name: "customtree",
        data() {
            const data = [{
                id: 1,
                label: '一级 1',
                children: [{
                    id: 4,
                    label: '二级 1-1',
                    children: [{
                        id: 9,
                        label: '三级 1-1-1'
                    }, {
                        id: 10,
                        label: '三级 1-1-2'
                    }]
                }]
            }, {
                id: 2,
                label: '一级 2',
                children: [{
                    id: 5,
                    label: '二级 2-1'
                }, {
                    id: 6,
                    label: '二级 2-2'
                }]
            }, {
                id: 3,
                label: '一级 3',
                children: [{
                    id: 7,
                    label: '二级 3-1'
                }, {
                    id: 8,
                    label: '二级 3-2'
                }]
            }];
            return {
                data: JSON.parse(JSON.stringify(data))
            }
        },

        methods: {
            append(data) {
                const newChild = {id: id++, label: 'test', children: []};
                if (!data.children) {
                    this.$set(data, 'children', []);
                }
                data.children.push(newChild);
            },

            remove(node, data) {
                const parent = node.parent;
                const children = parent.data.children || parent.data;
                const index = children.findIndex(d => d.id === data.id);
                children.splice(index, 1);
            },
            renderContent(h, {node, data}) {
                return (
                    <span class="custom-tree-node">
                    <span>{node.label}</span>
                    <span>
                    <el-button size="mini" type="text" on-click={() => this.append(data)}>Append</el-button>
                <el-button size="mini" type="text" on-click={() => this.remove(node, data)}>Delete</el-button>
                </span>
                </span>
            );
            }
        }
    }
</script>

<style>
    .custom-tree-node {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        font-size: 14px;
        padding-right: 8px;
    }
</style>

到此问题解决,基本的@vue/cli4+ element的项目例子搭建完成

Logo

前往低代码交流专区

更多推荐