Masonry瀑布流式布局库(中文翻译)

英文原版网站链接:http://masonry.desandro.com/。英文原版包含大量例程,请对照阅读。


Masonry是什么?

Masonry是一个JavaScript网格布局库。它的作用是在可用的竖直空间上将页面元素放置于页面最佳位置处,就像泥瓦匠将石头往墙上砌一样。你应该已经在网上很多地方见过它了。


安装


下载

CDN

直接链接至upmcdn上的Masonry文件。

<script src="https://npmcdn.com/masonry-layout@4.1/dist/masonry.pkgd.min.js"></script>
<!-- or -->
<script src="https://npmcdn.com/masonry-layout@4.1/dist/masonry.pkgd.js"></script>

包管理器安装

通过Bower安装: bower install masonry --save
通过npm安装:npm install masonry-layout


开始使用


HTML

将Masonry的.js文件include进你的站点。

<script src="/path/to/masonry.pkgd.min.js"></script>

Masonry的工作需要一个包含若干子项的容器。

<div class="grid">
  <div class="grid-item">...</div>
  <div class="grid-item grid-item--width2">...</div>
  <div class="grid-item">...</div>
  ...
</div>

CSS

所有项的尺寸都由你的CSS决定。

.grid-item { width: 200px; }
.grid-item--width2 { width: 400px; }

使用jQuery初始化

你能将Masonry作为一个jQuery插件使用:$('selector').masonry()

$('.grid').masonry({
  // options
  itemSelector: '.grid-item',
  columnWidth: 200
});

使用Vanilla JavaScript初始化

你可以通过vanilla JS使用Masonry:new Masonry( elem, options )。Masonry() 构造器接受两个参数:容器参数和一个设置对象。

var elem = document.querySelector('.grid');
var msnry = new Masonry( elem, {
  // options
  itemSelector: '.grid-item',
  columnWidth: 200
});

// element argument can be a selector string
//   for an individual element
var msnry = new Masonry( '.grid', {
  // options
});

在HTML中初始化

你可以在HTML中初始化Masonry,不需要写一行JavaScript。给容器元素添加data-masonry属性。通过修改它的值就能更改设置。

<div class="grid" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 200 }'>

在CodePen中编写这个demo

注意:HTML中的设置值必须是可用的JSON,键必须加引号,比如"itemSelector":。注意data-masonry的值是被单引号包'裹的,而JSON条目用的是双引号"

HTML初始化的完成是先于js-masonry的。Masonry v3和Masonry v4版本中data-masonry-options的设置同现在的代码是向后兼容的。

<div class="grid js-masonry"
  data-masonry-options='{ "itemSelector": ".grid-item", "columnWidth": 200 }'>

Layout(布局)


项尺寸

项的所有尺寸及样式都由你自己的CSS决定。

<div class="grid">
  <div class="grid-item"></div>
  <div class="grid-item grid-item--width2"></div>
  <div class="grid-item grid-item--height2"></div>
  ...
</div>
.grid-item {
  float: left;
  width: 80px;
  height: 60px;
  border: 2px solid hsla(0, 0%, 0%, 0.5);
}

.grid-item--width2 { width: 160px; }
.grid-item--height2 { height: 140px; }

查看并编辑demo

响应式布局

在响应式布局中项的大小可以以百分比的形式来设置。在masonry布局模式中,设置百分比宽度columWidth来更改元素的大小。设置percentPosition:true,项的位置也同样变为了百分比式,从而能够减少窗口大小变动时项位置的调整变动。

<div class="grid">
  <!-- width of .grid-sizer used for columnWidth -->
  <div class="grid-sizer"></div>
  <div class="grid-item"></div>
  <div class="grid-item grid-item--width2"></div>
  ...
</div>
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }
/* 2 columns */
.grid-item--width2 { width: 40%; }
$('.grid').masonry({
  // set itemSelector so .grid-sizer is not used in layout
  itemSelector: '.grid-item',
  // use element for option
  columnWidth: '.grid-sizer',
  percentPosition: true
})

查看并编辑demo

imagesLoaded

