vue一些使用技巧

89 阅读4分钟

vue.$watch使用

 watch(第一参数,第二个参数,第三个参数)
        功能:
            侦听数据的变化。和选项式api中的watch实现的功能一样,组合式api中watch功能更加强大,灵活。默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数。
        参数:
            第一个参数:侦听器的源,可以是以下几种:
                一个函数(返回一个值的函数)
                一个 ref
                一个响应式对象
                ...或是由以上类型的值组成的数组
            第二个参数:在(第一个参数的值)发生变化时要调用的回调函数。
                这个回调函数接受三个参数:
                    新值、旧值,以及一个用于注册副作用清理的回调函数。该回调函数会在副作用下一次重新执行前调用,可以用来清除无效的副作用,例如:等待中的异步请求。
                    当侦听多个来源时,回调函数接受两个数组,分别对应来源数组中的新值和旧值。
            第三个参数:可选的,是一个对象,支持以下这些选项:
                immediate:在侦听器创建时立即触发回调。第一次调用时旧值是undefined。
                deep:如果源是对象,强制深度遍历,以便在深层级变更时触发回调。
    1)当侦听多个来源时,回调函数接受两个数组,分别对应来源数组中的新值和旧值      
    2)当使用 getter 函数作为源时,回调只在此函数的返回值变化时才会触发。如果你想让回调在深层级变更时也能触发,你需要使用deep: true。
    3)强制侦听器进入深层级模式。在深层级模式时,如果回调函数由于深层级的变更而被触发,那么新值和旧值将是同一个对象。
    4)当直接侦听一个响应式对象时,侦听器会自动启用深层模式
    
    实例:
    vueData.$watch(
                function () {
                  return vueData.formData.multinfos[key].rows;
                },
                function (n, o) {
                  formData.multinfos[key].rows[index].structControl.forEach(
                    (row) => {
                      row.label == "资源分类id" ? (row.show = 0) : "";
                      row.label == "资源id" ? (row.show = 0) : "";
                      row.label == "是否填写数量" ? (row.show = 0) : "";
                    }
                  );
                },
                {
                  deep: true,
                  immediate: true,
                }
              );

[v-bind 缩写]

<!-- 完整语法 -->  
<a v-bind:href="url">...</a>  
  
<!-- 缩写 -->  
<a :href="url">...</a>  
  
<!-- 动态参数的缩写 (2.6.0+) -->  
<a :[key]="url"> ... </a>

[v-on 缩写]

<!-- 完整语法 -->  
<a v-on:click="doSomething">...</a>  
  
<!-- 缩写 -->  
<a @click="doSomething">...</a>  
  
<!-- 动态参数的缩写 (2.6.0+) -->  
<a @[event]="doSomething"> ... </a>

Class 与 Style 绑定

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

对象语法

<div v-bind:class="{ active: isActive }"></div>

上面的语法表示 active 这个 class 存在与否将取决于数据 property isActive 的 truthiness

你可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class attribute 共存。当有如下模板:

<div  
class="static"  
v-bind:class="{ active: isActive, 'text-danger': hasError }"  
></div>

和如下 data:

data: {  
isActive: true,  
hasError: false  
}

结果渲染为:

<div class="static active"></div>

当 isActive 或者 hasError 变化时,class 列表将相应地更新。例如,如果 hasError 的值为 true,class 列表将变为 "static active text-danger"

绑定的数据对象不必内联定义在模板里:

<div v-bind:class="classObject"></div>
data: {  
classObject: {  
active: true,  
'text-danger': false  
}  
}

渲染的结果和上面一样。我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:

<div v-bind:class="classObject"></div>
data: {  
isActive: true,  
error: null  
},  
computed: {  
classObject: function () {  
return {  
active: this.isActive && !this.error,  
'text-danger': this.error && this.error.type === 'fatal'  
}  
}  
}

绑定内联样式

数组形式与clss类似

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

多重值

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

# 条件渲染

在 <template> 元素上使用 v-if 条件渲染分组

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。

<template v-if="ok">  
<h1>Title</h1>  
<p>Paragraph 1</p>  
<p>Paragraph 2</p>  
</template>

数组更新检测

变更方法

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

你可以打开控制台,然后对前面例子的 items 数组尝试调用变更方法。比如 example1.items.push({ message: 'Baz' })

在 <template> 上使用 v-for

类似于 v-if,你也可以利用带有 v-for 的 <template> 来循环渲染一段包含多个元素的内容。比如:

<ul>  
<template v-for="item in items">  
<li>{{ item.msg }}</li>  
<li class="divider" role="presentation"></li>  
</template>  
</ul>

在组件上使用 v-for

<component v-for="(item, index) in currentMenu.components" :key="index + loadTime" :is="item.name" :ref="item.name"
        :itemdata="item"></component>

事件

你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 `v-on` 的 `.native` 修饰符:
vant 中阻止事件冒泡
 @click.stop.native

Prop

字符串参数

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

但是,通常你希望每个 prop 都有指定的值类型。这时,你可以以对象形式列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型:

props: {  
title: String,  
likes: Number,  
isPublished: Boolean,  
commentIds: Array,  
author: Object,  
callback: Function,  
contactsPromise: Promise // or any other constructor  
}

我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。

为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

props: {  
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)  
propA: Number,  
// 多个可能的类型  
propB: [String, Number],  
// 必填的字符串  
propC: {  
type: String,  
required: true  
},  
// 带有默认值的数字  
propD: {  
type: Number,  
default: 100  
},  
// 带有默认值的对象  
propE: {  
type: Object,  
// 对象或数组默认值必须从一个工厂函数获取  
default: function () {  
return { message: 'hello' }  
}  
},  
// 自定义验证函数  
propF: {  
validator: function (value) {  
// 这个值必须匹配下列字符串中的一个  
return ['success', 'warning', 'danger'].includes(value)  
}  
}  
}

.sync 修饰符

<text-document v-bind:title.sync="doc.title"></text-document>
this.$emit('update:title', newTitle)

自定义组件的 v-model

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的model 选项可以用来避免这样的冲突:

Vue.component('base-checkbox', {  
model: {  
prop: 'checked',  
event: 'change'  
},  
props: {  
checked: Boolean  
},  
template: `  
<input  
type="checkbox"  
v-bind:checked="checked"  
v-on:change="$emit('change', $event.target.checked)"  
>  
`  
})

现在在这个组件上使用 v-model 的时候:

<base-checkbox v-model="lovingVue"></base-checkbox>