vue学习笔记

Updated on in 程序人生 with 0 views and 0 comments

vue2 官方文档地址--介绍 — Vue.js (vuejs.org)

开发插件

开发在浏览器调试,浏览器界面很不友好,下载一个google浏览器插件,优化调试界面,通过点击下面的链接跳转,可以直接在对应的浏览器插件扩展管理安装,安装后记得启用插件,调试的时候会用到本地文件,要在插件管理里面开启允许访问文件URL

vue-devtools安装教程

不同给浏览器得插件设置可以参考不同浏览器插件设置

也可以在git自己下载编译

github项目地址

使用效果如下

image.png

安装

新建目录,执行 npm init -y

执行 npm install vue@2.7.14安装

新建index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>
        {{userName}},你好
    </h1>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            userName: 'wenyoulong'
        }
    })
</script>
</body>
</html>

基本用法

声明式渲染

Vue采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统,如上面实例中的 {{userName}}

{{ }}符号内,可以访问VUE实例中定义的变量,函数,并且可以访问js内置的方法函数,也可以进行四则运算,且只能放在html标签体内使用

{{ }}在页面刷新时,会先显示表达式内容,页面加载完成后,才会变更为对应的正确数据,可以通过 v-html或者 v-text处理,v-html会将字符串作为html代码输出,v-text会将字符串直接输出

<body>
<div id="app">
    <h1>
        {{userName}},你好
        <span v-html="htmlCode"></span>
        <span v-text="htmlCode"></span>
    </h1>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            userName: 'wenyoulong',
            htmlCode: '<h1>Happy</h1>'
        }
    })
</script>
</body>
</html>

运行结果

image.png

v-model双向绑定

v-model用于处理表单输入和应用状态之间的双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <input v-model="message"/>
    <h1>
        {{userName}},你好,{{message}}
    </h1>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            userName: 'wenyoulong',
            message: ''
        }
    })
</script>
</body>
</html>

界面如图

image.png

v-on事件处理

v-on指令可以在指定元素上添加一个事件监视器,可以使用@作为缩写,用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件

如下代码使用v-on指令添加一个点击事件监视器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <button v-on:click="changeUserName">戳我一下</button>
    <h1>
        {{userName}},你好
    </h1>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            userName: 'wenyoulong'
        },
        methods:{
            changeUserName: function(){
                this.userName = 'huanhuan'
            }
        }
    })
</script>
</body>
</html>

点击后数据变为

image.png

修饰符

image.png

例如下述代码夏至只能点击一次

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <button @click.once="onceClick">只能点一次</button>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{

        },
        methods:{
            onceClick:function () {
                console.log('点一次')
            }
        }
    })
</script>
</body>
</html>

调用结果如下

image.png

v-bind动态绑定HTML元素属性

{{ }}只能在元素标签体内使用,如果我们时要对HTML标签的某一个属性值做动态绑定,就需要使用v-bind实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>
        <a v-bind:href="baidu" target="_blank">百度一下</a><br>
        <a v-bind:href="myPage" target="_blank">Happy&Long</a>
    </h1>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            baidu: 'http://www.baidu.com',
            myPage: 'http://www.wenyoulong.com'
        }
    })
</script>
</body>
</html>

v-for遍历循环

v-for可用于遍历数据、也可用于遍历组件

遍历数组

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="(user, index) in users">
            {{ user.userName }} - {{ index }} - {{ user.age }}
        </li>
    </ul>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            users:[
                {userName:'long',age:'1'},
                {userName:'huan',age:'1'},
            ]
        },
        methods:{

        }
    })
</script>
</body>
</html>

结果如下

image.png

遍历对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="(value, name) in lover">
            {{ name }} - {{ value }}
        </li>
    </ul>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            lover:{
                name:'huan',
                age: '1',
                address: '四川'
            }
        },
        methods:{

        }
    })
</script>
</body>
</html>

结果

image.png

遍历时进行过滤

代码中判断数组内数据,对2求余

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="n in evenNumbers">{{ n }}</li>
    </ul>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            numbers:[1,2,3,4,5]
        },
        computed:{
            evenNumbers:function(){
                return this.numbers.filter(number => {
                    return number % 2 === 0
                })
            }
        }
    })
</script>
</body>
</html>

输出结果

image.png

v-if和v-show控制元素显示

这里先说明两个元素的区别,v-show和v-if得区别就是,v-show控制的元素,会一直在dom中,通过切换display属性来控制元素的显示与否,v-if在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,v-if为false时,控制的元素会从dom中删除,为true时则重新加载。

v-show元素总会被渲染,初始化开销高;

v-if元素第一次条件为真才会渲染,切换开销高;

若元素经常被使用,则使用v-show,否则使用v-if。

使用方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">

    <button @click="showInput">点击我</button><br/>
    <input placeholder="测试v-if" v-if="inputLoad"/><br/>
    <input placeholder="测试v-show" v-show="inputDisplay"/><br/>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            inputLoad:false,
            inputDisplay:false
        },

        methods:{
            showInput:function (){
                this.inputLoad = !this.inputLoad;
                this.inputDisplay = !this.inputDisplay;
            }
        }
    })
</script>
</body>
</html>

点击前dom元素如下,可以清晰看到,v-show控制的input已经加载到页面dom中,而v-if得则没有点击后两个都会显示

image.png

点击结果

image.png

此时如果在更改两个状态为false,则v-if控制的元素会从dom中删除,而v-show得则会将display改为false隐藏元素。

key管理可复用元素

vue通过复用元素来尽可能得高效渲染元素

如下述代码中,切换v-if,文本框内的数据不会变动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">

    <button @click="changeLoginType">切换登录</button><br/>
    <template v-if="loginType === 'username'">
        <label>用户名</label>
        <input placeholder="输入用户名">
    </template>
    <template v-else>
        <label>密码</label>
        <input placeholder="输入密码">
    </template>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            loginType:'username'
        },

        methods:{
            changeLoginType:function (){
                if(this.loginType === 'username'){
                    this.loginType = ''
                }else{
                    this.loginType = 'username'
                }
            }
        }
    })
</script>
</body>
</html>

在用户名输入框中输入一个值

image.png

点击切换登录发现输入的内容还在

image.png

这是因为这两个模板使用了相同的元素,input不会被替换,只是替换了placeholder

我们可以给两个input加上key来告诉vue这两个input不要复用,这样的话,每次切换,输入框都会重新加载渲染

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">

    <button @click="changeLoginType">切换登录</button><br/>
    <template v-if="loginType === 'username'">
        <label>用户名</label>
        <input placeholder="输入用户名" key="name-input">
    </template>
    <template v-else>
        <label>邮箱</label>
        <input placeholder="输入邮箱" key="email-input">
    </template>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            loginType:'username'
        },

        methods:{
            changeLoginType:function (){
                if(this.loginType === 'username'){
                    this.loginType = ''
                }else{
                    this.loginType = 'username'
                }
            }
        }
    })
</script>
</body>
</html>

computed计算属性与watch侦听器

基础示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">

   {{reverseMessage}}
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            message:'WenYL Huan'
        },

        computed:{
            reverseMessage:function (){
                return this.message.split(' ').reverse().join(' ')
            }
        }
    })
</script>
</body>
</html>

运行结果

image.png

计算属性与方法的区别

上面例子中得代码通用可用以下代码实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">

   {{reverseMessage()}}
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            message:'WenYL Huan'
        },

        methods:{
            reverseMessage:function (){
                return this.message.split(' ').reverse().join(' ')
            }
        }
    })
</script>
</body>
</html>

区别:

  • 使用methods中的函数,每次都会调用然后重新计算
  • 使用computed,只有只在相关响应式依赖发生改变时它们才会重新求值。

使用computed,是由当我们的message发生变化才会重新计算,否则都是返回之前计算好的值

计算属性和侦听器的区别

使用watch同样可以实现属性值的侦听,下述代码使用watch侦听两个属性的值,若值发生变化,则执行对应的方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    英语成绩<input type="number" min="0" v-model="englishScore" /> <br>
    数学成绩<input type="number" min="0" v-model="mathScore" /> <br>
    总成绩--{{totalScore}}
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            mathScore: 0,
            englishScore: 0,
            totalScore: 0
        },

        watch:{
            mathScore:function (newValue,oldValue){
                this.totalScore = parseFloat(newValue) + parseFloat(this.englishScore)
            },
            englishScore:function (newValue,oldValue){
                this.totalScore = parseFloat(newValue) + parseFloat(this.mathScore)
            }
        }
    })
</script>
</body>
</html>

同样的操作,使用computed用下面的代码即可实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    英语成绩<input type="number" min="0" v-model="englishScore" /> <br>
    数学成绩<input type="number" min="0" v-model="mathScore" /> <br>
    总成绩--{{computedTotalScore}}
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            mathScore: 0,
            englishScore: 0
        },

        computed:{
            computedTotalScore:function (){
                return  parseFloat(this.mathScore) + parseFloat(this.englishScore)
            },

        }
    })
</script>
</body>
</html>

二者的区别

  • computed侧重计算属性,watch侧重侦听属性的变化并执行相应的操作
  • computed有缓存机制属性不变调用方法时,会返回上次计算的结果,watch只要改变,每次都会重新执行
  • computed必须return一个计算结果,而watch不一定有return

如果我们只是计算结果,使用computed,如果出了要计算结果还要执行一系列的方法,则使用watch

计算属性的get和set

计算属性默认提供了get,我们也可以自己实现set,代码示例如下,当我们直接设置计算属性,就会调用对应的set方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    {{computedTotalScore}}
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    let vm = new Vue({
        el:"#app",
        data:{
            mathScore: 0,
            englishScore: 0,
            totalScore: ''
        },
        mounted() {
            this.computedTotalScore = "100 100"
        },
        computed:{
            computedTotalScore:{
                get: function (){
                    return  parseFloat(this.mathScore) + parseFloat(this.englishScore)
                },
                set: function (newValue){
                    console.log(newValue)
                    var scores = newValue.split(" ")
                    this.mathScore = parseFloat(scores[0])
                    this.englishScore = parseFloat(scores[1])
                }
            }

        }
    })
</script>
</body>
</html>

组件化

组件命名规则有两种

  • 首字母大写的驼峰命名规则,eg:MyComponent
  • -分割的命名规则,eg:my-component

全局组件

全局组件使用 Vue.component注册,代码示例如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <click-count></click-count>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>

    Vue.component('click-count',{
        template:'<button v-on:click="count++">点击了{{count}}次</button>',
        data(){
            return{
                count:0
            }
        }
    });
    let vm = new Vue({
        el:"#app",
        data:{

        },
    })
</script>
</body>
</html>

局部组件注册

局部组件通过components属性配置,代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <click-count></click-count>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    const countComponent = {
        template:'<button v-on:click="count++">点击了{{count}}次</button>',
        data(){
            return{
                count:0
            }
        }
    }
    let vm = new Vue({
        el:"#app",
        components: {
            'click-count' : countComponent
        },
        data:{

        },
    })
</script>
</body>
</html>

生命周期

组件交互

参考VUE父子组件通信 - 问尤龙の时光 (wenyoulong.com)


标题:vue学习笔记
作者:wenyl
地址:http://www.wenyoulong.com/articles/2023/05/09/1683621101866.html