第一阶段B(前端框架)11天 64学时
第7章 VUE进阶(6)
[学习课时] 本章共需要学习 18 课时
[目的要求]
- 掌握VUE组件的使用
[教学内容]
VUE组件
- 创建组件
语法:
参数:
{string} id
{Function | Object} [definition]
用法:
注册或获取全局组件。注册还会自动使用给定的id
设置组件的名称
// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* ... */ }))
// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', { /* ... */ })
// 获取注册的组件 (始终返回构造器)
var MyComponent = Vue.component('my-component')
注册局部组件
通过一个普通的 JavaScript 对象来定义组件:
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
然后在 components 选项中定义你想要使用的组件:
new Vue({
el: '#app'
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。
案例:demo01
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
{{ message }}
<button-counter></button-counter>
<button-counter></button-counter>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function() {
return {
count: 0
}
},
template: '<button v-on:click="count++">点击数字加一 {{ count }}</button>'
})
var app = new Vue({
el: '#app',
data: {
message: '你好呀,这是vue绑定的数据!'
}
})
</script>
</html>
效果图
当我们定义这个 <button-counter> 组件时,你可能会发现它的 data 并不是像这样直接提供一个对象:
|
取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
|
如果 Vue 没有这条规则,点击一个按钮就可能会像如下代码一样影响到其它所有实例:
- 通过 Props 向模版内传递数据
Props可以理解为组件的自定义属性,就像html元素的属性。
Vue.component('msg', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
案例:demo02
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
{{message}}
<ul>
<msg count="123"></msg>
<msg count="456"></msg>
</ul>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('msg', {
props: ['count'],
template: '<li> {{count}} </li>'
})
var app = new Vue({
el: '#app',
data: {
message: '你好呀,这是vue绑定的数据!'
}
})
</script>
</html>
效果图
使用 v-bind 来动态传递 prop,
v-bind:自定义属性名
案例:demo03
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.item {
height: 100px;
background-color: rgba(255,255,0,0.06);
padding: 10px 10px;
margin: 10px 0px;
box-shadow: 2px 3px 2px 1px gainsboro,
1px 1px 0px 1px gainsboro inset;
}
.item:hover{
background-color: rgba(255,0,0,0.06);
}
.avatar {
width: 100px;
height: 100px;
text-align: center;
float: left;
}
.avatar img {
width: 100%;
}
.content {
height: 100px;
padding-left: 100px;
}
.title {
height: 30px;
line-height: 30px;
font-size: 25px;
border-bottom: 1px solid gainsboro;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
padding: 0px 10px;
}
.desc {
height: 50px;
overflow: hidden;
color: grey;
padding: 10px 10px;
}
</style>
</head>
<body>
<div id="app">
<ul>
<msg v-for="n in news" v-bind:n="n"></msg>
</ul>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('msg', {
props: ['n'],
template: '<li> <div class="item"> <div class="avatar"> <img v-bind:src="n.img" /> </div> <div class="content"> <div class="title">{{n.title}}</div> <div class="desc">{{n.desc}}</div> </div> </div> </li>'
})
// 数据对象
var data = {
news: [{
img: 'img/avatar-1.jpg',
title: '拆解“高岭之花”十元女神的妆容小心机',
desc: '日剧《高岭之花》自从开播就收视不俗,剧中石原里美不停穿插时装与和服造型,让粉丝看得非常过瘾!'
}, {
img: 'img/avatar-2.jpg',
title: '一双乐福鞋 搞定秋季所有搭配',
desc: '天气转凉,夏天的各种露脚趾和露脚背的鞋都要准备收起来了,再也不用兢兢业业、精精致致地涂好每一颗脚趾甲(是不是松了一口气?)是时候提前把适合秋天的鞋子准备起来了,而单凭一己之力就能撑过整个秋天的鞋子非Loafer莫属。'
}, {
img: 'img/avatar-3.jpg',
title: '又不知道做什么样的美甲?莫兰迪色调了解一下',
desc: '因《延禧攻略》而爆红的「莫兰迪色调」最近成为热搜,挑选了「莫兰迪色」指甲油,做出五种美甲变化,其中有单色跳色的搭配,女孩可以直接模仿,或从中挑选出喜欢的颜色买回家自己擦'
}]
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
- 在组件中绑定事件$emit
$emit用在组件模版中,可以定义组件模版内自定义事件。
案例:demo04
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<ul>
<!--v-on:test="count++"——访问组件内的自定义事件test,并且让count自增-->
<!--v-bind:count——向组件内传入count变量-->
<msg v-on:test="count++" v-bind:count="count"></msg>
</ul>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('msg', {
props: ['count'],
//v-on:click="$emit(\'test\')"——通过$emit将自定义属性绑定到click事件上
template: '<button v-on:click="$emit(\'test\')">点击次数{{count}}</button>'
})
// 数据对象
var data = {
count: 0
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
还可以使用 $emit 的第二个参数来提供一个值,然后通过$event 访问到这个值。
案例:demo05
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<ul>
<!--v-on:test="fun"——访问组件内的自定义事件test,并且调用抛出的变量10-->
<!--v-bind:count——向组件内传入count变量-->
<msg v-on:test="count += $event" v-bind:count="count"></msg>
</ul>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('msg', {
props: ['count'],
//v-on:click="$emit(\'test\',10)"——通过$emit将自定义属性绑定到click事件上
template: '<button v-on:click="$emit(\'test\',10)">点击次数{{count}}</button>'
})
// 数据对象
var data = {
count: 0
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
也可以直接调用某个方法
案例:demo06
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<ul>
<!--v-on:test="fun"——访问组件内的自定义事件test,并且调用fun方法-->
<!--v-bind:count——向组件内传入count变量-->
<msg v-on:test="fun" v-bind:count="count"></msg>
</ul>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('msg', {
props: ['count'],
//v-on:click="$emit(\'test\',10)"——通过$emit将自定义属性绑定到click事件上
template: '<button v-on:click="$emit(\'test\',10)">点击次数{{count}}</button>'
})
// 数据对象
var data = {
count: 0
};
var app = new Vue({
el: '#app',
data: data,
methods: {
fun: function(enlargeAmount) {
alert(enlargeAmount);
}
}
})
</script>
</html>
效果图
- 在组件中使用v-model
为了让它正常工作,这个组件内的 <input> 必须:
- 将其 value 特性绑定到一个名叫 value 的 prop 上
- 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
案例:demo07
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<ul>
<msg v-model="searchText"></msg>
<span>{{searchText}}</span>
</ul>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('msg', {
props: ['searchText'],
//v-on:input="$emit(\'input\', $event.target.value)"——通过$emit将输入框的值传入input事件内
template: '<input v-bind:value="searchText" v-on:input="$emit(\'input\', $event.target.value)"></input>'
})
// 数据对象
var data = {
searchText: '默认文字'
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
- 模版内容slot
<slot></slot>用于在模版内将模版标签的内容添加到模版内的元素内容中
案例:demo08
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<ul>
<!--模版内的内容会通过<slot></slot>标签添加到模版内-->
<msg>添加的文字</msg>
<msg>
<div>
<img src="avatar.jpg" width="100"/>
</div>
</msg>
<span>{{searchText}}</span>
</ul>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('msg', {
props: ['searchText'],
template: '<span><slot></slot></span>'
})
// 数据对象
var data = {
searchText: '默认文字'
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
- 动态组件
动态组件就是可以在需要的时候动态的切换组件。
- 需要使用<component>组件
- 再在<component>上添加v-bind:is属性动态绑定组件名
案例:demo09
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button
v-for="tab in tabs"
v-bind:key="tab"
v-on:click="currentTab = tab">{{ tab }}</button>
<component
v-bind:is="currentTabComponent"></component>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('tab-page-1', {
template: '<div>第一个组件</div>'
})
Vue.component('tab-page-2', {
template: '<div>第二个组件</div>'
})
Vue.component('tab-page-3', {
template: '<div>第三个组件</div>'
})
// 数据对象
var data = {
currentTab: 'page-1',
tabs: ['page-1', 'page-2', 'page-3']
};
var app = new Vue({
el: '#app',
data: data,
computed: {
currentTabComponent: function() {
//必须使用this.currentTab
return 'tab-' + this.currentTab.toLowerCase();
}
}
})
</script>
</html>
效果图
VUE过度
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
- 条件渲染 (使用 v-if)
- 条件展示 (使用 v-show)
- 动态组件
- 组件根节点
案例:demo10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button v-on:click="show = !show">显示/隐藏</button>
<transition name="fade">
<p v-if="show">使用transition来实现fade属性</p>
</transition>
</div>
</body>
<script type="text/javascript">
// 数据对象
var data = {
show: true
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
- 自定义过渡效果
在进入/离开的过渡中,会有 6 个 class 切换。
v-enter
:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。v-enter-to
: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时v-enter
被移除),在过渡/动画完成之后移除。v-leave
: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。v-leave-to
: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时v-leave
被删除),在过渡/动画完成之后移除。
对于这些在过渡中切换的类名来说,如果你使用一个没有名字的<transition>,则 v-是这些类名的默认前缀。如果你使用了<transition name="my-transition">,那么v-enter 会替换为 my-transition-enter。
v-enter-active 和 v-leave-active 可以控制进入/离开过渡的不同的缓和曲线
案例:demo11
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/animate.min.css"/>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<style type="text/css">
.name-enter{
font-size: 0px;
}
.name-enter-to{
font-size: 30px;
color: red;
}
.name-enter-active{
transition-duration: 3s;
}
.name-leave{
font-size: 30px;
}
.name-leave-to{
font-size: 0px;
}
.name-leave-active{
transition-duration: 3s;
}
</style>
<div id="app">
<button v-on:click="show = !show">显示/隐藏</button>
<transition name="name">
<p v-if="show">使用transition来实现fade属性</p>
</transition>
</div>
</body>
<script type="text/javascript">
// 数据对象
var data = {
show: true
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
我们可以通过以下特性来自定义过渡类名:
enter-class
enter-active-class
enter-to-class
(2.1.8+)
leave-class
leave-active-class
leave-to-class
(2.1.8+)
他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。
案例:demo12
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/animate.min.css"/>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button v-on:click="show = !show">显示/隐藏</button>
<transition name="name"
enter-active-class="animated bounceInDown"
leave-active-class="animated bounceOutRight">
<p v-if="show">使用transition来实现fade属性</p>
</transition>
</div>
</body>
<script type="text/javascript">
// 数据对象
var data = {
show: true
};
var app = new Vue({
el: '#app',
data: data
})
</script>
</html>
效果图
- 过度事件
可以使用下面的如下如下这些事件:
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled" leaveCancelled 只用于 v-show 中
>
</transition>
案例:demo13
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/animate.min.css"/>
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button v-on:click="show = !show">显示/隐藏</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave">
<p v-if="show">使用transition来实现fade属性</p>
</transition>
</div>
</body>
<script type="text/javascript">
// 数据对象
var data = {
show: true
};
// 事件对象
var methods = {
beforeEnter: function(el) {
console.log('进入过度前');
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter: function(el, done) {
console.log('开始进入过度');
},
afterEnter: function(el) {
console.log('进入过度后');
},
beforeLeave: function(el) {
console.log('退出过度前');
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
leave: function(el, done) {
console.log('开始退出过度');
},
afterLeave: function(el) {
console.log('退出过度后');
}
};
var app = new Vue({
el:'#app',
data: data,
methods:methods
})
</script>
</html>
效果图
- 多个按钮状态切换
原理:
使用多个 v-if 的多个元素的过渡可以重写为绑定了动态属性的单个元素过渡。例如:
<transition>
<button v-if="docState === 'saved'" key="saved">
编辑
</button>
<button v-if="docState === 'edited'" key="edited">
保存
</button>
<button v-if="docState === 'editing'" key="editing">
取消
</button>
</transition>
可以重写为:
<transition>
<button v-bind:key="docState">
{{buttonMessage}}
</button>
</transition>
然后VUE会自动在多个按钮状态之间切换,当然也可以添加自定义的动画等
过渡模式有两种:
- in-out:新元素先进行过渡,完成之后当前元素过渡离开。
- out-in:当前元素先进行过渡,完成之后新元素过渡进入。
案例:demo14
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/animate.min.css" />
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<transition mode="in-out">
<button v-bind:key="docState" @click="change">
{{ buttonMessage }}
</button>
</transition>
<br>
<transition mode="out-in"
enter-active-class="animated bounceInDown"
leave-active-class="animated bounceOutRight">
<button v-bind:key="docState" @click="change">
{{ buttonMessage }}
</button>
</transition>
</div>
</body>
<script type="text/javascript">
// 数据对象
var data = {
index: 0,
isEditing: true,
arr: ['saved', 'edited', 'editing']
};
// 事件对象
var computed = {
docState: function() {
return this.arr[this.index];
},
buttonMessage: function() {
switch(this.docState) {
case 'saved':
return '编辑'
case 'edited':
return '保存'
case 'editing':
return '取消'
}
}
};
var methods = {
change:function() {
this.index = (++this.index) % 3;
}
};
var app = new Vue({
el: '#app',
data: data,
computed: computed,
methods: methods
})
</script>
</html>
效果图
- 多个组件过度切换
多个组件也可以利用这个原理来实现相互切换。
案例:demo15
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/animate.min.css" />
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button
v-for="tab in tabs"
v-bind:key="tab"
v-on:click="view = tab">{{ tab }}</button>
<transition
mode="out-in"
enter-active-class="animated bounceInDown"
leave-active-class="animated bounceOutUp">
<component v-bind:is="view"></component>
</transition>
</div>
</body>
<script type="text/javascript">
// 定义一个名为 button-counter 的新组件
Vue.component('tab-page-1', {
template: '<div>第1个组件</div>'
})
Vue.component('tab-page-2', {
template: '<div>第2个组件</div>'
})
Vue.component('tab-page-3', {
template: '<div>第3个组件</div>'
})
// 数据对象
var data = {
view: 'tab-page-1',
tabs: ['tab-page-1', 'tab-page-2', 'tab-page-3']
};
// 事件对象
var computed = {
currentTabComponent: function() {
//必须使用this.currentTab
return 'tab-' + this.currentTab.toLowerCase();
}
};
var app = new Vue({
el: '#app',
data: data,
computed: computed
})
</script>
</html>
效果图
- 列表过渡
列表需要显示所有的列表项,显然不能再使用<transition></transition>,因为<transition></transition>在同一时间只会显示一个元素,
所有需要使用另一个过度<transition-group></transition-group>,这个组件过渡模式不可用。
案例:demo16
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/animate.min.css" />
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button v-on:click="add">添加</button>
<button v-on:click="remove">删除</button>
<transition-group
mode="out-in"
enter-active-class="animated bounceInDown"
leave-active-class="animated bounceOutRight">
<div v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</div>
</transition-group>
</div>
</body>
<script type="text/javascript">
// 数据对象
var data = {
items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
nextNum: 10
};
// 事件对象
var methods = {
randomIndex: function() {
return Math.floor(Math.random() * this.items.length)
},
add: function() {
//splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目
//index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
//howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
//item1, ..., itemX 可选。向数组添加的新项目。
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function() {
this.items.splice(this.randomIndex(), 1)
},
};
var app = new Vue({
el: '#app',
data: data,
methods: methods
})
</script>
</html>
效果图
- 列表打乱顺序
想打乱顺序只需要打乱原本数据的顺序,VUE就会自动更新数据,并且当数据变化后,数据交换的时候还会出发过度效果。
案例:demo16
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="css/animate.min.css" />
<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
<script src="lodash.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button v-on:click="add">添加</button>
<button v-on:click="remove">删除</button>
<button v-on:click="shuffle">乱序</button>
<transition-group
mode="out-in"
enter-active-class="animated bounceInDown"
leave-active-class="animated bounceOutRight">
<div v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</div>
</transition-group>
</div>
</body>
<script type="text/javascript">
// 数据对象
var data = {
items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
nextNum: 10
};
// 事件对象
var methods = {
randomIndex: function() {
return Math.floor(Math.random() * this.items.length)
},
add: function() {
//splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目
//index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
//howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
//item1, ..., itemX 可选。向数组添加的新项目。
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function() {
this.items.splice(this.randomIndex(), 1)
},
shuffle: function() {
this.items.sort(function(){
return 0.5 - Math.random();
});
}
};
var app = new Vue({
el: '#app',
data: data,
methods: methods
});
function shuffle(arr) {
var index = -1;
var length = arr.length;
var lastIndex = length - 1;
var size = size === undefined ? length : size;
while(++index < size) {
var rand = index + Math.floor(Math.random() * (lastIndex - index + 1));
var value = arr[rand];
arr[rand] = arr[index];
arr[index] = value;
}
arr.length = size;
return arr;
}
</script>
</html>
效果图
[作业实验]
- 打乱矩阵
- HTML+CSS+JS精细化教程(新)适合学习和巩固基础(必掌握技能)
- JAVA语言(面向对象都不是事,重点是多线程、反射、网络编程、界面编程、设计模式、工程架构、文件系统)
- JAVA WEB(MySQL、JDBC、JSP、JSTL、EL、Servlet、Spring、Struts、MyBatis、SpringData等)
- Spring Boot2(新版2.X、底层原理深入剖析、更有点餐系统、大型博客系统、商铺平台等完整项目开始视频和源码)
- Python(小白基础语法、RESTfull API开发、爬虫、Django、Linux系统、制作小工具)
- Photoshop(CS5、CS6、CC2018视频教程、海量素材、酷炫特效制作、经典案例几百集)
- Unity2D/3D(手游开发、脚本开发、3D人物模型设计、3D动画、3D塔防游戏、第一人称游戏案例视频跟着做)
- Android原生开发(大型OA系统、游戏开发、物联网开发、3D模型显示、单机游戏开发)
- IOS原生开发(各种收费应用、游戏开发、工具开发、物联网开发)
- PHP(HTML+CSS+JS+PHP+MySQL+MVC+ThinkPHP+Linux+Nginx+Redis)