vue.js基础入门

2019-04-14  本文已影响0人  二熊不是熊二

该文章只是我对vue基础知识的一点总结,详细vue知识请看Vue官方文档

一、什么是vue.js

是一个轻量级MVVM框架,数据驱动+组件化的前端开发。

二、MVVM

响应式,双向数据绑定,即MVVM。是指数据层(Model)-视图层(View)-数据视图(ViewModel)的响应式框架。它包括:

1.修改View层,Model对应数据发生变化。

2.Model数据变化,不需要查找DOM,直接更新View。

mvvm.png MVVM框架.png

在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。

ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

三、vue基础

1、创建第一个vue实例
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Vue入门</title>
 <script src="vue.js"></script>
</head>
<body>
 <div id="root"><h1>{{msg}}</h1></div>
​
 <script>
 new Vue({
 el:"#root",
 data:{
 msg:"hello world"
 }
 })
 </script>
</body>
</html>
运行结果:
     new Vue({
         el:"#root",
         template:'<h1>{{msg}}</h1>',
         data:{
         msg:"hello world"
         }
        })
2、vue的生命周期

下面部分参考详解vue生命周期,可详细阅读该文章

生命周期函数就是vue实例在某一个时间点会自动执行的函数。

PS:其中created和mounted比较重要,一个是data数据和事件的初始化,一个是html模板,挂载渲染到页面完毕。

生命周期图示:下图展示了实例的生命周期。

lifecycle.png
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Vue实例生命周期函数</title>
 <script src="./vue.js"></script>
</head>
<body>
 <div id="app">
 <h1>{{message}}</h1>
 </div>
 <script>
 var vm = new Vue({
 el: '#app',
 data: {
 message: 'Vue的生命周期'
 },
 beforeCreate: function() {
 console.group('------beforeCreate创建前状态------');
 console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
 console.log("%c%s", "color:red","data   : " + this.$data); //undefined 
 console.log("%c%s", "color:red","message: " + this.message) 
 },
 created: function() {
 console.group('------created创建完毕状态------');
 console.log("%c%s", "color:red","el     : " + this.$el); //undefined
 console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化 
 console.log("%c%s", "color:red","message: " + this.message); //已被初始化
 },
 beforeMount: function() {
 console.group('------beforeMount挂载前状态------');
 console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
 console.log(this.$el);
 console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
 console.log("%c%s", "color:red","message: " + this.message); //已被初始化
 },
 mounted: function() {
 console.group('------mounted 挂载结束状态------');
 console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
 console.log(this.$el);
 console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
 console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
 },
 beforeUpdate: function () {
 console.group('beforeUpdate 更新前状态===============》');
 console.log("%c%s", "color:red","el     : " + this.$el);
 console.log(this.$el); 
 console.log("%c%s", "color:red","data   : " + this.$data); 
 console.log("%c%s", "color:red","message: " + this.message); 
 },
 updated: function () {
 console.group('updated 更新完成状态===============》');
 console.log("%c%s", "color:red","el     : " + this.$el);
 console.log(this.$el); 
 console.log("%c%s", "color:red","data   : " + this.$data); 
 console.log("%c%s", "color:red","message: " + this.message); 
 },
 beforeDestroy: function () {
 console.group('beforeDestroy 销毁前状态===============》');
 console.log("%c%s", "color:red","el     : " + this.$el);
 console.log(this.$el);
 console.log("%c%s", "color:red","data   : " + this.$data); 
 console.log("%c%s", "color:red","message: " + this.message); 
 },
 destroyed: function () {
 console.group('destroyed 销毁完成状态===============》');
 console.log("%c%s", "color:red","el     : " + this.$el);
 console.log(this.$el);
 console.log("%c%s", "color:red","data   : " + this.$data); 
 console.log("%c%s", "color:red","message: " + this.message)
 }
 })
 </script>
 </body>
</html>

控制台:

初始化实例: 更新实例: 销毁实例:
3、模板语法

区别:v-text会转译,v-html不会转译

<div id="app">
 <!-- 插值表达式 -->
 <div>{{name}}</div>          <!--  <h1>hello</h1> -->
 <!-- v-text 与 {{}} 作用相同 -->
 <div v-text="name"></div>    <!--  <h1>hello</h1> -->
 <div v-html="name"></div>    <!--  hello -->
 </div>

对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。注意:每个绑定都只能包含单个表达式

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
​
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}
<body>
         <div id="root">
         <!--  事件绑定 v-on: 简写为 @ -->
         <div v-on:click="handleClick"><h1>{{content}}</h1></div>
         </div>
        ​
         <script>
         new Vue({
         el:"#root",
         data:{
         content:"hello"
         },
         methods:{
         handleClick:function(){
         this.content = "world"
         }
         }
         })
         </script>
        </body>
