原创 vuejs 无node单页应用方案一(vue标签component ,is实现、vuejs without node signel page application)

分类:js,vuejs2017-06-19 23:04:55   692人阅读  评论   分享


前言

之前用angularjs写单页应用可以无需node处理,再加上酱油君是个后台开发,不想搞两套项目,于是开始了伤心的折腾之旅。

above all,惯性致死徒增伤亡。


系列文章目录

1、vuejs 无node单页应用方案一(vue标签component ,is实现)

2、vuejs 无node单页应用方案二(babel-standalone or traceur,vue-router实现


单页切换原理

1、通过以下标签动态切换组件

<component v-bind:is="currentView"><!-- 组件在 vm.currentview 变化时改变! --></component>


2、组件通过loadComponent(自定义方法)动态加载

function loadComponent(name,url){
        var result = null;
        console.log(new Date());
        $.ajax({
            type: "GET",
            url: url,
            async:false,
            dataType:'text',
            success(data) {
                var arr = [];
                arr = data.split('/*###*/');
                var template = arr[0];
                result = arr[1];
                result = result.replace('<script>','').replace('<\/script>','');
                result = eval(result);
                result.template = template;

            },error(){}
        });
        return result;
    }

NOTICE:这里有些优化点

a、组件如何按需加载

b、判断组件是否已创建

c、如何使用实现AMD、Commonjs标准的模块加载器


3、完整代码


topicZone.vue
说明:此处.vue文件和官网标准格式略有不同,但解析.vue文件生成component的算法完全自定义,所以完全可以使用和官网一样的格式
<el-table :data="tableData" style="width: 100%">
    <el-table-column prop="date" label="日期" width="180">
    </el-table-column>
    <el-table-column prop="name" label="姓名" width="180">
    </el-table-column>
    <el-table-column prop="address" label="地址">
    </el-table-column>
</el-table>
/*###*/
<script>
    (function(){
        return {
            data() {
                return {
                    tableData: [{
                        date: '2016-05-02',
                        name: 'IT小君',
                        address: '上海市普陀区金沙江路 1518 弄'
                    }, {
                        date: '2016-05-04',
                        name: '王小虎',
                        address: '上海市普陀区金沙江路 1517 弄'
                    }, {
                        date: '2016-05-01',
                        name: '王小虎',
                        address: '上海市普陀区金沙江路 1519 弄'
                    }, {
                        date: '2016-05-03',
                        name: '王小虎',
                        address: '上海市普陀区金沙江路 1516 弄'
                    }]
                }
            },
            mounted:function(){
                console.log('12222');
            }
        };
    })();
</script>


index.html

<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
    <title>IFace</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"/>
    <link rel="stylesheet" type="text/css" href="/style/bootstrap-3.3.7/css/bootstrap.css" />
    <link rel="stylesheet" type="text/css" href="/style/css/font-awesome-4.7.0/css/font-awesome.min.css" />
    <script src="/style/js/jquery.min.js" type="text/javascript"></script>
    <script src="/style/js/common.js" type="text/javascript"></script>
</head>
<body>
<div id="app">
    <el-row>
    <el-col :span="4"><div class="grid-content bg-purple">IFace后台</div></el-col>
    <el-col :span="20">
        <el-menu theme="dark" :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
            <el-menu-item index="1">处理中心</el-menu-item>
            <el-submenu index="2">
                <template slot="title">我的工作台</template>
                <el-menu-item index="2-1">选项1</el-menu-item>
                <el-menu-item index="2-2">选项2</el-menu-item>
                <el-menu-item index="2-3">选项3</el-menu-item>
            </el-submenu>
            <el-menu-item index="3"><a href="#" target="_blank">订单管理</a></el-menu-item>
        </el-menu>
    </el-col>
    </el-row>
    <el-row>
        <el-col :span="4">
            <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose">
                <el-submenu index="1">
                    <template slot="title"><i class="el-icon-message"></i>导航一</template>
                    <el-menu-item-group>
                        <template slot="title">分组一</template>
                        <el-menu-item index="1-1">选项1</el-menu-item>
                        <el-menu-item index="1-2">选项2</el-menu-item>
                    </el-menu-item-group>
                    <el-menu-item-group title="分组2">
                        <el-menu-item index="1-3">选项3</el-menu-item>
                    </el-menu-item-group>
                    <el-submenu index="1-4">
                        <template slot="title">选项4</template>
                        <el-menu-item index="1-4-1">选项1</el-menu-item>
                    </el-submenu>
                </el-submenu>
                <el-menu-item index="2"><i class="el-icon-menu"></i>导航二</el-menu-item>
                <el-menu-item index="3"><i class="el-icon-setting"></i>导航三</el-menu-item>
            </el-menu>
        </el-col>
        <el-col :span="20">
            <el-breadcrumb separator="/">
                <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
                <el-breadcrumb-item>活动管理</el-breadcrumb-item>
                <el-breadcrumb-item>活动列表</el-breadcrumb-item>
                <el-breadcrumb-item>活动详情</el-breadcrumb-item>
            </el-breadcrumb>
            <component v-bind:is="currentView"><!-- 组件在 vm.currentview 变化时改变! --></component>
        </el-col>
    </el-row>
</div>
</body>
<link rel="stylesheet" type="text/css" href="/style/css/font-awesome-4.7.0/css/font-awesome.min.css" />
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-default/index.css">
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="/style/js/jquery.min.js" type="text/javascript"></script>
<style>
    body{margin:0px}
</style>
<script>
    var vueApp = new Vue({
        el: '#app',
        data: {
            activeIndex: '1',
            activeIndex2: '1',
            currentView: 'home'
        },components: {
            home: loadComponent('home','backend/components/layout.vue'),
            posts: loadComponent('posts','backend/components/topicZone.vue'),
            archive: { /* ... */ }
        }, methods: {
            handleSelect:function(key, keyPath) {
                console.log(key, keyPath);
            },handleOpen:function(key, keyPath) {
                console.log(key, keyPath);
            },handleClose:function(key, keyPath) {
                console.log(key, keyPath);
            }
        }
    });
    function loadComponent(name,url){
        var result = null;
        console.log(new Date());
        $.ajax({
            type: "GET",
            url: url,
            async:false,
            dataType:'text',
            success(data) {
                var arr = [];
                arr = data.split('/*###*/');
                var template = arr[0];
                result = arr[1];
                result = result.replace('<script>','').replace('<\/script>','');
                result = eval(result);
                result.template = template;

            },error(){}
        });
        return result;
    }
</script>
</html>

献祭结束,请尽情享用

交流加群:391053981

分享到: