• [ Flask ] myblog_flask问题集(RESTfull风格)


    VUE问题


    • 前端VUE怎么捕获所有404NOT FOUND的路由呢?

    [ 解决方案 ] vue-router路由守卫,参考文档:动态路由匹配

     

    • 对于路由.../edit/<id>,自己能编辑自己的资料,不允许通过修改路由来编辑他人资料。如何实现呢?

     [ 描述 ] 试图处于个人资料修改页面,用户可能通过修改url的值来跳转到他人的资料修改页,这个行为应该制止。

     [ 解决方案1 ] 我是通过导航守卫 beforeRouteUpdate 来实现的,每次路由变化的时候判定to是自己的id还是他人的id,如果是他人的则阻止跳转。(或者不要判定,直接阻止)

    beforeRouteUpdate(to,from,next){
        if( 判定逻辑 ){
        next(false)
      } }

     

    • 对于路由.../user/<id>,作用是获取单个user信息,修改url访问不存在的用户会返回404的status,怎么实现的呢?

    [ 后端实现 ]

    #获取失败返回404
    @bp.route('/users/<int:id>',methods=['GET'])
    @token_auth.login_required
    def get_user(id):
        #返回一个用户
        #get_or_404()是根据primary_key来返回结果
        return jsonify(User.query.get_or_404(id).to_dict(include_email=True))

    [ 前端实现 ]

    前端通过axios拦截全局response,判断状态码来实现,核心代码如下

    axios.interceptors.response.use(function(response){
        return response
    },function(error){
        switch (error.response.status){
            case 404:
                Vue.toasted.error('404:NOT FOUND')
                router.back()
                break;
        }
        return Promise.reject(error)
    })
    • 我傻掉了,表单控件输入绑定居然用v-bind,其实VUE有更智能的v-model,详见文档。。。

    。。。

     

    • 问题:vue router什么时候是 route,什么时候是 router,呕

      • 访问路由数据的时候用 route,比如:this.$route.params.xxx
      • 路由方法的时候是 router,比如:this.$router.push()

     

    • 包含Header、Aside、Footer的布局如何写成单页的呢?

    [ 我的解决方案 ] 嵌套路由解决

    [ Layout ]

    <template>
      <a-layout id="top-layout">
        <a-layout-sider>siderbar</a-layout-sider>
    
        <a-layout>
          <a-layout-header>Header</a-layout-header>
          <!-- content入口 -->
          <router-view ></router-view>
        </a-layout>
      </a-layout>
    </template>

    [ 路由 ]

    routes:[
      {
        path:'/',
        components:()=>import('@/layout/index'), //Layout:包含head、sidebar、content
        children:[
          {
            path:'/a',
            components:'a' //想要展示在content里面的子组件a
          },{
            path:'/b',
            components:'b' //想要展示在content里面的子组件a
          }
        ]
      }
    ]

     

    • 今天写axios.get()请求的时候一直报跨域错误,如图:

    [ 描述 ]

    [ 代码 ]

    _getUserFollowers(id){
        let page = 1
        let per_page = 5
        const path = `/users/${id}/followers`
    const path = `/users/${id}/followers/`
    let payload = { page:page, per_page:per_page } this.$axios.get(path,{ params:payload }).then(res=>{ console.log(res) this.followeds = res.data }).catch(e=>{ console.error(e) }) }

    [ 原因分析 ]

      • 这样请求就会报错:http://localhost:5000/api/users/1/followers?page=1&per_page=5
      • 这样请求没问题:http://localhost:5000/api/users/1/followers/?page=1&per_page=5

    差别就是个 / 

    目前正在分析中。。。

     

    • 前端列表结构,我在文档载入完成后监听列表元素的点击,JQuery怎么判断点击了某个元素呢?(我想要表达啥?)

      [ 解决方案 ] this,用this。$(this)

     

    • VUE的路由如何去掉 "#" ?

      [ 解决方案 ] 用vue-router的history模式

    • vue-markdown插件用来展示Markdown会有xss攻击的风险,如何解决?

     [ 描述 ]

    [ 解决方案 ] 

    看了一下文档,加上html属性就好

     <vue-markdown :source="child.body" class="mb-2" :html="false"></vue-markdown> 

    但是这样会导致@用户功能失效,会把源码显示出来。。。

    • 评论系统中,编辑回复的内容,会把@某某某的源码显示出来,怎么解决呢?

    [ 描述 ]

    [ 解决方案 ]

    。。。

    • 前端在NavBar中显示消息提醒计数,使用setInterval来保持请求,这会占用很大的资源,如何优化呢?

    [ 问题描述 ]

    登出了也还会保持setInterval

    [ 我的思路 ]

    参照一些前端框架下的弹出框组件,该组件一般都会提供dispose()方法。去看看源码是怎么写的,每次登出的时候注销提醒控件,登录的时候加载提醒控件。

     

    • 如何实现页面强制刷新(局部刷新,只刷新组件)?

    [ 问题描述 ]

    VUE中如果路由不变,该组件是不会重新加载的。如何实现每次点击通知按钮,该组件重新刷新?

    [ 解决方案 ]

    使用v-if指令,点击通知按钮后让相关的 router-view 设置为 false,之后再设置为 true。

    因为导航栏和通知组件不在同一层面,所以我设置了一个全局变量来实现。

    详细参考:https://www.jianshu.com/p/1a60557b74c1

     

    • 前端页面在每次后退和前进的时候都会重新请求后端,如何做缓存来提升访问速度呢?

    [ 解决方案 ] 尝试使用vue-router的keep-alive。详见文档。

     

     

     

     

    FLASK/SQLALCHEMY问题


    • 惨痛的教训,url_for端点记得要写斜杠 "/"

    • 个人信息页面,有个注册时间,表明在什么时候注册的。这个是在后台哪里定义的呢?

    沙雕了,后台数据库定义了默认值的。。。

    [ 前端页面效果 ]

    [ 后端数据库设计 ]

    class User(PaginatedAPIMixin, db.Model):
        id = db.Column(db.Integer,primary_key=True)
       ...
       ...
    member_since = db.Column(db.DateTime(), default=datetime.utcnow) #这里定义default值为当前时间 last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
    • 为了实现无限评论/回复,后台提供给前端的数据格式应该是什么样的呢?

    [ 效果预览 ]

    [ 前端接收到的数据格式 ]

    items:[
      {
        body:'',  //顶层评论
        descendants:[{ //子孙评论,平级的显示在顶层评论下面
          body:'',
          parent_id:''
        }]
      },
    ]
    • 后台给前端的json里面不包含父评论的用户名,所以前端显示的时候不能实现这样的效果 -> xxx 评论了 xxx , 如何解决?

      [ 解决方案 ]

    既然前端显示的时候实现不了,那么就在回复评论的时候吧 “xxx 评论了 xxx” 给加到评论内容里面去,写进数据库。

    * 记得前端用vue-markdown来显示,不然带连接的名字会把源码显示出来

     

    • 评论系统如何实现子评论分页?

    • 写点赞功能的时候一直报错,如何解决?

    [ 描述 ]

    sqlalchemy.orm.exc.UnmappedColumnError: Can't execute sync rule for source column 'comments.id'; 
    mapper 'mapped class User->users' does not map this column.  
    Try using an explicit `foreign_keys` collection which does not include destination column 'comments_likes.comment_id' (or use a viewonly=True relation).

    [ 解决方案 ]

    参考如下代码,定义在Comment下的likers:

    likers = db.relationship(
        'User',
      
        secondary=comments_likes,
        #点赞是User和Comment之间多对多的关系,而不是自我引用,所以不需要写primaryjoin和secondaryjoin!
        # primaryjoin=(comments_likes.c.user_id == self.post.author_id)
        # secondaryjoin=(comments_likes.c.comment_id == id),
        backref=db.backref('liked_comments',lazy='dynamic')
    )

    [ 原因分析 ]

    User和Comment之间多对多的关系,不是自我引用,不用写primaryjoin和secondaryjoin

    • 如何实现点赞功能999+,大量点赞数据如何优化呢?

    • 网站部署到服务器上之后,刷新博客详情页面会发生404错误(前端路由采用history模式),如何解决?

    [ 解决方案 ]

    详见vue-router文档(https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90

    配置好nginx即可

    nginx

    location / {
      try_files $uri $uri/ /index.html;
    }

    •  sqlalchemy 一对多关系中,例如 User (1) ------ (N) Article。创建文章是给外键赋值还是给反向引用赋值呢?(这里是模糊描述,具体看项目中)

    • 私信功能,如何实现聊天数据分页加载呢?

    [ 描述 ]

    私信按照 1-2-3-4-5 的顺序读取,我需要这样进行分页加载:4-5,2-3,1

    即初始加载最新的消息,往上滚动加载历史消息。

     

  • 相关阅读:
    js搜索输入关键词
    pc端,自适应屏幕分辨率
    js获取锚点名称 #
    yourphp读取分类名称{$Categorys[$r[catid]]['catname']}
    收缩菜单 css变样
    ajax成功跨域_自己写的
    json 是个什么东西?
    json_encode详解,转义
    跨域代码 手机号码
    php json_decode
  • 原文地址:https://www.cnblogs.com/remly/p/11956355.html
Copyright © 2020-2023  润新知