第四 表单指令 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>

 

 

 

 

 

上一篇:关于vue 数据监听的处理


下一篇:form表单内部变化watch监听