12-vuePC端项目(mvvm,vuex,登录者身份不同展示菜单不同,利用路由元信息和导航守卫来动态更改标题,项目打包之前elemnet按需加载,路由懒加载,更改路径./,http-sever运行)

01-关于mvvm与mvc:

具体可以参考这个链接,直通车: link.

  • mvvm(比较适用于前端)
    m:model数据模型
    v:view 视图
    vm:view-model视图模型
  • mvc(更加的适用于后台)
    m:model数据模型
    v:view 视图
    c:controller控制器
    在这里插入图片描述

02-vuex仓库存储

  • 内存存储的数据仓库

    • 内存存储, 刷新之后就没有了
    • 数据仓库,可以存值,也可以取值
  • 步骤

    • 1、在我们当前项目中集成好vuex,它集成的过程其实跟路由很相似
      安装包 npm i vuex
      在 src/store/index.js 写好相应的代码,并且导出去
      在 main.js 中导入仓库,并且注入到根实例中
    • 2、如果我们要更改(存储)仓库中的值,需要在仓库中写上mutation的代码
    
    	 mutations: {
        /**
         * state 就代表上面 state对象
         * userInfo 代表要传递过来的用户信息 
         */
        setInfo(state, userInfo) {
            state.userInfo = userInfo
        }
    }
    
    • 3、如果要在组件中,调用上一步写好的mutations中setUserInfo 这个方法
             //这个是用户在layout页面发送请求得到的用户信息 存到仓库去 方便其他页面使用
    		// 触发 mutations 中的方法
        this.$store.commit('setInfo',res.data.data)
    
    • 4、我们想在 welcome 组件中获取仓库中的值,我们首先需要在仓库中写好 getters 代码
      // 所有获取仓库中值的代码,写在getters 中
    getters: {
        getInfo(state) {
            return state.userInfo
        }
    },
    
    • 5、我们要在 welcome 组件中,调用仓库中 getters的方法,获取用户信息
       	{{$store.getters.getInfo.username}} 欢迎您,您的角色是 {{$store.getters.getInfo.role}}
    
  • 注意
    我们在store的state中,在定义 userInfo 要把它设置为一个空对象或者空字符串,否则,第一次使用的时候因为是null,你再调用它里面的属性就会报错
    store文件夹下的index.js文件:在这里插入图片描述
    main.js文件中:
    在这里插入图片描述

vuex中action的使用:
在这里插入图片描述vuex中module的使用: 点击按钮可以把input输入框中的内容valueName显示在页面上{{name}}
在这里插入图片描述

细说:
1 . vuex
什么是vuex
vue的集中状态管理工具
使用:
步骤:
a. 安装
npm install vuex --save
b. 引用
import Vuex from ‘vuex’
Vue.use(Vuex)

2.1 state
  管理状态(数据)
	使用方式:
		1)this.$store.state.num  
			不用:太麻烦
		2)computed: {
				count() {
					return this.$store.state.num  
				}
			}
		3)mapState
			computed:mapState([
				'num'
			])
			缺点:无法改变变量的名称
		4)mapState
			computed:mapState({
				count: 'num'
			})
			缺点:无法添加新的computed属性
		5)mapState
			computed:{
				...mapState({
					count: 'num'
				})
			}
			缺点:无法添加新的computed属性
			将仓库中的状态映射到组件中
2.2 getters
  计算属性
	使用方式::
		1)this.$store.getters.newnum
		2)mapGetters来映射
			computed: {
				...mapGetters({
					newnum: 'newnum'
				})
			}
    mapGetters:
      将仓库中的计算属性映射到组件中
2.3 mutations
  修改状态
	使用方式:
		1)this.$store.commit('方法名',{})
		2)this.$store.commit({
			type: '方法名',
			name: ''...
			})
		3) mapMutations:
			methods: mapMutations([
				'chageNum'
			])
		4)
			methods: mapMutations({
				changnum: 'chageNum'
			})
		5) 
			methods: {
				mapMutations({
					changnum: 'chageNum'
				})
			}
		
		
