基于vue-router实现一个简单的后台框架

举报
花溪 发表于 2020/09/04 14:45:12 2020/09/04
【摘要】 基于vue-router实现一个简单的后台框架 vue-router的简单使用

 1.Vue.js是什么?

     1). 一位华裔前Google工程师(尤雨溪)开发的前端js库

     2). 作用: 动态构建用户界面

     3). 特点:

         * 遵循MVVM模式

         * 编码简洁, 体积小, 运行效率高, 移动/PC端开发

         * 它本身只关注UI, 可以轻松引入vue插件和其它第三库开发项目

     4). 与其它框架的关联:

         * 借鉴angular的模板和数据绑定技术

         * 借鉴react的组件化和虚拟DOM技术

     5). vue包含一系列的扩展插件(库):

         * vue-cli: vue脚手架

         * vue-resource(axios): ajax请求

         * vue-router: 路由

         * vuex: 状态管理

         * vue-lazyload: 图片懒加载

         * vue-scroller: 页面滑动相关

         * mint-ui: 基于vue的组件库(移动端)

         * element-ui: 基于vue的组件库(PC端)

2. 基本使用

1). 引入vue.js

2). 创建Vue实例对象(vm), 指定选项(配置)对象

     el : 指定dom标签容器的选择器

     data : 指定初始化状态数据的对象/函数(返回一个对象)

3). 在页面模板中使用{{}}或vue指令

3. Vue对象的选项

     1). el

          指定dom标签容器的选择器

         Vue就会管理对应的标签及其子标签

     2). data

         对象或函数类型

         指定初始化状态属性数据的对象

         vm也会自动拥有data中所有属性

         页面中可以直接访问使用

         数据代理: 由vm对象来代理对data中所有属性的操作(读/写)

    3). methods

         包含多个方法的对象

         供页面中的事件指令来绑定回调

         回调函数默认有event参数, 但也可以指定自己的参数

         所有的方法由vue对象来调用, 访问data中的属性直接使用this.xxx

     4). computed

         包含多个方法的对象

         对状态属性进行计算返回一个新的数据, 供页面获取显示

         一般情况下是相当于是一个只读的属性

         利用set/get方法来实现属性数据的计算读取, 同时监视属性数据的变化

         如何给对象定义get/set属性

         在创建对象时指定: get name () {return xxx} / set name (value) {}

         对象创建之后指定: Object.defineProperty(obj, age, {get(){}, set(value){}})

     5). watch

         包含多个属性监视的对象

         分为一般监视和深度监视

             xxx: function(value){}

         xxx : {

             deep : true,

             handler : fun(value)

         }

         另一种添加监视方式: vm.$watch('xxx', function(value){})

4. 过渡动画

     利用vue去操控css的transition/animation动画

     模板: 使用<transition name='xxx'>包含带动画的标签

     css样式

     .fade-enter-active: 进入过程, 指定进入的transition

     .fade-leave-active: 离开过程, 指定离开的transition

     .xxx-enter, .xxx-leave-to: 指定隐藏的样式

     编码例子

         .xxx-enter-active, .xxx-leave-active {

               transition: opacity .5s

         }

         .xxx-enter, .xxx-leave-to {

               opacity: 0

         }

         

         <transition name="xxx">

               <p v-if="show">hello</p>

         </transition>

    

5. 生命周期

     vm/组件对象

     生命周期图

     主要的生命周期函数(钩子)

         created() / mounted(): 启动异步任务(启动定时器,发送ajax请求, 绑定监听)

         beforeDestroy(): 做一些收尾的工作

 6. 自定义过滤器

    1). 理解

         对需要显示的数据进行格式化后再显示

    2). 编码

         1). 定义过滤器

         Vue.filter(filterName, function(value[,arg1,arg2,...]){

               // 进行一定的数据处理

               return newValue

         })

     2). 使用过滤器

         <div>{{myData | filterName}}</div>

         <div>{{myData | filterName(arg)}}</div>

