做了多年的前端开发,Vue.js也用了几年啦,总结了些常用的知识点纪录下来,方便自己查看。
常用指令
v-once 进入页面时 只渲染一次 不在进行渲染
v-cloak 防止闪烁
v-pre 把标签内部的元素原位输出
v-html 解析渲染html标签
v-text 解析文本 / {{title}}和v-text="title"等同
v-bind:class简写:class
v-on:click 主要用来监听dom事件,以便执行一些代码块,简写@click
v-on:keyup.enter 回车keyup事件,简写@keyup.enter
v-model 双向绑定(在input textarea select中使用)
v-model的修饰符 v-model.lazy 只有在input输入框发生一个blur时才触发(转变为在change事件再同步) v-model.trim 将用户输入的前后的空格去掉 v-model.number 将用户输入的字符串转换成number
动态添加类名 v-bind:class
三种绑定方法
1、对象型
<1>对象语法
data: {
isActive: true,
hasError: false
}
<div :class="{'is-active':isActive, 'text-danger':hasError}"></div>
渲染结果:
<!--因为hasError: false,所以text-danger不被渲染-->
<div class = "is-active"></div>
<2>直接绑定数据对象
data: {
classObject:{
'is-active': false,
'text-danger':true
}
}
<div :class="classObject">12345</div>
渲染结果:
<!--因为'is-active': false,所以is-active不被渲染-->
<div class = "text-danger"></div>
2、三目型
'isred ? "red" : "blue"'
3、数组型
data: {
activeClass: false,
errorClass: 'text-danger'
}
<p :class="[{'is-active':activeClass},errorClass]">12345</p>
渲染结果:
<!--因为'is-active': false,所以is-active不被渲染-->
<div class = "text-danger"></div>
Object.assign
Object.assign(this.$data,this.$options.data()) // 重置data
vm.$data
获取Vue实例的data选项(对象)
vm.$options
获取Vue实例的自定义属性(如vm.$options.methods,获取Vue实例的自定义属性methods)
this.ref
this.$el
获取Vue实例关联的DOM元素;
this.$refs
获取页面中所有含有ref属性的DOM元素(如this.$refs.hello,获取页面中含有属性ref = “hello”的DOM元素,如果有多个元素,那么只返回最后一个)
this.$el是在mounted中才会出现的,在created的时候是没有的,所以我们引用的时候
mounted () {
this.$el.addEventListener('touchstart', this.itemTouchStart)
}
不能再created中出现$el,在mounted中是ok的
1)$refs
首先给子组件做标记,例如:
<firstchild ref="one"></firstchild>
然后在父组件中,通过this.$refs.one就可以访问了这个自组件了,包括访问自组件的data里面的数据,调用它的函数。
2)$children
它返回的是一个组件集合,如果你能清楚的知道子组件的顺序,你也可以使用下标来操作;
for(let i=0;i<this.$children.length;i++){
console.log(this.$children[i].msg);输出子组件的msg数据;
}
3)$parent
示例:
this.$parent.$children[0].query()
总结一下:
1)组件只能一个根节点;
2)可以在自定义组件中使用this.$parent.属性值,或者函数;
3)在父组件中可以使用this.children[i].属性(方法名),访问子组件的属性或者方法;
4)需要注意this的指向。
事件修饰符
.stop 阻止事件继续传播
.prevent 事件不再重载页面
.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理
.self 只当在 event.target 是当前元素自身时触发处理函数
.once 事件将只会触发一次
.passive 告诉浏览器你不想阻止事件的默认行为
示例:
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用v-on:click.prevent.self会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
深层选择器
让组件内部样式生效的写法:
修改第三方组件的CSS,这些都是 scoped 样式,移除 scope 或打开一个新的样式是不可能的。 现在,深层选择器 >>> /deep/ ::v-deep 可以帮助你。
&::v-deep or /deep/ or >>>
Vue刷新当前页面数据(reload) 【Vue开发小程序】
reLoad () {
// console.log('getCurrentPages().length='+getCurrentPages().length)
// console.log(getCurrentPages())
// pages 获取到当前页码数,然后执行当前页的onLoad
//(如果页面中初始化Ajax函数写在onShow或者onReady中的,那么这里将使用onShow或者onReady)
const pages = getCurrentPages()
pages[pages.length - 1].onLoad()
},
vue-cli如何新增自定义指令?
1、创建局部指令
export default {
data: {
},
// 创建指令(可以多个)
directives: {
// 指令名称
dir1: {
// 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document 中)
inserted(el,binding) {
// 指令中第一个参数是当前使用指令的DOM
console.log(el);
console.log(arguments);
// 对DOM进行操作
el.style.width = '200px';
el.style.height = '200px';
el.style.background = '#000';
}
}
}
}
或者在组件中也接受一个 directives 的选项
export default {
data () {
return {
}
},
computed: {
},
directives: {
dir1 : {
// 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document 中)
inserted (el) {
el.focus()
}
}
}
}
2、全局指令
Vue.directive('dir2', {
inserted(el) {
console.log(el,binding);
el.focus()
}
})
3、指令的使用
<div id="app">
<div v-dir1></div>
<div v-dir2></div>
</div>
vue如何自定义一个过滤器?
html代码:
<div id="app">
<input type="text" v-model="msg" />
{{ msg| capitalize }}
</div>
JS代码:
var vm=new Vue({
el:"#app",
data:{
msg:''
},
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})
全局定义过滤器
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
过滤器接收表达式的值 (msg) 作为第一个参数。capitalize 过滤器将会收到 msg的值作为第一个参数。
Vue过滤器实际应用
<div class="item-border">总计(元): {{(order.salePrice?order.salePrice:price)|numFilter}}</div>
export default {
filters:{
numFilter(value) {
// 截取当前数据到小数点后两位
let realVal = Number(value).toFixed(2)
// num.toFixed(2)获取的是字符串
return Number(realVal)
}
}
}
如果组件里用使用计时器
// 在组件销毁时(即切换组件或关闭页面),调用destroyed方法清除计时器
destroyed(){
clearTimeout(this.timer)
}
props 类型为数组或者对象时,不能直接定义空对象的默认值,必须使用 工厂函数 return 回一个默认值
props: {
options: {
type: Array,
default: () => []
}
},
Vue中如何让v-for循环出来的列表里面的click事件只对当前列表内元素有效
<li v-for='item in items' @click="toggle(item)" key="item.id">
<span v-show='item.show'>{{item.content}}</span>
</li>
toggle:function(item){
item.show=!item.show
}
动态添加背景图片
<div class="img" :style="'background-image: url(https://images.weserv.nl/?url='+article.cover.url.substring(7)+');'"></div>
订阅多个变量突变
watcher 不能监听多个变量,但我们可以将目标组合在一起作为一个新的 计算属性,并监视这个新的 "变量"。
computed: {
multipleValues () {
return {
value1: this.value1,
value2: this.value2,
}
}
},
watch: {
multipleValues (val, oldVal) {
console.log(val)
}
}
定时器的销毁
export default {
data () {
return {
timer: null
}
},
mounted () {
this.timer = setInterval(() => {
console.log(Date.now())
}, 1000)
},
beforeDestroy () {
clearInterval(this.timer)
}
}
使其只能在生命周期钩子内访问。使用 $once 来放弃不必要的东西
export default {
mounted () {
let timer = null
timer = setInterval(() => {
console.log(Date.now())
}, 1000)
this.$once('hook:beforeDestroy', () => {
clearInterval(timer)
})
}
}