7. 循环遍历
- v-for遍历数组
<div id="app">
<ul>
<li v-for="item in names ">{{item}}</li>
</ul>
<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">
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<ul>
<li v-for="(value,key) in info">{{value}}---{{key}}</li>
</ul>
<ul>
<li v-for="(value,key,index) in info">{{value}}--{{key}}--{{index}}</li>
</ul>
</div>
<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(){
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" :value="message" @input="valueChange">
<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">
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>您选择的是:{{isAgree}}</h2>
<button :disable="!isAgree">下一步</button>
<br>
<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">
<select name="city" v-model="city">
<option value="上海">上海</option>
<option value="北京">北京</option>
<option value="郑州">郑州</option>
</select>
<h2>您选中的城市是:{{city}}</h2>
<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">
<input type="text" v-model.lazy="message">
{{message}}>
<input type="number" v-model.number="age">
<h2>{{typeof age}}</h2>
<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">
<my-cpn></my-cpn>
</div>
<script>
const cpnC = Vue.extend({
template: `
<div>
<h2>标题</h2>
<p>内容1</p>
<p>内容2</p>
</div>`
})
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>
const cpnC = Vue.extend({
template: `
<div>
<h2>标题</h2>
<p>内容1</p>
<p>内容2</p>
</div>`
})
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>
<script>
const cpnC1 = Vue.extend({
template: `
<div>
<h2>标题(1)</h2>
<p>内容(1)</p>
</div>
`
})
const cpnC2 = Vue.extend({
template: `
<div>
<h2>标题(2)</h2>
<p>内容(2)</p>
<cpn1></cpn1>
</div>
`,
components: {
cpn1: cpnC1
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn2:cpnC2
}
})
</script>
- 组件的语法糖注册方式
<script>
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>
<script type="text/x-template" id="cpn">
<div>
<h2>标题</h2>
<p>内容</p>
</div>
</script>
<template id="cpn2">
<div>
<h2>标题</h2>
<p>内容</p>
</div>
</template>
<script src="../js/vue.min.js"></script>
<script>
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(){
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: {
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(){
console.log(this.$children)
for (let c of this.$children){
console.log(c.name)
c.showMessage()
}
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(){
console.log(this.$parent)
console.log(this.$parent.name)
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>
<template slot-scope="slot">
<span>{{slot.data.join(' - ')}}</span>
</template>
</cpn>
</div>
<template id="cpn">
<div>
<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>
|