PVAJP计划:暨关于.Press全站使用VUE-AJAX-JSON-PYTHON的新规划

概论:一个网站必须使用单调视图为前端,单调指的是不直接由Python加载数据库内容。一般地,该单调视图仅包含在浏览器上运行的JS,而该JS(即VUE)负责动态加载数据库内容。

PVAJP的目的是解放全站所有UI互动的可能性,增强网站的互动性和编程自由度,同时减少服务器端内存的压力(因为减少了页面在服务器端提前渲染的过程)。本质上是将小网站推向中上规模网站的必经之路(PVAJP是模仿bilibili而制作的)

PVAJP实现了 “html模板页面”,“vue程序”,“Python数据” 三者的独立(互不影响),在编程上高度解绑,适合多个人同时编写代码的场景。

改造内容:

1.动态bulk改造,包括对动态详情改造

2.Message盒子改造(将点赞/投旗/评论/关注四个分类展示)

3.文章详情改造(主要是评论区)

具体实现

Vue-模块化

将所需的pva.html引入,其会自带.css和.js,而自带的pva.js的data里会引入一个在view.html里穿插的简单script内容的 transferbridge : window.transferbridge(其中包含各种local window 变量,且可用django方法写入变量)。

<script type="text/javascript">
transferbridge = {
	"citizen":{% if citizen %}{{citizen}}{%else%}false{%endif%},
}
</script>
mounted: function(){
  	this.fetchjson(window.transferbridge["x"])
},

Vue-HTML部分

如果对使用变量不确定存在,则保证引用它时不再引用它的下级,它本身的引入会不显示,同时不引起bug。 但下级的使用会造成 父级 undefined 错误。

对于{% verbatim %}则看情况放置。

<div id="Visible" v-show="mainstreamvisible" style="display:none;">

<div v-for="(bulk, index) in bulky">
{% verbatim %}

{% endverbatim %}
</div>
<div class="global_wait" v-show="bulkywait">{% include 'wait.html' %}</div>
<span @click="adds()" v-show="!bulkywait">点击加载更多</span>
</div>
#Visible{
	width: 100%;
	height: auto;
	flex-direction: column;
    align-items: center;
}

Vue-AJAX部分

fetchjson

注意判断combag里是否有空的查询,只允许非空部分进入。 

一般配合bulkywait使用,来完成加载前等待动画(CSS3)。

fetchjson 标准使用:最新内容在上,加载出的古老内容在下面(也即 加载更多按钮 在 内容 的下面) 。

  1. 注意在push之前,combag[i] 可以加入其它与数据源头无关的本地控制信息。比如一个UI开关的 status。
  2. 当然也可以加入combag[i][commebag] 评论包,在点开评论区后写入包内容,这叫附带包。但一开始是空包。直到另一个fetchjson push 加载入包
new Vue({
  el : '#Visible',
  data : {
  	bulky : [],
    bulkywait: true,
    transferbridge : function(){
      if(window.transferbridge){
        return window.transferbridge
      }else{
        return {"a":null,}
      }
    },
  }, 
  watch : {}, 
  methods : {
  	fetchjson : function(range){
      this.bulkywait = true
  		axios.post('',{limit:range}).then(response => {
        var res = response.data
        var combag = Object.assign([], res.combag);
        for (var i = 1; i < combag.length; i++) {
          //预处理
          combag[i]["???bag"] = []
          var tapeui = '/static/pvajp/img/tapeui/v'
          //status转icons
          combag[i]["icons"]['comment'] = tapeui + 'comment.svg'
          combag[i]["icons"]["flag"] = tapeui+'flag.svg'
          combag[i]["icons"]["flaged"] = tapeui+'flaged.svg'
          //推送
          this.bulky.push(combag[i])
          //index = this.bulky.push(combag[i]) - 1
          //得到hostUI的index,在套娃fetch时候有用。
          //例如this.fetchkid(bulkyid,index)
        };
        this.bulkywait = false
        this.from += 10
        this.to += 10
		});
  	},
  }, 
  mounted: function(){
  	this.fetchjson([0,10])
  },
})
fetchjson : function(range){
      this.bulkywait = true
  		axios.post('',{from:range[0],to:range[1]}).then(response => {
        var res = response.data
        var combag = Object.assign([], res.combag);
        for (var i = 1; i < combag.length; i++) {
          //预处理
          combag[i]["xxbag"] = []
          var tapeui = '/static/pvajp/img/tapeui/v'
           //status转icons
          combag[i]["icons"]['comment'] = tapeui + 'comment.svg'
          combag[i]["icons"]["flag"] = tapeui+'flag.svg'
          combag[i]["icons"]["flaged"] = tapeui+'flaged.svg'
          //推送
          this.bulky.push(combag[i])
        };
        this.bulkywait = false
        this.from += 10
        this.to += 10
		});
},

filterText

注意,这仅仅是所有VUE变量在html中被局部地处理的方法中的一种应用场景。 

可以直接filter变量,将所有数据高消耗变形放在浏览器部分,例如inteltime

