requirejs、vue、vuex、vue-route的结合使用,您认为可行吗?

在五一节之前和一网友讨论前端技术时,对方提到vue、vue-route如果配合requirejs应用。当时的我没有想得很明白,也没能这位网友一个准确的回复,但我许诺于他五一研究后给他一个回复。本是一天的研究却被我搞成了研究了一周,这拖延症。。。

闲话少数,进入正题

一、示例代码说明

代码结构说明:

  1. modules(存放的为组件,主要是模板与Js对象分成两个文件来写)

    1. route:测试子路由的组件
    2. title:就是一个简单的显示文字的组件
  2. app.js:核心类,提供vue的创建、以前modules组件加载的方法等
  3. chart.js:模拟的一个业务模块
  4. index.html:页面文件
  5. layout.css:整体样式文件(测试require加入样式文件)
  6. main.js:requirejs的配置文件(也是入口文件)
    丑陋的效果图:

此示例没有样式,只是为了验证require如何加载一个vue组件,以子路由的动态注入的能力,示例代码下载

二、从.vue文件入手

一个.vue文件可以包含模板、Js类、样式(可以不要)等三块。但我们通过vue的官网可以知道,vue提供了compile对象方法,可以把模板编译成VNode。并且我们通过webpack打包后生成的文件可以看出模板与Js类是混淆在一起了。这也就说明vue的组件就是一个Js对象。如下图所示:

三、requirejs对vue、vuex和vue-route的引入

引入这三个都很容易,并将这三个注入到Vue对象也是相对简单的,难道的是需要解决动态注入向vue-route实例注入路由,以及vuex的动态加入一个数据模块的能力。好在这两点官网都给出了解决方案:

  • vue-route如何动态注入路由
    根据官网帮助文档说明,存在addRoutes方法,向路由实体动态注入路由
  • vuex模块动态注入
    也是根据官网帮助文档提示有registerModule方法实现。
  • 实现的部分代码:
    初始化Vue对象
apt.init = function(){
    this.store = Object.create({
        modules:{}
    });
    this.Vue.use(VueRouter);
    this.Vue.use(Vuex);
    this.router = new VueRouter();
    this.store = new this.Vuex.Store(this.store);
}

首先提供一个init方法,对Vue对象进行一些初始化,也就是把Vuex、vue-route都注入到Vue对象中。在这里我把创建的vuex和vue-route的实例都放到this对象,方便后面提供给组件注册实使用。
创建Vue实例:

apt.createVue = function(){
    this.vue = new this.Vue({
        store: this.store,
        router: this.router,
        computed: {
            childs: function(){
                if(!this.$store.state.router) return null;
                return this.$store.state.router.childs;
            }
        }
    });
    return this.vue;
}

只创建vue对象,没有进行mount。
为其他模块提供的上下文:

apt.createContext = function(){
    return {
        Vue: this.Vue,
        router: this.router,
        $vue: this.vue
    };
}

四、如何通过require加载html和js方式的组件

从项目结构图中可以看出在modules文件夹中定义了两个组件,分别是:routet和title,而他们的模板则是一个html文件。以下是这类组件如何加载的代码:

apt.acquire = function(path){
    var arrayPath;
    if(!this.isArray(path)){
        arrayPath = [path];
    }else{
        arrayPath = path;
    }
    var promise = this.dfd(function(dfd){
        require(arrayPath,function(){
            dfd.resolve(Array.prototype.slice.call(arguments));
        },function(error){
            dfd.reject(error);
        });
    }).promise();
    return promise;
}

apt.createComponent = function(componentName){
    //可以重载,读取.vue的文件
    var path = this.$modulePrefix + componentName,
    html = ‘text!‘ + path + ‘/index.html‘,
    js = path + ‘/index.js‘,
    self = this;
    var promise = this.acquire([html,js]);
    promise.done(function(result){
        var obj = result[1], content = result[0];
        obj.template = content;
        obj.__path__ = path;
        self.$components.push(obj);
    });
    return promise;
}

说明: acquire:提供通过require加载JS或者是html等文件的方法,并返回一个promise,这样就方便调用者使用。 createComponet:会根据调用传入的名称在modules文件夹中找出对应的js和html文件,然后调用acquire加载组件。

五、main.js是这样引用的

提供注册全局组件方法

apt.registerGlobalComponents = function(componentNames){
    var gloadComponet = componentNames, self = this;
    var promises = gloadComponet.map(function(data,index){
        return self.createComponent(data);
    });
    var dfd = this.dfd();
    $.when.apply(null, promises).done(function(){
        var _router = [];
        self.$components.forEach(function(data,index){
            self.Vue.component(data.name, data);
            _router.push({
                path: ‘/‘ + data.name,
                component: data
            });
        });
        self.router.addRoutes(_router); //全局注册都注册为路由
        dfd.resolve(_router);
    });
    return dfd.promise();
}

main.js中的引用

var _app = app.createApp();
_app.registerGlobalComponents([‘title‘, ‘route‘]).done(function(){
    var vue = _app.createVue();
    var cxt = app.getVue().createContext();
    var r = {
        state: {
            childs: []
        },
        mutations: {
            childs: function(state, data){
                state.childs = data;
            }
        },
        actions: {
            childs: function(state, data){
                state.commit(‘childs‘, data);
            }
        }
    }
    vue.$store.registerModule(‘router‘, r);
    vue.$mount(‘#app‘);
});

说明:

  1. 创建App的一个实例;
  2. 注册全局的组件:title、route;
  3. 注册完成后创建vue实例,并且向实例的vuex注入二级路由展示的模块
时间: 2024-10-13 17:32:33

requirejs、vue、vuex、vue-route的结合使用,您认为可行吗?的相关文章

vue+vuex构建单页应用

基本 构建工具: webpack 语言: ES6 分号:行首分号规则(行尾不加分好, [ , ( , / , + , - 开头时在行首加分号) 配套设施: webpack 全家桶, vue 全家桶 项目结构 基本目录结构 api :封装与后端接口交互的操作 common :放置一些 reset.css 之类的 components :组件 entry :项目入口文件 index.js,index.css,index.html filters :过滤器.注:虽然 vue2.0 已经基本废弃(只保留

[Vue + TS] Using Route events inside Vue

vue-router introduces new hooks into the component. In this lesson we’ll show you how to use these new hooks in your class based Vue components in TypeScript. We’ll also go over how we can create and use routes in Vue. Default component: <template>

vuejs学习——vue+vuex+vue-router项目搭建(一)

前言 快年底了却有新公司邀请了我,所以打算把上家公司的学到一下技术做一些总结和分享. 现在vuejs都2.0了,我相信也有很多朋友和我一样实际项目还是选择vue1.0的或者给新手一些参考,不管在选择哪个版本的时候,希望你都熟读了vue+vuex+vue-router的官方文档.下面我们就开始吧. Vue搭建 这里我假设我们的电脑都安装了nodejs,那么我现在开始吧. 我们先新建一个文件(VueProject),通过命令行的方式进入这个文件夹,现在假设我们进入了VueProject文件夹,接下来

【mock.js】后端不来过夜半,闲敲mock落灯花 (附Vue + Vuex + mockjs的简单demo)

mock的由来[假] 赵师秀:南宋时期的一位前端工程师 诗词背景:在一个梅雨纷纷的夜晚,正处于项目编码阶段,书童却带来消息:写后端的李秀才在几个时辰前就赶往临安度假去了,!此时手头仅有一个简单的数据接口文档的赵师秀慨叹一声:"好吧,那还是我自己先模拟一下后端的接口吧" _(:3 」∠)_  再后来,就有了那句千古名句啦~~( 为了表示对赵师秀先生的歉意,文末我将附上原文)   如果我说这就是前后端分离思想和mock.js的由来,你会信么?(?´ω`?) mock的由来[真] 我们在Vu

vue+vuex+router+element ui

1. cnpm install -g vue-cli 项目的main.js引入import Vue from 'vue' 2. 创建项目 vue init webpack +项目名称 3.  cnpm install ----->下载依赖文件 npm run dev ----->运行项目 4.config文件夹,下面的index.js里面修改port端口号 /////////////////////////////////////// 好像vue 在2.0之后自动的就引入了router和vue

vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据

在vue项目中组件间相互传值或者后台获取的数据需要供多个组件使用的情况很多的话,有必要考虑引入vuex来管理这些凌乱的状态,今天这边博文用来记录这一整个的过程,后台api接口是使用webpack-server模拟的接口,这个前面的文章中有提到,需要的可以去翻阅. 整个的流程是在组件的created中提交dispatch,然后通过action调用一个封装好的axios然后再触发mutation来提交状态改变state中的数据,然后在组件的计算属性中获取state的数据并渲染在页面上 首先新需要在项

vue+vuex+axios+echarts画一个动态更新的中国地图

一. 生成项目及安装插件 # 安装vue-cli npm install vue-cli -g # 初始化项目 vue init webpack china-map # 切到目录下 cd china-map # 安装项目依赖 npm install # 安装 vuex npm install vuex --save # 安装 axios npm install axios --save # 安装 ECharts npm install echarts --save 二. 项目结构 ├── ind

Vue Vuex state mutations

Vuex 解决不同组件的数据共享,与数据持久化 1.npm install vuex --save 2.新建store.js 并引入vue vuex ,Vue.use(Vuex) 3.state在vuex中用于存储数据 var state = { count:1 } 4.mutations里放的是方法,主要用于改变state中的数据 var mutations = { incCount(){ ++state.count; } } 5.实例化vuex.Store consta store = ne

vue+vuex实现 counter计数器

vue+vuex实现 counter计数器 框架搭建好过后输入npm run dev的时候不会直接打开浏览器,在config文件夹找到index.js文件夹 把autoOpenBrowser: false改为autoOpenBrowser: true,从新在命令行输入npm run dev,这是就会自动打开浏览器. 如图修改 现在做个简单的demo示例:counter(计数器) 一.文件夹与文件的创建 1.首先要在components文件夹下面创建counter的一个文件夹 2.然后在count

VUE - vuex state的使用

1,安装 进入项目目录,执行 vue add vuex 命令 2,会在src的目录下新增store文件夹 3,打开store文件夹下的index.js  ,  给 state 设定一些数据 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count:0, todos:[ {id:'1', title:'todoItem1',completed: