Vue基础

137 阅读2分钟

Vue基础

1.v-model指令

v-model实现双向数据绑定

1.1 v-model实现原理

v-model:语法糖

v-model = :value + @input

<div id="app">
   方法一: <input type="text" v-bind:value="msg" v-on:input="iptChange"> 
   方法二: <input type="text" v-bind:value="msg" v-on:input="msg = $event.target.value">
    <h3>{{msg}}</h3>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        msg:"你好,世界"
    },
    methods:{
        iptChange(e){ //事件对象
            this.msg = e.target.value
        }
    }
})
</script>

1.2 v-model实现双向数据绑定

<div id="app">
    <input type="text" v-model="msg">
    <h3>{{msg}}</h3>
</div>

<script>
    //  v-model--双向数据绑定
    new Vue({
        el: "#app",
        data: {
            msg: '哈喽哈'
        }
    })
</script>

1.3 js实现双向数据绑定 ---面试题

<input type="text" id="ipt" value="你好" oninput="getIpt(this.value)">
<h3 class="txt">你好</h3>

<script>
    var ipt = document.querySelector('#ipt')
    var txt = document.querySelector('.txt')
    //声明一个data对象,专门用来存放数据
    var data = {}
    //Object.defineProperty(对象的名称,属性的名称,配置项)
    //get代表定义这个msg时,给他赋值的数据
    //set代表拿到最新的值是,要去做什么事情
    Object.defineProperty(data, 'msg', {
        get: function () {
            return '你好,世界'
        },
        set: function (newVal) {
            console.log(newVal);
            ipt.value = newVal
            txt.innerHTML = newVal
        }
    })
    //修改
    ipt.value = data.msg
    txt.innerHTML = data.msg
    //input值发生了改变
    function getIpt(val) {
        // console.log(val);
        //修改数据源(data.msg),会自动触发set方法
        data.msg = val
    }
</script>

1.4下拉选择框

<div id="app">
    <select  v-model="result">
        <option value="apple">苹果</option>
        <option value="banana">香蕉</option>
        <option value="orange">橘子</option>
        <option value="mango">芒果</option>
    </select>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        result:"banana"
    }
})
</script>

2.vue基本指令

2.1 v-pre

让胡子语法({{}})失效

<div id="app">
    <!-- v-pre  让胡子语法({{}})失效 -->
    <p>当你输入<span v-pre>{{msg}}</span>时,你可以看到{{msg}}</p>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        msg:"你好世界"
    }
})
</script>
<!--此时输出{{msg}}字符串-->

2.2 v-html和v-text

胡子语法和v-text一样

v-html会识别html标签

<div id="app">
    <!-- 胡子语法和v-text一样 -->
    <ul>
        <li>{{msg}}</li>  <!--你好世界-->
        <li v-html='msg'></li> <!--你好世界-->
        <li v-text='msg'></li> <!--你好世界-->

        <div>-----------------------------------------</div>

        <li>{{contain}}</li> <!--<s>12345</s>-->
        <li v-html='contain'></li> <!--12345-->
        <li v-text='contain'></li> <!--<s>12345</s>-->
    </ul>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        msg:'你好世界',
        contain:`<s>12345</s>`
    }
})
</script>

2.3 v-vloak

v-vloak用于在数据渲染出来之前,将标签隐藏掉,这样用户就看不到胡子语法

访问外部链接时,网不好的情况下会将胡子语法显现出来

<style>
    [v-vloak]{
        display: none;
    }
</style>
div id="app">
   <ul>
       <li>{{msg1}}</li>
       <li v-vloak>{{msg2}}</li>
   </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
new Vue({
    el: "#app",
    data: {
        msg1:'你好世界1',
        msg2:'你好世界2'
    
    }
})
</script>

2.4 显示隐藏

v-show和v-if

v-show:显示隐藏控制的是css的diaplay属性---频繁切换一个元素的隐藏

v-if:显示隐藏是通过创建和销毁dom元素--一次性渲染元素

<div id="app">
    <div class="box" v-show='flag'>盒子一</div>
    <div class="box" v-if='flag1'>盒子二</div>
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            flag: false,
            flag1: false
        }
    })

2.5 v-if

条件判断

div id="app">
   <ul>
       <li v-if="score>=90">优秀</li>
       <li v-else-if="score>=60">及格</li>
       <li v-else>不及格</li>
   </ul>
/div>
<script>
new Vue({
    el: "#app",
    data: {
        score:70
    }
})
</script>

2.6 v-on

事件

<div id="app">
    <button v-on:click="btnClick">按钮1</button>
    <!-- 简写 -->
    <button @click="btnClick">按钮2</button>
    <div class="box" v-show="flag">盒子</div>
</div>

<script>
new Vue({
    el: "#app",
    // data:存放数据
    data: {
        flag:true
    },
    //methods:存放方法
    methods:{
        btnClick(){
            this.flag = !this.flag
        }
    }
})
</script>

2.7 v-bind

属性绑定

<div id="app">
    <a v-bind:href="link">百度</a>
    <!-- 简写 -->
    <a :href="link">百度</a>
    
    <button @click="goSina()">切换为新浪</button>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        link:"http://baidu.com"
    },
    methods:{
        goSina(){
            this.link="http://sina.com.cn"
        }
    }
})
</script>

3.类名绑定

<style>
    .pink{
        color: pink;
    }
    .border{
        border: 1px solid rgb(40, 185, 230);
        
    }
</style>

<div id="app">
    <h3 v-bind:class="{'pink':isPink}">粉色</h3>
    <h3 :class="{'pink':isPink,'border':isBorder}">粉色文字,边框</h3>

    <!-- 三元运算符 -->
    <h3 :class="isPink ? 'pink ' : ''"  >粉色文字,边框</h3>
    <h3 :class="isPink&&isBorder ? 'pink border' : ''" >粉色文字,边框</h3>

    <!-- 数组 -->
    <h3 :class="['pink','border']">粉色文字,边框</h3>

    <!-- 函数 -->
    <h3 :class="fn()">粉色文字,边框</h3>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        isPink:true,
        isBorder:true
    },
    methods:{
        fn(){
            return ['pink','border']
        } 
    }
})
</script>

4 style绑定

<div id="app">
    <ul>
        <li style="background-color:pink;color:blue">背景粉色,文字蓝色</li>
        <li :style="{'background-color':bgcColor,color:txtColor}">背景粉色,文字蓝色</li>

        <!-- 数组方法 -->
        <li :style='colorObj'>背景粉色,文字蓝色</li>
        <li :style='[colorObj,italicObj]'>背景粉色,文字蓝色、倾斜</li>
        <!-- 函数方法 -->
        <li :style="getStyle()">背景粉色,文字蓝色、倾斜</li>
    </ul>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        bgcColor:'pink',
        txtColor:'blue',
        colorObj:{background:'pink',color:'blue'},
        italicObj:{fontStyle:'italic'}
    },
    methods:{
        getStyle(){
            return [this.colorObj,this.italicObj]
        }
    }
})
</script>

5 v-for遍历

key作为唯一标识符 ---尽量选择id,而不是index 如果选用index,那么他就失去了唯一性

index在数组发生改变时,自己也会变化,所以当数组是会变化的时候,尽量不要选择index作为key

总结: 当数组不发生变化时(一次性渲染) key可以选用index/id

当数组会发生变化时,这时候会引起html重排,此时选用id

<div id="app">
    <ul>
        <!-- key值为id -->
        <!-- <li v-for="(item,index) in arr" :key="item.id">{{item.name}}  <input type="text" ></li> -->
       
        <!--  key值为index -->
        <li v-for="(item,index) in arr" :key="index">{{item.name}}  <input type="text" ></li>
    </ul>
    <button @click="unshiftOne()">数组前添加一个</button>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        arr:[
            {id:"m1",name:"圈圈"},
            {id:"m2",name:"圆圆"},
            {id:"m3",name:"点点"},
        ]
    },
    methods:{
        unshiftOne(){
            this.arr.unshift({id:"m4",name:"翠花"})
        }
    }
})
</script>

