昨日内容回顾

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' }})

注意:如果提供了 pathparams 会被忽略,上述例子中的 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 等网站均支持这种格式。

中文文档链接:

http://www.markdown.cn/

在线编辑器:

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);
```

效果如下:

python 全栈开发,Day92(编程式的导航,vue页面布局,marked包的使用)的更多相关文章

  1. Python全栈开发【面向对象】

    Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...

  2. python 全栈开发之路 day1

    python 全栈开发之路 day1   本节内容 计算机发展介绍 计算机硬件组成 计算机基本原理 计算机 计算机(computer)俗称电脑,是一种用于高速计算的电子计算机器,可以进行数值计算,又可 ...

  3. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

  4. Python全栈开发【模块】

    Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...

  5. Python全栈开发【基础四】

    Python全栈开发[基础四] 本节内容: 匿名函数(lambda) 函数式编程(map,filter,reduce) 文件处理 迭代器 三元表达式 列表解析与生成器表达式 生成器 匿名函数 lamb ...

  6. Python全栈开发【基础三】

    Python全栈开发[基础三]  本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...

  7. Python全栈开发【基础二】

    Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...

  8. Python全栈开发【基础一】

    Python全栈开发[第一篇] 本节内容: Python 的种类 Python 的环境 Python 入门(解释器.编码.变量.input输入.if流程控制与缩进.while循环) if流程控制与wh ...

  9. Python全栈开发

    Python全栈开发 一文让你彻底明白Python装饰器原理,从此面试工作再也不怕了. 一.装饰器 装饰器可以使函数执行前和执行后分别执行其他的附加功能,这种在代码运行期间动态增加功能的方式,称之为“ ...

随机推荐

  1. scatter

    一.matplotlib.pyplot.scatter用来画散点图 import matplotlib.pyplot as plt import matplotlib as mpl mpl.rcPar ...

  2. H5利用canvas实现海报功能

    最近接到一个需求,微信中用户上传图片生成海报.这个需求比较常规,实现思路也比较简单,通过利用用户的input输入,对所上传的图片进行处理,最后通过第三方库html2canvas合成对应的图片即可.思路 ...

  3. Python生成唯一id的方法

    1. uuid import uuid def create_uid(): return str(uuid.uuid1()) if __name__ == '__main__': print(type ...

  4. 汉化DotNetBar中控件的系统文本

    作者:ComponentCN 出处:www.componentcn.com 2011年11月02日 阅读: DotNetBar很多子控件的系统文本.提示信息等都是可以本地化的,可以转化为多种语言,控件 ...

  5. 搭建Linux下Android程序开发环境

    从AndroidStudio中文社区下载SDK压缩包,http://dl.google.com/android/android-sdk_r24.2-linux.tgz. 解压到某个目录,比如我的~/p ...

  6. C++ 中 #ifndef, #define, #endif 宏定义

    目的:为了保证包含的内容只被程序(include) 和编译了一次.判断预处理器常量是否已被定义. 预编译将所有头文件(#include"XXX.h")用头文件中的内容来替换,头文件 ...

  7. Storm 集群

    Apache Storm Storm是一个分布式的,可靠的,容错的数据流处理系统.Storm集群的输入流由一个被称作spout的组件管理,spout把数据传递给bolt,bolt要么把数据保存到某种存 ...

  8. Synchronized和lock的区别和用法

    一.synchronized和lock的用法区别 (1)synchronized(隐式锁):在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要 ...

  9. hashMap之jdk1.7和jdk1.8

    参考链接: http://allenwu.itscoder.com/hashmap-analyse https://tech.meituan.com/java-hashmap.html

  10. D - 文理分科 (网络流->最小割)

    题目链接:https://cn.vjudge.net/contest/281959#problem/D 题目大意:中文题目 具体思路:我们需要求出最大的满意值,从另一方面想,我们可以求出总的满意值,然 ...