[Vue+Webpack] - Vue+Webpack开发可复用的单页面富应用教程(组件篇)

资源地址:
https://www.talkingcoder.com/article/6310724958473489215

一、单页面富应用(SPA)和路由

  • 何为SPA:
    在前后端分离的基础上再加一层前端路由
  • 前端路由:
    由前端来维护一个路由规则。
    实现方式2种:
    1、利用url的锚点 #
    2、html5的history模式

二、编写可复用的代码、模块化、组件

把一个页面分成不同的模块,再组装。
模块化 是一种开发模式,组件 就是这种模式的具体实现。
代码复用 :不同项目,不同文件,不同人员都可以使用

三、vue的路由和它的组件化

常见:vue.js+vue-router+webpack

1、组件的构造

vue组件特点:可插拔、独立作用域、观察者模式、完整生命周期

Vue.component( 'child',{ //child为组件的名称
    props: ['msg'],  //从父级通过html特性传递过来的数据,它可以是字符串、数字、布尔、数组、对象,默认是单向的,也可以设置为双向绑定的。props里的参数可以直接通过像this.msg这种方式调用,这与data的里的数据是一样的。
    template: '<span>{{msg}}</span>',  //组件使用的html片段,可以直接是字符串,也可以像'#child'这样标识一个dom节点
    data: function(){
      return  {
        title: 'libra'
      },
    methods: {},
    ready:function() {},  //在组件准备好时的一个回调,一般在这里我们可以使用获取数据、实例化第三方组件、绑定事件等
    beforeDestroy: function() {},//在组件即将被销毁时触发回调,在这里进行销毁自定义的实例、解绑自定义事件、定时器等。
    events:{}
 });

组件格式类似于vue实例,有methods和data,区别就是组件的data通过function返回一个对象。

2、如何使用组件

组件一般由他的父级来显示调用的

<child :msg="msg1"></child>
<child :msg.sync="msg2"></child>
new Vue({
    data: {
        msg1: 'Hello',
        msg2: '你好'
    }
})

上例使用了两次child组件,使用props传递了一个参数msg,并第二个组件的参数是双向绑定的,在双向绑定后,无论修改父级还是子元素的msg,双方的数据和view都会响应到,而单向绑定后,子组件修改是不会影响到父级的。

在渲染完,<child>的内容就会替换为组件template内的字符串了,虽然使用的是同一个child组件,但是两次使用的作用域是独立的,这也是为什么在组件内data要使用function来返回一个对象的原因。

3、父子组件间的通信

  • 在vue中,父子之间的通信主要通过事件来完成,这就是观察者模式。父组件通过Vue内置的broadcast()向下广播事件和传递数据,子组件通过dispatch()向上派发事件和传递数据,双方都可以在events对象内接收自定义事件,并且处理各自的业务逻辑。
  • 使用v-ref来标识组件
<child :msg="msg1" v-ref:child1></child>
<child :msg.sync="msg2" v-ref:child2></child>
new Vue({
    data: {
        msg1: 'Hello,TalkingCoder',
        msg2: '你好,TalkingCoder'
    },
    methods: {
        sendData: function() {
            this.$refs.child1.$emit('set-data', {});
            this.$refs.child2.$emit('set-data', {});
        }
    }
})
通过$refs就可以给指定的组件触发事件了,事实上,通过$refs是可以获取到子组件的整个实例的。
<child :msg="msg1" v-ref:child1 @child-event="handler1"></child>
<child :msg.sync="msg2" v-ref:child2 @child-event="handler2"></child>
new Vue({
    data: {
        msg1: 'Hello,TalkingCoder',
        msg2: '你好,TalkingCoder'
    },
    methods: {
        sendData: function() {
            this.$refs.child1.$emit('set-data', {});
            this.$refs.child2.$emit('set-data', {});
        },
        handler1: function() {
            // ...
        },
        handler2: function() {
            // ...
        }
    }
})
//@xxx或v-bind:xxx绑定自定义事件

4、内容分发slot

使用slot来分发自定义的内容


Paste_Image.png
<div>
    <h1>提示</h1>
    <slot name="content"></slot>
    <span>确定</span>
    <span>取消</span>
</div>
//父组件调用子组件:
<confirm>
    <p slot="content">欢迎来到TalkingCoder</p>
</confirm>
//最终渲染完的内容为:
<div>
    <h1>提示</h1>
    <p>欢迎来到TalkingCoder</p>
    <span>确定</span>
    <span>取消</span>
</div>

5、编写可复用组件

可复用组件要定义一个清晰的公开接口
vue组件API:

  • prop 允许外部环境传递数据给组件
  • 事件 允许组件触发外部环境的action
  • slot 允许外部环境插入内容到组件的视图结构内
<my-component  :foo="baz" :bar="qux" @event-a="doThis"  @event-b="doThat">
  <img slot="icon" src="">
  <p slot="main-text">Hello!</p>
</my-component>

6、路由、组件和组件化

import Vue from 'vue';
import VueRouter from 'vue-router';
import App from 'components/app.vue';
import Env from './config/env';
Vue.use(VueRouter); //安装路由模块
// 开启debug模式
Vue.config.debug = true;
// 路由配置
var router = new VueRouter({
    history: Env != 'production'
});
//设置路由匹配规则
router.map({
    '/index': {    //匹配127.0.0.1:8080/index
        name: 'index',
        component: function (resolve) {
            //在component的回调里使用require()异步按需加载
            require(['./routers/index.vue'], resolve);
        }
    }
});
//vue-router还有一些钩子函数,通俗就是在发生一次路由时某个状态的一些回调,如下
router.beforeEach(function () {   //路由切换开始时调用
    window.scrollTo(0, 0);
});
router.afterEach(function (transition) {  //路由成功切换到激活状态时调用,一般写一些自动导航或自动面包屑的全局工作
console.log(transition);
});
router.redirect({    //重定向
    '*': "/index"   //找不到路由时可以跳转到指定路由
});
router.start(App, '#app');  //app.vue组件挂载到#app内
  • main,js文件,是项目跑起来后第一个执行的js文件。
  • vue-router支持匹配带参数的路由,比如'/user/:id'可以匹配到'/user/123',或者'/user/any/bar'可以匹配到'/user/a/b/bar',:id是参数,any是全匹配,
  • 路径跳转
<a v-link="{path: '/index'}">首页</a>
<!--或者其他标签页可以-->
<p v-link="{path: '/index'}">首页</p>
//在js中跳转:
module.exports = {
    data: function() {return {} },
    methods: {
        go: function() {
            console.log(this.$route);//得到当前路由状态信息
            console.log(this.$router); //
            this.$router.go('/index');
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容