Vue数据的变更操作与表单数据的收集【6】
目录
- 1.数据的变更操作
- 案例:
- 需求1:给person对象添加sex属性,值为'男';
- 需求2:对person地age属性进行++操作
- 需求3:新增一位朋友到首位
- 需求4:修改第一位朋友的姓名为赵六
- 需求5:追加一个爱好--'学习'
- 需求6:将第一个爱好修改为学习:
- 需求7:过滤学习爱好
- 总结:
- 2.表单数据收集:
- 案例:
- 3.过滤器:
- 1.案例:
- 4.vue中的内置指令
1.数据的变更操作
案例:
<!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属性,值为’男’;
//添加一个按钮,绑定事件
<button @click="addSex">新增性别属性</button>
//在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属性进行++操作
//准备功能按钮,绑定事件(注意++或--操作直接可以绑定,不用再在methods中定义回调函数)
<button @click="person.age++">年龄++</button>
需求3:新增一位朋友到首位
//准备功能按钮,绑定事件<button @click="addfirstfriend">新增一位朋友到首位</button>
//定义回调函数methods: {addfirstfriend() {this.person.friends.unshift({name: '赵6', age: 33})}}
需求4:修改第一位朋友的姓名为赵六
//准备功能按钮,绑定事件<button @click="updatefriend">修改第一位朋友姓名为赵六</button>
//定义回调函数methods: {updatefriend() {this.person.friends[0].name = '赵六'},}
需求5:追加一个爱好–‘学习’
//准备功能按钮,绑定事件
<button @click="addhobby">追加学习爱好</button>
//定义回调函数methods: {addhobby(){this.person.hobby.push('学习')},}
需求6:将第一个爱好修改为学习:
//准备功能按钮,绑定事件
<button @click="updatehobby">修改第一个爱好为学习</button>
//定义回调函数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:过滤学习爱好
//准备功能按钮,绑定事件
<button @click="filterhobby">过滤学习爱好</button>
//定义回调函数
filterhobby(){this.person.hobby= this.person.hobby.filter((item)=>{return !(item !='学习');})}
总结:
1.Vue会监视data中所有层次的数据
- 如何监测对象中的数据
1. 通过settter实现监视,并且要在new Vue实例 传入要监测的数据2. 对象中后追加的属性,Vue默认不作出响应式处理的3. Vue.set(目标对象,属性名,值) / this.$set(目标对象,属性名,值)
3.如何监测数组中的数据通过包裹数组更新元素的方式实现的:
1.调用原生方法的对应的方法对数组进行更新2.重新解析模板,更新页面
2.表单数据收集:
案例:
构建一个form表单,用户输入数据后收集这些数据进行控制台展示
<!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.案例:
<!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中的内置指令
v-bind 单向数据绑定:
v-model 双向数据绑定
v-for 遍历 数组 对象 字符串 固定次数
v-on 绑定事件
v-if v-else-if v-else 条件的渲染v-show 条件的渲染
v-text 通过此指令的value值覆盖原本的文本内容例: <h2 v-text="name+',hello'">这是默认值</h2>等价于<h2 >{{name}},hello</h2>
v-html:通过此指令会将一个字符串作为 HTML 内容插入到元素中例: <p v-html="str"></p>str 变量的值会被解析为 HTML 并显示在 <p> 元素内。注意:此指令存在安全问题,不建议使用。如果 str 的值是由用户输入或者来自不可信的数据源,那么可能会导致跨站脚本攻击(XSS)
v-cloak:指令主要用于解决在 Vue 实例初始化之前,插值表达式或指令显示在页面上可能导致的 “闪动”问题。例:<h3 v-cloak>{{name}}</h3>此标签通过指令来解决网络不佳时显示html元素语法到页面上的问题
v-once 指令会使元素及其子元素只渲染一次。在初始渲染后,无论数据如何变化,这个元素及其子元素都不会再次更新。例:<button v-once @click="count++">{{count}}++</button>当页面首次加载时,按钮上会显示 count 的初始值,并带有 ++ 字样。由于使用了 v-once,无论 count 的值在后续如何变化,按钮上的显示内容都不会更新。但是,每次点击按钮,count 的值确实会增加,只是按钮上的显示不会反映这个变化。
v-pre 指令会跳过这个元素及其子元素的编译过程。也就是说,这个元素中的内容会被原样输出,不会被 Vue 的模板编译器处理。例:<p v-pre>这是一段内容:{{name}}</p>中,<p> 元素中的内容 “这是一段内容:{{name}}” 会直接显示在页面上,不会将 {{name}} 作为插值表达式进行解析和替换为 name 变量的值。