前言:这一篇旨在教大家快速入门Vue2,每个知识点用案例解释
不过学习vue2之前,建议学好JavaScript的基础知识:
前端程序员需要了解的JavaScript_成为前端大牛的博客-CSDN博客
目录
props验证:type,required,default(如果是数组对象类型,需要是工厂函数返回数组对象的格式),自定义validator验证函数,返回true
一:声明式渲染
vue是单页面应用,一个vue应用直接挂载到一个dom元素上,其余的都创建在vue的实例里面
文本插值{ {}},里面可以做字符串拼接,js逻辑运算(三元目算符等等)
<h1>{
{ data + 1 }}</h1>
<h1>{
{ data + '1' }}</h1>
<h1>{
{ `${data}1` }}</h1>
<h1>{
{ Math.round(data) }}</h1>
除了文本插值,我们还可以像这样来绑定元素 attribute:
<div id="app-2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
var app2 = new Vue({
el: '#app-2',
data: {
message: '页面加载于 ' + new Date().toLocaleString()
}
})
二:条件和渲染
条件:
- v-if 和 v-else-if 和 v-else。v-show是频繁的切换页面使用
- v-if可以绑定在复杂的div上,可以结合Vue过渡效果完美体现
- v-if 可以结合 key 标识唯一的attribute ,这样在不同模板中复用的元素就会独立起来,复用的元素也会重新渲染一遍
- 当
v-if
与v-for
一起使用时,v-for
具有比v-if
更高的优先级。请查阅列表渲染指南以获取详细信息。- v-if可以使用在模板语法template上
<h2 v-if="demo > 1">12</h2>
<h2 v-else-if="demo < 3">12</h2>
<h2 v-else>12</h2>
demo: 4,
只显示第一个
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
过渡显示例子:
渲染:
- v-for,可以渲染数组和对象,注意绑定唯一key值
v-for
也可以接受整数。<span v-for="n in 10">{ { n }} </span>- v-for可以使用在template上
<div v-for="(item, index) in arrlist" :key="index">
{
{ `${item}-${index}` }}
</div>
<div v-for="(value, key, index) in objlist" :key="index">
{
{ `${value}-${key}-${index}` }}
</div>
复杂demo:v-if和v-for结合使用
<template v-for="(i, index) in blist"> <div :key="index" v-if="i.status"> { { i.status }} </div> </template> blist: [{ status: true }, { status: false }, { status: true }],
三:处理用户操作
1:操作
- 为了让用户和你的应用进行交互,我们可以用
v-on
指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法:简写@- 注意:我们更新了应用的状态,但没有触碰 DOM——所有的 DOM 操作都由 Vue 来处理,你编写的代码只需要关注逻辑层面即可。
- 有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量
$event
把它传入方法- 六个事件修饰符
- 按键修饰符
.stop - 调用 event.stopPropagation()。 .prevent - 调用 event.preventDefault()。 .capture - 添加事件侦听器时使用 capture 模式。 .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。 .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。 .native - 监听组件根元素的原生事件。 .once - 只触发一次回调。 .left - (2.2.0) 只当点击鼠标左键时触发。 .right - (2.2.0) 只当点击鼠标右键时触发。 .middle - (2.2.0) 只当点击鼠标中键时触发。 .passive - (2.3.0) 以 { passive: true } 模式添加侦听器
2:文本框双向绑定
- Vue 还提供了
v-model
指令,它能轻松实现表单输入和应用状态之间的双向绑定。- v-model适用于表单元素上,它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
- 三个 v-model修饰符
v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
- text 和 textarea 元素使用
value
property 和input
事件;- checkbox 和 radio 使用
checked
property 和change
事件;- select 字段将
value
作为 prop 并将change
作为事件。
联合demo:
<button @click="todo">点我</button>
<input type="text" v-model="text" />
todo(e) {
this.text = e.target.innerHTML;
},
四:组件化
- 在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例
- 父组件可以将父级作用域的数据通过prop传给子组件
- 在我们编程中,尽可能可以把设计变成组件化,你可以选择传参给子组件,他只接受你的值然后把要做的事抛给父亲。
- 也可以单独在子组件内做请求的事情,你可以看作他是一个页面的一块,类似于elementui的每个组件,可以自己设计
- 每调用一次组件,就会有一个它的新实例被创建。
其他组件理解:
组件的样式:
- 对于父子组件来说,在父组件定义的样式控制着父组件里面的元素,包括子组件,所以对于布局样式,可以写在子组件标签上面,你也可以用一层div包裹着子组件,在div上面写布局样式。如果说样式写在了子组件标签上,则相当于把样式也直接给到了子组件实例上,直接干预子组件的css,他的层级比子组件自己定义的样式高。
- 子组件的样式控制子组件里面的元素。
- 所以对于组件样式的理解,就是哪个组件内的样式控制哪个组件的元素。
- 上面的图片例子 也可以直接说明我们使用类似于elementui框架的input组件一样的,直接在input组件上写class,能覆盖到他的样式
- 如果说样式写在包裹子组件的div上,子组件此时是div里面的内容,是没有宽高的。设置子组件内部样式时记得设置宽高,比如width: 100%; height: 100%;
- 我们常用的当然是:用div包裹子组件,在父组件清晰的css定义布局,然后子组件设置宽高,控制子组件里面的元素。
- 你把子组件标签当成一个div来理解,就清晰多了。
为啥data必须是一个函数:
如果不是函数的返回值,那这个data对象可能在多次调用该组件时,生成很多新实例时,该对象会共享引用,不会出现独立性的表现。会影响到该组件被别人调用时,状态的改变。
所以规定一个组件的
data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
组件传值prop:
一个 prop 被注册之后,你就可以像这样把数据作为一个自定义 attribute 传递进来:在组件实例里新增proprety。
props: {
date: {
type: String,
default: '默认值',
},
},
单向数据流:
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
如果你想修改props,我们有三种方法:
如果你是确定要改props值,而不是做其他事情,就直接使用.sync语法糖
1:在子组件data里定义一个property 来接受props,后续使用data里面的属性来操作,作为本地使用
这里有个注意的事情:就是你修改了本地的data,如果这个prop是个对象等引用类型,因为你data=prop的话,就会涉及传地址问题,修改了data的话也修改了prop传过来的父组件的值,可能会影响到父组件的状态
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
2:如果你是想对这个props进行一个复杂计算,我们也可以在子组件里使用computed来定义
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
3:.sync修饰符
下面自定义事件章节 有详细介绍
props验证:type,required,default(如果是数组对象类型,需要是工厂函数返回数组对象的格式),自定义validator验证函数,返回true
Vue.component('my-component', {
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'].indexOf(value) !== -1
}
}
}
})
优先级:
props的优先级最高
props > methods > data > computed > watch
组件的监听事件$emit:
可以将子组件发生的事件传给父组件。
this.$emit('todo', '是');
.sync修饰符:
就是一个语法糖,省略了在子组件标签上的自定义方法,优雅不是粗鲁的实现props双向修改
有两种情况使用:
1:字符串或者数字等标准数据结构
在子组件标签上 :demo.sync="demo"
在子组件里面的methods属性方法里写
methods: { demo() { this.$emit('update:demo', 2); }, },
区别就是加上update :加上props名
此时父组件的data值就改变了
2:给复杂的对象的引用类型,加上.sync
在子组件标签上写 v-bind.sync="edit" 这个edit是一个对象 edit:{ name:1 }
在子组件里面的props里面写 edit这个对象的属性,你要改哪个就写哪个edit的属性
props: { name: Number,//edit对象的属性 },
在子组件里面的methods属性方法里写
editdemo() { this.$emit('update:name', 2); },
此时父组件的data值就改变了
总结sync:简单地说就是props的那个子组件标签上的atrra加上.sync,然后子组件里的emit里面加上update,子组件标签上少写一个自定义事件。就形成了语法糖。
组件的v-model:
v-model的简单原理是:表单的input等表单事件改变$event.target.value(demo),将这个值给组件实例对象,对象属性监听触发set方法,把改的值传给dom节点的attra
<input v-model="searchText">
等价于:
<input
v-bind:value="searchText