下载安装新依赖

babel-runtime:对es6语法进行转译
fastclick:对移动端进行点击300毫秒延迟 ,,取消掉
babel-polyfill:API

先添加,在npm install

main.js

import 'babel-polyfill'
import Vue from 'vue'
import App from './App'
import router from './router'
import fastclick from 'fastclick' import 'common/stylus/index.styl' Vue.config.productionTip = false // 取消点击300毫秒的延迟
fastclick.attach(document.body) /* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})

头部栏引用header组件

1:

<template>
<div class="m-header">
<div class="icon"></div>
<h1 class="text">Chicken Music</h1>
<router-link tag="div" class="mine" to="/user">
<i class="icon-mine"></i>
</router-link>
</div>
</template> <script type="text/ecmascript-6">
export default {}
</script> <style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable"
@import "~common/stylus/mixin" .m-header
position: relative
height: 44px
text-align: center
color: $color-theme
font-size:
.icon
display: inline-block
vertical-align: top
margin-top: 6px
width: 30px
height: 32px
margin-right: 9px
bg-image('logo')
background-size: 30px 32px
.text
display: inline-block
vertical-align: top
line-height: 44px
font-size: $font-size-large
.mine
position: absolute
top:
right:
.icon-mine
display: block
padding: 12px
font-size: 20px
color: $color-theme
</style>

m-header。vue

2:在app.vue

<template>
<div id="app">
:显式
<m-header></m-header>
</div>
</template> <script>
:导入
import MHeader from './components/m-header/m-header'
export default {
components:{
:注册
MHeader
}
}
</script> <style scoped lang="stylus" rel="stylesheet/stylus"> </style>

二:导入歌手页面,搜索页面,排行榜,推荐页面

1:先在index.js入口注册这4个组件

import Reacommed from 'components/reacommed/reacommed'
import Search from 'components/search/search'
import Singer from 'components/singer/singer'
import Rank from 'components/rank/rank'

2:配置url

export default new Router({
routes: [
{
path: '/reacommed',
component:Reacommed
},
{
path:'/singer',
component:Singer
},
{
path:'/rank',
component:Rank
},
{
path:'/search',
component:Search
}
]
})
import Vue from 'vue'
import Router from 'vue-router'
import Reacommed from 'components/reacommed/reacommed'
import Search from 'components/search/search'
import Singer from 'components/singer/singer'
import Rank from 'components/rank/rank' Vue.use(Router) export default new Router({
routes: [
{
path: '/reacommed',
component:Reacommed
},
{
path:'/singer',
component:Singer
},
{
path:'/rank',
component:Rank
},
{
path:'/search',
component:Search
}
]
})

index。js

3:如何引入router实例

import 'babel-polyfill'
import Vue from 'vue'
import App from './App'
// 1这里的router是index。js的实例
import router from './router'
import fastclick from 'fastclick' import 'common/stylus/index.styl' Vue.config.productionTip = false // 取消点击300毫秒的延迟
fastclick.attach(document.body) /* eslint-disable no-new */
new Vue({
el: '#app',
//
router,
components: { App },
template: '<App/>'
})

main.js

注册url

import Vue from 'vue'
import Router from 'vue-router'
import Recommend from 'components/recommend/recommend'
import Search from 'components/search/search'
import Singer from 'components/singer/singer'
import Rank from 'components/rank/rank' Vue.use(Router) export default new Router({
routes: [
{
path: '/recommend',
component:Recommend
},
{
path:'/singer',
component:Singer
},
{
path:'/rank',
component:Rank
},
{
path:'/search',
component:Search
}
]
})

index.js

4:显示在App.vue页面

知识点:

router-linnk

a:里面有一个tag属性,控制其显示的为什么标签

如:tag=“a”,即显示为a标签

b:router-link-active

当前某个router-link被激活的时候,会添加样式

5:将导航条添加进去

a:先在app.vue导入进去tab组件

b:注册

c:渲染

<template>
<div id="app">
<m-header></m-header>
<tab></tab>
<router-view></router-view>
</div>
</template> <script>
import MHeader from './components/m-header/m-header'
import Tab from './components/tab/tab'
export default {
components:{
MHeader,
Tab
}
}
</script> <style scoped lang="stylus" rel="stylesheet/stylus"> </style>