未载入的图片可能脱离Masonry布局并导致项元素重叠。imagesLoaded解决了这个问题。imagesLoaded是单独的脚本,你可以在imagesloaded.desandro.com下载

初始化Masonry,然后再每张图片载入后触发layout(布局)。

// init Masonry
var $grid = $('.grid').masonry({
  // options...
});
// layout Masonry after each image loads
$grid.imagesLoaded().progress( function() {
  $grid.masonry('layout');
});

查看并编辑demo

或者当所有图片载入后在初始化Masonry。

var $grid = $('.grid').imagesLoaded( function() {
  // init Masonry after all images have loaded
  $grid.masonry({
    // options...
  });
});

查看并编辑demo


Options(选项)


所有的选项都是可选的,建议保留columWidthitemSelector

// jQuery
$('.grid').masonry({
  columnWidth: 200,
  itemSelector: '.grid-item'
});
// vanilla JS
var msnry = new Masonry( '.grid', {
  columnWidth: 200,
  itemSelector: '.grid-item'
});
<!-- in HTML -->
<div class="grid" data-masonry='{ "columnWidth": 200, "itemSelector": ".grid-item" }'>

推荐选项


itemSelector(项选择器)

指定将在布局中作为项的子元素。

我们建议总是保留设置itemSelector。在排除sizing elements(尺寸元素)或者其他非布局所需元素的时候它将很有用。

itemSelector: '.grid-item'
<div class="grid">
  <!-- do not use banner in Masonry layout -->
  <div class="static-banner">Static banner</div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  ...
</div>
columnWidth

将项排列在一个水平栅格上。

注意:我们建议设置columWidth。如果columWidth未设置,Masonry将使用第一个项的外部宽度。

columnWidth: 80

查看并编辑demo

在响应式布局中使用element sizing实现百分比宽度。设置columWidth为一个元素或者选择器的字符串名称来使用该元素的外部宽度作为该行的尺寸。

<div class="grid">
  <!-- .grid-sizer empty element, only used for element sizing -->
  <div class="grid-sizer"></div>
  <div class="grid-item"></div>
  <div class="grid-item grid-item--width2"></div>
  ...
</div>
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }
/* 2 columns wide */
.grid-item--width2 { width: 40%; }
// use outer width of grid-sizer for columnWidth
columnWidth: '.grid-sizer',
itemSelector: '.grid-item',
percentPosition: true

布局


Element sizing(元素尺寸)

尺寸选项cloumnWidthgutter可设置为某个元素。该元素的尺寸即成为了该选项的设置值。

<div class="grid">
  <!-- .grid-sizer empty element, only used for element sizing -->
  <div class="grid-sizer"></div>
  <div class="grid-item"></div>
  <div class="grid-item grid-item--width2"></div>
  ...
</div>
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }
/* 2 columns wide */
.grid-item--width2 { width: 40%; }
// use outer width of grid-sizer for columnWidth
columnWidth: '.grid-sizer',
// do not use .grid-sizer in layout
itemSelector: '.grid-item',
percentPosition: true

编辑并查看demo

尺寸选项也能设置为元素或者选择器的字符串名称。

// set to a selector string
// first matching element within container element will be used
columnWidth: '.grid-sizer'

// set to an element
columnWidth: $grid.find('.grid-sizer')[0]

元素尺寸选项让你可以用自己的CSS来控制Masonry布局的大小。它特别适用于响应式布局和媒体查询。

/* 3 columns by default */
.grid-sizer { width: 33.333%; }

@media screen and (min-width: 768px) {
  /* 5 columns for larger screens */
  .grid-sizer { width: 20%; }
}
gutter(沟槽)

添加项元素间的横向间隔。

gutter: 10

查看并编辑demo

要改变元素间竖直方向上的间隔,请使用margin CSS。

gutter: 10
.grid-item {
  margin-bottom: 10px;
}

查看并编辑demo

在响应式布局中,设置gutter为一个元素或者选择器名称的字符串来使用元素的外部尺寸。

<div class="grid">
  <div class="grid-sizer"></div>
  <div class="gutter-sizer"></div>
  <div class="grid-item"></div>
  <div class="grid-item grid-item--width2"></div>
  ...
</div>
.grid-sizer,
.grid-item { width: 22%; }

.gutter-sizer { width: 4%; }

.grid-item--width2 { width: 48%; }
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer',
itemSelector: '.grid-item',
percentPosition: true

查看并编辑demo

percentPosition(百分比位置)

将项的位置设为百分比优于设为像素值。percentPosition:true与百分比宽度项一起的效果不错,当窗口大小改变时项的相对位置将不会变化。

// set positions with percent values
percentPosition: true,
columnWidth: '.grid-sizer',
itemSelector: '.grid-item'
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }

查看并编辑demo

stamp(邮票)

指明布局里哪些元素会像邮票一样被贴在最面上。Masonry将在stamp元素之下布局各项。

stamp设置只有在Masonry实例第一次初始化的时候操作才有效。你可以用stamp方法随后添加额外的邮票元素。

<div class="grid">
  <div class="stamp stamp1"></div>
  <div class="stamp stamp2"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  ....
</div>
// specify itemSelector so stamps do get laid out
itemSelector: '.grid-item',
// stamp elements
stamp: '.stamp'
/* position stamp elements with CSS */
.stamp {
  position: absolute;
  background: orange;
  border: 4px dotted black;
}
.stamp1 {
  left: 30%;
  top: 10px;
  width: 20%;
  height: 100px;
}
.stamp2 {
  right: 10%;
  top: 20px;
  width: 70%;
  height: 30px;
}

查看并编辑demo

fitWidth(适应宽度)

基于容器父类的尺寸设置容器的宽度来适应恰当的行数。当设为可用,你能够通过CSS使容器剧中。

fitWidth在Masonry v3版本中是isFitWIdthisFitWidth在Masonry v4中依旧可用。

注意:fitWidth:true与element sizing一起的时候百分比宽度不会生效。要么columnWidth需要被设置为固定尺寸,比如columnWidth:120;要么项被设置为像素固定值,比如width:120px。如果不然,容器跟项宽将逐个重叠。

fitWidth: true
/* center container with CSS */
.grid {
  margin: 0 auto;
}

查看并编辑demo

originLeft(左起)

控制布局的水平流动。默认项元素从左向右安置,originLeft:true。设originLeft:false将变成由右向左的布局。

originLeft在Masonry v3中曾经是isOriginLeftisOriginLeft在Masonry v4中依旧可用。

originLeft: false

查看并编辑demo

originTop(顶起)

控制布局的垂向流动。默认originTop:true。设originTop:false将变为由下到上的布局,就像俄罗斯方块一样。

originTop: false

查看并编辑demo


设置


containerStyle(容器样式)

被应用于容器元素的CSS样式。

// default
// containerStyle: { position: 'relative' }

// disable any styles being set on container
// useful if using absolute position on container
containerStyle: null
transitionDuration(过渡效果持续时间)

当项改变位置或外观时过渡效果的持续时间,按照CSS时间的格式设置,默认:transitionDuration:'0.4s'

// fast transitions
transitionDuration: '0.2s'

// slow transitions
transitionDuration: '0.8s'

// no transitions
transitionDuration: 0
stragger(交错)

项转换位置时为其提供交错效果,使项能够一个接一个的转换位置。按照CSS时间的格式设置,'0.03s',或者用以毫秒为单位的数字,30

stagger: 30
resize(窗口大小改变)

当窗口大小改变时调整尺寸和位置。默认启用:resize:true

resize曾经在Masonry v3中为isResizeBoundisResizeBound在Masonry v4中依旧可用。

// disable window resize behavior
resize: false
/* grid has fixed width */
.grid {
  width: 320px;
}

查看并编辑demo

initLayout(初始布局)

使布局在初始化时启用。默认启用initLayout:true

initLayout:false将使初始化时的布局不可用,以便能够在初始布局之前调用方法或添加事件。

initLayout曾经在Masonry v3中为isInitLayout。在Masonry v4中isInitLayout将依旧可用。

var $grid = $('.grid').masonry({
  // disable initial layout
  initLayout: false,
  //...
});
// bind event
$grid.masonry( 'on', 'layoutComplete', function() {
  console.log('layout is complete');
});
// trigger initial layout
$grid.masonry();

查看并编辑demo


Methods(方法)


方法是由Masonry实例执行的各种动作。

用jQuery的时候,方法的使用遵从jQuery的UI模式.masonry( 'methodName' /* arguments */ )

$grid.masonry()
  .append( elem )
  .masonry( 'appended', elem )
  // layout
  .masonry();

注意:jQuery链会被那些返回值的方法打断:(比如getItemElements,getItem,on,off)。

Vanilla JavaScript方法是这样的masonry.methodName(/*arguments*/)。不同于jQuery方法,他们不能链在一起。

// vanilla JS
var msnry = new Masonry( '.grid', {...});
gridElement.appendChild( elem );
msnry.appended( elem );
msnry.layout();

布局


layout/.masonry()

布局出所有的项元素。当某一项改变了尺寸,所有项需要重新布局时layout很有用处。

// jQuery
$grid.masonry()
// vanilla JS
msnry.layout()
var $grid = $('.grid').masonry({
  columnWidth: 80
});
// change size of item by toggling gigante class
$grid.on( 'click', '.grid-item', function() {
  $(this).toggleClass('gigante');
  // trigger layout after item size changes
  $grid.masonry('layout');
});

查看并编辑jQuery demo或者vanilla JS demo

layoutItems

布局出特定的项。

// jQuery
$grid.masonry( 'layoutItems', items, isStill )
// vanilla JS
msnry.layoutItems( items, isStill )

items · Masonry.Items数组

isStill · 布尔值 · 禁止过渡效果

stamp(邮票)

在布局中“粘贴”元素。Masonry将会围绕邮票元素布局。

// jQuery
$grid.masonry( 'stamp', elements )
// vanilla JS
msnry.stamp( elements )

elements · Element, jQuery 对象, NodeList, 或者元素数组

设置itemSelector使邮票元素不被当作layout items(布局项)使用。

var $grid = $('.grid').masonry({
  // specify itemSelector so stamps do get laid out
  itemSelector: '.grid-item',
  columnWidth: 80
});
var $stamp = $grid.find('.stamp');
var isStamped = false;

$('.stamp-button').on( 'click', function() {
  // stamp or unstamp element
  if ( isStamped ) {
    $grid.masonry( 'unstamp', $stamp );
  } else {
    $grid.masonry( 'stamp', $stamp );
  }
  // trigger layout
  $grid.masonry('layout');
  // set flag
  isStamped = !isStamped;
});

查看并编辑jQuery demo 或者 vanilla JS demo

unstamp(取消邮票)

布局中取消元素的邮票效果,使Masonry不再围绕它们布局项元素。见上面的demo

// jQuery
$grid.masonry( 'unstamp', elements )
// vanilla JS
msnry.unstamp( elements )

elements · 元素, jQuery对象, NodeList, 或者元素数组


添加和移除项


appended(尾部添加)

在布局的末尾添加并展示新的项元素。

// jQuery
$grid.masonry( 'appended', elements )
// vanilla JS
msnry.appended( elements )

elements · 元素, jQuery对象, NodeList, 或者元素数组

$('.append-button').on( 'click', function() {
  // create new item elements
  var $items = $('<div class="grid-item">...</div>');
  // append items to grid
  $grid.append( $items )
    // add and lay out newly appended items
    .masonry( 'appended', $items );
});

查看并编辑jQuery demo或者vanilla JS demo

不像jQuery的.append()能直接添加一个HTML字符串,Masonry的appende不能。当通过jQeury ajax方法(比如$.get()$.ajax())添加内容的时候,应将HTML内容字符串包裹于一个jQuery对象当中,使得appended能够正常工作。

prepended(头部添加)

在布局的开头添加并展示新的项元素。

// jQuery
$grid.masonry( 'prepended', elements )
// vanilla JS
msnry.prepended( elements )

elements · 元素, jQuery对象, NodeList, 或者元素数组