Snipaste_2021-10-10_19-59-03.png 当key值为index时:

Snipaste_2021-10-10_20-01-41.png

当key值为id时:

Snipaste_2021-10-10_20-03-19.png

6.计算属性--computed

6.1基本

<div id="app">
    <ul>
        <li>名:{{firstname}}</li>
        <li>姓:{{lastname}}</li>
        <li>姓名:{{username}}</li>
    </ul>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        firstname:'Michael',
        lastname:'Jackson'
    },
    computed:{
        username(){
            return this.firstname+' '+this.lastname;
        }
    }
})
</script>

6.2小进阶

<div id="app">
    <ul>
        <li>名:{{firstname}}</li>
        <li>姓:{{lastname}}</li>
        
    </ul>
    姓名:<input type="text" v-model="username">
</div>

<script>
new Vue({
    el: "#app",
    data: {
        firstname:'Michael',
        lastname:'Jackson'
    },
    computed:{
        username:{
            get(){
            return this.firstname+' '+this.lastname;
            },
            set(newVal){
                console.log(newVal);
                let arr = newVal.split(" ")
                this.firstname = arr[0]
                this.lastname = arr[1] || ""
            }
            
        }
    }
})
</script>

7.computed对比methods

<div id="app">
    <ul>
        <li>名:{{firstname}}</li>
        <li>姓:{{lastname}}</li>
        <li>[computed]姓名:{{username}}</li>
        <li>[computed]姓名:{{username}}</li>
        <li>[methods]姓名:{{username1()}}</li>
        <li>[methods]姓名:{{username1()}}</li>
    </ul>  
</div>

<script>
new Vue({
    el: "#app",
    data: {
        firstname:'Michael',
        lastname:'Jackson'
    },
    methods:{
        username1(){
            console.log('methods'); //执行多次 methods没缓存
            return this.firstname+' '+this.lastname;
        }
    },
    computed:{
        username(){
            console.log('computed');//执行一次 computed有缓存
            return this.firstname+' '+this.lastname;
        }
    }
})
</script>

8.过滤器

8.1 全局过滤器

<div id="app">
    <h3>{{price | filterMoney}}</h3>
</div>
<!-- 全局过滤器的优点 全局使用-->
<div id="app1">
    <h3>{{price | filterMoney}}</h3>
</div>

<script>
    // Vue.filter('过滤器名称,配置项')
    //toFixed(n) 保留n位小数小数
    Vue.filter('filterMoney', (val) => {
        return "¥" + val.toFixed(2) + "元"
    })
    new Vue({
        el: "#app",
        data: {
            price: 21.4
        }

    })
    new Vue({
        el: "#app1",
        data: {
            price: 6.6
        }
    })
</script>

8.2 局部过滤器

<div id="app">
    <h3>{{price | filterMoney}}</h3>
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            price:6.6
        },
        filters:{
            filterMoney(val){
                return "¥" + val.toFixed(2)+"元"
            }
        }     
    })
</script>

9.存储

9.1 永久存储

localStorage --永久存储,除非手动删除,否则不会消失

<button id="btn">点击存储</button>
<script>
localStorage.setItem("username","备备")
localStorage.setItem("age","25")
localStorage.setItem("sex","女")
        
localStorage.removeItem("username")
localStorage.clear()
</script>

9.2 临时存储

sessionStorage --临时存储,只要页面关闭,否则就不会再消失

btn.onclick = function(){
    sessionStorage.setItem("username","羽羽")
}

9.3 cookie存储

localStorage和sessionStorage的存储空间有5M cookie的存储空间只有4k

btn.onclick = function(){
    document.cookie="username=123"
}