python 全栈开发,Day92(编程式的导航,vue页面布局,marked包的使用)
昨日内容回顾
1. 组件间的传值 1. bus --> 空Vue对象 通过向bus对象抛出自定义事件的方式在组件间传递信息 2. 注意事项: 1. bus.$on()应该在组件mounted(挂载在页面上)的时候就执行 2. this对象 2. Vue实例的生命周期钩子函数(8个) 1. beforeCreate data属性光声明没有赋值的时候 2. created data属性完成了赋值 3. beforeMount 页面上的{{name}}还没有被渲染成真正的数据 4. mounted 页面上的{{name}}被渲染成真正的数据 5. beforeUpdate 数据(data属性)更新之前会执行的函数 6. updated 数据(data属性)更新完会执行的函数 7. beforeDestroy 实例被销毁之前会执行的函数 8. destroyed 实例被销毁后会执行的函数 3. VueRouter 在前端做路由的 1. 基本使用 1. 先写路由 2. 生成路由实例 3. 将路由实例挂载到Vue对象上 4. <router-link></router-link> <router-view></router-view> <==> <router-view/> 2. 路由的模糊匹配 1. path: '/user/:name' ---> $route.params.name 2. /user/alex?age=9000 ---> $route.query.age 3. 子路由 children 4. 编程式导航 用JS代码去控制页面跳转 this.$router.push(...) 4. Vue-CLI 一个脚手架工具,帮助我们快速的搭建Vue项目 1. 查看本机安装的vueCLI的版本 vue -V ---> 2.9.6 2. 使用Vue CLI创建Vue项目 vue init webpack mysite 5. 组件中捕获原生事件 .native修饰符
一、编程式的导航
除了使用 <router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
router.push(location, onComplete?, onAbort?)
注意:在 Vue 实例内部,你可以通过 $router
访问路由实例。因此你可以调用 this.$router.push
。
想要导航到不同的 URL,则使用 router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
当你点击 <router-link>
时,这个方法会在内部调用,所以说,点击 <router-link :to="...">
等同于调用 router.push(...)
。
声明式 | 编程式 |
---|---|
<router-link :to="..."> |
router.push(...) |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
// 字符串 router.push('home') // 对象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: 123 }}) // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})
注意:如果提供了 path
,params
会被忽略,上述例子中的 query
并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name
或手写完整的带有参数的 path
:
const userId = 123 router.push({ name: 'user', params: { userId }}) // -> /user/123 router.push({ path: `/user/${userId}` }) // -> /user/123 // 这里的 params 不生效 router.push({ path: '/user', params: { userId }}) // -> /user
同样的规则也适用于 router-link
组件的 to
属性。
在 2.2.0+,可选的在 router.push
或 router.replace
中提供 onComplete
和 onAbort
回调作为第二个和第三个参数。这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。
**注意:**如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1
-> /users/2
),你需要使用 beforeRouteUpdate
来响应这个变化 (比如抓取用户信息)。
router.replace(location, onComplete?, onAbort?)
跟 router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
声明式 | 编程式 |
---|---|
<router-link :to="..." replace> |
router.replace(...) |
举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .active{ color:red; } </style> </head> <body> <div id="app"> <!--编程时导航--> <button @click="goHome">去首页</button> <button @click="goList">去列表</button> <router-view></router-view> </div> </body> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script> let home={ template:'<div>home</div>' }; let list={ template:'<div>list</div>' } const routes=[ {path:'/home',component:home}, {path:'/list',component:list} ] let router=new VueRouter({ routes:routes, linkActiveClass:'active' }); //默认加载第一个路径 router.push("/home"); let vm=new Vue({ el:"#app", methods:{ //编程式导航 goHome(){ //页面跳转,push是增加到历史管理 this.$router.history.push('/home') //go表示前进后退 //this.$router.history.go(-1) }, goList(){ this.$router.history.push('/list') //将当前历史管理替换成list //this.$router.history.replace('/list') } }, // 会在实例中提供两个属性this.$route(属性),this.$router(方法); router:router, }) </script> </html>
访问网页,效果如下:
二、vue页面布局
我们要完成这个效果
使用以下命令,创建一个vue项目,具体执行过程,请参考上一篇文章
$ npm install -g vue-cli $ vue init webpack my-project $ cd my-project $ npm install bootstrap@3.3.7 -D $ npm run dev
去除默认页面
进入目录my-project\src\router
查看index.js,在routes里面有一行,它表示组件HelloWorld
component: HelloWorld
查看上面的一行
import HelloWorld from '@/components/HelloWorld'
@表示src目录
@/components/HelloWorld 表示src\components\HelloWorld.vue
.vue后缀,可以不用写。
组件统一在目录中components
进入目录my-project\src\components,查看HelloWorld.vue
在<template></template> 之间的代码,就是默认首页,图片下面的一堆a标签。
修改<template></template> 之间的代码。HelloWorld.vue部分代码如下:
<template> <div class="hello"> <h1>这是首页!!!</h1> </div> </template>
返回上一级,打开App.vue文件,查看<template></template> 之间的代码
下面一行,表示一个图片。assets目录,可以放一些资源,比如图片之类的
<img src="./assets/logo.png">
再看下面一行
<router-view/>
它的完整代码是<router-view><router-view/>。<router-view/>是一个简写,它会自动闭合!
初学者,建议使用完整写法!
删除这2行代码,增加一个bootstrap的导航条
修改App.vue里面<template></template> 之间的代码,增加一个nav标签
修改App.vue里面<script></script> 之间的代码,导入bootstrap
修改App.vue里面<style><style> 之间的代码,去掉所有样式
App.vue完整代码如下:
<template> <div id="app"> <!--导航条--> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">我的首页</a></li> <li><a href="#">我的笔记</a></li> </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="#">登录</a></li> <li class="dropdown"> <li><a href="#">注册</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> </div> </template> <script> //导入bootstrap import 'bootstrap/dist/css/bootstrap.min.css' export default { name: 'App' } </script> <style> </style>
访问网页,效果如下:
增加我的笔记
首先增加路由,路由统一在router目录
进入目录my-project\src\router,修改index.js,增加路由/note
为了方便路由扩展,定义常量routeArray,它是一个路由数组
修改默认的导入路由方式
头部使用import导入Note.vue
index.js完整代码如下:
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Note from '@/components/Note.vue' //导入我的笔记组件 Vue.use(Router) // 生成路由数组 var routeArray = [ { path: '/', name: '我的首页', component: HelloWorld }, { path: '/note', name: '我的笔记', component: Note } ] // 生成路由实例 var routerObj = new Router({ mode: 'history', routes: routeArray }) //导入默认路由实例 export default routerObj
注意:component:Note 这里面的Note,对应就是Note.vue文件
进入目录my-project\src\components,新建文件Note.vue
<template> <div> <h1>这是我的笔记页面!</h1> </div> </template> <script> export default { name: "Note" } </script> <style> </style>
进入目录my-project\src,查看文件main.js,它是app 入口文件
查看这一行
router, 这个是简写,实际的完整代码是 router:router
因为键和值,都是router,所以可以简写为router
它实际对应的就是my-project\src\router目录,这个目录下有一个index.js,它会自动去加载它!
页面切换效果
在App.vue中的<template></template> 之间的代码,是网页导航部分。这里面的我的首页和我的笔记的a标签的herf属性是#,需要修改一下
由于我们使用的是Vue Router,它将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。
所以a标签,必须替换为router-link。必须指定,App.vue完整代码如下:
<template> <div id="app"> <!--导航条--> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"> <router-link to="/">我的首页</router-link> </li> <li> <router-link to="/note">我的笔记</router-link> </li> </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="#">登录</a></li> <li class="dropdown"> <li><a href="#">注册</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <!--路由出口--> <router-view></router-view> </div> </template> <script> //导入bootstrap import 'bootstrap/dist/css/bootstrap.min.css' export default { name: 'App' } </script> <style> </style>
注意:要指定路由出口,否则页面无法渲染!
那么Vue Router如何渲染网页导航的呢?
main.js,它是app入口文件,在Vue对象中,指定router就是src/router目录,默认会加载里面的index.js
index.js里面定义了2个path,/和/note,分别对应组件HelloWorld.vue和Note.vue
这2个组件,定义了<template></template>标签,标签之间的代码,就是页面渲染的部分
访问页面,效果如下:
为什么首页的url,后面没有内容呢?而我的笔记,url后面有一个note
因为首页的path,就是 / ,它和直接IP+端口访问,效果是一样的!
查看src\router\index.js文件
// 生成路由实例 var routerObj = new Router({ mode: 'history', routes: routeArray })
从我们学习vue的前5天,生成路由实例时,从未指定mode参数。它默认为hash,访问页面会发现,url后面,会带一个#号,发觉没有?
指定mode为history,就不会有#号了!
vue项目流程
到这里,先来梳理一下,Vue项目的流程。在开发过程中,一般我们只修改src目录下的文件。
路由流程如下:
解释:
1. main.js是app入口文件,它里面定义的router,实际就是router目录
2. router目录下有一个index.js文件,它会默认加载。就好像使用Apache或者Nginx,指定默认首页为index.html一样
3. index.js定义了路由数组,指定一些组件。组件统一存放在components目录,后缀为.vue的文件,就是一个组件!
再来看一下
页面渲染流程:
解释:
1. 在main.js中,定义了组件为{ App },它实际对应的就是App.vue
2. 在App.vue中,定义了<template></template>标签,它是存放html代码的。
一般使用vue,会先绑定一个<div id="app">,这个是约定俗成的!通俗的来讲,就是划分了一块田。
那么之后的所有操作,都是基于这个div来操作的!
必须指定路由出口,也就是<router-view></router-view>,(</router-view>是简写),它才能被浏览器渲染!
3. HelloWorld.vue是默认就有的组件,它里面也定义了<template></template>,但是并没有</router-view>标签(路由出口)
为什么呢?因为在组件App.vue,它里面已经定义了路由出口,我们所有的操作都是基于这个div来操作的!
不信?有图有真相!
使用浏览器工具,查看html代码
看到一条蓝线没有,它表示一对标签。看到h1标签没有?它是HelloWorld.vue组件才有的标签!
h1标签是在<div id="app"></div>里面的!
说到这里,我想大家应该明白了使用webpack模板创建vue项目的整个流程了吧!
for循环导航菜单
查看index.js,routeArray变量是一个数组。它对应的是App.vue中的2个a标签,这2个a标签写死了,我们可以改成for循环,来遍历数组。方便以后的扩展!
那么如何获取当前所有路由呢?
修改App.vue,增加一个计算属性
<template> <div id="app"> <!--导航条--> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"> <router-link to="/">我的首页</router-link> </li> <li> <router-link to="/note">我的笔记</router-link> </li> </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="#">登录</a></li> <li class="dropdown"> <li><a href="#">注册</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <!--显示所有路由--> {{allRoutes}} <!--路由出口--> <router-view></router-view> </div> </template> <script> //导入bootstrap import 'bootstrap/dist/css/bootstrap.min.css' export default { name: 'App', data:function(){ return {} }, //计算属性 computed:{ allRoutes:function(){ // 从Vue实例里面取出所有的路由 console.log(this.$router.options.routes) // return this.$router.options.routes } } } </script> <style> </style>
刷新页面,查看console,出现了2个路由
使用v-for循环allRoutes
修改App.vue,完整代码如下:
<template> <div id="app"> <!--导航条--> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <!--<li class="active">--> <!--<router-link to="/">我的首页</router-link>--> <!--</li>--> <!--<li>--> <!--<router-link to="/note">我的笔记</router-link>--> <!--</li>--> <!-- <router-link v-for="(route, index) in allRoutes" : allRoutes是一个计算属性 v-bind:to="route.path" : 取每一项路由的path v-bind:key=index : for循环vue推荐绑定key,key用来标示for循环的每一项 tag='li' : 告诉router-link渲染的时候 渲染成li标签 activeClass='active' : 当当前的router-link被选中的时候 添加的 class样式 exact : 指定路由为严格匹配模式,而不是默认的以。。。开头 > <a>{{route.name}}</a> : 取每一个路由的name </router-link> --> <router-link v-for="(route, index) in allRoutes" v-bind:to="route.path" v-bind:key=index tag='li' activeClass='active' exact > <a>{{route.name}}</a> </router-link> </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="#">登录</a></li> <li class="dropdown"> <li><a href="#">注册</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <!--路由出口--> <router-view></router-view> </div> </template> <script> //导入bootstrap import 'bootstrap/dist/css/bootstrap.min.css' export default { name: 'App', data:function(){ return {} }, //计算属性 computed:{ allRoutes:function(){ // 从Vue实例里面取出所有的路由 // console.log(this.$router.options.routes) return this.$router.options.routes } } } </script> <style> </style>
刷新网页,效果同上!
我的笔记面板
点击我的笔记,下面的内容,是一个面板
使用栅格系统,左侧笔记列表为3格,右边笔记编辑区为9格
访问 http://127.0.0.1:8080/note
效果如下:
左侧列表组件
左侧的列表组,是一个组件
在components文件夹下,新建NoteList.vue文件
将Note.vue中的列表组的html代码剪切过来
NoteList.vue完整代码如下:
<template> <ul class="list-group"> <li class="list-group-item">Cras justo odio</li> <li class="list-group-item">Dapibus ac facilisis in</li> <li class="list-group-item">Morbi leo risus</li> <li class="list-group-item">Porta ac consectetur ac</li> <li class="list-group-item">Vestibulum at eros</li> </ul> </template> <script> export default { name: "NoteList" } </script> <style scoped> </style>
修改Note.vue,导入NoteList组件,Note.vue完整代码如下:
<template> <div> <div class="container"> <div class="row"> <!-- 面板 --> <div class="panel panel-info"> <div class="panel-heading"> <h3 class="panel-title">我的笔记</h3> </div> <div class="panel-body"> <div class="col-md-3"> <!-- 左边笔记列表 开始 --> <NoteList></NoteList> <!-- 左边笔记列表 结束 --> </div> <div class="col-md-9"> <!-- 右边笔记编辑区 开始 --> <div class="note-edit"> </div> <!-- 右边笔记编辑区 结束 --> </div> </div> </div> </div> </div> </div> </template> <script> //导入NoteList import NoteList from '@/components/NoteList.vue' export default { name: "Note", // 加载这个组建的时候 先要去找 NoteList components: { NoteList, } } </script> <style> .note-edit { height: 600px; border: 1px solid grey; } </style>
刷新网页,效果同上!
分离左侧列表
每一个li标签都是组件,在components文件夹下,新建NoteItem.vue文件
<template> <div class="list-group-item"> </div> </template> <script> export default { name: "NoteItem" } </script> <style scoped> </style>
修改NoteList.vue,导入NoteItem.vue。NoteList.vue完整代码如下:
<template> <div> <div class="list-group"> <NoteItem v-for="(note, index) in NoteList" v-bind:name='note' v-bind:key="index" ></NoteItem> </div> </div> </template> <script> import NoteItem from '@/components/NoteItem.vue' export default { name: 'NoteList', components: { NoteItem }, data:function(){ return { //声明数组 NoteList: [ '吃饭', '睡觉', '打豆豆' ] } } } </script> <style> </style>
刷新网页,效果如下:
父子传值
从上图可以看到,左边的列表组是空的,需要父子传值。
父就是NoteList,子就是NoteItem
修改NoteList.vue,增加一个数组,使用for循环遍历
<template> <div> <div class="list-group"> <!-- 在子组件声明 我需要被传入的参数 v-for="(note, index) in NoteList" : NoteList是一个数组,note是数组每一个元素 v-bind:name=note : 子组件声明,被传入的参数为name,值为note,也就是数组的元素 v-bind:key=index : for循环vue推荐绑定key,key用来标示for循环的每一项 --> <NoteItem v-for="(note, index) in NoteList" v-bind:name='note' v-bind:key="index" ></NoteItem> </div> </div> </template> <script> //导入NoteItem组件 import NoteItem from '@/components/NoteItem.vue' export default { name: 'NoteList', components: { NoteItem }, data:function(){ return { //声明数组 NoteList: [ '吃饭', '睡觉', '打豆豆' ] } } } </script> <style> </style>
修改NoteItem.vue
<template> <!--渲染name变量--> <div class="list-group-item">{{name}}</div> </template> <script> export default { name: 'NoteItem', props: ['name'] // 在子组件声明 我需要被传入的参数 } </script> <style> </style>
刷新页面,效果如下:
查看html代码,和分离之前的代码,是一致的!
右侧笔记编辑区
右边区域,根据栅格系统,平均划分,就可以了。左边6格,右边6格
右边区域也是一个组件,在components目录下,创建NoteEdit.vue
<template> <div class="row"> <!-- 左边的 textarea 区域开始 --> <div class="col-md-6 height600"> <div class="input-group"> <span class="input-group-addon" id="basic-addon1">标题</span> <input type="text" class="form-control" placeholder="请输入标题" aria-describedby="basic-addon1"> </div> <!-- textarea --> <textarea class="my-textarea"></textarea> </div> <!-- 左边的 textarea 区域结束 --> <!-- 右边的 展示区 区域开始 --> <div class="col-md-6 height600"> <div> <button class="btn btn-success">添加</button> </div> <div class="right-box my-textarea"> </div> </div> <!-- 右变的 展示 区域结束 --> </div> </template> <script> // import marked from 'marked' export default { name: 'NoteEdit', } </script> <style> .my-textarea { margin-top: 15px; height: 80%; width: 100% } .height600 { height: 600px; } .right-box { border: 1px solid grey } </style>
编辑Note.vue,导入NoteEdit.vue组件,Note.vue完整代码如下:
<template> <div> <div class="container"> <div class="row"> <!-- 面板 --> <div class="panel panel-info"> <div class="panel-heading"> <h3 class="panel-title">我的笔记</h3> </div> <div class="panel-body"> <div class="col-md-3"> <!-- 左边笔记列表 开始 --> <NoteList></NoteList> <!-- 左边笔记列表 结束 --> </div> <div class="col-md-9"> <!-- 右边笔记编辑区 开始 --> <div class="note-edit"> <NoteEdit></NoteEdit> </div> <!-- 右边笔记编辑区 结束 --> </div> </div> </div> </div> </div> </div> </template> <script> //导入NoteList import NoteList from '@/components/NoteList.vue' import NoteEdit from '@/components/NoteEdit.vue' export default { name: "Note", // 加载这个组建的时候 先要去找 NoteList components: { NoteList, NoteEdit } } </script> <style> .note-edit { height: 600px; /*border: 1px solid grey;*/ } </style>
刷新网页,效果如下:
双向数据绑定
左边的textarea输入框的值一旦发现改变,要将数据实时展示在右边的div中
使用v-model就可以实现
修改NoteEdit.vue
<template> <div class="row"> <!-- 左边的 textarea 区域开始 --> <div class="col-md-6 height600"> <div class="input-group"> <span class="input-group-addon" id="basic-addon1">标题</span> <input type="text" class="form-control" placeholder="请输入标题" aria-describedby="basic-addon1"> </div> <!-- textarea --> <textarea class="my-textarea" v-model="content" > </textarea> </div> <!-- 左边的 textarea 区域结束 --> <!-- 右边的 展示区 区域开始 --> <div class="col-md-6 height600"> <div> <button class="btn btn-success">添加</button> </div> <div class="right-box my-textarea"> {{content}} </div> </div> <!-- 右变的 展示 区域结束 --> </div> </template> <script> // import marked from 'marked' export default { name: 'NoteEdit', data:function () { return { content:'' } } } </script> <style> .my-textarea { margin-top: 15px; height: 80%; width: 100% } .height600 { height: 600px; } .right-box { border: 1px solid grey } </style>
刷新网页,效果如下:
Markdown
Markdown 是一个 Web 上使用的文本到HTML的转换工具,可以通过简单、易读易写的文本格式生成结构化的HTML文档。目前 github、Stackoverflow 等网站均支持这种格式。
中文文档链接:
在线编辑器:
https://www.zybuluo.com/mdeditor
访问这个网站,
http://tool.oschina.net/markdown
它能将markdown语法,实时转换为Html
# 表示h1标签
```javascript``` 表示javascript代码
[]() 表示超链接
比如:
marked
marked是npm模块中,专门用来解析markdown语法的
先停止vue项目,安装marked
-D表示当前项目安装
E:\python_script\Vue\my-project>npm install marked -D
出现以下提示,表示安装成功
+ marked@0.4.0 added 1 package from 1 contributor and audited 8826 packages in 21.209s found 1 moderate severity vulnerability run `npm audit fix` to fix them, or `npm audit` for details
启动vue项目
E:\python_script\Vue\my-project>npm run dev
修改NoteEdit.vue,导入插件marked
<template> <div class="row"> <!-- 左边的 textarea 区域开始 --> <div class="col-md-6 height600"> <div class="input-group"> <span class="input-group-addon" id="basic-addon1">标题</span> <input type="text" class="form-control" placeholder="请输入标题" aria-describedby="basic-addon1"> </div> <!-- textarea --> <textarea class="my-textarea" v-model="content" > </textarea> </div> <!-- 左边的 textarea 区域结束 --> <!-- 右边的 展示区 区域开始 --> <div class="col-md-6 height600"> <div> <button class="btn btn-success">添加</button> </div> <!--展示原始html使用v-html--> <div class="right-box my-textarea" v-html="markedDownContent" > </div> </div> <!-- 右变的 展示 区域结束 --> </div> </template> <script> //导入marked模块,用来处理makedown语法 import marked from 'marked' export default { name: 'NoteEdit', data:function () { return { content:'' } }, //增加计算属性 computed:{ markedDownContent:function(){ return marked(this.content) } } } </script> <style> .my-textarea { margin-top: 15px; height: 80%; width: 100% } .height600 { height: 600px; } .right-box { border: 1px solid grey } </style>
刷新网页,输入几段makedown语法
#我的家在东北 ## 扫得寺内 ```python print("python是世界上最好的语言") ``` - [] 呵呵哒 - [x] 萌萌哒 ![很萌的卡通小猫](http://www.gaoxiaogif.com/d/file/4dddbd73cb24eaef339623e28784155f.gif)
效果如下:
markdown是程序员的必备神器,所以有时间的话,多了解一下markdown的语法!
因为很多程序员都在用它
highlight.js
highlight.js是一款轻量级的Web代码语法高亮库
使用highlight.js高亮你的代码,无论是java,js还是php等等语言,都会自动的对关键字进行高亮
安装highlight.js
E:\python_script\Vue\my-project>npm install highlight.js -D
出现以下提示,表示安装成功
+ highlight.js@9.12.0 added 1 package from 245 contributors and audited 8828 packages in 44.305s found 1 moderate severity vulnerability run `npm audit fix` to fix them, or `npm audit` for details
使用highlight.js
修改main.js,增加一段代码
//Web代码语法高亮库 import hljs from 'highlight.js' import 'highlight.js/styles/monokai.css' //样式文件 Vue.directive('highlight',function (el) { let blocks = el.querySelectorAll('pre code'); blocks.forEach((block)=>{ hljs.highlightBlock(block) }) })
注意:
Vue.directive要在实例初始化之前,不然会报错
main.js完整代码如下:
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' Vue.config.productionTip = false //Web代码语法高亮库 import hljs from 'highlight.js' import 'highlight.js/styles/monokai.css' //样式文件 Vue.directive('highlight',function (el) { let blocks = el.querySelectorAll('pre code'); blocks.forEach((block)=>{ hljs.highlightBlock(block) }) }) /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
修改NoteEdit.vue,增加v-highlight即可
<div class="right-box my-textarea" v-html="markedDownContent" v-highlight>
NoteEdit.vue完整代码如下
<template> <div class="row"> <!-- 左边的 textarea 区域开始 --> <div class="col-md-6 height600"> <div class="input-group"> <span class="input-group-addon" id="basic-addon1">标题</span> <input type="text" class="form-control" placeholder="请输入标题" aria-describedby="basic-addon1"> </div> <!-- textarea --> <textarea class="my-textarea" v-model="content" > </textarea> </div> <!-- 左边的 textarea 区域结束 --> <!-- 右边的 展示区 区域开始 --> <div class="col-md-6 height600"> <div> <button class="btn btn-success">添加</button> </div> <!--展示原始html使用v-html--> <div class="right-box my-textarea" v-html="markedDownContent" v-highlight > </div> </div> <!-- 右变的 展示 区域结束 --> </div> </template> <script> //导入marked模块,用来处理makedown语法 import marked from 'marked' export default { name: 'NoteEdit', data:function () { return { content:'' } }, //增加计算属性 computed:{ markedDownContent:function(){ return marked(this.content) } } } </script> <style> .my-textarea { margin-top: 15px; height: 80%; width: 100% } .height600 { height: 600px; } .right-box { border: 1px solid grey } </style>
刷新网页,增加一段python和javascript代码
```python class Student(object): def __init__(self, name, age, score): self.name = name self.age = age self.score = score def get_name(self): # 获取学生的姓名 return self.name def get_age(self): # 获取学生的年龄 return self.age def get_course(self): # 返回3门科目中最高的分数 return '{}\n{}\n{}'.format(self.name,self.age,max(self.score)) ``` ```javascript var name = "abc"; console.log(name); ```
效果如下: