一、Vue 介绍
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:
var vm = new Vue({ // 选项 })
虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此经常会使用 vm
(ViewModel 的缩写) 这个变量名表示 Vue 实例。
当创建一个 Vue 实例时,可以传入一个选项对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门</title> </head> <body> <!--div就是Vue实例作用的范围--> <!--{{message}}就是View Model,其包含了Vue实例中的data选项内定义的message变量--> <div id="app">{{message}}</div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> let option = {//选项 el: '#app', //指定Vue实例作用的元素,也就是View的范围 data: {//数据模型,也就是Model //message变量的值一旦发生变化,就会更新与之相关的View Model,View Model一旦更新, //View呈现的内容也会随着更新 message: '这是一条信息' } } new Vue(option) </script> </html>
二、Vue 生命周期钩子函数
三、模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层组件实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应性系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
1. 文本插值
<!-- {{msg}} 表示引用变量msg的值作为span标签的文本内容,变量msg的值发生变化时文本内容会发生变化--> <span>{{ msg }}</span> <!-- v-text="msg" 表示引用变量msg的值作为span标签的文本内容,变量msg的值发生变化时文本内容会发生变化--> <span v-text="msg"></span> <!-- v-once 表示引用变量msg的值作为span标签的文本内容,变量msg的值发生变化时文本内容不会发生变化,只生效一次--> <span v-once>{{ msg }}</span> <script type="text/javascript"> new Vue({ el: '#app', data: { content: '这是一条消息' } }) </script>
2. HTML 插值
<!-- v-html="content"表示引用变量content的值作为div标签的html内容,变量content的值发生变化时,div显示的html内容也跟随着发生变化 --> <div v-html="content"></div> <script type="text/javascript"> new Vue({ el: '#app', data: { content: '这是文本内容' } }) </script>
3. 属性绑定
<!-- v-bind:id="id" 表示引用变量id的值作为div标签的id属性值--> <div v-bind:id="id"></div> <!-- :id="id" 是 v-bind:id="id" 的缩写--> <div :id="id"></div> <!-- :[attr]="attrValue" 表示动态属性绑定, 引用变量attr的值作为属性名,引用attrValue的值作为属性值--> <div :[attr]="attrValue"></div> <script type="text/javascript"> new Vue({ el: '#app', data: { id: 'first', attr: 'name', attrValue: 'firstDiv' } }) </script>
4. 事件绑定
<!-- v-on:click="clickFun" 表示点击a标签时执行clickFun函数--> <a v-on:click="clickFun">点击</a> <!-- @click="clickFun" 是 v-on:click="clickFun" 的缩写--> <a @click="clickFun">点击</a> <!-- @click.prevent 表示点击时触发的事件调用event.preventDefault()--> <a @click.prevent="clickFun">点击</a> <script type="text/javascript"> new Vue({ el: '#app', data: { content: '这是文本内容' }, methods: { clickFun: function(){ console.log("你进行了点击操作") } } }) </script>
5. Class绑定
<!--div元素是否拥有类样式取决于data属性中isActive的值是否为true--> <div :class="{ active: isActive }"></div> <!--根据不同的条件控制类样式呈现--> <div :class="{ active: isActive, 'error-msg': isError }"></div> <!--通过数组绑定类样式--> <div :class="[activeClass, errorClass]"></div> <!--通过三元一次运算符绑定--> <div :class="[isActive ? 'active' : '']"></div> <script type="text/javascript"> new Vue({ el: '#app', data: { isActive: false, isError: false, activeClass: 'active', errorClass: 'error' } }) </script>
6. 条件渲染
<!--根据flag的值控制div及其子元素是否显示--> <div v-if="flag === 1">flag = 1</div> <div v-else-if="flag === 2">flag = 2</div> <div v-else>flag = 3</div> <!--根据errorMsg的值控制div是否显示--> <div v-show="errorMsg !=='' " v-text="errorMsg"></div> <!--v-if 和 v-show的区别: v-if切换时的开销高,v-show渲染时的开销高--> <script type="text/javascript"> new Vue({ el: '#app', data: { flag: 1, errorMsg: '' } }) </script>
7. 列表渲染
<select> <!--v-for表示循环遍历,(s,index)中的s表示每次遍历时使用的变量名,index表示元素所在的下标, :key表示option元素是唯一的,需要每次都重新渲染,:value表示每次选中该option选项时使用的值, {{s}}位于option标签对之间,其值作为option选项的内容呈现--> <option v-for="(s,index) in sexList" :key="index" :value="s">{{s}}</option> </select> <script type="text/javascript"> new Vue({ el: '#app', data: { sexList: ['男','女','其他'] } }) </script>
8. 表单输入绑定
<!--将文本框中内容与user对象中的username属性绑定在一起,这是一种双向绑定,文本框中的内容变化时, username属性值也会发生变化,username属性值发生变化时,文本框显示内容也会发生变化--> <input type="text" v-model="user.username"> <input type="password" v-model="user.password"> <!--绑定的数据必须是数字--> <input type="number" v-model.number="user.age"> <!--复选框组绑定时,必须进行分组,且绑定的数据是一个数组--> <input type="checkbox" name="hobby" v-model="user.hobbies" value="0">打游戏 <input type="checkbox" name="hobby" v-model="user.hobbies" value="1">撸代码 <input type="checkbox" name="hobby" v-model="user.hobbies" value="2">处对象 <!--单选框组绑定时,必须进行分组--> <input type="radio" name="sex" v-model="user.sex" value="0">男 <input type="radio" name="sex" v-model="user.sex" value="1">女 <input type="radio" name="sex" v-model="user.sex" value="2">其他 <input type="button" value="打印user对象" @click="showUser"> <script type="text/javascript"> new Vue({ el: '#app', data: { user: { username: '', password: '', age: '', hobbies: [], sex: '' } }, methods: { showUser: function () { //在方法中访问data属性中定义的变量时,必须要加this console.log(this.user) } } }) </script>
四、Vue组件
1. Vue组件定义
-
新建
template.js
//component函数就是用来定义组件的 //第一个参数就是组件的名称 //第二个参数就是组件的详细信息,包括使用的模板template和该组件使用的数 //据data,与普通页面不同的是,组件中的数据定义的方式使用的是一个data方法 //来获取,因此,需要返回一个定义好的数据对象 Vue.component("qf-pagination",{ //template模板只允许存在一个根标签 template: '<div>' + '<button v-for="page in totalPage" v-text="page" @click="gotoPage(page)"></button>' + '</div>', data(){ return { totalPage: 10 } }, methods: { gotoPage: function (page) { console.log(page) } } });
-
页面中引入
template.js
<body> <div id="app"></div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript" src="js/templates.js"></script> <script type="text/javascript"> new Vue({ el: '#app', data: { } }) </script>
-
页面中使用组件
<body> <div id="app"> <!--引用定义的组件--> <qf-pagination></qf-pagination> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript" src="js/templates.js"></script> <script type="text/javascript"> new Vue({ el: '#app', data: { } }) </script>
2. 组件传值
组件的主要作用就是进行重复利用。在重复利用的过程中就会涉及到数据的传递,那么,组件是怎么接收传递的过来的数据的呢?
在定义组件时,通过 props 属性定义组件接收的数据,在使用组件时,需要传递 props 中定义的属性值。
-
定义组件
Vue.component("user-info", { template: '<ul>' + '<li v-for="prop in Object.keys(user)">{{prop +"=>" + user[prop]}}</li>' + '</ul>', props: ['user'] })
-
调用组件
<body> <div id="app"> <!--引用定义的组件--> <user-info :user="user"></user-info> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript" src="js/templates.js"></script> <script type="text/javascript"> new Vue({ el: '#app', data: { user: { username: 'admin', password: '123456', name: '管理员' } } }) </script>
五、自定义指令
1. 语法
Vue.directive('指令名称', { //钩子函数 })
2. 自定义指令的钩子函数
-
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 -
inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 -
update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。 -
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 -
unbind
:只调用一次,指令与元素解绑时调用。指令钩子函数会被传入以下参数:
//el:指令所绑定的元素,可以用来直接操作 DOM。 //binding:一个对象,包含以下属性: //name:指令名,不包括 v- 前缀。 //value:指令的绑定值,例如:`v-test="1+1"中,绑定值为 2。 //oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。 //expression:字符串形式的指令表达式。例如 v-test="1 + 1" 中,表达式为 "1 + 1"。 //arg:传给指令的参数,可选。例如 v-test:foo 中,参数为 `"foo"`。 //modifiers:一个包含修饰符的对象。 //vnode:Vue 编译生成的虚拟节点。可以用于值的绑定 //oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
3. 案例
-
新建
directive.js
Vue.directive('file', { //el就是指令所绑定的元素,可以用来直接操作 DOM。 // bind: function (el, binding, vnode) { el.innerHTML = '<input type="text">' + ' <i>' + ' <input type="button" value="浏览...">' + ' <input type="file">' + ' </i>'; let i = el.children[1]; i.style.position = 'relative'; i.children[1].style.position = 'absolute'; i.children[1].style.left = '0'; i.children[1].style.top = '0'; i.children[1].style.width = '53px'; i.children[1].style.opacity = '0'; i.children[1].onchange = function () { if(i.children[1].files != null && i.children[1].files.length > 0){ //vnode.context记录当前的上下文,也就是实例对象 //binding.expression就是取到v-file="image"中的image //整条语句就是给image变量赋值 vnode.context[binding.expression] = i.children[1].files[0] el.children[0].value = i.children[1].files[0].name } else { vnode.context[binding.expression] = '' el.children[0].value = '' } } } });
-
引入
directive.js
,然后在页面上使用<body> <div id="app"> <div v-file="file"></div> <input type="button" value="显示选择的文件" @click="showFile"> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript" src="js/directive.js"></script> <script type="text/javascript"> new Vue({ el: '#app', data: { file: '' }, methods: { showFile: function () { console.log(this.file) } } }) </script>
六、导出与导入
1. 导出函数
common.js
/** * 日期转换为字符串 * @param date * @returns {string} */ export function date2Str(date){ let year = date.getFullYear(); let month = date.getMonth(); let day = date.getDate(); let hour = date.getHours(); let minute = date.getMinutes(); let seconds = date.getSeconds(); return year + "-" + zerofill(month + 1, 2) + "-" + zerofill(day, 2) + " " + zerofill(hour, 2) + ":" + zerofill(minute, 2) + ":" + zerofill(seconds, 2); } /** * 零填充 * @param value * @param length * @returns {string} */ export function zerofill(value, length) { if(value === undefined || value === null || value === ''){ throw new Error(value + "不能为空") } else if(length < 0){ throw new Error("填充长度length不能小于0:" + length) } else if(value.length > length){ throw new Error(value + "长度大于" + length) } else { let data = value + ""; while (data.length < length){ data = '0' + data } return data; } } /** * 拷贝对象 * @param o * @returns {{}} */ export function copyObject(o) { if(typeof o === 'object'){ let data = {}; Object.keys(o).forEach(key => data[key] = o[key]) return data; } else { throw new Error(o + "不是对象"); } }
2. 导入函数
<body> <div id="app"> <input type="button" value="显示日期" @click="showDate"> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <!--注意:这里的type属性的值必须是module,只有在module中才可以进行导入--> <script type="module"> //import导入的时候需要使用{}来指定导入的函数名,导入多个函数时函数名之间使用逗号隔开 //from表示函数的来源,后面接一个字符串地址,必须使用相对路径 import {date2Str } from './js/common.js' new Vue({ el: '#app', methods: { showDate: function () { console.log(date2Str(new Date())) } } }) </script>
3. 插件导出
file-plugin.js
//export default {} 就是用来定义插件的 {}中定义的是插件的内容,Vue规定,插件必须提供一个install方法 export default { //插件安装方法,可以带一个Vue类型参数,还可以带一个option选项参数 install(Vue) { //这里定制的是一个指令插件 Vue.directive('file', { //el就是指令所绑定的元素,可以用来直接操作 DOM。 // bind: function (el, binding, vnode) { el.innerHTML = '<input type="text">' + ' <i>' + ' <input type="button" value="浏览...">' + ' <input type="file">' + ' </i>'; let i = el.children[1]; i.style.position = 'relative'; i.children[1].style.position = 'absolute'; i.children[1].style.left = '0'; i.children[1].style.top = '0'; i.children[1].style.width = '53px'; i.children[1].style.opacity = '0'; i.children[1].onchange = function () { if(i.children[1].files != null && i.children[1].files.length > 0){ //vnode.context记录当前的上下文,也就是实例对象 //binding.expression就是取到v-file="image"中的image //整条语句就是给image变量赋值 vnode.context[binding.expression] = i.children[1].files[0] el.children[0].value = i.children[1].files[0].name } else { vnode.context[binding.expression] = '' el.children[0].value = '' } } } }); } }
4. 插件导入
<body> <div id="app"> <div v-file="file"></div> <input type="button" value="显示选择的文件" @click="showFile"> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="module"> //由于定义的插件是没有名称的,因此导入的时候可以给该插件命名 import filePlugin from './js/file-plugin.js' //use方法就是用来安装插件的,会调用插件中的install方法 Vue.use(filePlugin) new Vue({ el: '#app', data: { file: '' }, methods: { showFile: function () { console.log(this.file) } } }) </script>
5. 组件的导出
Navigation.js
export default { template: '<ul>' + ' <li v-for="title in titles" v-text="title" @click="showTitle(title)"></li>' + ' </ul>', data(){ return { titles: ["文章","评论","交友"] } }, methods: { showTitle: function (title) { console.log(title) } } }
6. 组件的导入
<body> <div id="app"> <!--引用调用的组件--> <navigation></navigation> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="module"> //导入定义的组件 import Navigation from "./component/Navigation.js"; //组件注册 Vue.component('Navigation', Navigation) new Vue({ el: '#app' }) </script>
七、Vue 路由
路由的整合需要使用到第三方库 vue-router.js
1. 路由导航
<!-- vue-router使用 router-link 组件来导航. 通过传入 to 属性指定链接. <router-link> 默认会被渲染成一个 <a>标签 --> <router-link to="/">首页</router-link> <router-link to="/nav">导航</router-link>
2. 路由出口
<!-- vue-router使用 router-view 来表示路由出口,路由匹配到的组件将渲染在这里 --> <router-view />
3. 路由组件定义
//Navigation.js export default { name: 'Navigation', template: '<ul>' + ' <li v-for="title in titles" v-text="title" @click="showTitle(title)"></li>' + ' </ul>', data(){ return { titles: ["文章","评论","交友"] } }, methods: { showTitle: function (title) { console.log(title) } } } //Home.js export default { name: 'Home', template: '<div>' + ' 这是首页' + ' </div>', data(){ return { } }, methods: { } }
4. 路由配置
<body> <div id="app"> <!-- vue-router使用 router-link 组件来导航. 通过传入 to 属性指定链接. <router-link> 默认会被渲染成一个 <a>标签 --> <router-link to="/">首页</router-link> <router-link to="/nav">导航</router-link> <!-- 路由出口,路由匹配到的组件将渲染在这里 --> <router-view /> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript" src="js/vue-router.js"></script> <script type="module"> import Home from './component/Home.js' import Navigation from './component/Navigation.js' //创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', component: Home },{ path: '/nav', component: Navigation }] }); //Vue实例的选项中配置路由 new Vue({ router: router }).$mount("#app") //Vue实例挂载在#app的元素上 </script>
5. 命名路由
//创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', name: 'Home', //路由的名称 component: Home },{ path: '/nav', name: 'Navigation', //路由的名称 component: Navigation }] });
<!-- 使用v-bind:[属性] 绑定当前使用的路由,绑定时根据路由的名称进行绑定 --> <router-link :to="{name: 'Home'}">首页</router-link> <router-link :to="{name: 'Navigation'}">导航</router-link>
6. 路由重定向
Login.js
export default { name: 'Login', template: '<div>\n' + ' <div>\n' + ' <input type="text" v-model="user.username">\n' + ' </div>\n' + ' <div>\n' + ' <input type="text" v-model="user.password">\n' + ' </div>\n' + ' <div>\n' + ' <input type="button" value="登录" @click="login">\n' + ' </div>\n' + ' </div>', data(){ return { user: { username: '', password: '' } } }, methods: { login: function () { console.log(this.user) } } }
import Home from './component/Home.js' import Login from './component/Login.js' import Navigation from './component/Navigation.js' //创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', redirect: '/login',//重定向,只要使用当前路由,就会重定向到/login name: 'Home', //路由的名称 component: Home },{ path: '/login', name: 'Login', //路由的名称 component: Login },{ path: '/nav', name: 'Navigation', //路由的名称 component: Navigation }] });
7. 路由守卫
-
全局前置守卫
//创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', redirect: '/login', name: 'Home', //路由的名称 component: Home },{ path: '/login', name: 'Login', //路由的名称 component: Login },{ path: '/nav', name: 'Navigation', //路由的名称 component: Navigation }] }); //全局前置守卫 //to: 即将要进入的目标路由对象 //from: 当前导航正要离开的路由对象 //next: 一定要调用该方法,否则,路由将不会跳转。执行效果依赖 next 方法的调用参数。 //next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 //next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL //地址会重置到 `from` 路由对应的地址。 //next('/') 或者 next({path: '/'}): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。 //next(error): 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递 //给router.onError() 注册过的回调。 router.beforeEach((to, from, next) => { console.log("路由准备从" + from.path + "跳转到" + to.path) next() })
8.路由元信息
//创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', redirect: '/login', name: 'Home', //路由的名称 component: Home, meta: {//路由元信息 name: '首页', keepAlive: true } },{ path: '/login', name: 'Login', //路由的名称 component: Login, meta: {//路由元信息 name: '登录', keepAlive: true } },{ path: '/nav', name: 'Navigation', //路由的名称 component: Navigation, meta: {//路由元信息 name: '导航', keepAlive: true } }] });
9. 路由懒加载
//创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', redirect: '/login', name: 'Home', //路由的名称 component: function () {//组件用到时,调用函数获取组件,这种方式称为懒加载 return import('./component/Home.js') }, meta: {//路由元信息 name: '首页', keepAlive: true } },{ path: '/login', name: 'Login', //路由的名称 component: function () {//组件用到时,调用函数获取组件,这种方式称为懒加载 return import('./component/Login.js') }, meta: {//路由元信息 name: '登录', keepAlive: true } },{ path: '/nav', name: 'Navigation', //路由的名称 component: function () {//组件用到时,调用函数获取组件,这种方式称为懒加载 return import('./component/Login.js') }, meta: {//路由元信息 name: '导航', keepAlive: true } }] });
//创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', redirect: '/login', name: 'Home', //路由的名称 component: () => import('./component/Home.js'), //箭头函数,相当于Java中lambda表达式 meta: {//路由元信息 name: '首页', keepAlive: true } },{ path: '/login', name: 'Login', //路由的名称 component: () => import('./component/Login.js'),//箭头函数,相当于Java中lambda表达式 meta: {//路由元信息 name: '登录', keepAlive: true } },{ path: '/nav', name: 'Navigation', //路由的名称 component: () => import('./component/Navigation.js'),//箭头函数,相当于Java中lambda表达式 meta: {//路由元信息 name: '导航', keepAlive: true } }] });
10. 嵌套路由
-
创建管理页面组件
Manage.js
export default { name: 'Manage', template: '<div class="main-container">\n' + ' <aside>\n' + ' <router-link v-for="m in menus" :to="{path: m.routePath}">\n' + ' <div v-text="m.name"></div>\n' + ' </router-link>\n' + ' </aside>\n' + ' <main>\n' + ' <header>头部信息</header>\n' + ' <section>\n' + ' <nav>导航条</nav>\n' + ' <article>\n' + ' <router-view />\n' + ' </article>\n' + ' <footer>页脚</footer>\n' + ' </section>\n' + ' </main>\n' + ' </div>', data(){ return { menus: [{ id: 1, name: '用户管理', routePath: '/user' },{ id: 2, name: '角色管理', routePath: '/role' }] } }, methods: { } }
-
创建二级路由组件
User.js
export default { name: 'User', template: '<div>用户界面</div>' }
-
创建二级路由组件
Role.js
export default { name: 'Role', template: '<div>角色界面</div>' }
-
二级路由配置
//创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', redirect: '/login', name: 'Home'//路由的名称 },{ path: '/login', name: 'Login', //路由的名称 component: () => import('./component/Login.js'),//箭头函数,相当于Java中lambda表达式 meta: {//路由元信息 name: '登录', keepAlive: true } },{ path: '/manage', name: 'Manage', //路由的名称 component: () => import('./component/Manage.js'),//箭头函数,相当于Java中lambda表达式 meta: {//路由元信息 name: '导航', keepAlive: true }, children: [{//子路由 path: '/user', name: 'User', component: () => import('./component/User.js'), meta: {//路由元信息 name: '用户管理', keepAlive: true }, },{ path: '/role', name: 'Role', component: () => import('./component/Role.js'), meta: {//路由元信息 name: '角色管理', keepAlive: true }, }] }] });
-
创建页面 css 样式
index.css
html,body, #app, .main-container{ width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } .main-container{ display: flex; flex-direction: row; } aside{ width: 200px; border-right: 1px solid #ddd; } main{ flex-grow: 1.5; flex-shrink: 0.5; display: flex; flex-direction: column; } header, nav{ height: 40px; border-bottom: 1px solid #ddd; } footer{ height: 40px; border-top: 1px solid #ddd; } section{ flex-grow: 1.5; flex-shrink: 0.5; display: flex; flex-direction: column; } article{ flex-grow: 1.5; flex-shrink: 0.5; }
-
整体引入
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门</title> <link rel="stylesheet" type="text/css" href="css/index.css"> </head> <body> <div id="app"> <router-view /> </div> </body> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript" src="js/vue-router.js"></script> <script type="module"> //创建 router 实例,里面包含一个 routes 配置数组 let router = new VueRouter({ //定义路由,每个路由应该映射一个组件 routes: [{ path: '/', redirect: '/login', name: 'Home'//路由的名称 },{ path: '/login', name: 'Login', //路由的名称 component: () => import('./component/Login.js'),//箭头函数,相当于Java中lambda表达式 meta: {//路由元信息 name: '登录', keepAlive: true } },{ path: '/manage', name: 'Manage', //路由的名称 component: () => import('./component/Manage.js'),//箭头函数,相当于Java中lambda表达式 meta: {//路由元信息 name: '导航', keepAlive: true }, children: [{ path: '/user', name: 'User', component: () => import('./component/User.js'), meta: {//路由元信息 name: '用户管理', keepAlive: true }, },{ path: '/role', name: 'Role', component: () => import('./component/Role.js'), meta: {//路由元信息 name: '角色管理', keepAlive: true }, }] }] }); //全局前置守卫 router.beforeEach((to, from, next) => { console.log("路由准备从" + from.path + "跳转到" + to.path) next() }) //Vue实例的选项中配置路由 new Vue({ router: router }).$mount("#app")//Vue实例挂载在#app的元素上 </script> </html>