# ElementUI 的使用
dj vue-element-demo
每个组件的方法在文档中查看 (https://element.eleme.cn/#/zh-CN/component/installation)
element-ui 的使用 基于 @vue-cli 3+
# 安装
命令行输入:vue add element
vue ui: 选择 element 插件安装
选择 import on damand (按需加载方式)
安装完之后,如果页面没有效果,需要重新启动一下
# 简单使用
Message 消息提示不需要 use,只需要 Vue.prototype.$message = Message,这样才可以使用 $message 方法
-
App.vue
<template> <div> <h1>hello element-UI</h1> <!-- element-ui 内的组件可以分为两种 --> <!-- 1.组件形式的 --> <!-- element-ui 组件的事件绑定如果没有文档特殊提示的话 直接像使用原生元素一样绑定事件,style 也是一样 --> <el-button type="danger" round :loading="isLoading" :style="{ width: '200px' }" @click="isLoading = true" >按钮</el-button > <el-date-picker v-model="date" :editable="false" @change="change" value-format="yyyy-MM-dd" /> <el-switch v-model="open" :width="50" inactive-icon-class="img" active-icon-class="img" @change="switchChange" /> <br /> <br /> <!-- 2.方法类型 --> <el-button @click="showMessage">测试 Message 方法</el-button> </div> </template> <script> // element-ui 的使用 基于 @vue-cli 3+ // element-ui 里面的方法哪个组件想用直接导入使用 // 也可以制作成 vue 全局的方法 直接使用 this 访问,需要使用 Vue.prototype 设置成全局方法 // import { Message } from "element-ui"; export default { name: "App", data() { return { isLoading: false, date: "", open: true, }; }, methods: { change(a) { console.log(a); //拿到的是选择的日期 }, switchChange(e) { console.log(e); //true和false }, showMessage() { // Message("这是一条提示信息"); this.$message("这是一条提示信息"); }, }, }; </script> <style> .img { width: 20px; height: 20px; background-size: 100%; background-image: url("./assets/logo.png"); } </style> -
element.js
import Vue from "vue"; import { Button, DatePicker, Switch, Message } from "element-ui"; // 将 Button 组件注册成全局组件 Vue.use(Button); Vue.use(DatePicker); Vue.use(Switch); // 将 Message 制作成全局方法 // $message 可以随便命名 Vue.prototype.$message = Message;
# 导航菜单 (elementUI 中的案例)
-
MenuDemo.vue, 自己生成标签
<template> <div> <el-menu class="el-menu-vertical-demo"> <!-- v-for 是生成多个同样的标签或组件 --> <template v-for="(item, index) in menu"> <el-submenu :key="item.id" :index="(index + 1) | toString" v-if="item.children && item.children.length" > <template #title> <span>{{ item.title }}</span> </template> <!-- 生成嵌套子菜单 --> <el-menu-item v-for="(ele, ind) in item.children" :key="ele.id" :index="`${(index + 1) | toString}-${(ind + 1) | toString}`" > <template #title> <span> {{ ele.title }}</span> </template> </el-menu-item> </el-submenu> <el-menu-item :key="item.id" :index="(index + 1) | toString" v-else> <template #title> <span>{{ item.title }}</span></template> </el-menu-item> </template> </el-menu> </div> </template> <script> export default { filters: { // 过滤器 传参 | 过滤器名称 toString: function (value) { return value.toString(); }, }, data() { return { // 后台提供的菜单数组 menu: [ { id: 1, title: "菜单1", children: [ { id: 3, title: "菜单1-1", }, { id: 4, title: "菜单1-2", }, ], }, { id: 2, title: "菜单2", }, { id: 5, title: "菜单3", }, ], }; }, }; </script>
# Tree 树形
-
TreeDemo.vue
<template> <div> <h2>Tree组件</h2> <el-input placeholder="输入关键字进行过滤" v-model="filterText" ></el-input> <el-tree ref="tree" :data="data" :props="defaultProps" @node-click="handleNodeClick" show-checkbox @check-change="checkChange" default-expand-all :filter-node-method="filterNode" > <!-- 借助作用域插槽 自定义树的节点内容 --> <!-- 默认的插槽就是节点内容 --> <!-- 在 tree 组件内已经向插槽传递了数据, 只需要在使用tree组件的时候,在传递的插槽中接收即可 --> <!-- 插槽传递的数据有两个 node:当前节点对象 data:树的初始数据(就是底下data中的整个data数组) --> <template v-slot:default="{ node }"> <span class="custom-tree-node"> <span v-html="$options.filters.filterNodeStr(node.label,filterText)" ></span> <span> <el-button type="text" size="mini">Append</el-button> <el-button type="text" size="mini">Delete</el-button> </span> </span> </template> </el-tree> </div> </template> <script> export default { name: "TreeDemo", data() { return { data: [ { label: "一级 1", children: [ { label: "二级 1-1", children: [ { label: "三级 1-1-1", }, ], }, ], }, { label: "一级 2", children: [ { label: "二级 2-1", children: [ { label: "三级 2-1-1", }, ], }, { label: "二级 2-2", children: [ { label: "三级 2-2-1", }, ], }, ], }, { label: "一级 3", children: [ { label: "二级 3-1", children: [ { label: "三级 3-1-1", }, ], }, { label: "二级 3-2", children: [ { label: "三级 3-2-1", }, ], }, ], }, ], defaultProps: { children: "children", // 节点子树的属性名 label: "label", // 指定的是节点标签的属性名 }, filterText: "", }; }, filters: { filterNodeStr(label, filterText) { const isHasKeyWord = label.includes(filterText); // 返回的字符串会使用 v-html 加载到 span 标签内 if (filterText === "" || !isHasKeyWord) return label; const startIndex = label.indexOf(filterText); // 这里最外层的span省略了,因为上边用了span标签 return `<span>${label.slice(0, startIndex)}</span> <span class='key-word'>${filterText}</span> <span>${label.slice(startIndex + filterText.length)}</span>`; }, }, watch: { // 监听 filterText 的变化 filterText(val) { // element-ui 内有的组件自带一些方法,使用对应的组件可以直接调用 // 通过 ref 获取组件 // ref 使用在组件身上的话获取的是组件本身 // ref 使用在非组件身上的话获取的是真实 dom 元素 console.log(this.$refs.tree); // filter 是 tree 组件自带的筛选节点方法 this.$refs.tree.filter(val); // 这个监听实现的是一旦 filterText 发生了改变就使用 tree 组件自带的 fitler 方法, // 执行 tree 组件接收的filter-node-method prop, // 并将 filterText 传递给该方法当作第一个参数 // filter-node-method tree 组件有多少个节点,执行多少次 }, }, methods: { handleNodeClick() { // 默认接收三个参数 obj, node, nodeCommonent // console.log(obj); // console.log(node); // console.log(nodeCommonent); }, checkChange() { // console.log("复选框发生了改变"); }, filterNode(value, data) { // console.log(value); // 该函数会默认接收两个参数 第一个是 tree 组件的filter方法传递的参数 // 第二个是当前节点的数据内容data(data中的data数组) // tree 组件有多少个节点,该方法执行多少次,每次需要设置返回值来控制节点的出现和消失 // console.log(data); if (!value) return true; return data.label.indexOf(value) !== -1; }, }, }; </script> <style> .custom-tree-node { display: flex; align-items: center; } .key-word { color: orange; } </style>
# 表格
-
案例 1
-
TableDemo.vue (data 中一共 100 条数据,这里省略了 95 个)
<template> <div> <h2>TableDemo</h2> <el-table :data="showTableData" border style="width: 100%"> <el-table-column prop="id" label="序号" width="180" align="center" ></el-table-column> <el-table-column prop="title" label="标题"></el-table-column> <el-table-column label="重要性" width="180" align="center"> <!-- table-column 的作用域插槽,slotProps是组件内部使用插槽的时候传递的数据,slotProps.row 就是对应的表格内的某一项 --> <template v-slot="{row}"> <el-rate v-model="row.important" disabled :max="row.important" :colors="['#000']" ></el-rate> </template> </el-table-column> <el-table-column label="操作" width="180" align="center"> <el-button type="primary" size="mini">编辑</el-button> <el-button type="danger" size="mini">删除</el-button> </el-table-column> </el-table> <!-- <el-pagination :current-page="currentPage" :page-size="10" background layout="prev, pager, next" :total="tableData.length" @current-change="pageChange" ></el-pagination>--> <el-pagination :current-page.sync="currentPage" :page-size="10" background layout="prev, pager, next" :total="tableData.length" ></el-pagination> </div> </template> <script> export default { name: "TableDemo", data() { return { tableData: [ { important: 2, userId: 1, id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto", }, { important: 4, userId: 1, id: 2, title: "qui est esse", body: "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla", }, { important: 5, userId: 1, id: 3, title: "ea molestias quasi exercitationem repellat qui ipsa sit aut", body: "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut", }, { important: 3, userId: 1, id: 4, title: "eum et est occaecati", body: "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit", }, { important: 2, userId: 1, id: 5, title: "nesciunt quas odio", body: "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque", }, ], currentPage: 1, }; }, computed: { showTableData() { return this.tableData.slice( (this.currentPage - 1) * 10, this.currentPage * 10 ); }, }, methods: { /* pageChange(page) { console.log(111); this.currentPage = page; } */ }, }; </script>
-
-
案例 2 在服务器中加载数据
-
项目下新建的 data 文件夹 中的 data.json 文件 (一共 100 条数据,这里省略了 95 个)
(要在 data.json 文件打开命令行工具输入 json-server --watch data.json -p 3008){ "posts": [ { "important": 3, "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }, { "important": 2, "userId": 1, "id": 2, "title": "qui est esse", "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" }, { "important": 4, "userId": 1, "id": 3, "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" }, { "important": 2, "userId": 1, "id": 4, "title": "eum et est occaecati", "body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit" }, { "important": 2, "userId": 1, "id": 5, "title": "nesciunt quas odio", "body": "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque" } ] } -
TableDemo.vue
<template> <div> <h2>TableDemo</h2> <div v-if="tableData.length"> <el-table :data="tableData" border style="width: 100%"> <el-table-column prop="id" label="序号" width="180" align="center" ></el-table-column> <el-table-column prop="title" label="标题"></el-table-column> <el-table-column label="重要性" width="180" align="center"> <!-- table-column 的作用域插槽,slotProps是组件内部使用插槽的时候传递的数据 ,slotProps.row 就是对应的表格内的某一项 --> <template v-slot="{ row }"> <el-rate v-model="row.important" disabled :max="row.important" :colors="['#000']" ></el-rate> </template> </el-table-column> <el-table-column label="操作" width="180" align="center"> <el-button type="primary" size="mini">编辑</el-button> <el-popconfirm title="确定删除这一条数据吗" @confirm="delPost()"> <template #reference> <el-button type="danger" size="mini">删除</el-button> </template> </el-popconfirm> </el-table-column> </el-table> <!-- <el-pagination :current-page.sync="currentPage" :page-size="10" background layout="prev, pager, next" :total="tableData.length" ></el-pagination> --> <!-- 对应1,2 created --> <!-- <el-pagination :current-page="currentPage" :page-size="10" background layout="prev, pager, next" :total="100" @current-change="pageChange" ></el-pagination> --> <!-- 对应的方法,这里pageChange没有被注释 --> <el-pagination :current-page.sync="currentPage" :page-size="10" background layout="prev, pager, next" :total="total" ></el-pagination> </div> <div v-else>我是 gif图,我在努力加载</div> </div> </template> <script> // 下载了 axios (npm i axios) 在项目文件夹中执行 import axios from "axios"; export default { name: "TableDemo", data() { return { tableData: [], currentPage: 5, total: 100, }; }, /* created() { axios .get("http://localhost:3008/posts?_page=1&_limit=10") .then((res) => { console.log(res.data); }); }, */ /* async created() { const res = await axios.get( `http://localhost:3008/posts?_page=${this.currentPage}&_limit=10` ); console.log(res.data); this.tableData = res.data; // 这里只会一进来展示第几页,点击页数的时候不会修改,所以需要一个methods方法pageChange // 也可以使用 监听器 watch 监听 currentPage }, */ /* created() { this.getPosts(this.currentPage); }, */ watch: { currentPage: { handler(newVal) { // newVal 新的一页 this.getPosts(newVal); }, immediate: true, }, }, computed: { /* showTableData() { return this.tableData.slice( (this.currentPage - 1) * 10, this.currentPage * 10 );f }, */ }, methods: { async getPosts(page) { const res = await axios.get( `http://localhost:3008/posts?_page=${page}&_limit=10` ); this.tableData = res.data; }, /* pageChange(page) { this.currentPage = page; this.getPosts(page); }, */ }, }; </script>
-
-
案例 3 过滤,编辑,删除,添加等功能
-
TableDemo.vue
<template> <div> <h2>TableDemo</h2> <!-- 对话框 --> <el-dialog title="添加文章" :visible.sync="showDialog" :close-on-click-modal="false" class="table" > <el-form :model="post" ref="elFormComponent"> <!-- rules 是规则数组,里面的每一项都是一个规则 --> <el-form-item prop="title" label="标题" :rules="[ { required: true, message: '请输入标题', trigger: 'blur' } ]" > <el-input v-model="post.title"></el-input> </el-form-item> <el-form-item label="作者ID" prop="userId" :rules="[ { required: true, message: '请输入作者 id', trigger: 'blur' } ]" > <el-input v-model.number="post.userId"></el-input> </el-form-item> <el-form-item label="重要性"> <el-rate v-model="post.important"></el-rate> </el-form-item> <el-form-item label="内容" prop="body" :rules="[ { required: true, validator:validateContent, trigger: 'blur' } ]" > <el-input v-model="post.body" type="textarea"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="closeDialog">取 消</el-button> <el-button type="primary" @click="dialogConfirmBtnClick" >确 定</el-button > </div> </el-dialog> <!-- 表格 --> <!-- <div v-if="tableData.length"> --> <div> <el-input style="width:150px" v-model="searchTxt" placeholder="标题" ></el-input> <el-button type="primary" icon="el-icon-search" @click="search" >搜索</el-button > <el-button type="primary" @click="openDialog">添加</el-button> <el-table :data="tableData" border style="width: 100%" v-loading="loading" > <el-table-column prop="id" label="序号" width="180" align="center" sortable ></el-table-column> <el-table-column prop="title" label="标题" sortable ></el-table-column> <el-table-column label="重要性" width="180" align="center" sortable> <!-- table-column 的作用域插槽,slotProps是组件内部使用插槽的时候传递的数据,slotProps.row 就是对应的表格内的某一项 --> <template v-slot="{ row }"> <el-rate v-model="row.important" disabled :max="row.important" :colors="['#000']" ></el-rate> </template> </el-table-column> <el-table-column label="操作" width="180" align="center" sortable> <!-- 点击删除的确认按钮,需要传递 id 作为参数进行删除操作,所以需要使用作用域插槽获取id --> <template v-slot="{ row }"> <el-button type="primary" size="mini" @click="edit(row.id)" >编辑</el-button > <!-- 点击删除的确认按钮需要传递 id 作为参数,进行删除操作,所以需要使用 --> <el-popconfirm title="确定删除这一条数据吗" @confirm="delPost(row.id)" > <template #reference> <el-button type="danger" size="mini">删除</el-button> </template> </el-popconfirm> </template> </el-table-column> </el-table> <!-- <el-pagination :current-page="currentPage" :page-size="10" background layout="prev, pager, next" :total="tableData.length" @current-change="pageChange" ></el-pagination>--> <el-pagination :current-page.sync="currentPage" :page-size="10" background layout="prev, pager, next" :total="total" ></el-pagination> </div> <!-- <div v-else>我是 gif图,我在努力加载</div> --> </div> </template> <script> import axios from "axios"; export default { name: "TableDemo", data() { return { tableData: [], currentPage: 1, total: 100, showDialog: false, post: { title: "", important: null, body: "", userId: null }, // 是否处于编辑状态,点击编辑的时候修改 editPostId: null, searchTxt: "", oldSearchTxt: "", isSearching: false, loading: false, // filterImportant:2 }; }, /* created() { axios.get("http://localhost:3008/posts?_page=1&_limit=10").then((res) => { console.log(res.data); }); }, */ /* created() { // const res = await axios.get( // `http://localhost:3008/posts?_page=${this.currentPage}&_limit=10` // ); // // console.log(res.data); // this.tableData = res.data; this.getPosts(this.currentPage); }, */ watch: { currentPage: { /* handler(newVal) { // 当点击分页器的时候,搜索过了和没搜索传递的 参数是有区别的 console.log(newVal); const option = this.isSearching ? { page: newVal.page, title: newVal.title } : { page: newVal.page }; this.getPosts(option); }, immediate: true, deep:true */ handler(newVal) { // 当点击分页器的时候,搜索过了和没搜索传递的 参数是有区别的 // console.log(newVal); const option = this.isSearching ? { page: newVal, title: this.searchTxt } : { page: newVal }; this.getPosts(option); // 参数很多 /* let option = { page: newVal }; if (this.isSearching) { if (title) { option.title = this.searchTxt; } if (important) { option.important = this.filterImportant; } } */ }, immediate: true, }, }, computed: { /* showTableData() { return this.tableData.slice( (this.currentPage - 1) * 10, this.currentPage * 10 ); }, */ }, methods: { // 获取的内容(请求数据的方法) async getPosts(option) { this.loading = true; const { page = 1, title } = option; const baseUrl = `http://localhost:3008/posts?_page=${page}&_limit=10`; const queryUrl = title ? `&title_like=${title}` : ``; // 参数很多时 /* const importantUrl = filterImportant ? `&important=${this.filterImportant}` : ``; */ const res = await axios.get(baseUrl + queryUrl); setTimeout(() => { this.tableData = res.data; this.loading = false; }, 500); }, // 查找函数 search() { const { searchTxt, oldSearchTxt } = this; if (oldSearchTxt !== searchTxt) { // 搜索结果默认展示第一页,分页器展示也是第一页 this.currentPage = 1; this.oldSearchTxt = searchTxt; this.isSearching = true; this.getPosts({ title: searchTxt }); } else if (searchTxt === "") { // 空的时候点搜索重置 console.log("重置"); this.getPosts({ page: 1 }); this.isSearching = false; this.currentPage = 1; this.oldSearchTxt = ""; } }, /* pageChange(page) { this.currentPage = page; this.getPosts(page); }, */ async delPost(id) { // console.log(id); await axios.delete(`http://localhost:3008/posts/${id}`); // json-server 删除的返回值就是空对象 没啥用 // 删了网上的数据需要更新本地数据 this.tableData = this.tableData.filter((post) => post.id !== id); this.total--; // 全局的 notify 方法 this.$notify({ title: "成功", message: "删除成功", // icon type: "success", }); }, // 文章内容的自定义校验规则 validateContent(rule, value, callback) { if (value === "") { callback(new Error("请输入内容")); } else if (value.length < 10) { // 包含敏感词汇,长度不够等等 callback(new Error("字数不够")); } else if (value.includes("yyds")) { callback(new Error("包含敏感词汇")); } else { callback(); } }, openDialog() { this.showDialog = true; }, closeDialog() { this.showDialog = false; this.editPostId = null; this.post = { title: "", important: null, body: "", userId: null, }; }, // 对话框确定按钮的单击事件 dialogConfirmBtnClick() { // this.$refs.elFormComponent.validate 表单整体的校验事件 this.$refs.elFormComponent.validate((result) => { if (result) { const { editPostId } = this; editPostId ? this.editPost(editPostId) : this.addPost(); } }); }, async addPost() { const res = await axios.post( `http://localhost:3008/posts`, this.post ); // console.log(res.data); this.tableData.unshift(res.data); this.total++; this.closeDialog(); // 添加成功需要清空,防止再次添加出现默认值 this.post = { title: "", important: null, body: "", userId: null, }; this.$notify({ title: "成功", message: "添加成功", // icon type: "success", }); // console.log(this.post); /* this.$refs.elFormComponent.validate(async result => { if (result) { const res = await axios.post( `http://localhost:3008/posts`, this.post ); // console.log(res.data); this.tableData.unshift(res.data); this.total++; this.closeDialog(); // 添加成功需要清空,防止再次添加出现默认值 this.post = { title: "", important: null, body: "", userId: null }; this.$notify({ title: "成功", message: "添加成功", // icon type: "success" }); } }); */ }, // 通过 id 获取对应的文章信息 getPostById(id) { return this.tableData.find((post) => post.id === id); }, // 点击编辑弹窗事件 edit(id) { this.openDialog(); // 需要做拷贝,不拷贝的话删除id 就相当于删除了原始 data 数据内的 id const editPost = { ...this.getPostById(id) }; // 删除对象的id属性 delete editPost.id; this.post = editPost; // 1.点击弹窗确定的时候判断什么时候添加还是编辑 // 2.点击确定的时候,根据id发请求 this.editPostId = id; }, // 修改函数 async editPost(id) { // 将修改的数据传回服务器 // patch 局部更新 const res = await axios.patch( `http://localhost:3008/posts/${id}`, this.post ); // console.log(res.data); // 将 data 内的对应的 id 那条数据替换成请求的结果 const ind = this.tableData.findIndex((post) => post.id === id); this.tableData.splice(ind, 1, res.data); this.closeDialog(); // 添加成功需要清空,防止再次添加出现默认值 this.editPostId = null; this.post = { title: "", important: null, body: "", userId: null, }; this.$notify({ title: "成功", message: "编辑成功", type: "success", }); }, }, }; </script> <style> /* 有的ui库可能加上scoped之后,你直接使用 ui 库内的class修改样式的时候会不起作用 */ .table .el-rate { display: flex; height: 40px; align-items: center; } </style>
-
# InfiniteScroll.vue 文件
<template>
<!-- 滚动条到底了 load 函数触发,但是加载有延迟,延迟时间过长,触底的load函数又会触发,导致 load 函数触发多次 -->
<!-- 使用 infinite-scroll-disabled 禁用加载,当加载的时候直接禁用 -->
<ul
class="infinite-list"
:infinite-scroll-disabled="disabled"
v-infinite-scroll="load"
infinite-scroll-distance="5"
style="overflow:auto"
>
>
<!-- infinite-scroll-distance="5" 距离底部还是5px的时候就触发 -->
<li v-for="i in count" :key="i" class="infinite-list-item">{{ i }}</li>
<li v-if="loading">加载中……</li>
<li v-if="noMore">没有更多了</li>
</ul>
</template>
<script>
export default {
name: "InfiniteScroll",
data() {
return {
count: 10,
loading: false,
};
},
computed: {
noMore() {
return this.count >= 30;
},
disabled() {
return this.loading || this.onMore;
},
},
methods: {
// load 函数设置给了 v-infinite-scroll 指令,当滚动条触底的时候会触发该函数
// 当设定指令的元素设置了滚动条但滚动条还没出现的时候 load 会自动触发,直到滚动条出现并且不触底
load() {
console.log("加2");
this.loading = true;
setTimeout(() => {
this.loading = false;
this.count += 2;
}, 500);
},
},
};
</script>
<style>
.infinite-list {
list-style: none;
padding-left: 0;
width: 400px;
margin: 0 auto;
height: 500px;
}
.infinite-list-item {
height: 50px;
background-color: #e8f3fe;
margin: 10px;
color: #7dbcfc;
}
</style>
# Item.vue 文件
<template>
<div>
<!-- 我是列表项 -->
<slot :x="qianzhui" />
</div>
</template>
<script>
export default {
name: "Item",
data() {
return {
qianzhui: "哈哈哈",
};
},
};
</script>
# JsonServerDemo.vue 文件
<template>
<div>
<h2>JsonServerDemo</h2>
<el-button type="primary" @click="edit">编辑第一条评论</el-button>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "JsonServerDemo",
// put 替换 patch 局部更新(一般改一个的时候用这个)
methods: {
edit() {
axios
.patch("http://localhost:3008/comments/1", { text: "yyds" })
.then((res) => {
console.log(res, "编辑成功");
});
},
},
};
</script>
# data.json 文件 (一共一百条数据,这里省略了 95 条)
{
"comments": [
{
"id": 1,
"text": "yyds",
"author": "小张"
},
{
"id": 2,
"text": "888",
"author": "小赵"
}
],
"posts": [
{
"important": 2,
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
},
{
"important": 4,
"userId": 1,
"id": 3,
"title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
"body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
},
{
"important": 2,
"userId": 1,
"id": 4,
"title": "eum et est occaecati",
"body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit"
}
]
}
# 以上用到的 element.js 文件
import Vue from "vue";
import {
Button,
DatePicker,
Switch,
Message,
Menu,
Submenu,
MenuItem,
MenuItemGroup,
RadioGroup,
RadioButton,
Tree,
Input,
Table,
TableColumn,
Rate,
Pagination,
Popconfirm,
Popover,
Notification,
Dialog,
Form,
FormItem,
Select,
Option,
Loading,
InfiniteScroll,
} from "element-ui";
// 按需引入 element 的国际化设置 默认是中文
import lang from "element-ui/lib/locale/lang/en";
import locale from "element-ui/lib/locale";
locale.use(lang);
// 将 Button 组件注册成全局组件
Vue.use(Button);
Vue.use(DatePicker);
Vue.use(Switch);
Vue.use(Menu);
Vue.use(Submenu);
Vue.use(MenuItem);
Vue.use(MenuItemGroup);
Vue.use(RadioGroup);
Vue.use(RadioButton);
Vue.use(Tree);
Vue.use(Input);
Vue.use(Table);
Vue.use(TableColumn);
Vue.use(Rate);
Vue.use(Pagination);
Vue.use(Popconfirm);
Vue.use(Popover);
Vue.use(Dialog);
Vue.use(Form);
Vue.use(FormItem);
Vue.use(Select);
Vue.use(Option);
// Loading 和 InfiniteScroll 是自定义指令, use 之后变成全局指令
Vue.use(Loading);
Vue.use(InfiniteScroll);
// 将 Message 制作成全局方法
// $message 可以随便命名
Vue.prototype.$message = Message;
Vue.prototype.$notify = Notification;
# 自定义主题
npm i element-themex element-theme-chalk -D
如果上边有错误就一个一个下载 ( npm i element-themex -D
npm i element-theme-chalk -D npm i node-sass@4.8.3 -D)
或者将 dijia vue-lesson 中的 vue-element-demo 中 node_modules 中的 node-sass 文件夹拷贝一下,
拷贝之后要在 package.json 中的 dependencies 中 将 “element-theme-chalk”: “^2.15.1”,“element-ui”: “^2.4.5”, 拷贝一下
然后回到根目录 (命令行输命令) node_modules/.bin/et -i 会发现有个 element-variables.css 文件,去里边修改对应样式
然后 node_modules/.bin/et (打勾就可以了,不用在意红色的),会有个新的 theme 文件夹
然后去 babel.config.js 中将 styleLibraryName 修改为 "theme"(代表根目录)
之后重新启动项目才会有效果