Vue2 初识

1年前 (2021-10-21) 2029次浏览 已收录 4个评论

vue的两个特性

数据驱动视图

vue会监听数据的变化,从而自动重新渲染页面的结构,数据驱动视图是单向的数据绑定。即vue帮我操作dom元素来渲染页面,开发者不用再操作dom了。

双向数据绑定

在网页中,form表单负责采集数据,ajax负责提交数据。

而vue呢,会在填写表单时,双向数据绑定可以辅助开发者在不操作dom的前提下,自动将用户填写的内容同步到数据源中。

数据驱动视图和双向数据绑定的底层原理是MVVM(Mode数据源、View视图、ViewMode就是vue的实例。

vue基础语法

基本使用步骤

  • 导入vue.js的script脚本文件
  • 在页面中声明一个将要被vue所控制的dom区域
  • 创建vm实例对象(vue实例对象)
//1.导入vue的库文件,在window全局就有个了vue这个构造函数
    <script src="./vue-2.6.12.js"></script>
    <script>
        //2.创建vue的实例对象
        const vm = new Vue({
            //4.属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,
            // 接收的值是一个选择器
            el:'#app',
            //5.data对象就是要渲染到页面上的数据
            data:{
                username:'zzl'
            }
        })
    </script>
结果演示

vue的指令

指令时vue为开发者提供的模版语法,用于辅助开发者渲染页面的基本结构。

  • 内容渲染指令
  • 属性绑定指令
  • 事件绑定指令
  • 双向绑定指令
  • 条件渲染指令
  • 列表渲染指令

内容渲染指令

用来辅助开发者渲染dom元素的文本内容,常用的内容渲染指令如下:

  • v-text
  • {{}}
  • v-html

v-text(不推荐)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>内容渲染指令</title>
</head>

<body>
    <!-- 3.希望vue能控制下面的这个div,把数据填充到div内部 -->
    <div id="app">
        <!-- 把username对应的值,渲染到第一个p标签中 -->
        <p v-text="username"></p>
        <p v-text="gender">性别</p>
    </div>

    <!-- 1.导入vue的库文件,在window全局就有个了vue这个构造函数-->
    <script src="./vue-2.6.12.js"></script>
    <script>
        //2.创建vue的实例对象
        const vm = new Vue({
            //4.属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,
            // 接收的值是一个选择器
            el: '#app',
            //5.data对象就是要渲染到页面上的数据
            data: {
                username: 'zzl',
                gender:'男'
            }
        })
    </script>
</body>

</html>
结果演示
缺点:它会覆盖标签内部原本内容

{{}} 插值表达式

它专门用来解决v-text会覆盖默认文本内容的问题,相当于占位符。

<p>性别:{{gender}}</p>
结果演示

v-html

v-text和插值表达式智能渲染纯文本内容,如果要把包含html标签的字符串渲染为页面的html元素,需要使用v-html指令

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-html</title>
</head>

<body>
    <!-- 3.希望vue能控制下面的这个div,把数据填充到div内部 -->
    <div id="app">
        <!-- 把username对应的值,渲染到第一个p标签中 -->
        <p v-text="username"></p>
        <p>性别:{{gender}}</p>
        <div v-html="info"></div>
    </div>

    <!-- 1.导入vue的库文件,在window全局就有个了vue这个构造函数-->
    <script src="./vue-2.6.12.js"></script>
    <script>
        //2.创建vue的实例对象
        const vm = new Vue({
            //4.属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,
            // 接收的值是一个选择器
            el: '#app',
            //5.data对象就是要渲染到页面上的数据
            data: {
                username: 'zzl',
                gender:'男',
                info:'<h1 style="color:red">渣渣龙</h1>'
            }
        })
    </script>
</body>

</html>
结果演示

属性绑定指令

v-bind属性绑定指令可以为元素属性动态单向绑定属性值。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>属性绑定指令</title>
</head>

<body>
    <!-- 3.希望vue能控制下面的这个div,把数据填充到div内部 -->
    <div id="app">
        <input type="text" placeholder="请看右边的框">
        <input type="text" v-bind:placeholder="tips">
        <!-- v-bind简写为: -->
        <input type="text" :placeholder="tips">

    </div>

    <!-- 1.导入vue的库文件,在window全局就有个了vue这个构造函数-->
    <script src="./vue-2.6.12.js"></script>
    <script>
        //2.创建vue的实例对象
        const vm = new Vue({
            //4.属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,
            // 接收的值是一个选择器
            el: '#app',
            //5.data对象就是要渲染到页面上的数据
            data: {
                tips:'zzl'
            }
        })
    </script>
</body>

</html>
结果演示

属性添加相关计算

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>属性绑定指令</title>
</head>

<body>
    <!-- 3.希望vue能控制下面的这个div,把数据填充到div内部 -->
    <div id="app">
        <div>1+2的结果是:{{1+2}}</div>
        <div :title="'box'+index">鼠标放我身上</div>
    </div>

    <!-- 1.导入vue的库文件,在window全局就有个了vue这个构造函数-->
    <script src="./vue-2.6.12.js"></script>
    <script>
        //2.创建vue的实例对象
        const vm = new Vue({
            //4.属性是固定的写法,表示当前vm实例要控制页面上的哪个区域,
            // 接收的值是一个选择器
            el: '#app',
            data:{
                index:3
            }
        })
    </script>
</body>

</html>
结果演示
即{{}}里面支持js表达式

{{number+1}}
{{ok ? 'yes' : 'no'}}
...

事件绑定指令

v-on事件绑定指令

用来辅助开发者为dom元素绑定事件监听

v-on:事件名称="事件处理函数的名称"
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件绑定指令</title>
</head>

<body>
    <div id="app">
        <p>count的值是{{count}}</p>
        <!-- 可以传参 -->
        <button v-on:click="add">+1</button>
        <!-- v-on可以简写为@ -->
        <button @click="sub">-1</button>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                count:0
            },
            //methods定义事件处理函数
            methods:{
                add(e){
                    // console.log(e)
                    this.count+=1
                },
                sub(){
                    vm.count-=1
                }
            }
        })
    </script>