$('.prepend-button').on( 'click', function() {
  // create new item elements
  var $items = $('<div class="grid-item">...</div>');
  // prepend items to grid
  $grid.prepend( $items )
    // add and lay out newly prepended items
    .masonry( 'prepended', $items );
});

查看并编辑jQuery demo或者vanilla JS demo

addItems(添加项)

给Masonry实例添加项元素。addItems并不会像appendedprepended一样将项元素展示出来。

// jQuery
$grid.masonry( 'addItems', elements )
// vanilla JS
msnry.addItems( elements )

elements · 元素, jQuery对象, NodeList, 或者元素数组

remove(移除)

移除Masonry实例和DOM中的元素。

// jQuery
$grid.masonry( 'remove', elements )
// vanilla JS
msnry.remove( elements )

elements · 元素, jQuery对象, NodeList, 或者元素数组

$grid.on( 'click', '.grid-item', function() {
  // remove clicked element
  $grid.masonry( 'remove', this )
    // layout remaining item elements
    .masonry('layout');
});

查看或编辑 jQuery demo 或者vanilla JS demo


事件


on

添加Masonry事件监听器。

// jQuery
var msnry = $grid.masonry( 'on', eventName, listener )
// vanilla JS
msnry.on( eventName, listener )

eventName · Masonry事件的字符串名称
listener · Function

off

移除一个事件监听器。

// jQuery
var msnry = $grid.masonry( 'off', eventName, listener )
// vanilla JS
msnry.off( eventName, listener )

eventName · string · Masonry事件的名称
listener · Function

once

添加一个仅会被触发一次的Masonry事件监听器。

// jQuery
var msnry = $grid.masonry( 'once', eventName, listener )
// vanilla JS
msnry.once( eventName, listener )

eventName · string · Masonry事件的名称
listener · Function

$grid.masonry( 'once', 'layoutComplete', function() {
  console.log('layout is complete, just once');
})

Utilities(公用程序)


reloadItems(项重载)

重新收集所有的项元素。

对于像Angular和React一类的框架,在DOM有变更时Masonry中可以用上。

// jQuery
$grid.masonry('reloadItems')
// vanilla JS
msnry.reloadItems()

destroy(销毁)

完全移除Masonry功能。destroy会使元素返回最初的状态。

var masonryOptions = {
  itemSelector: '.grid-item',
  columnWidth: 80
};
// initialize Masonry
var $grid = $('.grid').masonry( masonryOptions );
var isActive = true;

$('.toggle-button').on( 'click', function() {
  if ( isActive ) {
    $grid.masonry('destroy'); // destroy
  } else {
    $grid.masonry( masonryOptions ); // re-initialize
  }
  // set flag
  isActive = !isActive;
});

查看并编辑 jQuery demo 或者 vanilla JS demo

getItemElements(获取项元素)

以数组形式范围一组项元素。

// jQuery
var elems = $grid.masonry('getItemElements')
// vanilla JS
var elems = msnry.getItemElements()

elems · 元素数组

jQuery.fn.data(‘masonry’)

从jQuery对象中获取Masonry实例。Masonry实例在使用Masonry属性时很用有。

var msnry = $('.grid').data('masonry')
// access Masonry properties
console.log( msnry.items.length + ' filtered items'  )

Masonry.data

通过Masonry实例的元素获取Masonry实例。Masonry.data()在通过JavaScript获取Masonry实例时很有用,当Masonry在HTML中初始化以后。

var msnry = Masonry.data( element )

element · 元素或者选择器名称的字符串

msnry · Masonry

<!-- init Masonry in HTML -->
<div class="grid" data-masonry='{...}'>...</div>
// jQuery
// pass in the element, $element[0], not the jQuery object
var msnry = Masonry.data( $('.grid')[0] )

// vanilla JS
// using an element
var grid = document.querySelector('.grid')
var msnry = Masonry.data( grid )
// using a selector string
var msnry = Masonry.data('.grid')

Events(事件)


事件绑定


通过标准的jQuery事件方法.on() , .off() ,还有 .one() 绑定事件。

// jQuery
var $grid = $('.grid').masonry({...});

