1、Vue +Elment-UI后台管理系统

  • https://blog.csdn.net/qq_44651350/article/details/119388434?spm=1001.2014.3001.5501
  • https://blog.csdn.net/qq_43353619/article/details/110246669

官方链接

  • https://www.bilibili.com/video/BV1Si4y1M7iQ?p=21
  • Vue VSCode Snippets

2、总体知识点

  • element组件库常用部分
  • 封装组件的思路
  • EChart运用
  • 权限管理之动态生成菜单

3、初始化

1、安装cli3

npm install -g @vue/cli

2、创建项目

vue create project or vue ui

vue init webpack project

3、cli服务

cli3的启动方式是vue-cli-service serve

4、基础知识点

  • 父子组件传值
  • 非父子组件传值
  • Vue-router
  • Vuex

4.1、父子组件传值

  • props / $emit
  • $parent / children
  • $ref

1.1、父组件向子组件传值、通过绑定属性传递

  • 这是父组件里面调用子组件
  • Parent.vue
  • msg的值是字符串
  • :msg就是一个变量
<m-child msg="from Parent msg"></m-child>
  • 这是子组件里面的内容,负责接收父组件传递过来的值
  • Child.vue
<h5>{{msg}}</h5>

<script>
    export default{
        props: {
            msg: {
                type: String,
                default: ''
            },
        },
    }
</script>

4.1.2、子组件向父组件传值、通过事件触发

  • Child.vue、在子组件里面写$emit
<button @click='passMsg'>向父组件传值</button>

<script>
    export default{
        methods: {
            passMsg() {
                this.$emit('showMsg','I am Child')
            }
        },
    }
</script>
  • Parent.vue、接收从子组件传递过来的
<h3>{{msg}}</h3>
<m-child msg="from Parent msg" @showMsg='showMsg'></m-child>

<script>
    import MChild from './Child'
    export default{
        data() {
            return {
                msg:''
            }
        },
        components: {
            MChild,
        },
        methods: {
            showMsg(val) {
                this.msg=val
            }
        },
    }
</script>

4.1.3、$parent / children

  • Parent.vue
console.log(this.$children[0].childMsg);

4.1.4、$ref

  • Parent.vue
<m-child ref='refChild'></m-child>

<script>
    import MChild from './Child'
    export default{
        components: {
            MChild,
        },
        mounted () {
            console.log(this.$refs.refChild);
        },
    }
</script>

4.2、非父子间传值

4.2.1、事件总线

// 原理上就是建立一个公共的js文件,专门用来传递消息
// util/bus.js
import Vue from 'vue'
export default new Vue

// 在需要传递信息的地方引入,比如 App.vue
import bus from './util/bus'
<button @click='passMsg'>传你</button>
passMsg() {
  // 传递消息
  bus.$emit('msg','I am app')
}
// 接收消息 Child.vue
import bus from '../util/bus'
mounted() {
  // 监听msg
  bus.$on('msg', (val) => {
    this.childMsg = val
  })
}

4.2.2、$attrs / $listeners

// 解决多级组件间传值的问题

// $attr 将父组件中不包含props的属性传入子组件,通常配合interitAttrs选项一起使用
// $listeners监听子组件中数据变化,传递给父组件

4.2.3、vuex

4.3、Vue-router

4.3.1、路由的基本配置

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [{
    path: '/home',
    component: () => import('../views/Home.vue')
}]

const router = new VueRouter({
    routes
})

export default router
<router-view></router-view>

4.3.2、路由的跳转

4.3.3、router-link

<router-link to='/home'>home</router-link>
<router-view></router-view>

4.3.4、编程式导航

<button @click='tohome'>home</button>
<router-view></router-view>

methods: {
  tohome(){
    this.$router.push({
      path:'/home'
    })
  }
}

4.3.5、动态路由

rouer.js
const routes = [{
    path: '/home/:id',
    component: () => import('../views/Home.vue')
}]
Home.vue
<h1>{{$route.params.id}}</h1>

4.3.6、嵌套路由

const routes = [{
    path: '/home/:id',
    component: () => import('../views/Home.vue'),
    children:[{
        path: '/child',
        component: () => import('../views/Child.vue'),
    }]
}]

4.3.7、导航守卫

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