</body>

</html>
结果演示
原生dom对象里的onclick、oninput、onkeyup等事件,替换为vue的事件绑定形式为:v-on:click、v-on:input、v-on:keyup

事件对象

vue提供了内置变量$event,他就是原生dom的事件对象e

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件对象</title>
</head>

<body>
    <div id="app">
        <p>count的值是{{count}}</p>
        <!-- 如果count是偶数,则按钮背景颜色变成红色,否则取消背景颜色 -->
        <!-- vue提供了内置变量$event,他就是原生dom的事件对象e,不带小括号,它默认自带事件对象e,带小括号的话事件对象为$event,因为e被小括号里的值给覆盖了-->
        <button @click="add(1,$event)">+1</button>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                count: 0
            },
            //methods定义事件处理函数
            methods: {
                add(n,e){
                    this.count+=n
                    //判断count的值是否为偶数
                    if(this.count%2 ===0){
                        //偶数
                        e.target.style.backgroundColor='red'
                    }else{
                        e.target.style.backgroundColor=''
                    }
                }
            }
        })
    </script>
</body>

</html>
结果演示

事件修饰符

在事件处理函数中调用event.preventDefault()或event.stopPropagation(0是非常常见的需求,这里vue提供了事件修饰符的概念,来辅助开发者放方便的对事件的触发进行控制,常见的事件修饰符如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件修饰符</title>
</head>

<body>
    <div id="app">
        <!-- <a href="https://www.wangxuelong.vip" @click.prevent="show">跳转到你想看到的页面</a> -->
        <!-- 给a链接绑定一个click事件,同时要阻止链接的默认行为,这里用到了事件修饰符 -->
        <a href="https://www.wangxuelong.vip" @click.prevent="show">跳转到你想看到的页面</a>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            //methods定义事件处理函数
            methods: {
                show(e){
                    //阻止链接默认跳转
                    // e.preventDefault();
                    console.log('点击了')
                }
            }
        })
    </script>
</body>

</html>
结果演示

按键修饰符

实际开发中,esc和enter键使用的较多。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>按键修饰符</title>
</head>

<body>
    <div id="app">
        <!-- 判断用户是否按下了esc键 ,按下了就清空数据-->
        <input type="text" @keyup.esc="clear">
        <p>按esc键清空</p>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
            },
            //methods定义事件处理函数
            methods: {
                clear(e){
                    //重置为空
                    e.target.value=''
                }
            }
        })
    </script>
</body>

</html>
结果演示

双向绑定指令

v-model指令

vue提供了v-model双向绑定指令,可以在不操作dom的前提下来对表单元素进行表单数据操作。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>双向绑定指令</title>
</head>

<body>
    <div id="app">
        <p>用户的名字:{{username}}</p>
        <input type="text" v-model="username">
        <hr>
        <p>用户地址:{{city}}</p>
        <select v-model="city">
            <option value="">请选择城市</option>
            <option value="北京">北京</option>
            <option value="上海">上海</option>
        </select>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            //5.data对象就是要渲染到页面上的数据
            data: {
                username: 'zzl',
                city:'请选择城市'          
            }
        })
    </script>
</body>

