哪有什么岁月静好,不过是有人替你负重前行!

vue 基础练习

1、初识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>Vue 示例</title>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="book in books">{{book.name}}</li>
        </ul>
    </div>

    <script src="./vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data:{
                books:[
                    {name:'<<vue.js>>'},
                    {name:'<<Javascript>>'},
                    {name:'<<html>>'}
                ]
            }
        })
    </script>
</body>
</html>

显示结果:

 2、数据绑定和第一个vue应用    v-model

<!-- test1.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>Vue 示例</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="name" placeholder="你的姓名">
        <h1>你好!{{name}}</h1>
    </div>

    <script src="./vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data:{
                name
            }
        })
    </script>
</body>
</html>

 3、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>Document</title>
</head>
<body>
    <div id="app">

    </div>
    <script src="./vue.js"></script>
    <script>
        var myData = {
            a:1
        }
        var app = new Vue({
            el:'#app',
            data:myData,
        })
        console.log(app.a); //1

        // 修改vue属性,原数据也随之改动
        app.a=2;
        console.log(myData.a);  //2

        // 反之,修改原数据,vue的属性也随之改动
        myData.a=3;
        console.log(app.a); //3
    </script>
</body>
</html>

4、生命周期  created  mounted  beforeDestroy

<!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>Document</title>
</head>
<body>
    <div id="app">

    </div>

    <script src="./vue.js"></script>
    <script>
        /*
        • created 实例创建完成后调用,此阶段完成了数据的观测等,但尚未挂载, $el 还不可用。
        需要初始化处理一些数据时会比较有用,后面章节将有介绍.
        • mounted el 挂载到实例上后调用,一般我们的第一个业务逻辑会在这里开始
        • beforeDestroy 实例销毁之前调用。主要解绑一些使用 addEventListener 监听的事件等。
        这些钩子与 el data 类似,也是作为选项写入 Vue 实例内,并且钩子的 this 指向的是调用它
        的Vue 实例
        */
        var app = new Vue({
            el:'#app',
            data:{
                a:2
            },
            created:function(){
                console.log(this.a);  //2
            },
            mounted:function(){
                console.log(this.$el);  //<div id='app'></div>
            }
        })
    </script>
</body>
</html>

5、插值与表达式  { { } }

<!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">
        {{book}}
    </div>

    <script src="./vue.js"></script>
    <script>
        /*
        使用双大括号( Mustache 语法)“{{}}”是最基本的文本插值方法,它会自动将我们双向绑
        定的数据实时显示出来,例如:
        */
        new Vue({
            el:'#app',
            data:{
                book:'《Vue.js 实战》'  //《Vue.js 实战》
            }
        })
    </script>
</body>
</html>

6、使用vue实现每秒更新现在的实时时间  mounted  beforeDestroy  timer  设置定时器setInterval  清除定时器clearInterval  

<!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>使用vue实现每秒更新实时时间</title>
</head>
<body>
    <div id="app">
        {{date}}
    </div>

    <script src="./vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                date:new Date()
            },
            mounted:function () {
                var _this = this;   //声名一个变量指向vue实例this,保证作用域一致
                this.timer = setInterval(function() {
                    _this.date = new Date();    //修改数据 date
                }, 1000);
            },
            beforeDestroy: function() {               
                if(this.timer){
                    clearInterval(this.timer);  //在vue实例销毁前,清除定时器
                }
            }
        })
        //Thu Feb 24 2021 16:28:12 GMT+0800 (中国标准时间)
    </script>
</body>
</html>

7、使用v-html输出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输出HTML超链接</title>
</head>
<body>
    <div id="app">
        <span v-html="link"></span>
    </div>

    <script src="./vue.js"></script>
    <script>
        //如果有的时候就是想输出 HTML ,而不是将数据解释后的纯文本,可以使用 v-html:
        new Vue({
            el:'#app',
            data:{
                link:'<a href="#">这是一个连接</a>'
            }
        })
        /*
        link 的内容将会被渲染为 个具有点击功能的 标签,而不是纯文本。这里要注意,如果将用
        户产生的内容使用 v-html 输出后,有可能导致 xss 攻击,所以要在服务端对用户提交的内容进行
        处理, 般可将尖括号“< ”转义。
        */
    </script>
</body>
</html>

  输出结果:

 8、在{ { } }中运算,三元运算  

<!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">
        {{number / 10}}
        {{isOK ? '确定' : '取消'}}
        {{text.split(',').reverse().join(',')}}
    </div>

    <script src="./vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                number:200,
                isOk:false,
                text:'hello,world'
            }
        })
    </script>
</body>
</html>

 9、过滤器 filters 实例,实时时间格式化输出。

