AntDesignVue使用尝鲜
这次更新博客主要是总结上两周干的事情,方便整理一下目前的进度和后续的思路。首先是事情的起源,主要是因为在改写 simpleui 的过程中,总是会有一些不方便自己使用的东西,并且并不是很满意 simpleui 的展示效果,同时想扩展 simpleui 的使用性;后续在改写过程中,自己整理了一套新的解决思路,感觉可以将现代前端的组件化思路带入到 django template 里面来,所以自己重新开了一套 admin 的主题框架,经过两周的编写,越来越深入的感觉不仅可以做一套 admin 的 theme 出来;甚至可以像之前比较流向的 xadmin 一样写一套不同于 django admin 的中后台管理框架,所以应运而生了一个想法,经过两周的尝试,确实可以行得通。不过中间确实遇到了很多问题,需要将这些问题记录一下~
Q: 选择前端渲染还是后端渲染
A: 这个问题真的是个非常困扰人的问题,首先是想使用 django 的框架作为快速开发的后端,但是同时呢也不想舍弃现在前端在页面展示上的技术领先,两者皆不可抛。那么如何结合两者到一起呢? django 的 template 有着当时那个时代领先的 extends 和 include 机制,转念一想其实这一套机制本质上是不是十分相似于现在前端的 component 吗?于是从这里下手,进行尝试和构建~ 具体尝试过程就跳过不谈了,最终通过一种方式实现了这个机制
# 首先声明 a.html 最为我们的目标组件,进行开发
# 在 a.html 中 通过 <script type="x-template">...</script> 进行组件声明
<script type="text/x-template" id="home-iframe-content">
<div :style="contentStyle">
<iframe :src="href" :style="iframeStyle" frameborder="0"></iframe>
</div>
</script>
<script type="text/javascript">
Vue.component('iframe-wrapper', {
delimiters: ['<%', '%>'],
props: {
href: {
type: String,
required: true
},
height: {
type: String,
required: false
},
width: {
default: '100%',
type: String,
required: false
},
overflow: {
default: 'auto',
type: String,
required: false
}
},
template: '#home-iframe-content',
data() {
return {
contentStyle: {
margin: '0',
padding: '0',
borderRadius: '5px',
},
iframeStyle: {
height: this.height,
width: this.width,
overflow: this.overflow
}
}
}
})
</script>
# 之后我们可以在想引用该组件的地方通过 django 的 include 方式进行导入
# 在 b.html 中我们通过如下方式可以使用该组件
{% include 'web/a.html' %}
<script type="text/x-template" id="layout-demo-a">
···
<a-tab-pane v-for="(pane, index) in activePanes" :key="pane.key">
<span slot="tab"><a-icon :type="pane.icon"></a-icon><% pane.name %></span>
<iframe-wrapper :href="pane.content" :height="height"></iframe-wrapper>
</a-tab-pane>
···
</script>
Q: 如何混用 vue 的 template 和 django 的 template
A: 在这里目前只遇到了一种情况下的两者语法重复的问题,在 django 中对于 render 中的 context 取值是通过 双大括号进行的
{{ }}
但这同时也是 vue 的取值方式,这里我们可以通过对 vue 的声明进行修改
delimiters: ['<%', '%>']
将 vue 的取值方式改为 尖括号和百分号结合的方式,此外还有一种方式,就是在 django 自带的 tags 中包含了
openvariable => {{ 和 closevariable => }}
两种声明方式,这样我们可以在 django render template 之后在 vue 通过浏览器渲染数据时依然可以取到 双大括号的取值符号。
Q: 如何通过 extends 方法扩展 vue 全局的 instance
A: 我们通过在 base.html 中声明根 div 中声明了 vue 实例,但是通过 extends 方式继承了 base.html 页面之后,每个页面都需要声明不同的 data methods 和 vue 的其他属性方式,但是我们不能够将这些代码统统放到 base.html 页面里面,这样的话,势必造成内容的混乱。我们可以通过 vue 的 mixin 方式进行属性值的混入,我们在 base.html 中申明一个 vue 实例,混入一个 mixins 的对象,然后将独享绑定到 window 实例里面,这样我们就可以在继承 base.html 之后,通过 django render 的过程中生成所需要的 mixins 属性,增加到 windows.mixins 里面,这样在 后续 vue 实例运行时,就可以取到我们的实例属性了。
Q: 如何需改 django forms widgets 达到修改 django forms render 样式更改
A: 当我们实现了上述的三种方式之后,我们可以合理构建我们的 django 和 vue 的’混合体生物’了,但是还是无法渲染 django forms 的展示方式和内容,毕竟有点格格不入,相当不协调,配上我们的 ant design vue,所以我们需要修改 django forms widgets 来达到渲染我们需要的 vue 组件的问题,还好是最基础的组件和组织形式,所以比较容易实现~ 在 django 的 settings 里面添加如下内容就行了
INSTALLED_APPS = [
'django.forms',
...
]
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
# 并且在 django 的 templates 项目中创建 widgets 文件夹就行了,目录结构同 django forms 的
附:粘贴上几张正在做的 django admin 框架的 贴图
Dashboard 页面 Models 内容页
PS: 这个 框架开在开发阶段 后续会在 钟馗沙箱中作为展示前端使用 并且后续也将开源 名字暂定 django-vue-admin