一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
7. 循环遍历
- v-for遍历数组
<div id="app">
<!--1.在遍历的过程中,没有使用索引值(下标值)-->
<ul>
<li v-for="item in names ">{{item}}</li>
</ul>
<!--2.在遍历的过程中,获取索引值-->
<ul>
<li v-for="(item,index) in names">{{index+1}}.{{item}}</li>
</ul>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
names: ['a','b','c']
}
})
</script>
- v-for遍历对象
<div id="app">
<!--1.在遍历对象的过程中,如果只是获取到一个值,那么获取到的时value-->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<!--2.获取key和value-->
<ul>
<li v-for="(value,key) in info">{{value}}---{{key}}</li>
</ul>
<!--3.获取key和value和index格式:(value,key,index)-->
<ul>
<li v-for="(value,key,index) in info">{{value}}--{{key}}--{{index}}</li>
</ul>
</div>
<!--
why
18
1.88
why---name
18---age
1.88---height
why--name--0
18--age--1
1.88--height--2
-->
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
info: {
name: 'why',
age: 18,
height: 1.88
}
}
})
</script>
- 响应式方法
<div id="app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
<button @click="btnClick">按钮</button>
</div>
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['a','b','c','d']
},
methods: {
btnClick(){
//响应式: //1.push方法
//this.letters.push('f')
//2.pop():删除数组中最后一个元素
//this.letters.pop()
//3.shift():删除数组中的第一个元素
//this.letters.shift()
//4.unshift():在数组最前面添加元素
//this.letters.unshift('aaa','bbb')
//5.splice():删除元素/插入元素/替换元素
//删除元素:第二个参数传入你要删除几个元素(如果没有传,就删除后面所有元素)
//插入元素:第二个参数设置为0,并且后面跟上要插入的元素
//替换元素:第二个参数,表示我们要替换几个元素,后面是用于替换前面的元素
//this.letters.splice(1,2,'m','n')
//6.sort():排序
//this.letters.sort()
//7.reverse():反转
//this.letters.reverse()
//非响应式:
//通过我们的索引值修改数组中的元素(不是响应式的)
//this.letters[0] = 'bb' (X)
//this.letters.splice(0,1,'bb')
//Vue.set(要修改的对象,索引值,修改后的值)
//Vue.set(this.letters,0,'bb')
function sum (...num) {
console.log(num)
}
sum(1,2,3,4,5,6)
}
}
})
</script>
8. v-model的使用
- v-model的使用与原理
<div id="app">
<!-- <input type="text" v-model="message">-->
<input type="text" :value="message" @input="valueChange">
<!-- <input type="text" :value="message" @input="message=$event.target.value">-->
<h2>{{message}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
valueChange(event){
this.message = event.target.value;
}
}
})
</script>
- v-model结合radio
<div id="app">
<label for="male">
<input type="radio" id="male" value="男" v-model="sex">男
</label>
<label for="female">
<input type="radio" id="female" value="女" v-model="sex">女
</label>
<h2>您选择的性别是:{{sex}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
sex: '男'
}
})
</script>
- v-model结合checkbox使用
<div id="app">
<!--1.checkbox单选框-->
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>您选择的是:{{isAgree}}</h2>
<button :disable="!isAgree">下一步</button>
<br>
<!--2.checkbox多选框-->
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="排球" v-model="hobbies">排球
<h2>您的爱好是:{{hobbies}}</h2>
<label v-for="item in originHobbies" :for="item">
<input type="checkbox" :value="item" :id="item">{{item}}
</label>
</div>
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isAgree: false,//单选框
hobbies: [], //多选框
originHobbies: ['篮球','足球','排球']
}
})
</script>
- v-model结合select使用
<div id="app">
<!--1.选择一个-->
<select name="city" v-model="city">
<option value="上海">上海</option>
<option value="北京">北京</option>
<option value="郑州">郑州</option>
</select>
<h2>您选中的城市是:{{city}}</h2>
<!--2.选择多个-->
<select name="citys" v-model="citys" multiple>
<option value="上海">上海</option>
<option value="北京">北京</option>
<option value="郑州">郑州</option>
</select>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
city: '上海',
citys: []
}
})
</script>
- v-model的修饰符的使用
<div id="app">
<!--1.修饰符:lazy(只有输入完成后才会更新)-->
<input type="text" v-model.lazy="message">
{{message}}>
<!--2.修饰符: number v-model默认是String类型(将string类型改为number类型)-->
<input type="number" v-model.number="age">
<h2>{{typeof age}}</h2>
<!--3.修饰符:trim(去除首尾的空格)-->
<input type="text" v-model.trim="name">
<h2>您输入的名字:{{name}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
age: 0,
name: ''
}
})
</script>
9. 组件化开发
- 组件化的基本使用
- 创建组件构造器对象
- 注册组件
- 使用组件
<div id="app">
<!--3.使用组件-->
<my-cpn></my-cpn>
</div>
<script>
//1.创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>标题</h2>
<p>内容1</p>
<p>内容2</p>
</div>`
})
//2.注册组件
Vue.component('my-cpn',cpnC)
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
- 全局组件和局部组件
- 全局组件:多个Vue实例都可以使用
- 局部组件:只有单个Vue实例可以使用
<div id="app">
<cpn></cpn>
</div>
<div id="app2">
<cpn></cpn><!-- 没有作用 -->
</div>
<script src="../js/vue.min.js"></script>
<script>
//1.创建组件构造器
const cpnC = Vue.extend({
template: `
<div>
<h2>标题</h2>
<p>内容1</p>
<p>内容2</p>
</div>`
})
//2.注册组件(全局组件,意味着可以在多个Vue实例下使用)
//Vue.component('cpn',cpnC)
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: cpnC //注册局部组件
}
})
const app2 = new Vue({
el: '#app2',
data: {
message: '你好啊'
}
})
</script>
- 父组件和子组件
<div id="app">
<cpn2></cpn2>
</div>
<!--
标题(2)
内容(2)
标题(1)
内容(1)
-->
<script>
//1.创建第一个组件构造器(子组件)
const cpnC1 = Vue.extend({
template: `
<div>
<h2>标题(1)</h2>
<p>内容(1)</p>
</div>
`
})
//2.创建第二组件构造器(父组件)
const cpnC2 = Vue.extend({
template: `
<div>
<h2>标题(2)</h2>
<p>内容(2)</p>
<cpn1></cpn1>
</div>
`,
components: {
cpn1: cpnC1
}
})
//root组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn2:cpnC2
}
})
</script>
- 组件的语法糖注册方式
<script>
//全局组件语法糖
//1.创建组件构造器
//const cpn1 = Vue.extend()
//2.注册组件
Vue.component('cpn1',{
template: `
<div>
<h2>标题(1)</h2>
<p>内容(1)</p>
</div>`
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
'cpn2': {
template: `
<div>
<h2>标题(2)</h2>
<p>内容(2)</p>
</div>`
}
}
})
</script>
- 组件模板的分离写法
<div id="app">
<cpn></cpn>
<cpn2></cpn2>
</div>
<!--1.script标签,注意:类型必须是text/x-template-->
<script type="text/x-template" id="cpn">
<div>
<h2>标题</h2>
<p>内容</p>
</div>
</script>
<!--2.template标签-->
<template id="cpn2">
<div>
<h2>标题</h2>
<p>内容</p>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
//1.注册一个全局组件
Vue.component('cpn',{
template: '#cpn'
})
Vue.component('cpn2',{
template: '#cpn2'
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
- 组件中的数据存放
<div id="app">
<cpn></cpn>
</div>
<template id="cpnTemplate">
<div>
<h2>{{title}}</h2>
<p>{{content}}</p>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
Vue.component('cpn',{
template: '#cpnTemplate',
data(){
//组件中的data是函数
//是函数的原因是因为不想让多个实例引用这个组件导致其中一个改变使得其他的数据也改变
return {
title: '标题',
content: '内容'
}
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
10. 组件通信
- 父传子【props】
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpnTemplate">
<div>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
{{cmessage}}
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
// <!--父传子-->
const cpn = {
template: '#cpnTemplate',
//props: ['cmovies','cmessage'],
props: {
//1.类型限制:(支持的类型:String Number Boolean Array Object Date Function Symbol)
//cmovies: Array,
//cmessage:String
//2.提供一些默认值
cmessage: {
type: String,
default: 'test',
required: true
},
cmovies: {
type: Array,
default() {
return []
}
}
},
data(){
return {
}
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['火影忍者','海贼王','奥特曼']
},
components:{
'cpn':cpn
}
})
</script>
- 父传子【驼峰问题】
<div id="app">
<!--驼峰不能写,要改为'-' -->
<cpn :c-info="info"></cpn>
</div>
<template id="cpn">
<div>
<ul>
<li v-for="item in cInfo">{{item}}</li>
</ul>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
const cpn = {
template: '#cpn',
props: {
cInfo: {
type:Object,
default(){
return {}
}
}
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
info: {
name: 'go',
age: 18,
height: 1.71
}
},
components: {
'cpn':cpn
}
})
</script>
- 子传父【自定义事件】
<!--父组件模板-->
<div id="app">
<cpn @itemclick="cpnClick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories"
@click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
//子组件
const cpn = {
template: '#cpn',
data(){
return {
categories: [
{id:'a',name:'热门推荐'},
{id:'b',name:'手机数码'},
{id:'c',name:'家用家电'},
]
}
},
methods: {
btnClick(item){
//发射事件
this.$emit('itemclick',item)
}
}
}
//父组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn
},
methods: {
cpnClick(item){
console.log(item)
}
}
})
</script>
- 父访问子
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn ref="c"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>我是组件!</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data(){
return {
name: '我是子组件的name'
}
},
methods: {
showMessage(){
console.log('showMessage')
}
}
}
},
methods: {
btnClick(){
//1.$children
console.log(this.$children)
for (let c of this.$children){
console.log(c.name)
c.showMessage()
}
//2.$refs => 对象类型,默认是一个空对象,要加上ref
console.log(this.$refs.c.name)
}
}
})
</script>
- 子访问父
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>我是cpn组件</h2>
<ccpn></ccpn>
</div>
</template>
<template id="ccpn">
<div>
<h2>我是子组件</h2>
<button @click="btnClick">按钮</button>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data(){
return {
name: '我是cpn组件的name'
}
},
components: {
ccpn: {
template: '#ccpn',
methods: {
btnClick(){
//1.访问父组件$parent
console.log(this.$parent)
console.log(this.$parent.name)
//2.访问根组件$root
console.log(this.$root)
console.log(this.$root.message)
}
}
}
}
}
},
})
</script>
11. 插槽
- 插槽的基本使用
- 插槽用来预留空间的
<div id="app">
<cpn><button>按钮</button></cpn>
<cpn><span>哈哈</span></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>我是组件</h2>
<p>我是组件内容</p>
<!--插槽用来预留空间-->
<slot><button>按钮</button></slot>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>
- 具名插槽
- 具名插槽给插槽取名,然后可以指定改变哪个插槽内容
<div id="app">
<cpn>
<span slot="center">标题</span>
</cpn>
</div>
<template id="cpn">
<div>
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>
- 作用域插槽
<div id="app">
<cpn>
<!--获取到子组件中的planguages。slot名字是我们自己起的,可以用其他的-->
<template slot-scope="slot">
<span>{{slot.data.join(' - ')}}</span>
</template>
</cpn>
</div>
<template id="cpn">
<div>
<!-- data名字是我们自己起的,也可以起其他名字 -->
<slot :data="planguages">
<ul>
<li v-for="item in planguages">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data(){
return {
planguages: ['java','python','c','c++']
}
}
}
}
})
</script>