想利用暑假时间好好学习一下vue,会记录每一天的学习内容。
今天是学习vue的第4
天!
起起伏伏乃人生常态,继续加油~
学习内容
1. 表单绑定v-model
vue
中使用v-model
指令来实现表单元素和数据的双向绑定
- 当在输入框输入内容时,
input
中的v-model
绑定了message
,所以会实时将输入的内容传递给message
,message
发生改变 v-model
只能用于表单类
元素或者是有value
属性的元素
⚠️:v-bind
用于单向数据绑定
<textarea v-model="message"></textarea>
<p>输入的内容是:{{message}}</p>
v-model原理
v-model
其实是一个语法糖,它的背后本质上包含两个操作:- 1.
v-bind
绑定一个value
属性 - 2.
v-on
指令给当前元素绑定input
事件
- 1.
- 也就是说
<input type="text" v-model="message">
<!-- 等同于 -->
<input type="text" :value="message" @input="message = $event.target.value">
v-model:radio
当input
类型为radio
,则v-model
收集的是value
值
假如下面这里的input
没有value
属性,则不管单选框选不选中,gender
都没有值
所以一定要给input
配置value
值
v-model:checkbox
复选框分为以下几种情况:
- 配置了
input
的value
属性:v-model
绑定的数据的初始值是非数组
,那么v-model
收集的就是checked
值(勾选or不勾选,是布尔值)v-model
绑定的数据的初始值是数组
,那么v-model
收集到的就是由这些复选框的value
组成的数组
- 没有配置
input
的value
属性:- 那么
v-model
收集到的就是checked
值(勾选or不勾选,是布尔值)
- 那么
v-model:select
也分单选和多选:
- 单选:只能选中一个值
v-model
绑定的是一个值- 当我们选中
option
中的一个,会将它对应的value
赋值到mySelect
中
<!-- 选择一个值 -->
<select v-model="mySelect">
<option value="apple">苹果</option>
<option value="banana">香蕉</option>
<option value="grape">葡萄</option>
</select>
<h2>您选择的水果是: {{mySelect}}</h2>
- 多选:可以选中多个值
v-model
绑定的是一个数组- 当选中多个值时,就会将选中的
option
对应的value
添加到数组mySelects
中
<!-- 选择多个值 -->
<!-- 要加上multiple -->
<select v-model="mySelects" multiple>
<option value="apple">苹果</option>
<option value="banana">香蕉</option>
<option value="grape">葡萄</option>
</select>
<h2>您选择的水果是: {{mySelects}}</h2>
data: {
mySelect: 'apple', // 默认是苹果
mySelects: []
}
值绑定
我们可以动态的给value
赋值,而不是在定义input
的时候直接给定,因为在真实开发中,这些input
的值可能是从网络上获取,或定义在data
中的
可以用v-bind:value
动态给value
绑定值
<label v-for="item in originHobbies" :for="item">
<input type="checkbox" :value="item" :id="item" v-model="hobbies"> {{item}}
</label>
data: {
hobbies: [],
originHobbies: ["篮球","足球","乒乓球","橄榄球"]
},
:for="item"
和:id="item"
将label
和input
一一绑定,:value="item"
给value
动态绑定值,v-model="hobbies"
,当选中某个复选框,该input
对应的value
就会加入到hobbies
空数组中
v-model的修饰符
lazy
修饰符:- 默认情况下,
v-model
默认是在input
事件中同步输入框的数据 - 一旦有数据发生改变,对应的
data
中的数据就会自动发生改变 lazy
修饰符可以让数据在失去焦点或者敲回车时才会更新
- 默认情况下,
<input type="text" v-model.lazy="message">
number
修饰符:- 默认情况下,在输入框中无论我们输入的字母还是数字,都会被当作字符串类型进行处理
- 但是如果我们希望处理的是数字类型,那么最好直接将内容当作数字处理
number
修饰符可以让在输入框中输入的内容自动转成数字类型
<input type="number" v-model.number="age">
trim
修饰符:- 如果输入的内容首尾有很多空格,希望将其去除
trim
修饰符可以过滤内容左右两边的空格
<input type="text" v-model.trim="message">
2. 组件化
人面对复杂问题的处理方式:
- 任何一个人处理信息的逻辑能力都是有限的
- 所以当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆的内容
- 如果将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放进整体之中,发现大的问题也会迎刃而解
组件化也是类似思想:
- 如果我们将一个页面中所有的处理逻辑都放在一起,处理起来会变得非常复杂,不利于后续的管理及扩展
- 但是如果,我们将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易了
vue组件化思想
- 组件化提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用
- 任何的应用都会被抽象成一颗组件树
- 组件化思想的应用:
- 尽可能地将页面拆分成一个个小的、可复用的组件
- 这样让我们的代码更加方便组织和管理,并且扩展性也更强
注册组件的基本步骤
组件的使用分成三个步骤:
- 创建组件构造器:调用
Vue.extend()
方法 - 注册组件:调用
Vue.component()
方法 - 使用组件:在Vue实例作用范围内使用组件
Vue.component()
需要传递两个参数:
- 1.注册组件的标签名
- 2.组件构造器
组件必须挂载在某个Vue
实例下,否则他不会生效
全局组件和局部组件
- 当调用
Vue.component()
注册组件时,组件的注册是全局的- 全局组件可以在任意
Vue
实例下使用
- 全局组件可以在任意
- 如果注册的组件是挂载在某个实例中,那就是一个局部组件
const cpnConstructor = Vue.extend({
template: `
<div>
<h2>标题</h2>
</div>
`
});
// 局部组件在vue实例中注册
const app = new Vue({
el: '#app',
components: {
// 注册组件的标签名:组件构造器
'cpn': cpnConstructor
}
// 局部组件语法糖写法
components: {
'cpn':{
template: `
<div>
<h2>标题</h2>
</div>
`
}
}
})
父组件和子组件
组件树:
- 组件和组件之间存在层级关系
- 而其中一种非常重要的关系就是父子组件的关系
子组件构造器在父组件构造器中注册,父组件构造器在vue
实例中注册
⚠️:父子组件错误用法:以子组件标签形式在vue
实例挂载的DOM元素中使用
- 当子组件在父组件的
components
注册时,Vue
会编译好父组件的模版 - 该模版的内容已经决定了父组件将要渲染的
HTML
(相当于父组件中已经有了子组件的内容了) <child-cpn></child-cpn>
是只能在父组件中被识别的- 类似
<child-cpn></child-cpn>
是会被浏览器忽略的
3.组件模版的分离写法
将template
模版其中的HTML
分离出来写,然后挂载到对应的组件上,结构会变得非常清晰
Vue
提供了两种方案来定义HTML
模版内容
- 使用
<script>
标签
- 使用
<template>
标签
4. 组件中的数据存放问题
组件可以访问Vue实例数据吗?
- 组件是一个单独功能模块的封装:
- 这个模块有属于自己的
HTML
模版,也应该有属于自己的数据data
- 这个模块有属于自己的
- 组件中不能访问
Vue
实例中的data
,而且即使可以访问,如果将所有数据都放在Vue
实例中,Vue
实例会变的非常臃肿 Vue
组件应该有自己保存数据的地方
组件数据的存放
- 组件对象也有一个
data
属性 - 这个
data
属性必须是一个函数 - 而且这个函数返回一个对象,对象内部保存着数据
组件中的data为什么是个函数?
两个例子:
例1:
function person() {
return {
name: "a",
age: 22
}
};
const obj1 = person();
const obj2 = person();
obj1.name = "b"; // 修改了obj1的name属性
console.log(obj1);
console.log(obj2);
虽然修改了obj1
的name
属性,但obj2
未受到影响,其name
属性未改变
例2:
const obj = {
name: "a",
age:22
}
function person () {
return obj;
};
const obj1 = person();
const obj2 = person();
obj1.name = "b"; // 修改了obj1的name属性
console.log(obj1);
console.log(obj2);
随着obj1
的name
属性改变,obj2
的name
属性也改变了
总结:
- 第
一
个例子中,每调用一次函数就返回一个新的对象 - 第
二
个例子中,共用一个对象 - 所以在改变其中一个对象的属性的值时,第一例中的两个对象不会互相影响,而第二例中会互相影响
- 由于组件是可复用的,一个组件被创建好之后,就可能被用在各个地方
- 因此自然不希望数据共享,而是有自己的逻辑,组件中的
data
数据应该都是相互隔离不受影响的 - 如果
data
是一个对象的话,那么一旦修改其中一个组件的数据,其他组件相同数据就会被改变 - 而
data
是函数的话,每个vue
组件的data
都因为函数有了自己的作用域,互不干扰。
部分参考博文:
vue组件为什么是函数:
https://blog.csdn.net/qq_45473786/article/details/105178975.