• 在django中使用vue.js需要注意的地方


    有接口如下:

      http://127.0.0.1:8000/info/schemes/

      返回json数据:

    [
        {
            "name": "(山上双人标准间)黄山经典二日游(魅力黄山,日出云海,人间仙境,春暖花开)", 
            "day": 2, 
            "night": 1, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/a9836502.jpg", 
            "review_num": 2, 
            "unit_price": 0
        }, 
        {
            "name": "0购物+三环内接!郑州—焦作云台山二日游,含1晚住宿+1早2正餐,无强制消费", 
            "day": 2, 
            "night": 1, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/3a82e902.jpg", 
            "review_num": 1, 
            "unit_price": 329
        }, 
        {
            "name": "岛内酒店上门接>厦门至泉州开元寺+南少林+洛阳桥+西街+天后宫一日游", 
            "day": 1, 
            "night": 0, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/f8106f02.jpg", 
            "review_num": 2, 
            "unit_price": 0
        }, 
        {
            "name": "南宁✈西安兵马俑华清池延安黄帝陵壶口瀑布城墙5日/耳麦自助餐/0购物/接送机", 
            "day": 5, 
            "night": 4, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/93835fbb.jpg", 
            "review_num": 1, 
            "unit_price": 3045
        }, 
        {
            "name": "北京+天津纯玩6日游/餐餐特色/连锁酒店/专车专导/故宫/瓷房子赠升国旗", 
            "day": 6, 
            "night": 5, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/0f.water.jpg", 
            "review_num": 1, 
            "unit_price": 0
        }, 
        {
            "name": "住蒙古包>内蒙古希拉穆仁草原+响沙湾沙漠+成吉思汗陵+呼和浩特市内双飞五日游", 
            "day": 5, 
            "night": 4, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/4b806602.jpg", 
            "review_num": 1, 
            "unit_price": 0
        }, 
        {
            "name": "北京全景高端五星游丨餐餐特色&0购物0自费&24H接送&赠德云社+人民大会堂", 
            "day": 5, 
            "night": 4, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/ca841f56.jpg", 
            "review_num": 1, 
            "unit_price": 0
        }, 
        {
            "name": "机票+含餐>西安兵马俑/华清池/骊山/西岳华山/延安/黄帝陵/壶口瀑布6日", 
            "day": 6, 
            "night": 5, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/93835fbb.jpg", 
            "review_num": 1, 
            "unit_price": 2740
        }, 
        {
            "name": "高铁/动车往返>宁波—温州雁荡山2日游 净名谷+灵岩景区+大龙湫 赏灵峰夜景", 
            "day": 2, 
            "night": 1, 
            "favorites": 0, 
            "score_avg": 4, 
            "photo_url": "/media/images/scenic/7565abdd.jpg", 
            "review_num": 1, 
            "unit_price": 0
        }
    ]

    通过vue去请求这个api,并将数据遍历,生成多个div块模板,并渲染数据,效果图如下:

    api 返回json中有9条记录,所以对应应该生成9个上图的div块,开始动手:

    首先,在html页面上引入js

    <script type="text/javascript" src="{% static 'js/vue.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/axios.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/common.js' %}"></script>
    <script>
    $(document).ready(function () {
      getHotScheme();                             1. 在dom加载完之后执行getHotScheme函数
    });
    </script>

    要用到vue就少不vue.js,Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。

    我们将上面功能的实现写在common.js的getHotScheme中

    相关html如下:

                <div class="GridLex- gap-30-wrappper package-grid-item-wrapper">
    
                    <div class="GridLex-grid-noGutter-equalHeight" id="scheme_app">
    
                        <template v-for="schemeInfo in schemesInfo">
                            <div class="GridLex-col-4_sm-6_xs-12 mb-30">
                                <div class="package-grid-item">
                                    <a href="detail-page.html">
                                        <div class="image">
                                            <img :src="schemeInfo.photo_url" alt="Tour Package"/>
    
                                            <div class="absolute-in-image">
                                                <div class="duration"><span>{{ schemeInfo.day }} 天 {{ schemeInfo.night }} 夜</span></div>
                                            </div>
                                        </div>
                                        <div class="content clearfix">
                                            <h5>{{ schemeInfo.name }}</h5>
    
                                            <div class="rating-wrapper">
                                                <div class="raty-wrapper">
                                                    <div class="star-rating-read-only" v-bind:data-rating-score="schemeInfo.score_avg"></div>
                                                    <span> / {{ schemeInfo.review_num }} 评论</span>
                                                </div>
                                            </div>
                                            <div class="absolute-in-content">
                                                <span class="btn"><i class="fa fa-heart-o"></i></span>
    
                                                <div class="price">¥{{ schemeInfo.unit_price }}</div>
                                            </div>
                                        </div>
                                    </a>
                                </div>
                            </div>
                        </template>
    
                    </div>
    
                </div>

    js:getHotScheme

    function getHotScheme(){
        new Vue({
            el: '#scheme_app',
            data () {
                return {
                schemesInfo: null
                }
            },
            mounted () {
                axios
                .get('/info/schemes')
                .then(response => (this.schemesInfo = response.data))
                .catch(function (error) { // 请求失败处理
                    console.log(error);
                });
            }
        })
    }

    解释一下:

      getHotScheme()在DOM加载后执行,其中创建了vue对象,el表示vue的作用范围,它被绑定到了html中的id为scheme_app的div,data中我们需要使用schemesInfo,初始为null,当axios请求成功之后,schemesInfo的值为api的返回的json

      在html中:

      我们要遍历schemesInfo数据,在需要重复生成的div块外添加 template ,<template v-for="schemeInfo in schemesInfo">````````</template>

      被template标签包含的内容将被生成多份,text部分通过{{}}取数据进行渲染,但是在标签属性中使用数据需要做出修改:比如img标签,指定src时不应该使用<img scr=''{{schemeInfo.photo_url}}''> 这将是无效的,应该改为<img :src="schemeInfo.photo_url"> src前面的:时v-bind的简写,用于属性绑定,当然,你也可以写完整,如<div class="star-rating-read-only" v-bind:data-rating-score="schemeInfo.score_avg"></div>

      现在看似已经完成了,但是实际上我们的数据并没有被渲染到模板上,这是因为vue 取值的方法{{ }}与django的模板语言冲突,vue取值并未生效,其实解决办法至少有三个,可以参考这篇博客:https://blog.csdn.net/jyfu2_12/article/details/79058819

      我还是喜欢第三种:

      将vue相关的html代码块禁用django模板:

      在上述html代码前添加{% verbatim %},尾部添加{% endverbatim %},这样vue就可以生效了,

      但是还有一个问题

           没有被显示出来,原因是类属性为star-rating-read-only的div的js函数需要在数据完成之后加载才能生效

      正好,Vue.js 有一个方法 watch,它可以用来监测Vue实例上的数据变动。

      我们要监听schemesInfo,如果数据变化,说明vue开始渲染,渲染完成DOM将发生变化,在vue中有个Vue.$nextTick(callback),当dom发生变化,更新后执行的回调。

      在这个回调函数中执行star-rating-read-only对应的js函数应该就可以解决这个问题,试一下修改common.js中的代码:

      

    function loadGrade(){
        $('.star-rating-read-only').raty({
            readOnly: true,
            round: {down: .2, full: .6, up: .8},
            half: true,
            space: false,
            score: function () {
                return $(this).attr('data-rating-score');
            }
        });
    }
    
    function getHotScheme(){
        new Vue({
            el: '#scheme_app',
            data () {
                return {
                schemesInfo: null
                }
            },
            watch:{
                schemesInfo:function(){
                    this.$nextTick(function(){
                        loadGrade()
                    })
                }
            },
            mounted () {
                axios
                .get('/info/schemes')
                .then(response => (this.schemesInfo = response.data))
                .catch(function (error) { // 请求失败处理
                    console.log(error);
                });
            }
        })
    }

      绿色部分是star-rating-read-only对应的js处理函数,红色部分是我们对vue的修改完善,这样修改以后,果不其然,数据都正确的渲染在了模板上

      

  • 相关阅读:
    英语语法入门十五(名词所有格)
    在线调试Arduino
    CANopen和Canfestival
    嵌入式系统中的printf
    云原生爱好者周刊:Lens 5.0 发布,更炫、更快、更强!
    基于 KubeSphere 的 Nebula Graph 多云架构管理实践
    KubeSphere Meetup 北京站火热报名中 | 搭载 CIC 2021 云计算峰会
    KubeSphere Helm 应用仓库源码分析
    开启 Calico eBPF 数据平面实践
    KubeSphere 在直播应用中的实践
  • 原文地址:https://www.cnblogs.com/wangbaojun/p/11145887.html
Copyright © 2020-2023  润新知