第四 表单指令 v-model 双向数据绑定
Posted 3526527690qq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第四 表单指令 v-model 双向数据绑定相关的知识,希望对你有一定的参考价值。
表单指令 v-model 双向数据绑定
<!--
v-model 双向数据绑定
后台的框架模式
MVC (单向的)
M model 模型 数据
V view 视图
C controller 控制器
MVVM(双向的)
M model 模型 数据 <=> V view 视图
VM view-model 视图模型 (相当于controller 控制器)
MVVM模式
M-model 模型-数据 V-view 视图-浏览器 VM-viewModel 视图模型-控制器
模型通过控制器决定视图,视图可以通过控制器修改模型的数据,控制器就是模型和视图之前的桥梁。
-->
<div id="a"> <input type="text" value="默认值" v-model=val> <!-- value 属性规定 <input> 元素的值。 value 属性对于不同 input 类型,用法也不同: 对于 "button"、"reset"、"submit" 类型 - 定义按钮上的文本 对于 "text"、"password"、"hidden" 类型 - 定义输入字段的初始(默认)值 对于 "checkbox"、"radio"、"image" 类型 - 定义与 input 元素相关的值,当提交表单时该值会发送到表单的 action URL。 注意:value 属性对于 <input type="checkbox"> 和 <input type="radio"> 是必需的。 注意:value 属性不适用于 <input type="file" file 定义文件选择字段和 "浏览..." 按钮,供文件上传。>。
type属性详解: https://www.runoob.com/tags/att-input-type.html --> <h3>{{val}}</h3> </div> <script> new Vue({ el: "#a", data: { val: "", } }) </script>
动态class
动态class 的几种使用方法
第一种 设定一个动态的变量 在页面中去直接接收这个变量
<div :class="classS">{{msg}}</div>
第二种方法 设定一个 三目运算 来实现动态样式的切换
:class="[条件?‘类名A‘:‘类名B‘]"
第三种方法
:class = ‘{ ‘类名A‘:true(条件A), ‘类名B‘:false, "类名C":true }‘
-->
<div id="app"> <!-- 普通的class写法 --> <div class="box">{{test}}</div> <!-- 动态的class第一种写法 --> <div @mousemove=‘move‘ @mouseout=‘out‘ :class="classS">{{msg}}</div> <hr> <hr> <!-- 动态的class第二种写法 --> <!-- <div @click=‘select(index)‘ :class="[index==num?‘gold‘:‘gray‘]" v-for=‘(item,index) in gameList‘ :key=‘item‘> {{item}} </div> --> </div> <hr> <hr> <div id="aaa"> <div class="box">{{msg}}</div> <div @mousemove="move01" @mouseout="out01" :class="classS">{{msg01}}</div> <hr> <hr> <hr> <div @click="select01(index)" :class="[index==num?‘gold‘:‘gray‘]" v-for=‘(item,index) in gameList‘ :key=‘item‘> {{item}} {{msg}}
<!-- 点击变色 -->
</div> </div> <!-- <div v-for=‘item in gameList‘ :key=‘item‘> {{item}} </div> --> <script> new Vue({ el:"#aaa", data:{ msg: ‘锄禾日当午‘, classS:"", msg01:"第二个class方法", gameList:[‘第三种‘,‘王者荣耀‘,‘和平精英‘,‘LOL‘,‘超级玛丽‘], num:-1, //识点击变色的class不会被触发 因为index的值一定是大于零的值 }, methods:{ move01(){ this.classS="box"; }, out01(){ this.classS="bigBox" }, select01(i){ this.num = i } } }); </script>
动态class第二种方法
css类 style
.gray {
background: gray;
}
.gold {
background: gold;
}
<!-- 需求是 点击谁 给谁加颜色 颜色只有两种 灰 和 土豪金 --> <!-- <div id="app"> <div @click=‘select(index)‘ :class="[index==num?‘gold‘:‘gray‘]" v-for=‘(item,index) in test‘ :key=‘item‘> {{item}} </div> </div> --> <div id="app"> <div @click="select(index)" :class="[index == num?‘gold‘:‘gray‘]"v-for=‘(item,index) in test‘ :key=‘item‘> {{item}} </div> </div> <script> new Vue({ el:‘#app‘, data:{ num:-1, test:[‘第三class方法‘,‘汽车‘,‘iphone‘,‘大炮‘,‘橘子‘] }, methods: { select(i){ this.num = i } }, }) </script>
动态class第三种方法
<style> .red { color: red; } .pink { color: indigo; } .blue { color: blue; } .ye { color: yellow } </style> </head> <body> <!-- 动态class第三种方法 多条件判断 true或者false改成条件 :class = ‘{ ‘类名A‘:true(条件A), ‘类名B‘:false, "类名C":true }‘ --> <div id="app"> <h1 :class="{ ‘red‘:true, ‘pink‘:false, ‘blue‘:true, ‘ye‘:1!=1 }">{{test}}</h1> </div> <script> new Vue({ el: ‘#app‘, data: { test: ‘地瓜地瓜 我是土豆‘ } }) </script>
动态style
<div id="app"> <!-- 行内样式 普通的style --> <h1 style="color:red;font-size:30px;" >{{test}}</h1> <!-- 动态style 变量要以json格式 如果遇见font-size 这种带-形式的 我们要把它转化成 驼峰命名法 或者 “font-size” --> <div :style="sty">{{test}}</div> </div> <script> new Vue({ el:‘#app‘, data:{ test:‘地瓜地瓜 我是土豆‘, sty:{ color:"pink", fontSize:"80px", "background-color":"#ccc" } } }) </script>
watch的方法 有两种
①浅监听
它可以监听 string number Boolean 简单的数组
<div id="app"> 请输入搜索内容: <input type="text" v-model=‘val‘> </div> <script> new Vue({ el:‘#app‘, data:{ val:‘‘ }, watch: { val(newVal,oldVal){ //a是 新值 newVal //b是 上一次的值 oldVal console.log(newVal,‘aaa‘) console.log(oldVal,‘bbbbbb‘) console.log(‘你已经被监视了‘) } }, }) </script>
栗子 百度搜索 思路:
当用户在输入框 每输入一次内容 都会实时调取接口(ajax 会产生跨域 jsonp 它可以解决跨域问题)
jsonp 实现的原理
第一 创建一个 script标签
第二 给标签添加src属性
第三 把创建好的标签 插入到 body中
它有一个 回调函数 可以实时返回接口的返回参数
在watch中 我们去做以上操作 等到数据之后 渲染到 页面中
通过键盘上下键 去给搜索结果 加颜色(选中它)
‘https://www.baidu.com/s?wd=‘ 获取搜索结果
---------
<div id="app"> <div> 请输入你要搜索的内容: <input type="text" v-model=‘val‘ @keydown=‘down‘ @keyup=‘up‘> </div> <ul> <!-- <li>这是我得到的搜索结果----</li> --> <li @click=‘getDetail(item)‘ :class="[i==num?‘select‘:‘‘]" v-if=‘4>i‘ v-for=‘(item,i) in arr‘ :key=‘item‘> {{item}} </li> </ul> </div> <script> let vm = new Vue({ el: ‘#app‘, //挂载点 data: { //属性 val: ‘‘, arr: [], num: -1 }, mounted() { //生命周期函数 挂载 页面一加载就会触发这个内置函数 console.log(‘页面加载 我就被触发了‘) //调用封装好的方法 this.ca() }, methods: { //方法 不一定非要写到事件中 也可以 自己封装函数 然后在需要的时候调用 ca() { return 1 }, //键盘下箭头事件 down(e) { // console.log(e,‘eeee‘) if (e.keyCode == 40) { //每按一次下箭头 num就+1 this.num++ if (this.num > 3) { this.num = 0 } } if (e.keyCode == 13) { window.open(‘https://www.baidu.com/s?wd=‘ + this.arr[this.num]) } }, //键盘上箭头事件 up(e) { //console.log(e,‘444‘) if (e.keyCode == 38) { this.num-- if (this.num < 0) { this.num = 3 } } }, //点击结果 跳转详情 getDetail(keyword) { //地址跳转方法 这个方法 是在当前页面打开 // window.location.href=‘https://www.baidu.com/s?wd=‘+keyword //window.open() 这个方法 是在新的tab打开内容 window.open(‘https://www.baidu.com/s?wd=‘ + keyword) } }, watch: { //监听 val(newVal, oldVal) { //输入框内容判空 if (newVal == ‘‘) { this.arr = [] return } // console.log(newVal,oldVal,‘我被监听了‘) //创建jsonp let script = document.createElement(‘script‘) script.src = ‘http://suggestion.baidu.com/su?cb=callback&wd=‘ + newVal document.body.appendChild(script) } }, }) console.log(vm.arr, ‘5555‘) //调取jsonp的返回函数 function callback(res) { console.log(res.s) vm.arr = res.s } </script>
②深度监听
②深度监听 可以监听 对象 和复杂数组的元素变化
深度监听 会造成页面卡顿 不建议 使用
方法 例如 对象:{deep:true,handler(newVal){newVal}}
浅监听无法监控对象的变化 有地址空间 觉得地址空间内容没变化 所以监控不到
<div id="app"> <div> 监听一个普通字符串的变化 <input type="text" v-model=‘msg‘> </div> <div> 监听简单数组内部元素的变化 <input type="text" v-model=‘arr[1]‘> </div> <div> 监听当前对象的变化: <!-- 如果你监听的是json [object Object] 就会出现 --> <input type="text" v-model=‘json.name‘> </div> <div> 监听复杂数组元素的变化: <input type="text" v-model=‘nameList[1].name‘> </div> </div> <script> new Vue({ el:‘#app‘,//挂载点 data:{//属性 msg:‘‘, arr:[‘宫保鸡丁‘,‘海底捞‘,‘满汉全席‘], json:{ name:‘大大‘, age:80 }, nameList:[ { name:‘楠楠‘, age: 29 }, { name:‘北北‘, age: 40 } ] }, methods: {//方法 }, watch: {//监听 msg(newVal){ console.log(newVal) }, arr(newVal){ console.log(newVal) }, /* 浅监听无法监控对象的变化 有地址空间 觉得地址空间内容没变化 所以监控不到 我们可以利用 深度监听 去监控整个对象的变化 ***深度监听 不建议 大家 经常使用 它会造成页面卡顿 深度监听方法 有一个参数 deep 深度 deep:true 还有一个 handler(){} handler:function(){} json(newVal){ console.log(newVal) 这个方式不行 浅监听 } */ json:{//深度监听 deep:true, handler(d){ //d你可以写成newVal console.log(d,‘你是谁‘) console.log(d.name) } }, nameList:{ handler(newVal){ console.log(newVal) }, deep:true } }, }) </script>
computed 计算属性
首先它可以当做一个属性去使用 不需要在data中做定义
然后 你可以在计算属性中 定义大量的逻辑计算 最终得到你想要的结果
一般的使用场景 购物车
计算属性有自己的set和get方法
<div id="app"> <h1>{{msg}}</h1> <h1>普通写法:{{x+y}}</h1> <h1>计算属性的写法:{{result}}</h1> <h1>字符串翻转----{{str.split(‘‘).reverse().join(‘‘)}}</h1> <h1>利用计算属性翻转---{{reverse}}</h1> </div> <script> new Vue({ el:‘#app‘,//挂载点 data:{//属性 x:10, y:50, str:‘zhangDaDa‘ }, methods: {//方法 }, watch: {//监听 }, computed: {//计算属性 msg(){ //这里面可以写大量数据 最终得到你要的结果 //return 1 return ‘我努力加标点!!!‘ }, result(){ // let a = this.x + this.y // return a return this.x + this.y +10 }, reverse(){ //split 以什么方式切割 和 join 以什么方式进行拼接 是什么是什么意思 //在工作中 或者是项目 有时候 java或者php 你要传给我一个字符串 以,形式split(‘,‘) return this.str.split(‘‘).reverse().join(‘‘) } }, }) </script>
内置get 和 set
<div id="app"> <h1>{{sum}}</h1> <div> <input type="text" v-model=‘info‘> </div> <h2>计算属性---{{info}}</h2> </div> <script> new Vue({ el:‘#app‘,//挂载点 data:{//属性 num:0 }, methods: {//方法 }, watch: {//监听 }, computed: { sum(){ //普通的写法 返回的就是你要写入的逻辑值 return 10 }, info:{ //通过当前计算属性的变化 我们可以重新 给get赋值 get(num){ // console.log(num.num,"get的值") 修改后没有上传的值 console.log(this.num,"get的值") return this.num }, set(val){ console.log(val,‘我是要被设置的值‘) this.num = val } } }, }) </script>
以上是关于第四 表单指令 v-model 双向数据绑定的主要内容,如果未能解决你的问题,请参考以下文章