7. vue内置指令

     v-text/v-html: 指定标签体

              * v-text : 当作纯文本

             * v-html : 将value作为html标签来解析

     v-if v-else v-show: 显示/隐藏元素

             * v-if : 如果vlaue为true, 当前标签会输出在页面中

             * v-else : 与v-if一起使用, 如果value为false, 将当前标签输出到页面中

             * v-show: 就会在标签中添加display样式, 如果vlaue为true, display=block, 否则是none

     v-for : 遍历

             * 遍历数组 : v-for="(person, index) in persons"   

             * 遍历对象 : v-for="value in person"   $key

     v-on : 绑定事件监听

             * v-on:事件名, 可以缩写为: @事件名

             * 监视具体的按键: @keyup.keyCode   @keyup.enter

             * 停止事件的冒泡和阻止事件默认行为: @click.stop   @click.prevent

             * 隐含对象: $event

     v-bind : 强制绑定解析表达式  

         * html标签属性是不支持表达式的, 就可以使用v-bind

         * 可以缩写为:  :id='name'

             * :class

               * :class="a"

             * :class="{classA : isA, classB : isB}"

             * :class="[classA, classB]"

             * :style

             :style="{color : color}"

     v-model

             * 双向数据绑定

             * 自动收集用户输入数据

     ref : 标识某个标签

             * ref='xxx'

             * 读取得到标签对象: this.$refs.xxx

8. 自定义指令

        1). 注册全局指令

            Vue.directive('my-directive', function(el, binding){

              el.innerHTML = binding.value.toUpperCase()

            })

        

         2). 注册局部指令

            directives : {

              'my-directive' : function(el, binding) {

                  el.innerHTML = binding.value.toUpperCase()

              }

            }

        

        3). 使用指令

            <div v-my-directive='xxx'>

9.vue-router

    编写路由的3步

        1. 定义路由组件    

        2. 映射路由

        3. 编写路由2个标签

    使用vue-router

        1. 创建路由器: router/index.js

              new VueRouter({

                routes: [

                  { // 一般路由

                    path: '/about',

                    component: about

                  },

                  { // 自动跳转路由

                    path: '/', 

                    redirect: '/about'

                  }

                ]

              })

        2. 注册路由器: main.js

               import router from './router'

                new Vue({

                    router

                })

        3. 使用路由组件标签:

                <router-link to="/xxx">Go to XXX</router-link>

                <router-view></router-view>

    嵌套路由

            children: [

                {

                  path: '/home/news',

                  component: news

                },

                {

                  path: 'message',

                  component: message

                }

             ]

    向路由组件传递数据

            params: <router-link to="/home/news/abc/123">

            props: <router-view msg='abc'>

    缓存路由组件

            <keep-alive>

                  <router-view></router-view>

            </keep-alive>

    路由的编程式导航

     this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)

     this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)

     this.$router.back(): 请求(返回)上一个记录路由

先看效果图

image.png

image.pngimage.png