</html>
结果演示
v-model会在内部判断自己绑定的表单类型(value/checkbox等)

下面的案例代码会检测到checkbox类型,会把item.flag绑给checked

v-model指令的修饰符

.lazy不会实时更新数据源
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-model修饰符</title>
</head>

<body>
    <div id="app">
        <input type="text" v-model.number="n1">+<input type="text" v-model.number="n2">=<span>{{n1+n2}}</span>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            //5.data对象就是要渲染到页面上的数据
            data: {
                n1:1,
                n2:2
            }
        })
    </script>
</body>

</html>
结果演示

条件渲染指令

它用来按需控制dom的显示与隐藏,它分别有以下两个主要指令。

  • v-if:它会动态的创建和移除元素,即源代码里看不到
    • 如果刚进入页面,某些元素不需要首先加载,并且后期这个元素很可能也不会被展示出来,这个时候v-if性能更好,因为它时动态创建和移除。
  • v-show:它只是添加样式disply:none来显示隐藏,源代码里能看到。
    • 如果要频繁的切换元素的显示状态,v-show性能更好。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>条件渲染指令</title>
</head>

<body>
    <div id="app">       
        
        <p v-if="flag">这是被v-if控制的元素</p>
        <p v-show="flag">这是被v-show控制的元素</p>

        <button v-on:click="ft">改为true</button>
        <button @click="ff">改为flase</button>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            //5.data对象就是要渲染到页面上的数据
            data: {
                // flag为true则显示被控制的元素,否则隐藏被控制的元素
                flag:true
            },
            methods:{
                ft(){
                    this.flag=true;
                },
                ff(){
                    this.flag=false;
                }
            }
        })
    </script>
</body>

</html>
结果演示

v-else-if指令

它充当v-if的”else-if”块,可以连续使用,它必须和v-if指令搭配才能使用。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>elseif</title>
</head>

<body>
    <div id="app">
        <div v-if="type==='zzl'">渣渣龙</div>
        <div v-else-if="type==='wxl'">王学龙</div>
        <div v-else="type==='ll'">龙</div>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            //打开开发者工具控制type
            data: {
                type:'zzl'
            },
        })
    </script>
</body>

</html>
结果演示

列表渲染指令

v-for是基于一个数组来循环渲染一个列表结构。它还支持一个可选的第二个参数,即当前项的索引,语法格式为(item,index) in list。

建议:

<tr v-for="(item,index) in list" :key="item.id">
只要用到了v-for指令,那么一定要绑定一个:key属性,既提升性能,又防止列表状态紊乱。
尽量把id(字符串或者数字类型)作为key的值,且不能重复。
避免使用index索引当作key值,因为index相较于与值的绑定,它就不具有唯一性。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>列表渲染指令</title>
    <link rel="stylesheet" href="./bootstrap.css">
</head>

<body>
    <div id="app">
        <table class="table table-bordered table-hover">
            <thead>
                <th>索引</th>
                <th>id</th>
                <th>姓名</th>
            </thead>
            <tbody>
                <!-- 在tr身上也可访问到item -->
                <!-- <tr v-for="(item) in list" :title="item.name"> -->
                
                    <!-- 官方建议:只要用到了v-for指令,那么一定要绑定一个:key属性 -->
                    <!-- 尽量把id(字符串或者数字类型)作为key的值,且不能重复 -->
                    <tr v-for="(item,index) in list" :key="item.id">
                    <td>{{index}}</td>
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                list:[
                    {id:1,name:'zzl'},
                    {id:2,name:'wxl'},
                    {id:3,name:'ll'}
                ]
            }
        })
    </script>
</body>

</html>、
结果演示

案例

需求,做一个动态列表,可以通过状态来控制是否可以被删除,可以添加数据。利用双向绑定、条件渲染、列表渲染来实现,具体代码如下。

    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                nextId:4,
                brand:'',
                list: [
                    { id: 1, flag:true, name: 'zzl' },
                    { id: 2, flag:false,name: 'wxl' },
                    { id: 3, flag:true,name: 'll' }
                ],        
            },
            methods:{
                add(){
                    if(this.brand===''){
                        return alert('不能输入空')
                    }
                    this.list.push({id:this.nextId,flag:true,name:this.brand})
                    this.nextId++
                },
                remove(id){
                    this.list=this.list.filter(row=>row.id!==id)
                }
            }
        })
    </script>
结果演示

过滤器

在vue3中已经删去了过滤器,所以本篇文章只记个基础的笔记。过滤器常用语文本的格式化,它可以用在插值表达式和v-bind属性绑定上,而且过滤器应该添加到表达式的尾部,由管道符把表达式传给过滤器函数内部。

