(1).计算属性
1.通过双向绑定与计算属性实现复选框自动选择
双向绑定计算属性,从而实现点击三个checkbox最后一个被选中
<div id="app">
<input
type="checkbox"
v-for="item in items"
:key="item.id"
v-model="item.completed"
/>
<input type="checkbox" v-model="allComputed"/>
</div>
<script>
new Vue({
el:'#app',
data(){
return{
items:[
{
id:1,
completed:true
},
{
id:2,
completed:false
},
{
id:3,
completed:true
},
]
}
},
computed:{
allComputed(){
return this.items.every(item=>{
return item.completed === true
})
}
}
})
</script>
2.计算属性得对象写法
<div id="app">
<input
type="checkbox"
v-for="item in items"
:key="item.id"
v-model="item.completed"
/>
<input type="checkbox" v-model="allComputed"/>
</div>
<script>
new Vue({
el:'#app',
data(){
return{
items:[
{
id:1,
completed:true
},
{
id:2,
completed:false
},
{
id:3,
completed:true
},
]
}
},
computed:{
allComputed:{
get(){
return this.items.every((item)=>{
return item.completed === true
})
},
set(newValue){
this.items.forEach(item => item.completed = newValue)
}
}
}
})
</script>
(2).watch与computed的不同
1.watch能做到得计算属性做不到得
watch:{
question(newQuestion,oldQuestion){
axios.get('https://yesno.wtf/api')
.then(function(res){
console.log(res.data.answer)
})
}
}
2.设置防抖函数 lodash库
<script>
data(){
return{
question:''
}
},
created(){
this.debouceGetAnswer = _.debounce(this.getAnswer,500)
},
watch:{
question:function(newQuestion,oldQuestion){
this.debouceGetAnswer();
}
},
methods:{
getAnswer(){
axios.get('https://yesno.wtf/api').then(function(res){
console.log(res.data.answer)
})
}
}
</script>
3.lodash设置中间状态
<script>
data(){
return{
question:'',
answer:'输入问题'
}
},
created(){
this.debouceGetAnswer = _.debounce(this.getAnswer,500)
},
watch:{
question:function(newQuestion,oldQuestion){
this.getAnswer();
}
},
methods:{
getAnswer(){
this.answer="搜索中.."
axios.get('https://yesno.wtf/api').then(function(res){
this.answer=res.data.answer;
})
}
}
</script>
(3).filter函数过滤器
1.基本使用方式
通过|将原始值传入到value中,return又可以把值再返回出去
<div id="app">
{{timestamp | format('YYYY-MM-DD')}}
<div>
<script>
Vue.filter('format',function(value,formatter){
console.log(value);//值
console.log(formatter);//参数
return moment(value).format(formatter);
})
new Vue({
el:'#app',
data(){
return{
timestamp:1233211233211
}
}
})
</script>
2.多次传递可以有多个,多次传递,先把currency处理了再通过test处理
<div id="app">
{{number | currency | test}}
</div>
<script>
Vue.filter('currency',function(value){
return `$${value}`
})
Vue.filter('test',function(value){
return value
})
</script>
(4).自定义指令实例
1.指令的基本用法
app.vue
<template>
<div>
<NavBar/>
</div>
</template>
<script>
import NavBar from './components/NavBar';
export default{
components:{
NavBar
}
}
navbar.vue
<template>
<div class="nav-bar">
<div
:class="['nav-item',{'nav-active':index === currentIndex}]"
@click="changeIndex(index)"
v-for="(item,index) in items"
:key="index"
>
{{item}}-{{index}}
</div>
</div>
</template>
<script>
export default{
data(){
return{
currentIndex:1,
items:['项目1','项目2','项目3','项目4']
}
},
methods:{
changeIndex(index){
this.currentIndex = index;
}
}
}
</script>
<style>
.nav-bar{
width:300px;
height:50px;
border:1px solid #000;
margin: 0 auto;
}
.nav-item{
float:left;
width:25%;
height:100%;
line-height:50px;
text-align:center;
}
</style>
2.变为自定义指令
<template>
<div class="nav-bar" v-nav-active>
<div
:class="['nav-item',{'nav-active':index === currentIndex}]"
@click="changeIndex(index)"
v-for="(item,index) in items"
:key="index"
>
{{item}}-{{index}}
</div>
</div>
</template>
<script>
import NavActive from '../directives/navActive'
export default{
data(){
return{
currentIndex:1,
items:['项目1','项目2','项目3','项目4']
}
},
methods:{
changeIndex(index){
this.currentIndex = index;
}
}
}
</script>
navActive.js
在div上一绑定就会执行bind的函数
当操作这个div的时候一旦有更新就会执行update函数
可以接收参数
上边下边都要访问不然会报错
1.基本形式
export default{
bind(){
console.log('bind');
},
update(){
console.log('update')
}
}
2.传参
export default{
bind(el,binding){
console.log('bind');
console.log(el);//dom元素
console.log(binding);//一些乱七八糟的参数
},
update(el,binding){
console.log('update');
console.log(el);
console.log(binding)
}
}
3.自定义可以通过.value获取传递过来的值
<div class="nav-bar" v-nav-active="{{message}}">//不可以
<div class="nav-bar" v-nav-active="message">//变量是可以的
<div class="nav-bar" v-nav-active="‘reverseMessage’">//传递字符串
4.实现自定义组件切换样式
<template>
<div class="nav-bar" v-nav-active="{
activeClass:'nav-active',
currentIndex:currentIndex,
className:'nav-item'
}">
<div
class="nav-item"
@click="changeIndex(index)"
v-for="(item,index) in items"
:key="index"
>
{{item}}-{{index}}
</div>
</div>
</template>
<script>
import NavActive from '../directives/navActive'
export default{
data(){
return{
currentIndex:1,
items:['项目1','项目2','项目3','项目4']
}
},
methods:{
changeIndex(index){
this.currentIndex = index;
}
}
}
</script>
navActive.js
这样会导致之前的类去除不掉,所有被点击的都会被加上类
export default{
bind(el,binding){
const element = el,
options = binding.value,
children = element.getElementsByClassName(options.className);
const {activeClass,currentIndex} = options;
children[currentIndex].className+= `${activeClass}`
},
update(el,binding){
console.log('update');
console.log(el);
console.log(binding)
}
}
通过update解决(update中的binding中有新的值和旧的值)
navActive.js
这样写没问题
export default{
bind(el,binding){
const element = el,
options = binding.value,
children = element.getElementsByClassName(options.className);
const {activeClass,currentIndex} = options;
children[currentIndex].className+= `${activeClass}`
},
update(el,binding){
console.log('update');
const element = el,
options = binding.value,
oldOptions = binding.oldValue
children = element.getElementsByClassName(options.className);
const {activeClass,currentIndex} = options;
const {currentIndex:oldIndex,className} = oldOptions;
children[currentIndex].className += `${activeClass}`
children[oldIndex].className = className
}
}
5.自定义指令的拓展(Vue.directive做内部指令)
<div id="xx">
<h3>abc</h3>
<p v-pin:[direction]="200">
cde
</p>
</div>
<script>
Vue.directive('pin',{
bind(el,binding,vnode){
el.style.position = 'fixed';
var s = binding.arg = 'left' ? 'left' : 'top';
el.style[s] = binding.value +'px'
}
})
new Vue({
el:'#xx',
data(){
return {
direction:'left'
}
}
})
</script>