function onLayout() {
  console.log('layout done');
}
// bind event listener
$grid.on( 'layoutComplete', onLayout );
// un-bind event listener
$grid.off( 'layoutComplete', onLayout );
// bind event listener to be triggered just once. note ONE not ON
$grid.one( 'layoutComplete', function() {
  console.log('layout done, just this one time');
});

jQuery事件监听器具有一个event参数,而 vanilla JS 没有。

// jQuery, has event argument
$grid.on( 'layoutComplete', function( event, items ) {
  console.log( items.length );
});

// vanilla JS, no event argument
msnry.on( 'layoutComplete', function( items ) {
  console.log( items.length );
});

Vanilla JS 事件绑定

用vanilla JS 的方法.on() , .off() ,还有 .once() 绑定事件。

// vanilla JS
var msnry = new Masonry( '.grid', {...});

function onLayout() {
  console.log('layout done');
}
// bind event listener
msnry.on( 'layoutComplete', onLayout );
// un-bind event listener
msnry.off( 'layoutComplete', onLayout );
// bind event listener to be triggered just once
msnry.once( 'layoutComplete', function() {
  console.log('layout done, just this one time');
});

Masonry 事件


layoutComplete(布局完成)

在布局和所有的位置转换效果完成后触发。

// jQuery
$grid.on( 'layoutComplete', function( event, laidOutItems ) {...} )
// vanilla JS
msnry.on( 'layoutComplete', function( laidOutItems ) {...} )

laidOutItems · Masonry.Items数组 · 被展示出的项

$grid.on( 'layoutComplete',
  function( event, laidOutItems ) {
    console.log( 'Masonry layout completed on ' +
      laidOutItems.length + ' items' );
  }
);

查看并编辑 jQuery demo 或者 vanilla JS demo

removeComplete(移除完成)

在某个项元素被移除后触发。

// jQuery
$grid.on( 'removeComplete', function( event, removedItems ) {...} )
// vanilla JS
msnry.on( 'removeComplete', function( removedItems ) {...} )

removedItems · Masonry.Items数组 · 被移除的项

$grid.on( 'removeComplete',
  function( event, removedItems ) {
    notify( 'Removed ' + removedItems.length + ' items' );
  }
);

查看并编辑 jQuery demo 或者 vanilla JS demo


后续ExtrasFAQ部分内容请查看英文原文


译者: DK
微信: dksyydnr

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
瀑布流布局是一种能够自适应不同尺寸图片的布局方式,常用于图片墙等展示图片的场景。在 Vue 中实现瀑布流布局可以通过以下步骤: 1. 安装并引入第三方,如 Masonry 或 Waterfall 等,这些提供了实现瀑布流布局的 API。 2. 在 Vue 组件中,使用第三方提供的 API 实现瀑布流布局。通常需要在组件的 `mounted` 钩子中初始化瀑布流布局,并在数据变化时更新布局。 下面是一个使用 Masonry 实现瀑布流布局的示例代码: ``` <template> <div class="masonry"> <div v-for="item in items" class="masonry-item" :key="item.id"> <img :src="item.src" :alt="item.title"> </div> </div> </template> <script> import Masonry from 'masonry-layout'; export default { data() { return { items: [ { id: 1, src: '...', title: '...' }, { id: 2, src: '...', title: '...' }, // ... ] } }, mounted() { this.masonry = new Masonry('.masonry', { itemSelector: '.masonry-item', columnWidth: '.masonry-sizer', percentPosition: true }); }, updated() { this.$nextTick(() => { this.masonry.reloadItems(); this.masonry.layout(); }); } } </script> <style> .masonry { position: relative; } .masonry-item { margin-bottom: 20px; } .masonry-sizer { width: 25%; } </style> ``` 在上面的代码中,我们使用 Masonry 提供的 API 初始化了瀑布流布局,并在数据变化时更新了布局。需要注意的是,我们在模板中使用了一个 `masonry-sizer` 元素来设置列宽,这是 Masonry 实现瀑布流布局的必要条件之一。 当然,以上只是一个简单的示例代码,具体的实现方式还需要根据具体情况进行调整。希望能对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值