数据相关
Vue.set
向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。
对于没有响应式的数据,进行数据的双向绑定。例如:没有在data中初始化声明的数据,后期添加的数据,就不是响应式的数据
使用方法:Vue.set(target, propertyName/index, value)
vm.$set(target, propertyName/index, value)
<!-- input中会以字符串的形式,传输到数据中,这里需要加修饰符.number,将来这个值会转换成数字-->
<p><input type="text" v-model.number="price"><button @click="batchPrice">批量更新价格</button></p>
<div>
<p v-if="courses.length == 0">暂无课程数据</p>
<ul v-else>
<li v-for="item in courses" :key="item.name" :class="{active: item.name === selectedCourse}" @click="selectedCourse = item.name">{{item.name}} -- ¥{{item.price}}</li>
</ul>
</div>
// 将vue绑定到宿主元素中
// 1.创建vue实例
const app = new Vue({
el: '#app',
data: {
courses: [{name: '大数据'}, {name: ' web'}]
price: 0
},
created () {
this.batchPrice();
},
methods: {
// 批量更新价格
batchPrice () {
this.courses.forEach(item => {
// 使用下面的写法价格不会被批量更新,因为price不是响应式的数据
// item.price = this.price;
// 两种方式调用
this.$set(item, 'price', this.price)
// Vue.set(item, 'price', this.price)
// this.$set是Vue.set的别名
})
}
}
})
Vue.delete
删除响应式的数据。如果使用delete 属性
的方式来删除响应式的数据的话,页面是不会被重新渲染的(即监听不到数据的删除)
有两种使用方式
Vue.delete(target, propertyName/index)
this.$delete(target, propertyName/index)
// vm.$delete是Vue.delete的别名
事件相关的API
vm.$on
vm表示vue的实例,或者是组件的实例
事件监听
这个如果是写在模板中的话,则会写成@名称="函数/表达式"
// 如果写在模板中,则写成
// @test="callback"
// 编程的方式来写
vm.$on('test', (msg) => {
console.log(msg)
})
事件的派发者和监听者是同一个实例
vm.$emit
派发事件
this.$emit('test', 'param')
vm.$once
事件只监听一次
监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除
vm.$once('test', (msg) => {
console.log(msg)
})
vm.$off
移出事件监听
this.$off() // 移除当前实例所有的监听
this.$off('test') // 移除该事件的所有监听
this.$off('test', callback) // 移除该事件的回调的监听
典型的应用:事件总线的案例
事件的监听者和派发者必须是同一个组件
<!-- 提示 -->
<!-- 默认插槽 -->
<message :show="show" @close="show = $event">新增成功</message>
<!-- 修饰符sync的使用 -->
<message2 :show2="show2" @update:show2="show2 = $event">新增成功</message2>
// 派发事件总线
<button @click="$bus.$emit('clear')">清除全部的提示</button>
// 设置事件总线,为了在任意组件中可以访问到$bus
Vue.prototype.$bus = new Vue();
// 提示框 --- 默认插槽
Vue.component('message', {
props: ['show'],
mounted () {
// 监听事件总线
this.$bus.$on('clear', () => {
this.$emit('close', false);
})
},
template: `
<div v-if="show">
<slot>默认提示</slot>
<span @click="$emit('close', false)">×</span>
</div>
`
})
// 提示框 --- 默认插槽 -- 修饰符sync的使用
Vue.component('message2', {
props: ['show2'],
mounted () {
// 监听事件总线
this.$bus.$on('clear', () => {
this.$emit('update:show2', false);
})
},
template: `
<div v-if="show2">
<slot>默认提示</slot>
<span @click="$emit('update:show2', false)">×</span>
</div>
`
})
const app = new Vue({
el: '#app',
data: {
title: '购物车',
list: [{name: '大数据'}, {name: ' web'}],
course: '',
price: 0,
show: false,
show2: false
},
created () {
this.batchPrice();
},
methods: {
addCourse () {
this.list.push({name: this.course});
this.course = '';
this.show = true;
this.show2 = true;
}
}
})
节点引用的API
组件或元素引用(使用ref和vm.$refs)
例如获取焦点事件
<input type="text" ref="inp" />
mounted () {
// mounted之后才能访问到ref
this.$refs.inp.focus()
}
如果ref写在普通的DOM元素上,获取的是DOM元素。ref写在组件(包括子组件)上,获取的是组件的实例
ref放在组件上的实例
<!-- 默认插槽 -->
<message ref="message">新增成功</message>
// 提示框 --- 默认插槽
Vue.component('message', {
data () {
return {
show: false
}
},
methods: {
toggle () {
this.show = !this.show
}
},
template: `
<div v-if="show">
<slot>默认提示</slot>
</div>
`
})
// 将vue绑定到宿主元素中
// 1.创建vue实例
const app = new Vue({
el: '#app',
data: {
title: '购物车',
list: [{name: '大数据'}, {name: ' web'}],
course: ''
}
mounted: {
this.$refs.message.toggle();
}
})
- ref是作为渲染结果被创建的,则在初始渲染的时候是不能访问他们的,则至少在mounted中访问(在created和beforecreated中无法访问)
- $refs不是响应式的,不要试图用他在模板中做数据绑定
- 当v-for用于元素或组件时,引用信息将时包含DOM节点或数组实例的数组。
```javascript
- {{item}}
mounted() { console.log(this.$refs.li) } ```