router.beforeEach((to,from,next)=>{
    console.log(to.path);
    next()
})


new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

4.3.8、路由懒加载

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [{
    path: '/home/:id',
    name:'home',
    // 路由懒加载   
    component: () => import('../views/Home.vue'),
    children:[{
        path: '/child',
        component: () => import('../views/Child.vue'),
    }]
}] 

const router = new VueRouter({
    routes
})

export default router

4.4、Vuex

状态管理中心

采用集中式存储管理应用的所有组件的状态

image-20211022214239563

4.4.1、State 数据

4.4.2、Mutations 数据怎么改变 同步操作

4.4.3、Actions 异步操作改变

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        count: 0
    },
    getters: {
        doubleCount(state) {
            return state.count * 2
        }
    },
    mutations: {
        add(state) {
            state.count++
        },
        decrease() {
            state.count--
        }
    },
    actions: {
        delayAdd(context) {
            setTimeout(() => {
                context.commit('add')
            }, 1000)
        }
    },
    modules: {}
})

页面使用

<h5>vuex {{count}}</h5>
<button @click='add'>+</button>
<h5>getters {{doubleCount}}</h5>

/*
computed: {
  count() {
    return this.$store.state.count 
  }
}
*/

computed: {
  ...mapState({
    count: 'count'
  })
},
methods: {
  add(){
    // this.$store.commit('add')
    this.$store.dispatch('delayAdd')
  }
}

4.4.4、计算属性-Getters

computed: {
  ...mapState({
    // 'count'
    count: state=>state.text.count
  }),
  ...mapGetters([
    'doubleCount'
  ])
  // doubleCount(){
  //     return this.$store.getters.doubleCount
  // }
}

4.4.5、模块化概念-Modules

text.js

export default {
    state: {
        count: 0
    },
    getters: {
        doubleCount(state) {
            return state.count * 2
        }
    },
    mutations: {
        add(state) {
            state.count++
        },
        decrease() {
            state.count--
        }
    },
    actions: {
        delayAdd(context) {
            setTimeout(() => {
                context.commit('add')
            }, 1000)
        }
    },
}

store index.js

import Vue from 'vue'
import Vuex from 'vuex'
import text from './text'

Vue.use(Vuex)

export default new Vuex.Store({
    modules: {
        text
    }
})

5、ElementUI

  • yarn add element-ui -S

  • https://element.eleme.cn/#/zh-CN/component/quickstart

  • import ElementUI from ‘element-ui’;

  • import ‘element-ui/lib/theme-chalk/index.css’;

  • Vue.use(ElementUI);

5.1、布局组件

5.1.1、布局组件

  • el-row、el-col 24分栏
  • el-container、el-header、el-aside、el-main、el-footer

5.1.2、常用属性

  • span
  • gutter

5.1.3、如何构建5等分布局

5.2、弹出类型组件

5.2.1、常用弹出组件

  • el-dialog
  • el-popover

5.2.2、sync修饰符的作用

  • 示例:ElemenyUI中的el-dialog
// 第一种写法
<el-dialog :visible.sync="dialogVisible">
 
// 第二种写法
<el-dialog :visible="dialogVisible" :before-close="beforeClose">
  
// 第一种写法关闭或是点击空白处无需特别处理,el-dialog组件内部会修改当前值状态,通过.sync修饰符传递给父组件
  
// 第二种写法,需要再beforeClose方法内手动处理this.dialogVisible = false

5.2.3、diglog组件中的插槽

5.3、表格组件

5.3.1、基础表格

5.3.2、表格常用属性介绍

image-20211023104653014

5.3.3、列常用属性介绍

image-20211023104713218

5.3.4、通过v-for封装实用性更好的表格

<template>
    <div>
        <!-- 基本表格 -->
        <!-- <el-table :data="tableData" border style="width: 100%" height="200px">
            <el-table-column prop="date" label="日期" width="180">
            </el-table-column>
            <el-table-column prop="name" label="姓名" width="180">
            </el-table-column>
            <el-table-column prop="address" label="地址" show-overflow-tooltip>
            </el-table-column>
            <el-table-column label="操作">
                <template slot-scope="scope">
                    <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
                    <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table> -->
        <!--  -->
        <el-table :data="tableData"  width='100%'>
            <el-table-column v-for="(val,key) in tableLable" :key="key" :prop="key" :lable="val">
            </el-table-column>
            <el-table-column label="操作" v-if="isShowOperate">
                <template slot-scope="scope">
                    <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
                    <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script>
    export default {
        props: {
            isShowOperate: {
                type: Boolean,
                default: true
            },
        },
        data() {
            return {
                tableData: [{
                    date: '2016-05-02',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1518 弄'
                }, {
                    date: '2016-05-04',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1517 弄'
                }, {
                    date: '2016-05-01',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1519 弄'
                }, {
                    date: '2016-05-03',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路 1516 弄'
                }],
                tableLable:{
                    date:'日期',
                    name:'姓名',
                    address:'地址'
                }
            }
        },
        methods: {
            handleEdit(index, row) {
                console.log(index, row);
                this.$emit('edit',row);
            },
            handleDelete(index, row) {
                console.log(index, row);
            }
        }
    }
</script>

5.4、表单组件

5.4.1、基础表单

在Form组件中,每一个表单域由一个Form-Item组件构成,Form-Item可以是下拉框、输入框、日期选择器等各种表单组件

5.4.2、添加表单验证

5.4.3、封装表单组件

<template>
    <div>
        <!-- <el-form ref="form" :model="form" label-width="80px">
            <el-form-item label="活动名称">
                <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="活动区域">
                <el-select v-model="form.region" placeholder="请选择活动区域">
                    <el-option label="区域一" value="shanghai"></el-option>
                    <el-option label="区域二" value="beijing"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="活动时间">
                <el-col :span="11">
                    <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;">
                    </el-date-picker>
                </el-col>
                <el-col class="line" :span="2">-</el-col>
                <el-col :span="11">
                    <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
                </el-col>
            </el-form-item>
            <el-form-item label="即时配送">
                <el-switch v-model="form.delivery"></el-switch>
            </el-form-item>
            <el-form-item label="活动性质">
                <el-checkbox-group v-model="form.type">
                    <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
                    <el-checkbox label="地推活动" name="type"></el-checkbox>
                    <el-checkbox label="线下主题活动" name="type"></el-checkbox>
                    <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
                </el-checkbox-group>
            </el-form-item>
            <el-form-item label="特殊资源">
                <el-radio-group v-model="form.resource">
                    <el-radio label="线上品牌商赞助"></el-radio>
                    <el-radio label="线下场地免费"></el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="活动形式">
                <el-input type="textarea" v-model="form.desc"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="onSubmit">立即创建</el-button>
                <el-button>取消</el-button>
            </el-form-item>
        </el-form> -->
        <el-form ref="form" :model="form" label-width="80px">
            <el-form-item :label="item.lable" v-for="(item,index) in formLable" :key="index">
                <el-input v-model="form[item.key]" v-if="item.type === 'input'"></el-input>
                <el-select v-model="form[item.key]" placeholder="请选择活动区域" v-if="item.type === 'select'">
                    <el-option :label="subitem.lable"
                        v-for="(subitem,index) in item.options" 
                        :key="index" 
                        :lable="subitem.lable"
                        :value="subitem.value"
                        ></el-option>
                </el-select>
                <el-date-picker 
                v-if="item.type === 'date-picker'"
                type="date" 
                placeholder="选择日期" 
                v-model="form[item.key]" 
                style="width: 100%;">
                </el-date-picker>
            </el-form-item>
        </el-form>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                form: {
                    name: '',
                    region: '',
                    date1: '',
                    date2: '',
                    delivery: false,
                    type: [],
                    resource: '',
                    desc: ''
                },
                formLable: [
                    {
                        lable: '活动名称',
                        key: 'name',
                        type: 'input'
                    },
                    {
                        lable: '活动区域',
                        key: 'region',
                        type: 'select',
                        options: [
                            {
                                lable: '区域1',
                                value: 'shanghai'

                            }, {
                                lable: '区域2',
                                value: 'beijing'

                            }
                        ]
                    },
                    {
                        lable: '活动时间',
                        key: 'date1',
                        type: 'date-picker'
                    },
                ]
            }
        },
        methods: {
            onSubmit() {
                console.log('submit!');
            }
        }
    }
</script>

<style scoped>

</style>
Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