<body>
         <div id="root">
         <!-- 属性绑定 v-bind: 简写为 : -->
         <div :title="title">hello world</div>
         </div> 
        ​
         <script>
         new Vue({
         el:"#root",
         data:{
         title:"this is hello world"
         }
         })
         </script>
        </body>
<body>
         <div id="root">
         <!-- 双向数据绑定 v-model -->
         <input v-model="content"/>
         <div>{{content}}</div>
         </div> 
        ​
         <script>
         new Vue({
         el:"#root",
         data:{
         content:"this is content"
         }
         })
         </script>
        </body>
       <body>
         <div id="root">
         <!-- v-if 条件渲染指令,存在与否,它根据表达式的真假来删除和插入元素
         当show=false时,直接从dom中移除 -->
         <div v-if="show">hello world</div>
         <!-- v-if的值为false时显示v-else内容,v-if 与 v-else必须紧贴
         另外 还有 v-else-if  -->
         <div v-else>bye world</div>
         <button @click="handleClick">toggle</button>
         </div>
        ​
         <script>
         new Vue({
         el: "#root",
         data: {
         show: true
         },
         methods:{
         handleClick:function(){
         this.show = !this.show
         }
         }
         })
         </script>
        </body>
<body>
         <div id="root">
         <!-- v-show 条件渲染指令,显示与否
         当show=false时,div中的display属性变为none,不会dom中移除。
         推荐使用v-show -->
         <div v-show="show">hello world</div>
         <button @click="handleClick">toggle</button>
         </div>
        ​
         <script>
         new Vue({
         el: "#root",
         data: {
         show: true
         },
         methods:{
         handleClick:function(){
         this.show = !this.show
         }
         }
         })
         </script>
        </body>
<body>
         <div id="root">
         <ul>
         <!-- v-for 循环显示  :key 提升每一项渲染效率,不能相同
         一般与后端数据库相连时该项为数据id -->
         <li v-for="(item,index) of list" :key="index">{{item}}</li>
         </ul>
         </div>
        ​
         <script>
         new Vue({
         el: "#root",
         data: {
         list: [1,2,3]
         }
         })
         </script>
        </body>
<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>
4、计算属性、方法与监听器
<body>
     <div id="example">
     <p>Original message: "{{ message }}"</p>
     <p>Computed reversed message: "{{ reversedMessage }}"</p>
     </div>

     <script>
     var vm = new Vue({
     el: '#example',
     data: {
     message: 'Hello'
     },
     computed: {
     // 计算属性的 getter
     reversedMessage: function () {
     // `this` 指向 vm 实例
     return this.message.split('').reverse().join('')
     }
     }
     })
     </script>
    </body>

结果:

Original message: "Hello"

Computed reversed message: "olleH"

        // 在组件中
        methods: {
         reversedMessage: function () {
         return this.message.split('').reverse().join('')
         }
        }

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

       computed: {
             now: function () {
               return Date.now()
           }
        }

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

      var vm = new Vue({
          el: '#demo',
          data: {
            firstName: 'Foo',
            lastName: 'Bar',
            fullName: 'Foo Bar'
          },
          watch: {
            firstName: function (val) {
              this.fullName = val + ' ' + this.lastName
            },
            lastName: function (val) {
              this.fullName = this.firstName + ' ' + val
            }
          }
        })

侦听属性有缓存,但是代码是命令式且重复的。

将它与计算属性的版本进行比较:

        var vm = new Vue({
          el: '#demo',
          data: {
            firstName: 'Foo',
            lastName: 'Bar'
          },
          computed: {
            fullName: function () {
              return this.firstName + ' ' + this.lastName
            }
          }
        })
        // ...
        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[names.length - 1]
            }
          }
        }
        // ...

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

<body> 
    <div id="root">
        姓:<input v-model="firstName" />
        名:<input v-model="lastName" />
        <div>{{fullName}}</div>
        <div>{{count}}</div>
    </div>

    <script>
        new Vue({
            el:"#root",
            data:{
                firstName: '',
                lastName: '',
                count: 0
            },
            // 计算属性,内置缓存,其中内置属性没改变就不会再次计算
            computed:{
                fullName: function() {
                    return this.firstName + ' ' + this.lastName
                }
            },
            // 侦听器,监听变化次数
            watch: {
                fullName: function() {
                    this.count++
                }
            }
        })
    </script>
</body>
5、class与style绑定