<!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">
        {{date | formatDate}}
    </div>

    <script src="./vue.js"></script>
    <script>
        //在月份、日期、小时等小于10时前加补0
        var padDate = function(value){
            return value < 10 ? '0' + value : value;
        }
        var app = new Vue({
            el:'#app',
            data:{
                date:new Date()
            },
            filters: {
                formatDate: function(value) {   //这里的value就是需要过滤的数据
                    var date = new Date(value);
                    var year = date.getFullYear();
                    var month = padDate(date.getMonth() + 1);
                    var day = padDate(date.getDate());
                    var hours = padDate(date.getHours());
                    var minutes = padDate(date.getMinutes());
                    var seconds = padDate(date.getSeconds());
                    //将整理好的数据返回出去
                    return year + '-' + month + '-' + day + '-' + hours + ':' + minutes + ':' + seconds;
                }
            },
            mounted:function(){
                var _this = this;   //声明一个变量指向 Vue实例this,保证作用域一致
                this.timer = setInterval(function(){
                    _this.date = new Date();    //修改数据date
                },1000)
            },
            beforeDestroy:function(){
                if(this.timer){
                    clearInterval(this.timer);  //在vue实例销毁前,清除我们的定时器
                }
            }
        })
        //输出:2021-12-26-11:39:10
    </script>
</body>
</html>

输出:2021-12-26-11:39:10

10、指令与事件   v-if="show"实现网页上的内容显示与否

指令( Directives )是 ue 模板中最常用的 项功能,它带有前缀 -, 在前文我们已经使用 过不少指令了,比如 -if v-html v-pre 等。指令的主要职责就是当其表达式的值改变时,相应地 将某些行为应用到 DOM 上,以 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>v-if="show"实现网页上的内容显示与否</title>
</head>
<body>
	<div id="app">
		<p v-if="show">显示这段文字</p>
	</div>

	<script src="./vue.js"></script>
	<script>
		var app = new Vue({
			el:'#app',
			data:{
				show:true 	//当数据 show 的值为 true 时, 元素会被插入,为 false 时则会被移除
			}
		})
	</script>
</body>
</html>

结果:

11、v-bind更新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>11、v-bind更新HTML元素属性</title>
</head>
<body>
  <div id="app">
    <a v-bind:href="url">链接</a>
    <img v-bind:src="imgUrl" alt="#">
  </div>

  <script src="./vue.js"></script>
  <script>
    //v-bind 的基本用途是动态更新 HTML 元素上的属性
    var app = new Vue({
      el:'#app',
      data:{
        url:'https://www.github.com',
        imgUrl:'https://img0.baidu.com/it/u=2936746125,1314779078&fm=253&fmt=auto&app=138&f=JPG?w=200&h=200'
      }
    })
  </script>
</body>
</html>

  显示结果:

12、v-on绑定事件监听

另一个非常重要的指令就是 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>12、v-on绑定事件监听</title>
</head>
<body>
    <div id="app">
        <p v-if="show">这是一段文字</p>
        <button v-on:click="handleClose">点击隐藏</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                show:true
            },
            methods: {
                handleClose() {
                    this.show = false
                }
            },
        })
    </script>
</body>
</html>

结果:

在button 按钮上,使用 v-on:click 给该元素绑定了 个点击事件,在普通元素上, v-on 可以监 昕原生的 DOM 事件,除了 click 外,还有 dblclick keyup, mousemove 等。表达式可以是 个方 法名,这些方法都写在 Vue 实例的 methods 属性内,并且是函数的形式,函数内的 this 指向的是当 Vue 实例本身,因此可以直接使用 this.xxx 的形式来访问或修改数据,如示例中的 this.show = false ;把数据 show 修改为了 false ,所以点击按钮时,文本 素就被移除了。

表达式除了方法名, 也可以直接是 个内联语旬,上例也可以改写为:

<!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>12、v-on绑定事件监听</title>
</head>
<body>
    <div id="app">
        <p v-if="show">这是一段文字</p>
        <!-- //<button v-on:click="handleClose">点击隐藏</button> -->
        <button v-on:click="show = false">点击隐藏</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                show:true
            },
            // methods: {
            //     handleClose() {
            //         this.show = false
            //     }
            // },
        })
    </script>
</body>
</html>

13、语法糖  <a v-bind:href= "url" >链接 </a> 可以缩写成<a :href= "url" >链接 </a>  v- on 可以直接用 @来缩写

语法糖是指在不影响功能的情况下 添加某种方法实现同样的效果 从而方便程序开发。 Vue.js里 v-bind和 v-on 指令都提供了语法糖 也可以说是缩写 比如 v-bind 可以省略 v-bind, 直接写一个冒号 :

例如:

<a v-bind:href="url"></a>
<img v-bind:src="imgUrl" alt="">

可以缩写成

<a :href="url"></a>
<img :src="imgUrl" alt="">

v- on 可以直接用 @来缩写:

<button v-on:click="handleClose">点击隐藏</button>

可缩写为:

<button @click="handleClose">点击隐藏</button>

 第三章 计算属性

14、计算属性

通过上一章的介绍,我们己经可以搭建出一个简单的 Vue 应用,在模板中双向绑定 些数据 或表达式了。但是表达式如果过长,或逻辑更为复杂时,就会变得雕肿甚至难以阅读和维护,比如:

<div id="app">
    {{text.split(',').reverse().join(',')}}
</div>

这里的表达式包含 3个操作,并不是很清晰,所以在遇到复杂的逻辑时应该使用计算属性。 上例可以用计算属性进行改写:

<!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>13、计算属性</title>
</head>
<body>
    <div id="app">
        <!-- //{{text.split(',').reverse().join(',')}} -->
        {{reverseText}}
    </div>

    <script src="./vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                text:'123,456'
            },
            computed: {
                reverseText:function() {
                    return this.text.split(',').reverse().join(',')
                }
            },
        })
        // 输出:456,123
    </script>
</body>
</html>

 所有的计算属性都以函数的形式写在vue的实例内的computed选项内,最终返回计算后的结果。

15、计算属性的用法-计算购物车内两个包裹的总价

在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回 一个结 果就可以。除了上例简单的用法,计算属性还可以依赖多个 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>15、计算属性的用法-计算购物车内两个包裹的总价</title>
</head>
<body>
    <div id="app">
        总价:{{prices}}
    </div>
    <script src="./vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                package1:[
                    {
                        name:'iphone13',
                        price:3000,
                        count:1
                    },
                    {
                        name:'huawei',
                        price:5000,
                        count:5
                    }
                ],
                package2:[
                    {
                        name:'xiaomi',
                        price:4000,
                        count:2
                    },
                    {
                        name:'vivo',
                        price:3500,
                        count:3
                    }
                ]
            },
            computed: {
                prices:function() {
                    var prices = 0;
                    for(var i = 0; i < this.package1.length; i ++){
                        prices += this.package1[i].price * this.package1[i].count;
                    } 
                    for(var i = 0; i < this.package2.length; i ++){
                        prices += this.package2[i].price * this.package2[i].count;
                    }
                    return prices
                }
            },
        })
        // 输出:总价:46500
    </script>
</body>
</html>

当package1或 package2 中的商品有任何变化,比如买数量变化或增删商品时,计算属性prices 就会自动更新 视图中的总价也会自动变化。

每一个计算属性都包含一个 getter 和一个 setter,我们上面的两个示例都是计算属性的默认用法,只是利用了getter 来读取。在你需要时,也可以提供一个setter函数,当手动修改计算属性的值就像修改一个普通数据那样时,就会触发setter函数,执行一些自定义的操作,例如:

16、getter读取和setter写入

<!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>16、getter读取和setter写入</title>
</head>
<body>
    <div id="app">
        姓名:{{fullName}}
    </div>
    <script src="./vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                firstName:'Jack',
                lastName:'Green',
            },
            computed: {
                fullName: {
                    // getter用于读取
                    get:function(){
                        return (this.firstName + '' + this.lastName);
                    },
                    // setter在写入时触发
                    set:function(newValue){
                        var names = newValue.split('');
                        this.firstName = names[0];
                        this.lastName = names[name.length];
                    }
                }
            },
        })
        // 输出:姓名:JackGreen
    </script>
</body>
</html>

当执行 app.fullName = 'John Green';时,setter就会被调用,数据firstName和 lastName 都会相对更新,视图同样也会更新。

绝大多数情况下,我们只会用默认的getter方法来读取一个计算属性,在业务中很少用到setter,所以在声明一个计算属性时,可以直接使用默认的写法,不必将getter和 setter都声明。

计算属性除了上述简单的文本插值外,还经常用于动态地设置元素的样式名称class和内联样式style,在下章会介绍这方面的内容。当使用组件时,计算属性也经常用来动态传递props,这也会在第7章组件里详细介绍。

计算属性还有两个很实用的小技巧容易被忽略:一是计算属性可以依赖其他计算属性;二是计算属性不仅可以依赖当前Vue实例的数据,还可以依赖其他实例的数据,例如:

 

posted @ 2022-02-23 18:01  longfei825  阅读(286)  评论(0)    收藏  举报