目录
1.数据的变更操作
案例:
plain
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
button {
margin-top: 10px;
}
</style>
</head>
<body>
<div id="root">
<h3>姓名:{{person.name}}</h3>
<h3>年龄:{{person.age}}</h3>
<h3>爱好:</h3>
<ul>
<li v-for="(item,index) in person.hobby" :key="index">
{{item}}
</li>
</ul>
<h3>朋友:</h3>
<ul>
<li v-for="(item,index) in person.friends" :key="index">
{{item.name}}--{{item.age}}
</li>
</ul>
</div>
<script src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
data() {
return {
person: {
name: '张三',
age: 26,
hobby: ['测试数据1', '测试数据2', '测试数据3'],
friends: [
{name: '李四', age: 35},
{name: '王武', age: 27}
]
}
}
}
}).$mount('#root')
</script>
</body>
</html>
在上面案例中Vue示例有一些基础属性,我们通过一些指令,将其渲染到页面上

现在我们有一些需求,需要对上述Vue实例中的数据进行变更
需求1:给person对象添加sex属性,值为'男';
plain
//添加一个按钮,绑定事件
<button @click="addSex">新增性别属性</button>
plain
//在Vue实例中添加methods对象,定义上面事件的回调函数
methods: {
addSex() {
//注意不能直接对person对象添加sex属性,因为Vue识别不到
//Vue.set(this.person,'sex','男')
this.$set(this.person, 'sex', '男')
}
}
测试:

通过测试结果发现,我们将sex属性成功添加到了person对象中,同时也成功地渲染到了页面。
但有个问题需要注意,在进行属性添加时,应使用上面地两种方式,而不能直接使用js中**对象名.属性名='值'**地语法。
因为,这样只是把sex属性添加到了person对象中,而没有把数据添加到Vue实例所复制地对象中,因此在页面渲染时,自然不会把新增地属性渲染出来;
需求2:对person地age属性进行++操作
plain
//准备功能按钮,绑定事件(注意++或--操作直接可以绑定,不用再在methods中定义回调函数)
<button @click="person.age++">年龄++</button>
需求3:新增一位朋友到首位
plain
//准备功能按钮,绑定事件
<button @click="addfirstfriend">新增一位朋友到首位</button>
plain
//定义回调函数
methods: {
addfirstfriend() {
this.person.friends.unshift({name: '赵6', age: 33})
}
}
需求4:修改第一位朋友的姓名为赵六
plain
//准备功能按钮,绑定事件
<button @click="updatefriend">修改第一位朋友姓名为赵六</button>
plain
//定义回调函数
methods: {
updatefriend() {
this.person.friends[0].name = '赵六'
},
}
需求5:追加一个爱好--'学习'
plain
//准备功能按钮,绑定事件
<button @click="addhobby">追加学习爱好</button>
plain
//定义回调函数
methods: {
addhobby(){
this.person.hobby.push('学习')
},
}
需求6:将第一个爱好修改为学习:
plain
//准备功能按钮,绑定事件
<button @click="updatehobby">修改第一个爱好为学习</button>
plain
//定义回调函数
methods: {
updatehobby(){
//不能直接覆盖,需要调用数组原生方法
this.person.hobby.splice(0,1,'学习')
},
}
注意:在对数组元素进行变更时,不能直接使用=进行覆盖,而应该使用数组的原生方法进行操作;
原因解释:
在 Vue 中,数据是响应式的。当一个组件实例被创建时,Vue 会对其`data`选项中的数据进行遍历,通过`Object.defineProperty`(在 Vue 3 中是通过`Proxy`)来进行数据劫持。这意味着 Vue 能够追踪数据的变化,当数据发生改变时,会自动更新与之绑定的 DOM 元素。
当使用`=`直接覆盖一个数组元素时,实际上是切断了 Vue 对原始数组的响应式追踪。因为 Vue 的响应式系统并不知道这个数组新的元素的存在,它只对最初定义在`data`中的数组进行了劫持。
当对数组中的一个元素的单个属性进行变更(使用`=`覆盖)时,实际上是触发了这个属性对应的`setter`函数。因为 Vue 已经对这个属性进行了数据劫持,所以`setter`会通知响应式系统数据发生了变化。(参考需求4)
需求7:过滤学习爱好
plain
//准备功能按钮,绑定事件
<button @click="filterhobby">过滤学习爱好</button>
plain
//定义回调函数
filterhobby(){
this.person.hobby= this.person.hobby.filter((item)=>{
return !(item !='学习');
})
}
总结:
1.Vue会监视data中所有层次的数据
- 如何监测对象中的数据
plain
1. 通过settter实现监视,并且要在new Vue实例 传入要监测的数据
2. 对象中后追加的属性,Vue默认不作出响应式处理的
3. Vue.set(目标对象,属性名,值) / this.$set(目标对象,属性名,值)
3.如何监测数组中的数据通过包裹数组更新元素的方式实现的:
1.调用原生方法的对应的方法对数组进行更新
2.重新解析模板,更新页面
2.表单数据收集:
案例:
构建一个form表单,用户输入数据后收集这些数据进行控制台展示
plain
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--2.准备一个容器-->
<div id="root">
//阻止表单提交
<form @submit.prevent="demo">
//构建输入框用于用户输入账号密码及年龄
//使用v-model指令双向绑定数据
账号:<input type="text" v-model.trim="userInfo.account"/> <br/>
密码:<input type="password" v-model="userInfo.password"/><br/>
年龄:<input type="number" v-model.number="userInfo.age"/><br/>
性别:
//构建两个单项选择器,用于用户选择性别并将其绑定到userInfo对象的sex属性上
//动态绑定了值为 0,表示选择 "男" 时,这个单选按钮的值为 0,如果data中用户的性别为0时
//即表示男性为默认选项
<label>男: <input type="radio" name="sex" :value="0" v-model="userInfo.sex"/></label>
<label>女: <input type="radio" name="sex" :value="1" v-model="userInfo.sex"/></label><br/>
爱好:
//构建多选框,用于用户选择爱好,并将其绑定到userInfo对象的hobby属性上
<label><input type="checkbox" v-model="userInfo.hobby" value="2"/>游戏</label>
<label><input type="checkbox" v-model="userInfo.hobby" value="3"/>吃饭</label>
<label><input type="checkbox" v-model="userInfo.hobby" value="4"/>篮球</label><br/>
地区:
//构建下拉选择框,用于用户选择地区,并绑定到userInfo的city属性中
<select v-model="userInfo.city">
<option value="">请选择</option>
<option value="北京">北京</option>
<option value="西安">西安</option>
<option value="上海">上海</option>
</select><br/>
其他信息:
<!-- lazy 在失去焦点后收集数据 number:将字符串转换为数字 trim 取出前后空格在收集 -->
<textarea rows="10" cols="20" v-model.lazy="userInfo.other">
</textarea><br/>
<label><input type="checkbox" v-model="userInfo.agree"/>阅读并接收<a href="#">《用户协议》</a></label>
<br/>
<button type="submit">提交</button>
</form>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">
//3.创建Vue对象
let vm = new Vue({
data() {
return {
//构建对象,用于绑定用户输入的信息,当选择框的value值与此对象默认的值相同时,
//此值即表示了选择框上的默认值
userInfo: {
account: '',
password: '',
age: 18,
sex: 0,
hobby: ['2'],
city: '北京',
other: '',
agree: false
}
}
},
methods: {
//阻止调单提交事件的回调函数
demo() {
console.log(JSON.stringify(this.userInfo))
}
}
}).$mount("#root");
</script>
</body>
</html>
先展示form表单界面