app.vue

url重定向

redirect

三:在app.vue导入组件

import MHeader from './components/m-header/m-header'
    import Tab from './components/tab/tab'

首字母要大写,因为其本质上是class,class书写规范为首字母大写

jsonp

jsonp(url, opts, fn)
url (String) url to fetch
opts (Object), optional
    param : 指定回调函数名
    timeout : 超时时间,默认一分钟
    prefix : __jp 默认添加前缀
    name
fn callback (回调函数)

四:抓取qq音乐的数据

XHR:ajax请求

1:可以自己手写

2:引用插件

下载安装jsonp

npm install jsonp

.jsonp是什么?jsonp是目前可以跨域的(基本上标签带有src属性的都是可以不受任何访问限制),且要动态生成script标签在ajax无法跨域的情况下可以使用jsonp进行请求但它跟ajax是不一样的..jsonp利用url链接进行请求发送和调用回调函数(callblack)使用数据。

1:封装一个jsonp方法

用于拼接url
import originJsonp from 'jsonp' // 引用 export default function jsonp(url, data, option) {
  // 将url和data对象进行拼接成url拼接
url += (url.indexOf('?') < ? '?' : '&') + param(data)
// param 是一个拼接函数将data专门转化成url形式

  
  return new Promise((resolve, reject) => {
originJsonp(url, option, (err, data) => {
if (!err) {
resolve(data)
} else {
reject(err)
}
})
})
} export function param(data) {
let url = ''
for (var k in data) {
let value = data[k] !== undefined ? data[k] : ''
url += '&' + k + '=' + encodeURIComponent(value)
}
return url ? url.substring() : ''
}

Promise对象有2个参数(resolve,reject)

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),
在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),
在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

promise()充当异步操作和回调函数的中介,起到代理的作用

param()data数据对象转化成url格式

function param(data){
let url = '';
//遍历拼接对象
for(var k in data){
//以&a=123=yu=789 这样形式拼接
let value = data[k] !== undefined ?data[k] : '';
url += `&${k}=${encodeURIComponent(value)}`; //es6语法
}
return url ? url.substring():'';
}

在创建的config.js下写入jsonp请求通用公共参数

xport const commonParams = {
g_tk: ,
inCharset: 'utf-8',
outCharset: 'utf-8',
notice: ,
format: 'jsonp',
}
// 设置常量 param
export const options = {
param: 'jsonpCallback'
}
// 设置常量 错误信息 0 是 ok
export const ERR_OK =

recommend.js文件下写入抓取QQ音乐轮播图需要发送数据

import jsonp from '../common/js/jsonp' //引入自定义封装的jsonp函数
import { commonParams, options } from './config'
export function getRecommend() {
//轮播图请求地址
const url = 'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg';
利用es6对象方法进行浅拷贝将数组对象合并到第一个{}对象中
const data = Object.assign({}, commonParams, {
platform: 'h5',
uin: ,
needNewCode:
})
//调用jsonp方法 进行url拼接
return jsonp(url, data, options)
}

.组件页面得到数据

将其js文件引入组件中

import {getRecommend} from 'api/recommend';
import {ERR_OK} from 'api/config'g'

获取数据

  _getRecommend(){
//因为return new Promise中有.then表示如果异步成功完成就执行
getRecommend().then(res=>{
if(res.code === ERR_OK){
console.log(res.data.slider)
this.recommend = res.data.slider;
//放入组件data中接着传入到轮播组件中使用v-for渲染
}
})
}

编写拼接url的方法(getRecommend)

MusicJsonCallback30832226944503405({"code":,
"subcode":,"msg":"",
"data":{"total":,"items":[{"from":,"status":,"msg_num":},
{"from":,"status":,"msg_num":},{"from":,"status":,"msg_num":},
{"from":,"status":,"msg_num":}]}})

从recommend调用getRecommend方法

推荐页面

recommend。vue

_getRecommend() {
getRecommend().then((res) => {
if(res.code === ERR_OK){
// 轮播图数据
this.recommends = res.data.slider
}
})
},

手写轮播图组件 base/slider

better-scroll文档**

slider.vue

<!-- 轮播图 -->
<template>
// slider为最外容器
<div class="slider" ref="slider">
  // sliderGroup为内层容器