例子中,filterText是 Vue里的method,而comme.text是变量。

*注意,涉及输出HTML标签的,要放在v-html里当作变量输出。

<span class="text" v-html="filterText(comme.text)"></span>
filterText : function(val){
    return val.replace(/\n/g,'<br/>')
},

 Vue 方法

更新bulk的属性

直接修改属性,不需要Vue.set()而能够直接动态响应修改。

注意:不能新建一个不存在的属性为数组后再定义数组的内部结构。

update : function(bulkyid){
    this.bulky[bulkyid]["xxx"]= ""
}
update : function(bulkyid){
    var pickout = this.bulky[bulkyid]
    pickout["content"]["citizen"]["name"] = "被点击了,来自PVAJP"
}

 两种方式都可以,用PICKOUT变量,可以让代码结构变得简约。

兼容性介绍:电脑端在 SAFARI ,CHROME,EDGE,搜狗浏览器有效。手机端在  SAFARI ,CHROME,夸克浏览器,QQ浏览器,百度APP有效。有效面积广大。

清空bulky 

this.bulky = []

 删除某个bulk

this.bulky.splice(bulkyid,1)

增加一个bulk (ajax请求后在头部添加)

if(res.combag[key]){
  this.bulky.unshift(res.combag[key])
}

 定位 $refs 和 $nextTick

 reftranslate 将index数字转化为更special的字符串名片,例如 1 变为 apple_1。

 [0]是必须的,否则.focus()找不到对象。

this.$refs[this.reftranslate(index)][0].focus()

一般用来做input/textarea的聚焦。

如果需要v-if/v-show展示后聚焦,需要

this.$nextTick(() =>{
    this.$refs[this.reftranslate(index)][0].focus()
})

JSON-PYTHON部分

Status 规范

每一条的bulk数据包将自行携带一些信息,其中包括status属性

(*一般将主要DICT放在 content 内)

bulk 在Vue时候将自行判断Status信息,用来指示用户一些操作。而用户能否使用该操作见Vue-Ajax部分。

#Status 设计
status = {}
if request.session.get('pass_print'): 
	status["pass"] = 1
	#Flagship
	waiter_f = Flagship.objects.filter(aflags=request.session['citizen']['id'], bisflaged=x['belongsto'], what_id=x['id'], what_type=1)
	status["flag"] = 1 if waiter_f else None
	#Likeship
	waiter_l = Likeship.objects.filter(alikes=request.session['citizen']['id'], bisliked=x['belongsto'], what_id=x['id'], what_type=1)
	status["like"] = 1 if waiter_l else None
else:
	status["pass"] = None
	status["flag"] = None
	status["like"] = None

	pass

注意,注入status的地方是count的地方,所以对象是bulk。 

organised[count] = {'status':status,'content':content,...}
<img @click="flagit(index,bulk.content.id)" class="visibleicon" :class="{'red':bulk.status.flag}" />

lazyfetch

一个PVAJP重要特征,惰性加载(有需要才加载,被动)。

lazyfetch是一个类似视图的py文件,但它只会返回JSON数据 count - based DICT。

里面的方法在实现上很独立(不套叠)。

#
def lazy(request):
    load = json.loads(request.body.decode("utf-8"))
    #
    inf = .objects.filter()
	count = 1
	combag = {}
	for i in inf:
		i = model_to_dict(i)
		tem_i =.objects.get(id=i["id"])
		i.update(model_to_dict(tem_i))
		combag[count] = i
		count += 1
	return JsonResponse({"combag":combag})

在urls.py里设定 

from . import lazyfetch
urlpatterns = [
#lazy
	path('lazycomme', lazyfetch.comme),
	path('lazyreply', lazyfetch.reply),
]

JSON只能处理DICT数据,因此Python返回的数据格式必须是 model_to_dict 后的,且不能包含图片对象。 如下法则处理最佳。

summarized = {}
summarized.update(model_to_dict(waiter))
summarized.update(model_to_dict(waitress))
#平庸化
summarized["avatar"] = {}
summarized["avatar"]["url"] = waitress.avatar.url
summarized["bgcover"] = {}
summarized["bgcover"]["url"] = waitress.bgcover.url

 静态URL的处理(在tools类里面),比如 href 和 src。

vars = Capitalvars()
summarized["href"] = vars['GENERAL_CITIZEN_PAGE'] + str(waiter.citizen_id)
<!--例子 1 -->
<a :href="bulk.content.citizen.href" class="link"></a>
<img :src="bulk.content.citizen.avatar.url" />

 需要让URL在Python上处理好,VUE只负责绑定,绑定的时候使用 :src 这样类型

这样是方便不必每次在VUE里重复重写数据。

开发规范

整数规范

models.IntegerField() 分类工作

消息规范

0-comme

(subtype: 0-comment,1-reply)

1-follow

2-like

(subtype: 0-dyna,1-arti,2-comme,3-reply)

3-flag

(subtype: 0-dyna,1-arti)

  • 16
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值