0. 组件注意事项!!! data属性必须是一个函数! 1. 注册全局组件 Vue.component('组件名',{ template: `` }) var app = new Vue({ el: '#app' }) 2. 注册局部组件 var app = new Vue({ el: '#app', components:{ 局部组件名:{ template: `...` } } }) 3. 传值 1. 父组件 --> 子组件 1. 父组件经过 v-bind:变量='值' 2. 子组件须要经过props 声明我须要的变量 2. 子组件 --> 父组件 子组件经过触发自定义事件的方式向外传递信息 1. 子组件: this.$emit('自定义事件') 2. 父组件: v-on:自定义事件='方法名' 3. 组件间传值 1. 补充:Vue实例的生命周期钩子函数(共8个) 1. beforeCreate --> 数据属性声明但没有赋值 2. created --> 数据属性赋值 3. beforeMount --> 页面上的 {{name}} 尚未被渲染 4. mounted --> 页面上的 {{name}} 被替换成真正的内容 ... 2. 基于bus对象实现 4. 插槽(slot) 插槽是占位置的!!! 插槽多了能够起名字,进行区分! --> <span slot='heihei'>嘿嘿!</span> <alert>根本不显示</alert> 5. 组件的注意事项: 1. 特殊的组件须要使用is语法声明一下 好比 table、select、ul等内部使用的组件 2. 捕获子组件的原生事件
有些 HTML 元素,诸如 <ul>
、<ol>
、<table>
和 <select>
,对于哪些元素能够出如今其内部是有严格限制的。而有些元素,诸如 <li>
、<tr>
和 <option>
,只能出如今其它某些特定的元素内部。javascript
这会致使咱们使用这些有约束条件的元素时遇到一些问题。例如:css
<table> <blog-post-row></blog-post-row> </table>
这个自定义组件 <blog-post-row>
会被做为无效的内容提高到外部,并致使最终渲染结果出错。幸亏这个特殊的 is
特性给了咱们一个变通的办法:html
<table> <tr is="blog-post-row"></tr> </table>
须要注意的是若是咱们从如下来源使用模板的话,这条限制是不存在的:vue
template: '...'
).vue
)<script type="text/x-template">
到这里,你须要了解的解析 DOM 模板时的注意事项——实际上也是 Vue 的所有必要内容,大概就是这些了。java
举例:table标签插入一个trnode
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <table border="1"> <tbody> <!--自定义组件--> <zsq></zsq> </tbody> </table> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: {}, components:{ zsq: { template: `<tr>我是一个tr标签!</tr>` }, } }) </script> </body> </html>
打开网页,效果以下:python
查看html代码,发现它提高到外部了。通俗来说,就是漂移到table外面了webpack
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <table border="1"> <tbody> <!--自定义组件--> <tr is=zsq></tr> </tbody> </table> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: {}, components:{ zsq: { template: `<tr>我是一个tr标签!</tr>` }, } }) </script> </body> </html>
刷新网页,效果以下:git
查看html代码,这样就正常了github
也就是
你可能有不少次想要在一个组件的根元素上直接监听一个原生事件。这时,你可使用 v-on
的 .native
修饰符:
<base-input v-on:focus.native="onFocus"></base-input>
在有的时候这是颇有用的,不过在你尝试监听一个相似 <input>
的很是特定的元素时,这并非个好主意。好比上述 <base-input>
组件可能作了以下重构,因此根元素其实是一个 <label>
元素:
<label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > </label>
这时,父级的 .native
监听器将静默失败。它不会产生任何报错,可是 onFocus
处理函数不会如你预期地被调用。
为了解决这个问题,Vue 提供了一个 $listeners
属性,它是一个对象,里面包含了做用在这个组件上的全部监听器。例如:
{ focus: function (event) { /* ... */ } input: function (value) { /* ... */ }, }
有了这个 $listeners
属性,你就能够配合 v-on="$listeners"
将全部的事件监听器指向这个组件的某个特定的子元素。对于相似 <input>
的你但愿它也能够配合 v-model
工做的组件来讲,为这些监听器建立一个相似下述 inputListeners
的计算属性一般是很是有用的:
Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], computed: { inputListeners: function () { var vm = this // `Object.assign` 将全部的对象合并为一个新对象 return Object.assign({}, // 咱们从父级添加全部的监听器 this.$listeners, // 而后咱们添加自定义监听器, // 或覆写一些监听器的行为 { // 这里确保组件配合 `v-model` 的工做 input: function (event) { vm.$emit('input', event.target.value) } } ) } }, template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on="inputListeners" > </label> ` })
如今 <base-input>
组件是一个彻底透明的包裹器了,也就是说它能够彻底像一个普通的 <input>
元素同样使用了:全部跟它相同的特性和监听器的均可以工做。
举例:第一种写法,使用.native修饰符
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <ztz v-on:click.native='hehe'></ztz> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { name: 'ztz', age: 24 }, components: { ztz: { template: `<button>赵天柱 逃课!</button>` }, }, methods:{ hehe:function(){ alert(123); } } }) </script> </body> </html>
刷新网页,点击按钮,效果以下:
举例:第二种写法,绑定自定义事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <!--<ztz v-on:click.native='hehe'></ztz>--> <ztzsb v-on:click='hehe'></ztzsb> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { name: 'ztz', age: 24 }, components: { // ztz: { // template: `<button>赵天柱 逃课!</button>` // }, ztzsb: { template: `<button v-on:click='shangkele'>赵天柱 逃课!</button>`, methods:{ shangkele:function(){ this.$emit('click') } } } }, methods:{ hehe:function(){ alert(123); } } }) </script> </body> </html>
刷新网页,点击按钮,效果同上!
针对这2种写法,推荐使用第一种!
每一个 Vue 实例在被建立时都要通过一系列的初始化过程——例如,须要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程当中也会运行一些叫作生命周期钩子的函数,这给了用户在不一样阶段添加本身的代码的机会。
好比 created
钩子能够用来在一个实例被建立以后执行代码:
new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 实例 console.log('a is: ' + this.a) } }) // => "a is: 1"
也有一些其它的钩子,在实例生命周期的不一样阶段被调用,如 mounted
、updated
和 destroyed
。生命周期钩子的 this
上下文指向调用它的 Vue 实例。
不要在选项属性或回调上使用箭头函数,好比 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。由于箭头函数是和父级上下文绑定在一块儿的,this 不会是如你所预期的 Vue 实例,常常致使 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。
下图展现了实例的生命周期。你不须要立马弄明白全部的东西,不过随着你的不断学习和使用,它的参考价值会愈来愈高。
Vue的生命周期,就是从Vue实例被建立开始到实例销毁时的过程,整个过程主要能够分为八个阶段分别是:
以上各个阶分别会有对应的“钩子函数”以Vue实例的选项的形式存在。
Vue提供的生命周期钩子以下:
① beforeCreate
在实例初始化以后,数据观测(data observer,开始监控Data对象数据变化)和初始化事件(init event,Vue内部初始化事件)以前被调用。
② created
在实例已经建立完成以后被调用。实例已完成如下的配置:数据观测(data observer),属性和方法的运算,event事件回调。挂载阶段还没有开始,$el 属性不可见。
③ beforeMount
在挂载开始以前被调用。相关的render函数首次被调用。实例已完成如下的配置:编译模板,把data里面的数据和模板生成html。注意此时尚未挂载html到页面上。
④ mounted
在el 被新建立的 vm.$el 替换,并挂载到实例上去以后调用。实例已完成如下的配置:用上面编译好的html内容替换el属性指向的DOM对象。此时模板中的html渲染到了html页面中,此时通常能够作一些Ajax操做。注意mounted只会执行一次。
⑤ beforeUpdate
在数据更新以前调用,发生在虚拟DOM从新渲染和打补丁以前。能够在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
⑥ updated
在因为数据更改致使的虚拟DOM从新渲染和打补丁以后调用。调用时,组件DOM已经更新,因此能够执行依赖于DOM的操做。然而在大多数状况下,应该避免在此期间更改状态,由于这可能会致使更新无限循环。该钩子在服务器端渲染期间不被调用。
⑦ beforeDestroy
在实例销毁以前调用。实例仍然彻底可用。
⑧ destroyed
在实例销毁以后调用。调用后,全部的事件监听器会被移除,全部的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
关于Vue生命周期的详细解释,请参考文章:
http://www.javashuo.com/article/p-gfficcpo-bg.html
这篇文章,写的很是详细,你们能够观摩一下!
若是有想作Vue开发的,vue生命周期必问。大概描述一下Vue实例被建立开始到实例销毁时的过程,就能够了!
中央事件总线 - 就是一个名字能够叫作bus的vue空实例,里边没有任何内容; var bus = new Vue(); 人如其名,她就像一个公交车同样,来回输送人,将a站点的A输送到b站点,再将b站点的B输送到a站点; 这里a,b站点就像父、子组件,也像兄、弟组件,或者像两个没有任何亲戚关系的任何组件; 而A,B就像是各个组件内部要传输的数据或者要执行的命令信息,靠bus来通讯。
中央事件总线 - 就是一个名字能够叫作bus的vue空实例,里边没有任何内容;
var bus = new Vue();
人如其名,她就像一个公交车同样,来回输送人,将a站点的A输送到b站点,再将b站点的B输送到a站点;
这里a,b站点就像父、子组件,也像兄、弟组件,或者像两个没有任何亲戚关系的任何组件;
而A,B就像是各个组件内部要传输的数据或者要执行的命令信息,靠bus来通讯。
若是有父子组件通讯知识基础的,应该记得当初父子组件通讯,父组件中用$on监听,子组件中用$emit发射。
现现在父子组件(或任何其余关系的两个组件之间)达成一致协议:
将监听和发射的工做交给了bus来搞,就好像他们两头不自驾接送了,改乘公交了本身出发本身回家了。
那局面就是下边这样
$on和$emit如今绑在bus上了
bus.$emit(‘同名自定义事件名’,‘$on发送过来的数据’);
在a站点(第一个组件)中的methods方法里,准备用bus的$emit发射事件任务。
bus.$on(‘自定义事件名’,function(){ //而后执行什么你本身懂的。。。 });
在b站点(另外一个组件)实例初始化(mounted钩子中)时,用bus的$on监听自家$emit触发的事件。
能够再添加data、methods、computed等选项,在初始化时让bus获取一下,任何组件均可以公用了。就像公交车上的座位,只要有座谁都能坐。
能够包括一些共享通用的信息:好比用户登陆的姓名、性别、邮箱等,还有油壶受权的token等。
举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <component_1></component_1> <hr> <component_2></component_2> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var bus = new Vue(); //中央事件总线 var app = new Vue({ el: '#app', data: { name: 'component_1' }, components:{ //注册局部组件 component_1:{ //v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码 template: `<button v-on:click='paolu'>点我</button>`, methods:{ paolu(){ alert(123); bus.$emit('taopao'); //绑定到bus上 } } }, component_2: { template: `<div>{{num}}</div>`, data:function(){ return { num: 0 } }, mounted:function(){ // 在这个做用域中 this 指的是 component_2 组件实例 console.log(this.num); var _this = this; // el被挂载以后就监听bus bus.$on('taopao', function(){ // 在这个做用域中 this 指的是 bus console.log(this.num); // undefined alert('赵天柱跑路了...'); // 修改component_2组件中的num值 // 此时this是谁?是bus // this.num += 1; // 有问题 _this.num += 1; }) } } } }) </script> </body> </html>
刷新网页,效果以下:
、
Vue Router中文文档
Vue全家桶:Vue + VueRouter + VueX
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
先来看一个网页
点击不一样的选项时,页面并无刷新。如何判断页面有没有刷新呢?看浏览器左侧这个按钮,有没有闪动。
虽然看到url地址变化了,但它并无刷新。这个,就是用vue实现的!
用 Vue.js + Vue Router 建立单页应用,是很是简单的。使用 Vue.js ,咱们已经能够经过组合组件来组成应用程序,当你要把 Vue Router 添加进来,咱们须要作的是,将组件 (components) 映射到路由 (routes),而后告诉 Vue Router 在哪里渲染它们。下面是个基本例子:
必须先引用vue.js,再引用vue-router.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--路由的入口--> <!-- 使用 router-link 组件来导航. --> <!-- 经过传入 `to` 属性指定连接. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <!--/index表示下面定义的path--> <router-link to="/index">index页面</router-link> <router-link to="/home">home页面</router-link> <hr> <!--路由的出口--> <!-- 路由匹配到的组件将渲染在这里 --> <router-view></router-view> </div> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script> //写路由 const routeArray = [ { path:'/index', component:{ template:`<div><h1>这是index页面</h1></div>` }, }, { path:'/home', component:{ //component表示用什么渲染 //template 表示使用模板 template:`<div><h1>这是home页面</h1></div>` }, } ] //生成VueRouter实例 const routerObj = new VueRouter({ //routes是关键字,它的值必须是一个数组 routes:routeArray }) //建立和挂载根实例,记得要经过 router 配置参数注入路由 //从而让整个应用都有路由功能 var app = new Vue({ el:'#app', //router是关键字 router:routerObj //将路由实例挂载到vue实例中 }) </script> </body> </html>
刷新网页,效果以下:
咱们常常须要把某种模式匹配到的全部路由,全都映射到同个组件。例如,咱们有一个 User
组件,对于全部 ID 各不相同的用户,都要使用这个组件来渲染。那么,咱们能够在 vue-router
的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
const User = { template: '<div>User</div>' } const router = new VueRouter({ routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User } ] })
如今呢,像 /user/foo
和 /user/bar
都将映射到相同的路由。
一个“路径参数”使用冒号 :
标记。当匹配到一个路由时,参数值会被设置到 this.$route.params
,能够在每一个组件内使用。因而,咱们能够更新 User
的模板,输出当前用户的 ID:
const User = { template: '<div>User {{ $route.params.id }}</div>' }
你能够看看这个在线例子。
你能够在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params
中。例如:
模式 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: 123 } |
除了 $route.params
外,$route
对象还提供了其它有用的信息,例如,$route.query
(若是 URL 中有查询参数)、$route.hash
等等。你能够查看 API 文档 的详细说明。
举例:显示xx的页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--路由的入口--> <!-- 使用 router-link 组件来导航. --> <!-- 经过传入 `to` 属性指定连接. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <!--/index表示下面定义的path--> <router-link to="/user/zly">赵丽颖</router-link> <router-link to="/user/hx">韩雪</router-link> <hr> <!--路由的出口--> <!-- 路由匹配到的组件将渲染在这里 --> <router-view></router-view> </div> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script> //写路由 const routeArray = [ { path: '/user/:name', component: { template: `<div> <h1>这是{{$route.params.name}}的主页页面!</h1> </div>` } } ] //生成VueRouter实例 const routerObj = new VueRouter({ routes: routeArray }) var app = new Vue({ el:'#app', data:{}, //router是关键字,它的值必须是数组 router:routerObj //将路由实例挂载到vue实例中 }) </script> </body> </html>
刷新网页,效果以下:
举例2: 获取url中的年龄和爱好
好比: file:///E:/python_script/Vue/test.html#/user/hx?age=18&hobby=sing
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--路由的入口--> <!-- 使用 router-link 组件来导航. --> <!-- 经过传入 `to` 属性指定连接. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <!--/index表示下面定义的path--> <router-link to="/user/zsp">赵丽颖</router-link> <router-link to="/user/hx">韩雪</router-link> <hr> <!--路由的出口--> <!-- 路由匹配到的组件将渲染在这里 --> <router-view></router-view> </div> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script> //写路由 const routeArray = [ { path: '/user/:name', component: { template: `<div> <h1>这是{{$route.params.name}}的主页页面!</h1> <p>芳龄: {{$route.query.age}}</p> <p>爱好: {{$route.query.hobby}}</p> </div>` } } ] //生成VueRouter实例 const routerObj = new VueRouter({ //routes是关键字参数,它必须对应一个数组 routes: routeArray }) var app = new Vue({ el:'#app', data:{}, //router是关键字,它的值必须是数组 router:routerObj //将路由实例挂载到vue实例中 }) </script> </body> </html>
刷新网页,访问如下url:
file:///E:/python_script/Vue/test.html#/user/hx?age=18&hobby=看电影
注意:后面的参数是手动加的!效果以下:
实际生活中的应用界面,一般由多层嵌套的组件组合而成。一样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:
/user/foo/profile /user/foo/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
借助 vue-router
,使用嵌套路由配置,就能够很简单地表达这种关系。
接着上节建立的 app:
html代码
<div id="app"> <router-view></router-view> </div>
js代码:
const User = { template: '<div>User {{ $route.params.id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ] })
这里的 <router-view>
是最顶层的出口,渲染最高级路由匹配到的组件。一样地,一个被渲染组件一样能够包含本身的嵌套 <router-view>
。例如,在 User
组件的模板添加一个 <router-view>
:
const User = { template: ` <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div> ` }
要在嵌套的出口中渲染组件,须要在 VueRouter
的参数中使用 children
配置:
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 当 /user/:id/profile 匹配成功, // UserProfile 会被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 当 /user/:id/posts 匹配成功 // UserPosts 会被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
要注意,以 /
开头的嵌套路径会被看成根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。
你会发现,children
配置就是像 routes
配置同样的路由配置数组,因此呢,你能够嵌套多层路由。
此时,基于上面的配置,当你访问 /user/foo
时,User
的出口是不会渲染任何东西,这是由于没有匹配到合适的子路由。若是你想要渲染点什么,能够提供一个 空的 子路由:
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ // 当 /user/:id 匹配成功, // UserHome 会被渲染在 User 的 <router-view> 中 { path: '', component: UserHome }, // ...其余子路由 ] } ] })
举例:点击用户后,展现用户详细信息,并能点击查看
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--路由的入口--> <!-- 使用 router-link 组件来导航. --> <!-- 经过传入 `to` 属性指定连接. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <!--/index表示下面定义的path--> <router-link to="/user/zsp">赵丽颖</router-link> <router-link to="/user/hx">韩雪</router-link> <hr> <!--路由的出口--> <!-- 路由匹配到的组件将渲染在这里 --> <router-view></router-view> </div> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script> // 写路由 // route --> 路由 // routes --> 多个路由 // router --> 路由实例 const routeArray = [ { path: '/user/:name', component: { //append表示当前路由拼接url,好比/user/hx/info //router-view对应子路由的template的内容 template: `<div> <h1>这是{{$route.params.name}}的主页页面!</h1> <p>{{$route.query.age}}</p> <p>{{$route.query.hobby}}</p> <hr> <router-link to='info' append>用户详细信息</router-link> <router-view></router-view> </div>` }, // 定义子路由 children:[ { path: 'info', component:{ template: ` <div> <h1>钗头凤 唐婉</h1> <p>忠厚老实人的恶毒像饭里的砂砾或脱骨鱼片里未净的刺给人一种不期待的伤痛。</p> </div> ` } }, ] } ] //生成VueRouter实例 const routerObj = new VueRouter({ //routes是关键字参数,它必须对应一个数组 routes: routeArray }) var app = new Vue({ el:'#app', data:{}, //router是关键字,它的值必须是数组 router:routerObj //将路由实例挂载到vue实例中 }) </script> </body> </html>
刷新网页,效果以下:
总结:
1. 基本使用 1. 必须导入vue-router.js文件 2. 要有VueRouter()实例 3. 要把VueRouter实例挂载到Vue实例中 4. 路由的入口 <router-link to='/index'>index页面</router-link> 5. 路由的出口 <router-view></router-view> 2. 路由的参数 1. path: '/user/:name' --> 匹配路由 $route.params.name --> 取值 2. /user/alex?age=9000 --> url中携带参数 $route.query.age --> 取出url的参数 3. 子路由 children:[ { path: '', component: { template: `...` } } ] <router-link to='info' append></router-link>
官方文档:
https://vuejs-templates.github.io/webpack/
这个样板是针对大型,严肃的项目,并假设您有点熟悉Webpack和vue-loader
。请务必阅读经常使用工做流程配方vue-loader
的文档。
若是您只想尝试vue-loader
或制做快速原型,请使用webpack-simple模板。
要使用此模板,请使用vue-cli构建项目。建议使用npm 3+以得到更高效的依赖树。
$ npm install -g vue-cli $ vue init webpack my-project $ cd my-project $ npm install $ npm run dev
vue-cli 是进行vue开发的脚手架工具,方便快速生成一个vue项目
先来查看node和npm的版本
C:\Users\xiao>node -v v10.7.0 C:\Users\xiao>npm -v 6.1.0
新建一个文件夹vue-cli_demo,进入到此目录
C:\Users\xiao>e: E:\>cd E:\python_script\Vue\vue-cli_demo
安装vue-cli,-g表示全局
E:\python_script\Vue\vue-cli_demo>npm install -g vue-cli npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen) C:\Users\xiao\AppData\Roaming\npm\vue -> C:\Users\xiao\AppData\Roaming\npm\node_modules\vue-cli\bin\vue C:\Users\xiao\AppData\Roaming\npm\vue-init -> C:\Users\xiao\AppData\Roaming\npm\node_modules\vue-cli\bin\vue-init C:\Users\xiao\AppData\Roaming\npm\vue-list -> C:\Users\xiao\AppData\Roaming\npm\node_modules\vue-cli\bin\vue-list + vue-cli@2.9.6 added 252 packages from 218 contributors in 29.948s
查看vue版本
E:\python_script\Vue\vue-cli_demo>vue -V
2.9.6
基于webpack模板建立项目mysite
E:\python_script\Vue\vue-cli_demo>vue init webpack mysite
提示项目名,直接回车
? Project name (mysite)
项目描述,直接回车
? Project name mysite
? Project description (A Vue.js project)
做者,直接回车
? Project name mysite
? Project description A Vue.js project
? Author (xiao <383697894@qq.com>)
这个时候,文字是有颜色的,表示选中状态,能够用光标上下移动。选择默认的Runtime + 便可!
是否安装vue-router,直接回车
? Project name mysite ? Project description A Vue.js project ? Author xiao <383697894@qq.com> ? Vue build standalone ? Install vue-router? (Y/n)
是否使用ESLint来编写代码?输入n
它是javascript代码检测工具,必须遵循必定的规则才行,不然会有提示!
对于初学者而言,不建议开启,不然写代码会很痛苦的!
? Project name mysite ? Project description A Vue.js project ? Author xiao <383697894@qq.com> ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? (Y/n) n
设置单元测试,输入n
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工做。
为了快速开发,直接关闭掉
? Project name mysite ? Project description A Vue.js project ? Author xiao <383697894@qq.com> ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? No ? Set up unit tests (Y/n) n
是否使用Nightwatch设置e2e测试,输入n
Nightwatch.js是一个测试web app和web 站点的自动化测试框架, 使用Node.js编写, 基于Selenium WebDriver API.
它是一个完整的浏览器端真实用户场景测试解决方案, 致力于简化继续集成和编写自动化测试。
小白表示一脸懵逼,关闭掉!
? Project name mysite ? Project description A Vue.js project ? Author xiao <383697894@qq.com> ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? No ? Set up unit tests No ? Setup e2e tests with Nightwatch? (Y/n) n
最后提示,使用npm安装组件
直接回车便可
上面的选项,是一条最简单的路。初学时,使用最简单的便可!
下面就表示开始安装了,耐心等待几分钟!
出现finished,表示安装成功
根据提示,执行2个命令,启动项目
它会开启本机的8080端口,经过便可
提示运行的应用在 http://localhost:8080
访问url,效果以下:
. ├── build/ # webpack 配置文件 │ └── ... ├── config/ │ ├── index.js # 主项目配置 │ └── ... ├── src/ │ ├── main.js # app 入口文件 │ ├── App.vue # 主应用程序组件 │ ├── components/ # ui组件 │ │ └── ... │ └── assets/ # 模块资产(由webpack处理) │ └── ... ├── static/ # 纯静态资产(直接复制) ├── test/ │ └── unit/ # 单元测试 │ │ ├── specs/ # 测试规范文件 │ │ ├── eslintrc # eslint的配置文件,仅用于单元测试的额外设置 │ │ ├── index.js # 测试构建入口文件 │ │ ├── jest.conf.js # 使用Jest进行单元测试时的配置文件 │ │ └── karma.conf.js # 使用Karma进行单元测试时测试运行器配置文件 │ │ ├── setup.js # 在Jest运行单元测试以前运行的文件 │ └── e2e/ # e2e测试 │ │ ├── specs/ # 测试规范文件 │ │ ├── custom-assertions/ # e2e测试的自定义断言 │ │ ├── runner.js # 测试运行脚本 │ │ └── nightwatch.conf.js # 测试运行器配置文件 ├── .babelrc # babel 配置 ├── .editorconfig # 缩进,空格/制表符和编辑器的相似设置 ├── .eslintrc.js # eslint 配置 ├── .eslintignore # eslint 忽略规则 ├── .gitignore # 默认的忽略设置 ├── .postcssrc.js # postcss 配置 ├── index.html # index.html 模板 ├── package.json # 构建脚本和依赖项 └── README.md # 默认 README 文件
主要几个文件说明:
build/
此目录包含开发服务器和生产webpack构建的实际配置。一般,您不须要触摸这些文件,除非您想要自定义Webpack加载器,在这种状况下您应该查看build/webpack.base.conf.js
。
config/index.js
这是主要配置文件,它公开了构建设置的一些最多见的配置选项。有关详细信息,请参阅开发期间的API代理和与后端框架集成。
src/
这是您的大多数应用程序代码所在的位置。如何构建此目录中的全部内容在很大程度上取决于您; 若是您使用的是Vuex,则能够参考Vuex应用程序的建议。
static/
此目录是您不但愿使用Webpack处理的静态资产的转义窗口。它们将直接复制到生成webpack构建资产的同一目录中。
有关详细信息,请参阅处理静态资产。
test/unit
包含单元测试相关文件。有关详细信息,请参阅单元测试
test/e2e
包含e2e测试相关文件。有关更多详细信息,请参阅端到端测试。
index.html
这是咱们单页面应用程序的模板 index.html
。在开发和构建期间,Webpack将生成资产,这些生成的资产的URL将自动注入此模板以呈现最终的HTML。
package.json
包含全部构建依赖项和构建命令的NPM包元文件。
全部构建命令都经过NPM脚本执行。
npm run dev
启动Node.js本地开发服务器。有关详细信息,请参阅开发期间的API代理。
vue-loader
用于单个文件Vue组件。npm run build
为生产创建资产。有关更多详细信息,请参阅与后端框架集成。
index.html
使用适当的URL自动生成生产,以生成这些生成的资产。npm run unit
npm run e2e
使用Nightwatch运行端到端测试。有关更多详细信息,请参阅端到端测试。
npm run lint
运行eslint并报告代码中的任何linting错误。请参阅Linter配置
先中止vue项目
安装bootstrap,执行版本为3.3.7。-D表示当前项目安装
E:\python_script\Vue\vue-cli_demo\mysite>npm install bootstrap@3.3.7 -D
再开启vue项目
E:\python_script\Vue\vue-cli_demo\mysite>npm run dev
查看package.json,搜索bootstrap
它会自动增长一行
进入node_modules目录,里面有一个bootstrap文件夹
进入mysite\src,这里面才是咱们须要编辑的文件
文件说明:
main.js # app 入口文件 App.vue # 主应用程序组件 components/ # ui组件 assets/ # 模块资产(由webpack处理)
查看App.vue文件内容,它由3部分组成
<template></template> html代码 <script></script> js代码 <style></style> css代码
修改App.vue,导入bootstrap的css文件
<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> <img src="./assets/logo.png"> <router-view/> </div> </template> <script> //导入bootstrap import 'bootstrap/dist/css/bootstrap.min.css' export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; /*margin-top: 60px;*/ } </style>
查看网页,效果以下:
注意:修改代码时,网页会自动加载,不须要刷新页面!
做业:
使用vue-cli,实现下面的效果:
修改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 class="container-fluid text-left"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="row clearfix"> <div class="panel panel-info"> <div class="panel-heading"> <h3 class="panel-title"> 个人笔记 </h3> </div> <div class="panel-body"> <div class="col-md-2 column"> <ul class="list-group"> <li class="list-group-item"> 个人笔记1 <span class="glyphicon glyphicon-trash pull-right"></span> <span class="glyphicon glyphicon-pencil pull-right" style="margin-right: 15px"></span> </li> <li class="list-group-item"> 个人笔记2 <span class="glyphicon glyphicon-trash pull-right"></span> <span class="glyphicon glyphicon-pencil pull-right" style="margin-right: 15px"></span> </li> <li class="list-group-item"> 测试测试1 <span class="glyphicon glyphicon-trash pull-right"></span> <span class="glyphicon glyphicon-pencil pull-right" style="margin-right: 15px"></span> </li> <li class="list-group-item"> 测试测试2 <span class="glyphicon glyphicon-trash pull-right"></span> <span class="glyphicon glyphicon-pencil pull-right" style="margin-right: 15px"></span> </li> </ul> </div> <div class="col-md-5 column"> <form> <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> <div style="height: 20px"></div> <textarea class="form-control" style="width: 100%;height: 600px;" placeholder="Textarea"></textarea> </form> </div> <div class="col-md-5 column"> <button type="button" class="btn btn-default btn-success">添加</button> <div style="height: 20px"></div> <div style="border: #C1C1C1 solid 1px;height: 600px"> </div> </div> </div> <!--<div class="panel-footer">--> <!--Panel footer--> <!--</div>--> </div> </div> </div> </div> </div> <!--<img src="./assets/logo.png">--> <!--<router-view/>--> </div> </template> <script> //导入bootstrap import 'bootstrap/dist/css/bootstrap.min.css' export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; /*margin-top: 60px;*/ } </style>
访问网页,效果以下: