上次我们学习了Vue.js的基础,并且通过综合的小实例进一步的熟悉了Vue.js的基础应用。今天我们就继续讲讲Vue.js的组件,更加深入的了解Vue,js的使用。首先我们先了解一下什么是Vue.js的组件,组件其实就是页面组成的一部分,它是一个具有独立的逻辑和功能或页面,组件可以扩展 HTML 元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树,如下图:
接下来我们就仔细讲讲组件的使用吧。
1 全局组件 |
以下就是我们注册的第一个简单的全局组件my-Com。所有实例都能用全局组件,组件在注册之后,便可以作为自定义元素
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <my-Com></my-Com>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script type="text/javascript">
- // 注册
- Vue.component('myCom', {
- template: '<h1>自定义组件!</h1>'
- })
- // 创建根实例
- new Vue({
- el: '#app'
- })
- </script>
- </html>
2 局部组件 |
以下就是我们注册的第一个简单的局部组件。其实可以不必把每个组件都注册到全局的,局部组件可以直接在vue实例里,使用components注册,这种封装也适用于其它可注册的 Vue 功能,比如指令。我们建议将模板定义在全局变量。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <mycom></mycom>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script type="text/javascript">
- var Child = {
- template: '<h1>自定义组件!</h1>'
- }
- // 创建根实例
- new Vue({
- el: '#app',
- components: {
- // mycom 将只在父模板可用
- 'mycom': Child
- }
- })
- </script>
- </html>
3 使用Prop传递数据 |
组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件 A 在它的模板中使用了组件 B。在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。组件实例的作用域是孤立的。这意味着不可以 在子组件的模板内直接引用父组件的数据。prop 是父组件用来传递数据的一个自定义属性。父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop"。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <com message="hello!"></com>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script type="text/javascript">
- // 注册
- Vue.component('com', {
- // 声明 props
- props: ['message'],
- template: '<span>{{ message }}</span>'
- })
- // 创建根实例
- new Vue({
- el: '#app'
- })
- </script>
- </html>
4 动态Prop |
动态Prop 类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <div>
- <input v-model="parent">
- <br>
- <child v-bind:message="parent"></child>
- </div>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script type="text/javascript">
- // 注册
- Vue.component('child', {
- // 声明 props
- props: ['message'],
- template: '<span>{{ message }}</span>'
- })
- // 创建根实例
- new Vue({
- el: '#app',
- data: {
- parent: '父组件内容'
- }
- })
- </script>
- </html>
当然我们也能可以使用
的缩写语法:
- v-bind
- 1 < child: my - message = "parentMsg" > </child>/
以下实例中将 v-bind 指令将com传到每一个重复的组件中。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <ol>
- <item v-for="item in sites" v-bind:com="item"></item>
- </ol>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script type="text/javascript">
- Vue.component('item', {
- props: ['com'],
- template: '<li>{{ com.text }}</li>'
- })
- new Vue({
- el: '#app',
- data: {
- sites: [
- { text: 'Vue.js' },
- { text: 'BootStrap' },
- { text: 'JQuery' }
- ]
- }
- })
- </script>
- </html>
注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。但是,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着不可以在子组件内部改变 prop。如果这么做了的话,Vue 会在控制台出现警告。
5 使用 v-on 绑定自定义事件 |
父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口,即:
监听事件
- $on(eventName)
触发事件
- $emit(eventName)
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <div id="example">
- <p>{{ num }}</p>
- <button-counter v-on:vue="com"></button-counter>
- </div>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script type="text/javascript">
- Vue.component('button-counter', {
- template: '<button v-on:click="vue">{{ counter }}</button>',
- data: function () {
- return {
- counter: 0
- }
- },
- methods: {
- vue: function () {
- this.counter += 1
- this.$emit('vue')
- }
- },
- })
- new Vue({
- el: '#example',
- data: {
- num: 0
- },
- methods: {
- com: function () {
- this.num += 1
- }
- }
- })
- </script>
- </html>
6 给组件绑定原生事件 |
如果想在某个组件的根元素上监听一个原生事件。可以使用
的修饰符
- v-on
。
- .native
- 1 < comv - on: click.native = "something" > </com>/
7 自定义指令 |
默认情况下,一个组件的
会使用
- v-model
prop 和
- value
事件。Vue 也允许注册自定义指令。
- input
以下例子就是我们注册的一个全局指令 v-focus, 该指令的功能就是在页面加载时,元素会自动获得焦点。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <p>页面载入时,input 元素会自动获取焦点:</p>
- <input v-focus>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script type="text/javascript">
- Vue.directive('focus', {
- inserted: function (el) {
- // 聚焦元素
- el.focus()
- }
- })
- // 创建根实例
- new Vue({
- el: '#app'
- })
- </script>
- </html>
8 Vue 路由实例应用 |
Vue框架的兼容性非常好,可以很好的跟其他第三方的路由框架进行结合。Vue官方给出了路由的方案 ---
- vue-router。下面我们就使用Vue的路由实现简单的单页应用。
- <script type="text/javascript" src="js/vue.js" ></script>
- <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
使用 router-link 组件来导航.,通过传入 `to` 属性指定链接,<router-link> 默认会被渲染成一个 `<a>` 标签。
- <router-link to="/Vue">路由</router-link>
- <router-link to="/BootStrap">栅格</router-link>
定义(路由)组件,可以从其他文件 import 进来。
- const Foo = {
- template: '<div>Vue</div>'
- }
- const Bar = {
- template: '<div>BootStrap</div>'
- }
定义路由,每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,或者只是一个组件配置对象。
- const routes = [{
- path: '/Vue',
- component: Foo
- },
- {
- path: '/BootStrap',
- component: Bar
- }
- ]
- const router = new VueRouter({
- routes
- })
要通过 router 配置参数注入路由,从而让整个应用都有路由功能。
- const app = new Vue({
- router
- }).$mount('#app')
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <h1>Vue 路由实例</h1>
- <p>
- <router-link to="/Vue">路由</router-link>
- <router-link to="/BootStrap">栅格</router-link>
- </p>
- <!-- 路由出口 -->
- <!-- 路由匹配到的组件将渲染在这里 -->
- <router-view></router-view>
- </div>
- </body>
- <script type="text/javascript" src="js/vue.js" ></script>
- <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
- <script type="text/javascript">
- const Foo = {
- template: '<div>Vue</div>'
- }
- const Bar = {
- template: '<div>BootStrap</div>'
- }
- const routes = [{
- path: '/Vue',
- component: Foo
- },
- {
- path: '/BootStrap',
- component: Bar
- }
- ]
- const router = new VueRouter({
- routes
- })
- const app = new Vue({
- router
- }).$mount('#app')
- </script>
- </html>
9 综合实例应用 |
上边已经了解了Vue路由,下边就是一个小小的综合实例,通过点击按钮,在当前页面切换不同的组件。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>综合实例</title>
- <script src="https://unpkg.com/vue/dist/vue.js"></script>
- <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
- <style>
- ul,
- li {
- list-style: none;
- }
- ul {
- overflow: hidden;
- }
- li {
- float: left;
- width: 100px;
- }
- h1 {
- background-color: #98D361;
- }
- h2 {
- background-color: #FF9209;
- }
- h3 {
- background-color: #D84C29;
- }
- </style>
- </head>
- <body>
- <div id="app">
- <bar> </bar>
- <hr>
- <p>buttons: {{ buttons }}</p>
- <router-view class="items"></router-view>
- <footer-bar></footer-bar>
- </div>
- <script>
- var topbarTemp = `
- <nav>
- <ul>
- <li v-for="item in list">
- <router-link :to="item.url">{{ item.name }}</router-link>
- </li>
- </ul>
- </nav>
- `;
- // 定义组件:topbar
- Vue.component('bar', {
- template: topbarTemp,
- data: function() {
- return {
- list: [{
- name: '小说',
- url: '/story'
- },
- {
- name: '动漫',
- url: '/carton'
- },
- {
- name: '绘画',
- url: '/draw'
- },
- ]
- }
- }
- });
- Vue.component('footer-bar', {
- template: `
- <footer>
- <p>Vue 路由<p>
- </footer>
- `
- });
- var story = {
- template: `<div> <h1>{{ msg }}<h1></div>`,
- data: function() {
- return {
- msg: 'Vue 基础'
- }
- }
- };
- var carton = {
- template: `<div> <h2>{{ msg }}<h2></div>`,
- data: function() {
- return {
- msg: 'Vue 组件'
- }
- }
- }
- var draw = {
- template: `<div> <h3>{{ msg }}<h3></div>`,
- data: function() {
- return {
- msg: 'Vue 路由实例'
- }
- }
- }
- // 定义路由对象
- var router = new VueRouter({
- routes: [{
- path: '/story',
- component: story
- },
- {
- path: '/carton',
- component: carton
- },
- {
- path: '/draw',
- component: draw
- }
- ]
- });
- // 初始化一个Vue实例
- var app = new Vue({
- el: '#app',
- data: {
- buttons: '点击按钮,切换不同组件'
- },
- router: router
- });
- </script>
- </body>
- </html>
Vue知识还有很多,希望通过对Vue一些基础知识的学习,对于正在学习前端的知识的你可以有所帮助。
来源: http://www.cnblogs.com/lgc-17862800193/p/7817993.html