🖼️ Vue 页面用法

ThinkAdmin 的后台静态插件内置了 Vue2 与 vue.sortable 的 RequireJS 映射。项目没有提供全局 Vue 组件库,实际业务页面通常在当前模板中按需 require(['vue']),再注册页面级组件或创建 Vue 实例。

🚀 主要功能

  • Vue 引入: admin.jsvue 映射到 plugs/vue/vue.min
  • 拖拽组件: vue.sortable 依赖 vuesortablejs
  • 页面实例: 业务模板通过 new Vue({ el: '...' }) 管理局部交互
  • 局部组件: 组件由页面自行注册,例如商品规格页的 UploadImage
  • 后台联动: 可继续使用 LayUI、jQuery 插件、$.form$.msg 等后台工具

📋 内置映射

admin.js 中已配置以下与 Vue 相关的 RequireJS 路径:

paths: {
    vue: ['plugs/vue/vue.min'],
    sortablejs: ['plugs/sortable/sortable.min'],
    'vue.sortable': ['plugs/sortable/vue.draggable.min']
},
shim: {
    'vue.sortable': {deps: ['vue', 'sortablejs']}
}

因此,在已继承后台模板并加载 admin.js 的页面中,可以直接使用:

require(['vue'], function (Vue) {
    new Vue({
        el: '#VueData',
        data: {items: []}
    });
});

页面实例

{extend name="../../admin/view/main"}

{block name='content'}
<div id="VueData">
    <input class="layui-input" v-model="form.name" lay-ignore>
    <button class="layui-btn" type="button" @click="submit">保存</button>
</div>
{/block}

{block name='script'}
<script>
    require(['vue'], function (Vue) {
        new Vue({
            el: '#VueData',
            data: {form: {name: ''}},
            methods: {
                submit: function () {
                    $.form.load('{:url("save")}', this.form, 'post');
                }
            }
        });
    });
</script>
{/block}

被 Vue 管理的原生表单控件建议加上 lay-ignore,避免 LayUI 表单渲染接管控件状态。需要提交到 ThinkAdmin 后端时,可以继续调用 $.form.load(),或把 Vue 负责的字段同步到普通表单再交给 data-auto="true"

局部组件

业务页面可以在当前 require(['vue']) 回调内注册组件。微商城商品规格页中的图片组件就是这种局部注册方式:

require(['md5', 'vue', 'ckeditor'], function (md5, Vue) {
    Vue.component('UploadImage', {
        data: () => ({eid: Math.random().toString().replace('0.', 'up')}),
        model: {prop: 'mvalue', event: 'change'},
        props: {mvalue: {type: String, default: ''}},
        template: '<input class="layui-hide" v-model="mvalue" :id="eid" readonly>',
        mounted: function () {
            this.$nextTick(() => {
                $('#' + this.eid).uploadOneImage().on('change', e => {
                    this.$emit('change', e.target.value);
                });
            });
        }
    });
});

模板中按 Vue 组件使用:

<upload-image v-model.trim="item.v.image"></upload-image>

拖拽排序

商城装修页使用 vue.sortable 提供的 vuedraggable

require(['vue', 'validate', 'vue.sortable'], function (Vue, Validate, Sortable) {
    new Vue({
        el: '#TemplateApp',
        components: {draggable: Sortable},
        data: function () {
            return {items: []};
        }
    });
});
<draggable v-model="items" v-bind="{group:'items', animation:200}">
    <!-- 拖拽内容 -->
</draggable>

后端处理 base64 图片

<?php
declare(strict_types=1);

namespace app\admin\controller;

use think\admin\Controller;
use think\admin\Storage;

/**
 * 示例控制器
 * @class Example
 * @package app\admin\controller
 */
class Example extends Controller
{
    /**
     * 保存内容(处理 base64 图片)
     * @auth true
     */
    public function save()
    {
        $content = input('content');

        // 抓取内容的 base64 图片并上传到云端
        $content = preg_replace_callback(
            '/"data:image\/([a-zA-Z]+);base64,(.*)"/',
            function ($matches) {
                // 保存 base64 图片到云存储
                $result = Storage::saveImage(trim($matches[0], '"'));
                return '"' . $result['url'] . '"';
            },
            $content
        );

        // 保存处理后的内容
        // ...

        $this->success('保存成功');
    }
}
最近更新:
Contributors: 邹景立, Anyon