2.4 actions
  异步得到参数,并且将结果返回给mutation
	使用方式:
		1)this.$store.dispatch('方法名')
		2)this.$store.dispatch({
			type: '方法名'
		})
		3) mapActions:
			methods: mapActions([
				'chageNum'
			])
		4)
			methods: mapActions({
				changnum: 'chageNum'
			})
		5) 
			methods: {
				mapActions({
					changnum: 'chageNum'
				})
			}
      将仓库中的异步操作的方法映射到组件中

2.5 moudles:
	步骤:	
		1)定义仓库模块:
			let a = {
				namespaced: true
				state: {....},
				getters: {....},
				mutations: {....},
				actions: {....},
			}
		2)仓库模块管理到仓库中
			var store = new Vuex.Store({
				modules: {
					a:a
				}
			})
		3)使用:在其它组件中:
			import {mpa...} from "vuex"
			export default {
				computed: {
					...mapState('a', {
						name: 'name'
					})
				},
				methods: {
					...mapMutations('a', {
						fn: 'fn'
					}),
					...mapActions('a', {
						fnn: 'fnn'
					})
				}
			}

03-权限控制

  • 后台
    1、前端可以展示哪些菜单,应该登陆之后,后台根据你究竟是哪个角色,给你返回该角色对应的菜单数据
  • 前端
    1、真实开发中,我们应该是登录之后,根据登录的用户是那个角色,后台把与该角色对应的权限列表返回,返回之后,我们就for循环来展示出来
    2、如果后台没有返回权限列表,那么我们只能在前端做一些力所能及的控制
       a、不能在 layout.vue 中写死我们的那些菜单了,因为写死之后无论谁登陆进来,都能看到那些菜单,所有不行
       b、我们利用路由配置时候,给我们每个路由通过配置元数据的方式,来简单控制下我们权限
const router = new VueRouter({
    routes: [{
            path: '/login',
            component: Login,
            meta: {
                title: '登录'
            }

        },
        {
            path: '/layout',
            component: Layout,
            meta: {
                roles: ['超级管理员', '管理员', '老师', '学生']
            },
            children: [{
                    path: 'welcome',
                    component: Welcome,
                    //借助路由元信息,对这条路径做个具体的描述
                    meta: {
                        roles: ['超级管理员', '管理员', '老师', '学生'],
                        icon: 'el-icon-date',
                        fullPath: '/layout/welcome',
                        title: '个人信息'
                    },
                },
                {
                    path: 'chart',
                    component: Chart,
                    meta: {
                        roles: ['超级管理员', '管理员', '老师'],
                        icon: 'el-icon-pie-chart',
                        fullPath: '/layout/chart',
                        title: '数据预览'
                    },
                },
                {
                    path: 'user',
                    component: User,
                    meta: {
                        roles: ['超级管理员', '管理员', '老师'],
                        icon: 'el-icon-user',
                        fullPath: '/layout/user',
                        title: '用户列表'
                    },
                },
                {
                    path: 'enterprise',
                    component: Enterprise,
                    meta: {
                        roles: ['超级管理员', '管理员', '老师'],
                        icon: 'el-icon-office-building',
                        fullPath: '/layout/enterprise',
                        title: '企业列表'
                    },
                },
                {
                    path: 'question',
                    component: Question,
                    meta: {
                        roles: ['超级管理员', '管理员', '老师', '学生'],
                        icon: 'el-icon-edit-outline',
                        fullPath: '/layout/question',
                        title: '题库列表'
                    },
                },
                {
                    path: 'subject',
                    component: Subject,
                    meta: {
                        roles: ['超级管理员', '管理员', '老师'],
                        icon: 'el-icon-notebook-2',
                        fullPath: '/layout/subject',
                        title: '学科列表'

                    },
                },
            ]
        },
        {
            path: '/',
            redirect: '/login'
        }
    ]
});

配置之后呢,我们就要在layout页面上显示我们不同的菜单啦(根据用户身份展示不同菜单)
在这里插入图片描述

