昨日内容回顾

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. python 内建函数专题

    all 用来控制 import , 甚至可以改变 _private 为 public enter , exit 用于上下文管理器 iter 用于迭代器 repr 给计算机读, str ==> s ...

  2. ubuntu上zip格式解压乱码解决

    在windows上压缩的文件,是以系统默认编码中文来压缩文件.由于zip文件中没有声明其编码,所以linux上的unzip一般以默认编码解压,中文文件名会出现乱码. 虽然2005年就有人把这报告为bu ...

  3. 20155302 2016-2017-2 《Java程序设计》第九周学习总结

    20155302 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 基本数据库操作相关的JDBC接口或类是位于java.sql包中.在程序中要取得数据库联机,我 ...

  4. QPushButton按钮

    需要 from PyQt5.QtWidgets import QPushButton继承 QAbstractButton 创建按钮控件:QPushButton() 创建一个无父控件的按钮控件QPush ...

  5. oracle锁表

    一.锁表的处理 Oracle锁表比较简单,查询锁表的session杀掉就可以了. 1.以下几个为相关表 SELECT * FROM V$LOCK; SELECT * FROM V$SQLAREA; S ...

  6. keepalived高可用系列~通用基础

    简介:今天咱们来聊聊keepalived一 keepalived 架构 1  标准架构: keepalived+lvs/haproxy+后端 real server(mysql从库,nginx.myc ...

  7. DSO windowed optimization 代码 (1)

    这里不想解释怎么 marginalize,什么是 First-Estimates Jacobian (FEJ).这里只看看代码,看看Hessian矩阵是怎么构造出来的. 1 优化流程 整个优化过程,也 ...

  8. Maven私服

    1.关于中央仓库注意事项地址: 目前来说: http://repo1.maven.org/maven2/是真正的 Maven 中央仓库的地址,该地址内置在Maven 的源码中,其他的都是镜像.索引: ...

  9. Ubuntu 14.04 apt-get更换阿里云源

    https://blog.csdn.net/satomic/article/details/78997611

  10. win10-Anaconda2-Theano-cuda7.5-VS2013

    两天的辗转反侧,终于灵光一现找到了错误. 首先,我在win10下配置好了gpu和cudnn版本的caffe.但是因为win平台的限制,caffe用的不够舒服.因为之前用过一阵子theano,虽然很慢, ...