用户输入信息,并点击提交

此时在控制台看查看用户输入的信息

3.过滤器:
1.案例:
plain
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--2.准备一个容器-->
<div id="root">
<h1>时间</h1>
<h2>当前时间戳:{{time}}</h2>
//如果有多个过滤规则,可以依次往后拼接,值会从前往后依次传递,直到最终的结果进行渲染
<h2>转换后的时间:{{time | timeFormater}}</h2>
<h2>转换后的时间:{{time | timeFormater | timeFormaterStr}}</h2>
</div>
<!--1.引入Vue.js 和dayjs.js文件-->
<script src="vue/dayjs.min.js"></script>
<script src="vue/vue.js"></script>
<script type="text/javascript">
//3.创建Vue对象
let vm = new Vue({
data() {
return {
//当前时间的时间戳
time: 1732159777000
}
},
filters: {
//对data中的time属性的值进行格式过滤转换
timeFormater(value, str = 'YYYY年MM月DD日 HH:mm:ss SSS') {
console.log("执行了timeFormater")
// 注意 value的类型
return dayjs(value).format(str);
},
timeFormaterStr(value) {
return value.substring(0, 11);
}
}
})
vm.$mount("#root");
</script>
</body>
</html>

4.vue中的内置指令
plain
v-bind 单向数据绑定:
plain
v-model 双向数据绑定
plain
v-for 遍历 数组 对象 字符串 固定次数
plain
v-on 绑定事件
plain
v-if v-else-if v-else 条件的渲染
v-show 条件的渲染
plain
v-text 通过此指令的value值覆盖原本的文本内容
例: <h2 v-text="name+',hello'">这是默认值</h2>
等价于<h2 >{{name}},hello</h2>
plain
v-html:通过此指令会将一个字符串作为 HTML 内容插入到元素中
例: <p v-html="str"></p>str 变量的值会被解析为 HTML 并显示在 <p> 元素内。
注意:此指令存在安全问题,不建议使用。
如果 str 的值是由用户输入或者来自不可信的数据源,那么可能会导致跨站脚本攻击(XSS)
plain
v-cloak:指令主要用于解决在 Vue 实例初始化之前,插值表达式或指令显示在页面上可能导致的 "闪动"问题。
例:<h3 v-cloak>{{name}}</h3>此标签通过指令来解决网络不佳时显示html元素语法到页面上的问题
plain
v-once 指令会使元素及其子元素只渲染一次。
在初始渲染后,无论数据如何变化,这个元素及其子元素都不会再次更新。
例:<button v-once @click="count++">{{count}}++</button>
当页面首次加载时,按钮上会显示 count 的初始值,并带有 ++ 字样。由于使用了 v-once,
无论 count 的值在后续如何变化,按钮上的显示内容都不会更新。
但是,每次点击按钮,count 的值确实会增加,只是按钮上的显示不会反映这个变化。
plain
v-pre 指令会跳过这个元素及其子元素的编译过程。
也就是说,这个元素中的内容会被原样输出,不会被 Vue 的模板编译器处理。
例:<p v-pre>这是一段内容:{{name}}</p>中,
<p> 元素中的内容 "这是一段内容:{{name}}" 会直接显示在页面上,
不会将 {{name}} 作为插值表达式进行解析和替换为 name 变量的值。