04-利用路由元信息和导航守卫来动态更改标题

  • 全局前置守卫,进入页面之前
    router.beforeEach,可以做导航守卫
  • 全局后置钩子,进入到了页面之后
    router.afterEach,可以做一些事情比如把标题动态更改
    这样写:document.title = to.meta.title || ‘黑马面面’
    这里的to就是你进入到的那个页面的路由,根据上面配置的路由元信息可以拿到每个路由给设置的title,如果进入的没有设置元信息没有title的就把标题设置为‘黑马面面’
    在这里插入图片描述在这里插入图片描述

05-项目打包之前要做的内容

  • 把element-ui进行按需加载:项目中用了哪些组件,我们就加载哪些组件,参考element快速上手: link.
    • 步骤
      1、安装包: npm install babel-plugin-component -D
      2、更改babel的配置,更改 babel.config.js
module.exports = {
  presets: ["@vue/cli-plugin-babel/preset"],
  plugins: [
    [
      "component",
      {
        libraryName: "element-ui",
        styleLibraryName: "theme-chalk",
      },
    ],
  ],
};

              3、在 src/plugins/element.js 中按需导入以及注册我们项目需要的组件

import Vue from 'vue'
//全部导入注册
// import ElementUI from 'element-ui';
// import 'element-ui/lib/theme-chalk/index.css';

// Vue.use(ElementUI);

//把element全局注册弄成局部注册,需要哪个组件就导入哪个组件,免得体积太大:
// 1.安装 npm install babel-plugin-component -D 
// 2. 在babel.config.js文件下面复制element官网下要复制的代码
// 3.把全部导入注册变成按需导入然后按需注册

// 按需导入
import {
    Form,
    FormItem,
    Input,
    Button,
    Icon,
    Row,
    Col,
    Checkbox,
    Link,
    Message,
    Dialog,
    Upload,
    Header,
    Main,
    Aside,
    Container,
    Menu,
    MenuItem,
    Card,
    Select,
    Option,
    MessageBox,
    Table,
    TableColumn,
    Pagination,
    DatePicker,
    Cascader,
    Radio,
    RadioGroup
  } from 'element-ui'
  
  Vue.use(Form)
  Vue.use(FormItem)
  Vue.use(Input)
  Vue.use(Button)
  Vue.use(Icon)
  Vue.use(Row)
  Vue.use(Col)
  Vue.use(Checkbox)
  Vue.use(Link)
  Vue.use(Dialog)
  Vue.use(Upload)
  Vue.use(Header)
  Vue.use(Main)
  Vue.use(Aside)
  Vue.use(Container)
  Vue.use(Menu)
  Vue.use(MenuItem)
  Vue.use(Card)
  Vue.use(Select)
  Vue.use(Option)
  Vue.use(Table)
  Vue.use(TableColumn)
  Vue.use(Pagination)
  Vue.use(DatePicker)
  Vue.use(Cascader)
  Vue.use(Radio)
  Vue.use(RadioGroup)
  
  Vue.prototype.$message = Message
  Vue.prototype.$confirm = MessageBox.confirm
  • 路由懒加载
    提交首页的加载效率,可以在浏览器network看 这样只会加载对应路由要用的组件,不会全部加载出来
    改一下我们之前导入组件的方式,更改 src/router/index.js
    import Login from “@/views/login”;
    const Login = () => import(’@/views/login’)
    在这里插入图片描述
  • 更改一下项目根目录下 vue.config.js 中的publicPath: ‘./’
// vue.config.js
module.exports = {
    // 选项...
  lintOnSave: false,//vue-cli底层是基于node ,所以用nodejs的导出,关闭eslint
  publicPath:'./'//更改访问打包资源的路径
};
  • 打包操作 :npm run build

06-打包之后运行

因为我们的项目,必须运行在 8080 端口,我们直接右键用vs自带的live server端口是5050,是会有跨域的 ,所以我们可以借助于一个全局包 http-server
使用步骤
1、安装这个全局包: npm i http-server -g
2、切换到项目根目录,在终端中,使用http-server 运行我们的代码:http-server dist

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值