实现方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>基于vue-router的案例</title>
        <style type="text/css">
            html,
            body,
            #app {
                margin: 0;
                padding: 0px;
                height: 100%;
            }
            
            .header {
                height: 50px;
                background-color: #545c64;
                line-height: 50px;
                text-align: center;
                font-size: 24px;
                color: #fff;
            }
            
            .footer {
                height: 40px;
                line-height: 40px;
                background-color: #888;
                position: absolute;
                bottom: 0;
                width: 100%;
                text-align: center;
                color: #fff;
            }
            
            .main {
                display: flex;
                position: absolute;
                top: 50px;
                bottom: 40px;
                width: 100%;
            }
            
            .content {
                flex: 1;
                text-align: center;
                height: 100%;
            }
            
            .left {
                flex: 0 0 20%;
                background-color: #545c64;
            }
            
            .left a {
                color: white;
                text-decoration: none;
            }
            
            .right {
                margin: 5px;
            }
            
            .btns {
                width: 100%;
                height: 35px;
                line-height: 35px;
                background-color: #f5f5f5;
                text-align: left;
                padding-left: 10px;
                box-sizing: border-box;
            }
            
            button {
                height: 30px;
                background-color: #ecf5ff;
                border: 1px solid lightskyblue;
                font-size: 12px;
                padding: 0 20px;
            }
            
            .main-content {
                margin-top: 10px;
            }
            
            ul {
                margin: 0;
                padding: 0;
                list-style: none;
            }
            
            ul li {
                height: 45px;
                line-height: 45px;
                background-color: #a0a0a0;
                color: #fff;
                cursor: pointer;
                border-bottom: 1px solid #fff;
            }
            
            table {
                width: 100%;
                border-collapse: collapse;
            }
            
            td,
            th {
                border: 1px solid #eee;
                line-height: 35px;
                font-size: 12px;
            }
            
            th {
                background-color: #ddd;
            }
        </style>                                                                                                                                                                    
        <script src="./lib/vue_2.5.22.js"></script>
        <script src="./lib/vue-router_3.0.2.js"></script>
    </head>
    <body>
        <!-- 要被 vue 实例所控制的区域 -->
        <div id="app">
        <!-- 路由占位符 -->
        <    router-view></router-view>
        </div>
    
        <script>
        // 定义 APP 根组件
        const App = {
            template: `<div>
                      <!-- 头部区域 -->
                      <header>后台管理系统</header>
                      <!-- 中间主体区域 -->
                      <div>
                        <!-- 左侧菜单栏 -->
                        <div class="content left">
                          <ul>
                            <router-link to="/users"> <li>用户管理</li></router-link>
                            <router-link to="/rights"><li>权限管理</li></router-link>
                            <router-link to="/goods"><li>商品管理</li></router-link>
                            <router-link to="/orders"><li>订单管理</li></router-link>
                            <router-link to="/settings"><li>系统设置</li></router-link>
                          </ul>
                        </div>
                        <!-- 右侧内容区域 -->
                        <div class="content right"><div>
                          <router-view />
                        </div></div>
                      </div>
                      <!-- 尾部区域 -->
                      <footer>版权信息</footer>
                    </div>`
            }
        
        const Users = {
            data() {
                return {
                    userlist: [{
                        id: 1,
                        name: '张三',
                        age: 10
                    },
                    {
                        id: 2,
                        name: '李四',
                        age: 20
                    },
                    {
                        id: 3,
                        name: '王五',
                        age: 30
                    },
                    {
                        id: 4,
                        name: '赵六',
                        age: 40
                    }
                ]
            }
        },
        methods: {
            goDetail(id) {
                console.log(id)
                this.$router.push('/userinfo/' + id)
            }
        },
        template: `<div>
                <h3>用户管理区域</h3>
                <table>
                  <thead>
                    <tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
                  </thead>
                  <tbody>
                    <tr v-for="item in userlist" :key="item.id">
                      <td>{{item.id}}</td>
                      <td>{{item.name}}</td>
                      <td>{{item.age}}</td>
                      <td>
                        <a href="javascript:;" @click="goDetail(item.id)">详情</a>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>`
        }
        
        const UserInfo = {
            props: ['id'],
            template: `<div>
                      <h5>用户详情页 --- 用户Id为:{{id}}</h5>
                      <button @click="goback()">后退</button>
                    </div>`,
            methods: {
                goback() {
                    // 实现后退功能
                    this.$router.go(-1)
                }
            }
        }
        
        const Rights = {
        template: `<div>
                <h3>权限管理区域</h3>
              </div>`
        }
        const Goods = {
        template: `<div>
                <h3>商品管理区域</h3>
              </div>`
        }
        const Orders = {
        template: `<div>
                <h3>订单管理区域</h3>
              </div>`
        }
        const Settings = {
        template: `<div>
                <h3>系统设置区域</h3>
              </div>`
        }
        
        // 创建路由对象
        const router = new VueRouter({
            routes: [{
                path: '/',
                component: App,
                redirect: '/users',
                children: [{
                        path: '/users',
                        component: Users
                    },
                    {
                        path: '/userinfo/:id',
                        component: UserInfo,
                        props: true
                    },
                    {
                        path: '/rights',
                        component: Rights
                    },
                    {
                        path: '/goods',
                        component: Goods
                    },
                    {
                        path: '/orders',
                        component: Orders
                    },
                    {
                        path: '/settings',
                        component: Settings
                    }
                ]
            }]
        })
        
        const vm = new Vue({
            el: '#app',
            router
        })                                    
        </script>
    </body>
</html>


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。