一. 计算属性
1.1. 计算属性的本质
-
fullname: {set(), get()}
计算属性不加动词,一般不用set(),为只读属性。
computed:{ fullName:{ get:function () { return this.firstName+' '+this.lastName } } // 等价于 // fuLLName:function () { // return this.firstName+' '+this.lastName // } // } })
1.2. 计算属性和methods对比
- 计算属性computed在多次使用时, 只会调用一次。
- methods每次值更新都会调用
- computed是有缓存的
二. 事件监听
2.1. 事件监听基本使用
- v-on: 语法糖 @:
2.2. 参数问题
-
btnClick
无参数时默认传入event事件
-
btnClick(event)
-
btnClick(abc, event) -> $event
2.3. 修饰符
- stop
- prevent
- .enter
- .once
- .native
<div id="app">
<!-- .stop阻止冒泡-->
<div @click="divClick">
<button @click.stop="btnClick">按钮</button>
</div>
<br>
<!-- prevent阻止默认事件-->
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<!-- 监听某个键盘的操作-->
<input type="text" @keyup.enter="keyUp">
<!-- .once修饰符的使用-->
<button @click.once="btn2Click">按钮2</button>
</div>
三. 条件判断
3.1. v-if/v-else-if/v-else
略
3.2. 登录小案例
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="请输入账号">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="请输入邮箱">
</span>
<button @click="isUser=!isUser">切换类型</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data:{
isUser:true,
}
})
</script>
3.3. v-show
- v-show和v-if区别
<!-- v-if当条件为false时,不会存在Dom中-->
<h2 v-if="isShow" id="aaa">{{message}}</h2>
<!-- V-show只是给元素添加了行内样式:dispaly:none-->
<!-- V-show并不会消失,其依旧存放在Dom中-->
<h2 v-show="isShow" id="bbb">{{message}}</h2>
四. 循环遍历
4.1. 遍历数组
v-for自带index下标
<div id="app">
<ul>
<li v-for="item in letters" :key="index">{{item}}</li>
</ul>
</div>
<script>
const app=new Vue({
el: '#app',
data:{
letters:['A','B','C','D','E']
}
})
</script>
4.2. 遍历对象
- value
- value, key
- value, key, index
4.3. 数组哪些方法是响应式的
1.push方法 this.letters.push('aaa')
2.通过索引值修改数组中的元素(不响应 this.letters[1]='bbb';
3.pop() 删除最后元素 响应
4.shift() 删除第一元素 响应
5.unshift() 在数组最前面添加元素 响应
6.splice(start,start+X,追加元素值) 删除\替换\插入元素 响应
7.sort() 排序 响应
8.reverse() 反转 响应
9.set(要修改的对象,索引值,修改后的值)
4.4. 作业完成
题目:点哪哪亮
<style>
.active{
color: red;
}
</style>
<body>
<div id="app">
<ul>
<li v-for="(item,index) in movies" //关键点:传入index索引
:class="{active: currentIndex === index}"
@click="currentIndex=index">
{{index}}--{{item}}
</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data:{
movies:['海王','海贼王','加勒比海盗','海尔兄弟'],
currentIndex:0
}
})
</script>
五. 书籍案例
六. v-model的使用
6.1. v-model的基本使用
- v-model <=> v-bind:value && v-on:input
6.2. v-model和radio/checkbox/select
6.3. 修饰符
- lazy:失去焦点后更新
- number:指定数字类型
- trim:修剪空格
七. 组件化开发(重点)
7.1. 认识组件化
组件化实现组件模块复用
7.2. 组件的基本使用
<script>
//1.创建组件构造器对象
const cpnC=Vue.extend({
template:` //使用` `可换行
<div>
<h2>我是标题</h2>
<h2>我是内容AAA</h2>
<h2>我是内容BBB</h2>
</div>`
})
//2.注册组件
Vue.component('my-cpn',cpnC)
const app=new Vue({
el: '#app',
data:{
message: '你好啊'
}
})
</script>
7.3. 全局组件和局部组件
<script>
const cpnC=Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容AAAA</p>
</div>
`
})
Vue.component('cpn',cpnC) //全局组件,可以在多个Vue的实例下使用
const app=new Vue({
el: '#app',
data:{
message: '你好啊'
},
components:{ //局部组件,只能在当前Vue实例下使用
//cpn使用组件时的标签名
cpn:cpnC
}
})
</script>
7.4. 父组件和子组件
<script>
const cpnC1=Vue.extend({ //子组件
template:`
<div>
<h2>我是标题</h2>
<p>哈哈哈哈哈哈</p>
</div>
`
})
const cpnC2=Vue.extend({ //父组件
template:`
<div>
<h2>我是标题2</h2>
<p>呵呵呵呵呵呵</p>
<cpn1></cpn1>
</div>
`,
components:{
cpn1:cpnC1
}
})
const app=new Vue({ //root根组件
el: '#app',
data:{
message: '你好啊'
},
components:{
cpn2:cpnC2
}
})
</script>
7.5. 注册的语法糖
<script>
Vue.component('cpn1',{ //全局组件注册的语法糖
template:`
<div>
<h2>我是标题2</h2>
<p>呵呵呵呵呵呵</p>
</div>
`
})
const app=new Vue({
el: '#app',
data:{
message: '你好啊'
},
components:{
'cpn2':{ //注册局部组件语法糖
template:`
<div>
<h2>我是标题2</h2>
<p>呵呵呵呵呵呵</p>
</div>
`
}
}
})
</script>
7.6. 模板的分类写法
-
script
<!--1.script标签模板写法--> <script type="text/x-template" id="cpn1"> <div> <h2>我是标题</h2> <p>我是内容</p> </div> </script>
-
template
<!--2.template标签模板写法--> <template id="cpn2"> <div> <h2>我是标题2</h2> <p>呵呵呵呵呵呵</p> </div> </template>
template:’#ID’
Vue.component('cpn',{
template: '#cpn2',
})
7.7. 数据的存放
- 子组件不能直接访问父组件
- 子组件中有自己的data, 而且必须是一个函数.
- 为什么必须是一个函数.
7.8. 父子组件的通信
-
父传子: props
<script> // <!-- 父传子props--> const cpn={ template:'#cpn', //数组方式 // props:['cmovies','cmessage'], props:{ //与子组件通信 //1.类型限制 // cmovies:Array, // cmessage:String //2.提供一些信息 cmessage:{ type:String, default:'aaaaaaaa' }, cmovies:{ type:Array, default:[], } }, data(){ return{} }, methods:{} } const app=new Vue({ el: '#app', data:{ message: '你好啊', movies:['海王','海贼王','海尔兄弟'] }, components:{ cpn } }) </script>
使用:
<div id="app"> <cpn v-bind:cmovies="movies" :cmessage="message"></cpn> </div> <template id="cpn"> <div> <ul> <li v-for="item in cmovies">{{item}}</li> </ul> <h2>{{cmessage}}</h2> </div> </template>
-
子传父: $emit
<script> //子组件 const cpn={ template:'#cpn', data(){ return{ categories:[ {id:'aaa',name: '热门推荐'}, {id:'bbb',name: '手机数码'}, {id:'ccc',name: '家用家电'}, {id:'ddd',name: '电脑办公'} ] } }, methods:{ btnClick(item){ //发射自定义事件 this.$emit('itemclick',item) } } } //父组件 const app=new Vue({ el: '#app', data:{ info:{ name:'why', age:18, height:1.88 }, message:'aaaaaa' }, components:{ cpn }, methods: { cpnClick(item){ console.log('clickhappen',item); } } }) </script>