下面通过一个点击改变颜色例子来说明样式绑定。

 <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>class的对象绑定</title>
        <script src="./vue.js"></script>
        <style>
            .activited {
                color: red;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <!-- 方法一:class的对象绑定 -->
            <div @click="handleDivClick"
                 :class="{activited:isActivited}">
                 Hello world
            </div>
        </div>

        <script>
            var vm = new Vue ({
                el: "#app",
                data: {
                    isActivited: false
                },
                methods: {
                    handleDivClick: function() {
                        this.isActivited = ! this.isActivited
                    }
                }
            })
        </script>
    </body>
    </html>
<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>class的数组绑定</title>
        <script src="./vue.js"></script>
        <style>
            .activited {
                color: red;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <!-- 方法二:class的数组绑定 -->
            <div @click="handleDivClick1"
                 :class="[activited]">
                 Hello world!
            </div>
        </div>

        <script>
            var vm = new Vue ({
                el: "#app",
                data: {
                    activited:""
                },
                methods: {
                    handleDivClick1: function() {
                        this.activited = this.activited === "activited" ? "" : "activited"
                    }
                }
            })
        </script>
    </body>
    </html>
 <body>
        <div id="app">
            <!-- 方法三:style的对象绑定 -->
            <div @click="handleDivClick2"
                 :style="styleObj">
                 Hello world!!
            </div>
        </div>

        <script>
            var vm = new Vue ({
                el: "#app",
                data: {
                    styleObj: {
                        color: ""
                    }
                },
                methods: {
                    handleDivClick2: function() {
                        this.styleObj.color = this.styleObj.color === "" ? "red" : "";
                    }
                }
            })
        </script>
    </body>
<body>
        <div id="app">
        <!-- 方法四:style的数组绑定(与方法三相似) -->
            <div @click="handleDivClick3"
                 :style=[styleObj]>
                 Hello world!!!
            </div>
        </div>

        <script>
            var vm = new Vue ({
                el: "#app",
                data: {
                    styleObj: {
                        color: ""
                    }
                },
                methods: {
                    handleDivClick3: function() {
                        this.styleObj.color = this.styleObj.color === "" ? "red" : "";
                    }
                }
            })
        </script>
    </body>
6、条件渲染

v-ifv-elsev-show基础知识详见上文指令部分。

<template v-if="ok">
      <h1>Title</h1>
      <p>Paragraph 1</p>
      <p>Paragraph 2</p>
    </template>
   <div v-if="type === 'A'">
      A
    </div>
    <div v-else-if="type === 'B'">
      B
    </div>
    <div v-else-if="type === 'C'">
      C
    </div>
    <div v-else>
      Not A/B/C
    </div>

类似于 v-elsev-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。

<body>
    <!-- 通过增加key能使v-if 与 v-else 切换时的内容清空 -->
        <div id="app">
            <div v-if="show">
                用户名:<input key="username" />
            </div>
            <div v-else>
                邮箱名:<input key="email"/>
            </div>
            <button @click="toggle">切换</button>
        </div>

        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    show: true,
                },
                methods: {
                    toggle: function() {
                        this.show = !this.show
                    }
                }
            })
        </script>
    </body>
7、列表渲染
<body>
    <div id="app">
    <!-- v-for 循环显示  :key 提升每一项渲染效率,不能相同 一般与后端数据库相连时该项为数据id -->
    <!-- 可以用 of 替代 in 作为分隔符,因为它是最接近 JavaScript 迭代器的语法 -->
        <div v-for="(item, index) in list"
             :key="item.id">
            {{index}}----{{item.text}}----{{item.id}}
        </div>
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                list: [{
                    id:"010120201",
                    text:"hello"
                },{
                    id:"010120202",
                    text:"hello"
                },{
                    id:"010120203",
                    text:"hello"
                }]
            }
        })
    </script>
</body>
输出结果:
<body>
    <div id="app">
        <div v-for="(value, key, index) in object">
          {{ index }}. {{ key }}: {{ value }}
        </div>
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                object: {
                    firstName: 'John',
                    lastName: 'Doe',
                    age: 30
                }
            }
        })
    </script>
</body>
输出结果:

当我们要在此基础上再加一个数据,在控制台中我们要重新定义该对象才能使页面改变。

vm.object={
                firstName: 'John',
                lastName: 'Doe',
                age: 30,
                address: 'hangzhou'
            }

除此之外,我们还可以通过set方法向对象注入数据,同时页面更新。

方法一:Vue.set(vm.object,"address","hangzhou")

方法二:vm.$set(vm.object,"address","hangzhou")

结果:
    example1.items = example1.items.filter(function (item) {
      return item.message.match(/Foo/)
    })
        // Vue.set
        Vue.set(vm.items, indexOfItem, newValue)
        // Array.prototype.splice
        vm.items.splice(indexOfItem, 1, newValue)

你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

vm.items.splice(newLength)

上一篇 下一篇

猜你喜欢

热点阅读