<!-- 通过管道符把message传给capitalize过滤器并调用,对message的值进行格式化 -->
<p>{{message | capitalize}}</p>

私有过滤器

只在当前vue实例中使用。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>过滤器</title>
</head>

<body>
    <div id="app">
        <p>h变成大写字母:{{message | daxie}}</p>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                message:'h'
            },
            //过滤器函数必须定义到filters节点下
            filters:{
                //mes就是管道符前面的message
                daxie(mes){
                    //一定要有一个返回值
                    return mes.charAt(0).toUpperCase()
                }
            }
        })
    </script>
</body>

</html>

结果演示

全局过滤器

如果希望在多个vue实例之间共享过滤器,需要定义全局过滤器。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>全局过滤器</title>
</head>

<body>
    <div id="app">
        <p>h变成大写字母:{{message | daxie}}</p>
    </div>
    <div id="app2">
        <p>g变成大写字母:{{message | daxie}}</p>
    </div>
    <script src="./vue-2.6.12.js"></script>
    <script>
        // 全局过滤器
            // Vue.filter()方法接收两个参数,
            // 第一个是全局过滤器的名字,第二个是过滤器的v处理函数
            Vue.filter('daxie', (mes) => {
                return mes.charAt(0).toUpperCase()
            })
        const vm = new Vue({
            el: '#app',
            data: {
                message:'h'
            }         
        })
        const vm2 = new Vue({
            el: '#app2',
            data: {
                message:'g'
            }
        })
    </script>
</body>

</html>
结果演示
如果全局过滤器和私有过滤器名字一样,将会就近采用私有过滤器
连续调用多个过滤器

message会传给第一个过滤器,第一个过滤器return的结果会传给第二个过滤器pipei
 <p>h变成大写字母:{{message | daxie | pipei}}</p>

过滤器传惨

<p>{{message | daxie(age1,age2)}}</p>
        /////////////////////////////////////
Vue.filter('daxie',(mes,arg2,arg2))


动画与过渡

动画

<template>
  <div>
      <button @click="isShow=!isShow">显示/隐藏</button>
      <!-- appear首次进入就有动画效果 -->
      <transition name="zzlActive" :appear="true">
          <h1 v-show="isShow">zzl</h1>
      </transition>
  </div>
</template>

<script>
export default {
    name:'Act',
    data(){
        return{
            isShow:true
        }
    }
}
</script>

<style scoped>
h1{
    background-color: blue;
}
.zzlActive-enter-active{
    animation: act 1s;
}
.zzlActive-leave-active{
    /* reverse就是反向 */
    animation: act 1s reverse;
}
@keyframes act{
    from{
    //类似从-100像素到0像素
        transform: translateX(-100%);
    }
    to{
        transform: translateX(0px);
    }
}
</style>

过渡

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!-- transition-group可以针对里面有多个过渡,必须指定key -->
    <transition-group name="zzl" :appear="true">
      <h1 v-show="isShow" key="1">wxl</h1>
      <h1 v-show="isShow" key="2">ll</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: 'Act',
  data() {
    return {
      isShow: true
    }
  }
}
</script>

<style scoped>
h1 {
  background-color: blue;
  transition: 0.5s;
}
/* 进入的起点 离开的终点*/
.zzl-enter ,.zzl-leave-to {
  transform: translateX(-100%);
}
/* 进入和离开的整个过程 */
/* .zzl-enter-active,.zzl-leave-active{
      transition: 1s;
} */
/* 进入的终点 离开的起点*/
.zzl-enter-to, .zzl-leave {
  transform: translateX(0);
}
</style>

引入第三方动画库

<!--https://animate.style/-->
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!-- transition-group可以针对里面有多个过渡,必须指定key -->
    <transition-group 
    name="animate__animated animate__bounce"
    enter-active-class="animate__swing"
    leave-active-class="animate__swing"
    :appear="true"
    >
      <h1 v-show="isShow" key="1">wxl</h1>
      <h1 v-show="isShow" key="2">ll</h1>
    </transition-group>
  </div>
</template>

<script>
import 'animate.css'
export default {
  name: 'Act',
  data() {
    return {
      isShow: true
    }
  }
}
</script>

<style scoped>
h1 {
  background-color: blue;
  transition: 0.5s;
}

</style>

渣渣龙, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Vue2 初识
喜欢 (6)

您必须 登录 才能发表评论!

(4)个小伙伴在吐槽
  1. 大哥牛逼,yyds
    Iᴛ'sᴅᴇsᴛɪɴʏ²⁸2021-10-27 17:21
  2. 666
    百事2021-11-14 22:47
  3. 7777
    百事2021-11-14 22:48
  4. 77778
    百事2021-11-14 22:49