<div class="slider-group" ref="sliderGroup">
<slot> </slot>
</div>
</div>
</template> <script>
// 轮播图组件
import BScroll from 'better-scroll'
import {addClass} from 'common/js/dom' export default{
data(){
return {
dots:[]
}
},
props:{
loop:{
// 循环轮播
type:Boolean,
default: true
},
autoPlay:{
// 自动轮播
type:Boolean,
default: true
},
interval:{
// 时间间隔
type:Number,
default:
}
},
mounted(){
setTimeout(() =>{
this._setSliderWidth()
this._initSlider()
this._initDots()
},)
},
methods:{
_setSliderWidth(){
this.children = this.$refs.sliderGroup.children let width =
let sliderWidth = this.$refs.slider.clientWidth
for (let i = ; i < this.children.length;i++){
let child = this.children[i]
addClass(child,'slider-item') child.style.width = sliderWidth + 'px'
width += sliderWidth
}
if(this.loop){
width += * sliderWidth
}
this.$refs.sliderGroup.style.width = width + 'px'
},
_initDots() {
this.dots = new Array(this.children.length-)
},
_initSlider(){
this.slider = new BScroll(this.$refs.slider,{
scrollX:true,
scrollY:false,
momentum:false,
snap:true,
snapLoop:this.loop,
snapThreshold:0.3,
snapSpeed:,
click:true
} )
}
}
}
</script> <style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable" .slider
min-height: 1px
.slider-group
position: relative
overflow: hidden
white-space: nowrap
.slider-item
float: left
box-sizing: border-box
overflow: hidden
text-align: center
a
display: block
width: %
overflow: hidden
text-decoration: none
img
display: block
width: %
.dots
position: absolute
right:
left:
bottom: 12px
text-align: center
font-size:
.dot
display: inline-block
margin: 4px
width: 8px
height: 8px
border-radius: %
background: $color-text-l
&.active
width: 20px
border-radius: 5px
background: $color-text-ll
</style>

slider。vue

<div class="slider" ref="slider">---> 最外层容器
<div class="slider-group" ref="sliderGroup">---> 内层容器 sliderGroup轮播图,只能设置宽度,高度固定
:获取整个列表有多少个元素
this.children = this.$refs.sliderGroup.children :父元素的宽度,图片撑开的宽度
let sliderWidth = this.$refs.slider.clientWidth

给轮播图图片添加样式

(手动写的class,耦合性太强)

a、dom。js--->只对dom元素进行操作的方法(通用)

b、再导入dom。js

    // 对dom元素操作的组件
import {addClass} from 'common/js/dom'

c、将slider-item样式添加进去

addClass(child,'slider-item')

计算部分
// 子容器的宽度 要等于父容器的宽度 需要添加单位'px'
child.style.width = sliderWidth + 'px'
// 总宽度需要+父容器的宽度
width += sliderWidth loop:{
       // 循环轮播
      type:Boolean,
      default: true
}, // 保证其能进行循环切换,需克隆2个sliderWidth-->即宽度需要加2倍sliderWidth
if(this.loop && !isResize){
     width += 2 * sliderWidth
} 最后设置宽度
this.$refs.sliderGroup.style.width = width + 'px'

问题:当后面方法需要获取数据时,而获取数据的方法还未执行完毕

在recommend。vue进行判断数据长度
<div v-if='recommends.length' class="slider-wrapper">
<slider>
<div v-for="item in recommends">
<a :href="item.linkUrl">
<img :src="item.picUrl">
</a>
</div>
</slider>
</div>

recommend.vue推荐页面

