通过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 请求。
相关html如下:
div div template v-for="schemeInfo in schemesInfo" div div " rel="external nofollow" div img :src="schemeInfo.photo_url" alt="Tour Package"/ div div span {{ schemeInfo.day }} 天 {{ schemeInfo.night }} 夜 /span /div /div /div div h5 {{ schemeInfo.name }} /h5 div div div v-bind:data-rating-score="schemeInfo.score_avg" /div span / {{ schemeInfo.review_num }} 评论 /span /div /div div span i /i /span div ¥{{ schemeInfo.unit_price }} /div /div /div /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 v-bind:data-rating-score="schemeInfo.score_avg" /div
现在看似已经完成了,但是实际上我们的数据并没有被渲染到模板上,这是因为vue 取值的方法{{ }}与django的模板语言冲突,vue取值并未生效,其实解决办法至少有三个,可以参考:
我还是喜欢第三种:
将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-mon.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的修改完善,这样修改以后,果不其然,数据都正确的渲染在了模板上