<!-- 推荐页面 -->
<template>
<div class="recommend">
<div class="recommend-content">
<!-- 轮播图 -->
<div v-if='recommends.length' class="slider-wrapper">
<slider>
<div v-for="item in recommends">
<a :href="item.linkUrl">
<img :src="item.picUrl">
</a>
</div>
</slider>
</div>
<div class="recommend-list">
<h1 class="list-title">热门歌单推荐</h1>
</div>
<ul> </ul>
</div>
</div>
</template> <script>
// 导入轮播图组件
import Slider from 'base/slider/slider'
// 导入获取轮播数据的方法
import {getRecommend} from 'api/recommend'
// 语义化下面的err_ok
import {ERR_OK} from 'api/config'
// 获取数据created
export default {
data() {
// 定义轮播图数据
return{
recommends:[]
}
},
// 钩子函数
created() {
this._getRecommend()
},
methods: {
_getRecommend() {
getRecommend().then((res) => {
if(res.code === ERR_OK){
// 轮播图数据
this.recommends = res.data.slider
}
})
}
},
components:{
Slider,
}
} </script> <style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable" .recommend
position: fixed
width: %
top: 88px
bottom:
.recommend-content
height: %
overflow: hidden
.slider-wrapper
position: relative
width: %
overflow: hidden
.recommend-list
.list-title
height: 65px
line-height: 65px
text-align: center
font-size: $font-size-medium
color: $color-theme
.item
display: flex
box-sizing: border-box
align-items: center
padding: 20px 20px 20px
.icon
flex: 60px
width: 60px
padding-right: 20px
.text
display: flex
flex-direction: column
justify-content: center
flex:
line-height: 20px
overflow: hidden
font-size: $font-size-medium
.name
margin-bottom: 10px
color: $color-text
.desc
color: $color-text-d
.loading-container
position: absolute
width: %
top: %
transform: translateY(-%)
</style>

推荐页面

轮播图下的圆圈

<!-- 轮播图 -->
<template>
<div class="slider" ref="slider">
<div class="slider-group" ref="sliderGroup">
<slot> </slot>
</div>
<!-- 圆圈 -->
<div class="dots">
<span class="dot" v-for = 'item in dots'></span>
</div>
</div>
</template> <script>
// 轮播图组件
import BScroll from 'better-scroll'
import {addClass} from 'common/js/dom' export default{
data(){
return {
dots:[]
}
},
props:{
loop:{
// 循环轮播
type:Boolean,
default: true
},
autoPlay:{
// 自动轮播
type:Boolean,
default: true
},
interval:{
// 时间间隔
type:Number,
default:
}
},
mounted(){
setTimeout(() =>{
this._setSliderWidth()
this._initSlider()
this._initDots()
},)
},
methods:{
_setSliderWidth(){
this.children = this.$refs.sliderGroup.children let width =
let sliderWidth = this.$refs.slider.clientWidth
for (let i = ; i < this.children.length;i++){
let child = this.children[i]
addClass(child,'slider-item') child.style.width = sliderWidth + 'px'
width += sliderWidth
}
if(this.loop){
width += * sliderWidth
}
this.$refs.sliderGroup.style.width = width + 'px'
},
_initDots() {
this.dots = new Array(this.children.length-)
},
_initSlider(){
this.slider = new BScroll(this.$refs.slider,{
scrollX:true,
scrollY:false,
momentum:false,
snap:true,
snapLoop:this.loop,
snapThreshold:0.3,
snapSpeed:,
click:true
} )
}
}
}
</script> <style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable" .slider
min-height: 1px
.slider-group
position: relative
overflow: hidden
white-space: nowrap
.slider-item
float: left
box-sizing: border-box
overflow: hidden
text-align: center
a
display: block
width: %
overflow: hidden
text-decoration: none
img
display: block
width: %
.dots
position: absolute
right:
left:
bottom: 12px
text-align: center
font-size:
.dot
display: inline-block
margin: 4px
width: 8px
height: 8px
border-radius: %
background: $color-text-l
&.active
width: 20px
border-radius: 5px
background: $color-text-ll
</style>

slider.vue

将轮播图当前页与小圆圈绑定样式

 <div class="dots">
<span class="dot" v-for = '(item,index) in dots' :class="{active: currentPageIndex === index}">
  </span>
</div>

index--->索引当前第几个元素

添加样式active

 :class="{active: currentPageIndex === index}">
currentPageIndex:标识当前页数  
需要先在data() 方法里面初始化currentPageIndex export default{
data(){
return {
dots:[],
// 标识当前页数
currentPageIndex:
}
}, 到索引的页面就添加active类

当前对象。也就是指.dot

当dot是active的时候,就添加样式

维护currentPageIndex

currentPageIndex什么时候切换的?如何将滚动到的页面与currentPageIndex结合?

当初始化slider的时候,绑定事件

 // 当滚动到下一张会触发scrollEnd事件
scrollEnd事件会派发一个回调函数
this.slider.on('scrollEnd', ()=>{
// 获取当前 getCurrentPage()为slider的方法 返回的对象有个pageX方法
pageX--->当前第几个元素
let pageIndex = this.slider.getCurrentPage().pageX
if (this.loop) {
pageIndex -=
//再循环模式下,会默认在第一个元素添加一个拷贝 所以要减1
}
this.currentPageIndex = pageIndex
})

这里我们用到了 Vue 的特殊元素—— slot 插槽,它可以满足我们灵活定制列表 DOM 结构的需求。接下来我们来看看 JS 部分:
<script type="text/ecmascript-6">
import BScroll from 'better-scroll'
export default {
props: {
/** * 1 滚动的时候会派发scroll事件,会截流。
* 2 滚动的时候实时派发scroll事件,不会截流。
* 3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件
*/
probeType: {
type: Number,
default:
},
/**
* 点击列表是否派发click事件
*/
click: {
type: Boolean,
default: true
},
/** * 是否开启横向滚动 */
scrollX: {
type: Boolean,
default: false
},
/** * 是否派发滚动事件 */
listenScroll: {
type: Boolean,
default: false
},
/** * 列表的数据 */
data: {
type: Array,
default: null
},
/** * 是否派发滚动到底部的事件,用于上拉加载 */
pullup: {
type: Boolean,
default: false
},
/** * 是否派发顶部下拉的事件,用于下拉刷新 */
pulldown: {
type: Boolean,
default: false
},
/** * 是否派发列表滚动开始的事件 */
beforeScroll: {
type: Boolean,
default: false
},
/** * 当数据更新后,刷新scroll的延时。 */
refreshDelay: {
type: Number,
default: }
},
mounted() {
// 保证在DOM渲染完毕后初始化better-scroll
setTimeout(() => {
this._initScroll()
}, )
},
methods: {
_initScroll() {
if (!this.$refs.wrapper) {
return
}
// better-scroll的初始化
this.scroll = new BScroll(this.$refs.wrapper, {
probeType: this.probeType,
click: this.click,
scrollX: this.scrollX
})
// 是否派发滚动事件
if (this.listenScroll) {
let me = this this.scroll.on('scroll', (pos) => {
me.$emit('scroll', pos)
})
}
// 是否派发滚动到底部事件,用于上拉加载
if (this.pullup) {
this.scroll.on('scrollEnd', () => {
// 滚动到底部
if (this.scroll.y <= (this.scroll.maxScrollY + )) {
this.$emit('scrollToEnd')
}
})
}
// 是否派发顶部下拉事件,用于下拉刷新
if (this.pulldown) {
this.scroll.on('touchend', (pos) => {
// 下拉动作
if (pos.y > ) {
this.$emit('pulldown')
}
})
}
// 是否派发列表滚动开始的事件
if (this.beforeScroll) {
this.scroll.on('beforeScrollStart', () => {
this.$emit('beforeScroll')
})
}
},
disable() {
// 代理better-scroll的disable方法
this.scroll && this.scroll.disable()
},
enable() {
// 代理better-scroll的enable方法
this.scroll && this.scroll.enable()
},
refresh() {
// 代理better-scroll的refresh方法
this.scroll && this.scroll.refresh()
},
scrollTo() {
// 代理better-scroll的scrollTo方法
this.scroll && this.scroll.scrollTo.apply(this.scroll,
arguments)
},
scrollToElement() {
// 代理better-scroll的scrollToElement方法
this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
}
},
watch: {
// 监听数据的变化,延时refreshDelay时间后调用refresh方法重新计算,保证滚动效果正常
data() {
setTimeout(() => {
this.refresh()
}, this.refreshDelay)
}
}
}
</script>

JS 部分实际上就是对 better-scroll 做一层 Vue 的封装,通过 props 的形式,
把一些对 better-scroll 定制化的控制权交给父组件;
通过 methods 暴露的一些方法对 better-scroll 的方法做一层代理;
通过 watch 传入的 data,当 data 发生改变的时候,
在适当的时机调用 refresh 方法重新计算 better-scroll 确保滚动效果正常,
这里之所以要有一个 refreshDelay 的设置是考虑到如果我们对列表操作用到了 transition-group 做动画效果
,那么 DOM 的渲染完毕时间就是在动画完成之后。 有了这一层 scroll 组件的封装,我们来修改刚刚最复杂的代码(假设我们已经全局注册了 scroll 组件)。
<template>
<scroll class="wrapper"
:data="data"
:pulldown="pulldown"
@pulldown="loadData">
<ul class="content">
<li v-for="item in data">{{item}}</li>
</ul>
<div class="loading-wrapper"></div>
</scroll>
</template>
<script>
import BScroll from 'better-scroll'
export default {
data() {
return {
data: [],
pulldown: true
}
},
created() {
this.loadData()
},
methods: {
loadData() {
requestData().then((res) => {
this.data = res.data.concat(this.data)
})
}
}
}
</script> 可以很明显的看到我们的 JS 部分精简了非常多的代码,没有对 better-scroll 再做命令式的操作了,
同时把数据请求和 better-scroll 也做了剥离,父组件只需要把数据 data 通过 prop 传给 scroll 组件,
就可以保证 scroll 组件的滚动效果。
同时,如果想实现下拉刷新的功能,只需要通过 prop 把 pulldown 设置为 true,
并且监听 pulldown 的事件去做一些数据获取并更新的动作即可,整个逻辑也是非常清晰的。
动态的给子元素设置宽度,当能滑动或者自动轮播的时候,子元素的宽度乘以2,用来切换,因为轮播图想无缝滑动,
必须将第一张图放到最后一个位置,最后一张图放到第一张的位置前面,假如有五个轮播图的话,
事实上,获取的宽度是七张图的宽度。

自动播放

slider.vue

 props:{
loop:{
// 循环轮播
type:Boolean,
default: true
},
autoPlay:{
// 自动轮播
ype:Boolean,
default: true

优化:

当屏幕宽度变化的时候,图片错位,而宽度是由sliderWidth控制的

方法: 监听Windows的resizer事件,重新渲染sliderWidth

        //监听窗口改变事件
window.addEventListener('resize', () => {
if (!this.slider){
        // 初始化的时候直接返回
return
}
// 重新调用计算宽度的方法
this._setSliderWidth(true)
})
},

window窗口改变事件:resize

addEventListener() 方法

用于向指定元素添加事件句柄

element.addEventListener(event, function, useCapture)

参数:
event:
必须。字符串,指定事件名。 注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick" function
必须。指定要事件触发时执行的函数。 当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如,
"click" 事件属于 MouseEvent(鼠标事件) 对象。 useCapture
可选。布尔值,指定事件是否在捕获或冒泡阶段执行。 可能值: true - 事件句柄在捕获阶段执行
false- false- 默认。事件句柄在冒泡阶段执行

参数

添加标志位,重置过的设置为true

        methods:{
        // isResize标志位判读是不是重置过来的
_setSliderWidth(isResize){
this.children = this.$refs.sliderGroup.children let width =
let sliderWidth = this.$refs.slider.clientWidth
for (let i = ; i < this.children.length;i++){
let child = this.children[i]
addClass(child,'slider-item') child.style.width = sliderWidth + 'px'
width += sliderWidth
}
          // && !isResize
if(this.loop && !isResize){
          // 刚开始进来只需要加一次宽度
width += * sliderWidth
}
this.$refs.sliderGroup.style.width = width + 'px'
},

知识点

1:slot---> 插槽

2:使用better-scroll

3:created和mounted

created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
其实两者比较好理解,通常created使用的次数多,而mounted通常是在一些插件的使用或者组件的使用中进行操作,比如插件chart.js的使用: var ctx = document.getElementById(ID);通常会有这一步,而如果你写入组件中,你会发现在created中无法对chart进行一些初始化配置,一定要等这个html渲染完后才可以进行,那么mounted就是不二之选。下面看一个例子(用组件)。

vue music-抓取歌单列表数据(渲染轮播图)的更多相关文章

  1. Vue实现音乐播放器(七):轮播图组件(二)

    轮播图组件 <template> <div class="slider" ref="slider"> <div class=&qu ...

  2. 05-06 Flutter JSON和序列化反序列化、创建模型类转换Json数据、轮播图数据渲染:Flutter创建商品数据模型 、请求Api接口渲染热门商品 推荐商品

    Config.dart class Config{ static String domain='http://jd.itying.com/'; } FocusModel.dart class Focu ...

  3. 使用 Python 抓取欧洲足球联赛数据

    Web Scraping在大数据时代,一切都要用数据来说话,大数据处理的过程一般需要经过以下的几个步骤    数据的采集和获取    数据的清洗,抽取,变形和装载    数据的分析,探索和预测    ...

  4. H5音乐播放器【歌单列表】

    上篇详细描述了播放页歌词如何实现跟随跟单滚动,如何解析歌词,那么歌单页又是如何生成的呢,话不多说,直接上图上代码! 首先需要获取数据,具体获取数据api请转到我跟我大兄弟博客去观看学习去,同时也感谢我 ...

  5. 抓取Js动态生成数据且以滚动页面方式分页的网页

    代码也可以从我的开源项目HtmlExtractor中获取. 当我们在进行数据抓取的时候,如果目标网站是以Js的方式动态生成数据且以滚动页面的方式进行分页,那么我们该如何抓取呢? 如类似今日头条这样的网 ...

  6. 如何用python抓取js生成的数据 - SegmentFault

    如何用python抓取js生成的数据 - SegmentFault 如何用python抓取js生成的数据 1赞 踩 收藏 想写一个爬虫,但是需要抓去的的数据是js生成的,在源代码里看不到,要怎么才能抓 ...

  7. 如何抓取电商的数据 & Python

    如何抓取电商的数据 & Python https://www.zhihu.com/question/40720286 https://www.zhihu.com/question/382455 ...

  8. Python小爬虫——抓取豆瓣电影Top250数据

    python抓取豆瓣电影Top250数据 1.豆瓣地址:https://movie.douban.com/top250?start=25&filter= 2.主要流程是抓取该网址下的Top25 ...

  9. Fiddler 抓取 app 网络请求数据

    通过设置代理在同一个路由器下可以通过 Fiddler 实现抓取 app 的网络数据 步骤如下: 手机(Android ,iOS 都可以)和 PC 连到同一个路由器 对手机连接的 WIFI 设置代理,代 ...

随机推荐

  1. visio基础教程(一)

  2. C语言的 32个关键之和9个控制语言之关键字

    auto   break  case  char  const  continue  default  do double  else  enum  extern  float for  goto  ...

  3. 从Linux服务器下载文件到本地命令

    从Linux服务器下载文件夹到本地1.使用scp命令 scp /home/work/source.txt work@192.168.0.10:/home/work/ #把本地的source.txt文件 ...

  4. object类之toString方法

    object是所有类的基类 如果没有使用extends关键字指明其基类,则默认基类为object类 public class Person{ ........ } 等价于: public class ...

  5. Ubuntu 16.04 (官方命令行)安装MongoDB 3.6.2(社区版)

    概述 使用本教程从 .deb 包在LTS Ubuntu Linux系统上安装MongoDB Community Edition. 虽然Ubuntu包含自己的MongoDB包,但官方的MongoDB社区 ...

  6. #include <ntifs.h>出现PEPROCESS redefinition问题处理

    转载:http://blog.csdn.net/ytfrdfiw/article/details/23334297 如果在自己的程序中,即包含ntddk.h和ntifs.h的时候,编译的时候会出现如下 ...

  7. 子网掩码与ip有实际关系吗?

    子网掩码是作为ip地址的标识,还是本身就是ip地址的一部分?例如10.10.10.1/24和10.10.10.1/25是同一个ip地址吗? 作者:知乎用户链接:https://www.zhihu.co ...

  8. Uva 12304 - 2D Geometry 110 in 1!

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  9. sqlplus中文问号

    添加两个环境变量后重启. 1.LANG=zh_CN.GBK(GBK是这样形式的,不同编码这里的value值需要跟着改变) 2.NLS_LANG=AMERICAN_AMERICA.ZHS16GBK(这个 ...

  10. UVA-1343 The Rotation Game (IDA*)

    题目大意:数字1,2,3都有八个,求出最少的旋转次数使得图形中间八个数相同.旋转规则:对于每一长行或每一长列,每次旋转就是将数据向头的位置移动一位,头上的数放置到尾部.若次数相同,则找出字典序最小旋转 ...