zoukankan      html  css  js  c++  java
  • vue学习简单入门

    1、MVVM思想

    • M:即Model,模型。包括数据和一些基本操作。
    • V:即View,视图。页面渲染结果。
    • VM:即View-Model,模型与视图间的双向操作。(无需开发人员干涉)

    在MVVM之前,开发人员从后端获取到需要的数据模型,然后通过DOM操作Model渲染到View中。而后当用户操作视图,我们还需要通过DOM获取到View中的数据,然后同步到Model中去。

    而MVVM中的VM就是要做这样的事情:把DOM操作完全封装起来,开发人员不用再关心Model和View之间是如何影响的。

    2、Vue简介

    官网: https://cn.vuejs.org/

    3、入门案例

    4、概念

    1)、创建Vue实例

    <!DOCTYPE html>
    <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    
    <div id="app">
        <h1>{{a}}</h1>
        <button v-on:click="b">点击</button>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vue = new Vue({
            el: '#app',
            data: {
                a: 666
            },
            methods: {
                b() {
                    this.a--;
                }
            }
        })
    </script>
    </body>
    </html>
    
    

    1、new 出来的vue实例管控这 id选择器为app的标签,整个div。
    2、想要给这个div绑定一些数据,我们就要将所有的数据写在vue对象的另一个属性data里面。由于未来可能有很多的数据,所以我们写成一个对象{},这样很多的key-value都能用。
    3、在标签体里面我们可以使用vue的插值表达式: {{}} 就可以从数据data里面取出key的value。
    4、现在数据变,视图就会变目前是一个单向的过程。
    5、这么强大的功能,我们只需要让vue管控这个元素,而元素里面的所有东西,我们都可以使用vue更强大的功能,更简化的语法。

    创建vue实例(new),关联页面的模板,将自己的数据(data)渲染到关联的模板上。这个渲染过程是自动的。而且,只要data里的数据发生变化,那么模板也会跟着变。我们把这个过程称为响应式。

    我们还可以通过指令,来简化对DOM的操作。比如:我们要双向绑定,我们使用v-model,点击事件的时候可以使用v-on,也可以绑定自定义的方法等。

    声明的方法要放在vue的methods属性对象里面。

    在方法中使用data中的数据,要用this.xx的方式。

    总结:

    • el:绑定元素;
    • data:封装数据;
    • methods:封装方法;
    • ... vue对象还有很多属性,上面3个最常用。

    2)、插值表达式

    ①、说明

    格式:{{表达式}}

    • 该表达式支持js语法,可以调用js内置函数(但是必须要有返回值)。
    • 表达式必须有返回结果。
    • 可以直接获取vue实例中定义的数据和函数。

    如:{{msg}}、{{1+1}}、{{func()}}、{{1+1=2?正确:错误}}

    ②、插值闪烁

    使用{{}}这种方式在网速较慢的时候会出现问题。在数据未加载完成时,页面会显示原始的{{}},加载完毕后才显示正确数据,我们称它为插值闪烁。

    F12开发者模式下,模拟网速慢,Network 可以调成slow 3G,就可以看到效果。

    缺点:{{}}插值表达式只能用在标签体里面,如果标签的属性也要调用vue中定义的数据或函数,就不能使用{{}}插值表达式了。

    那么,我们如何给属性动态的绑定vue实例定义的值呢?

    3)、Vue指令

    ①、单向绑定: v-bind

    {{}}只能给标签体绑定值,而给标签的属性绑定值则使用v-bind指令。

    使用:

    • v-bind:属性名="数据"
    • :属性名="数据"

    对标签的class和style属性的增强:

    我们只需要写一个对象,然后这个对象的某个属性值跟vue实例中的数据进行绑定。

    如: :class='{active:isActive,textDanger:hasError}'
    如: :style='{color:color1,fontSize:size}'

    ②、双向绑定: v-model

    v-model一般用于表单项、自定义组件。只有它们才需要双向绑定。

    我们只需要将元素的跟模型里面的某一个属性进行绑定,以后我们页面输入框值变了,我们data中属性的值就会跟着变。而且,属性的值变化了,输入框里的值对应也会跟着变。这就是双向绑定的过程。

    在我们日常开发中,我们都是使用v-model将我们表单里面的某一项跟数据进行绑定,这样我们实时来获取值也会很方便。

    ③、事件处理: v-on

    我们用v-on绑定事件,我们可以直接对data里面的数据进行操作,而我们用jquery等框架则是不可以的。

    使用:

    • v-on:事件名="方法名"
    • @事件名="方法名"

    事件修饰符:

    阻止事件的默认行为,如事件冒泡等,可以使用事件修饰符。

    事件修饰符,是由点开头的指令后缀来表示的。

    • .stop:阻止事件冒泡到父元素。
    • .prevent:阻止默认事件发生。
    • .capture:使用事件捕获模式
    • .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
    • .once:只执行一次。

    按键修饰符:

    在监听键盘事件时,我们经常需要检查常见的键值。Vue允许为v-on在监听事件时添加按键修饰符。

    // 只有在keyCode为13的时候调用vm.submit()
    <input v-on:keyup.13="submit"/>
    

    记住所有的keyCode比较困难,所以Vue为所有常见的键值取了别名。

    //同上
    <input v-on:keyup.enter="submit"/>
    
    //缩写语法
    <input @keyup.enter="submit"/>
    

    全部的按键别名

    • .ctrl
    • .enter
    • .tab
    • .delete
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right

    ④、单向绑定:v-text 和 v-html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    
    <div id="app">
    
        <span v-html="msg"></span>
        <span v-text="msg"></span>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vue = new Vue({
            el: '#app',
            data: {
                msg: '<h1>hello</h1>'
            }
        })
    </script>
    </body>
    </html>
    
    
    • v-html:不会对html标签进行转义,直接会在浏览器中显示标签。
    • v-text:会对html标签进行转义。
    • 这2个指令都是单向绑定的。

    ⑤、遍历循环:v-for

    • 1、显示user信息: v-for="item in items"
    • 2、获取数组下标: v-for="(item,index) in items"
    • 3、遍历对象:
      v-for="value in obj"
      v-for="(value,key) in obj"
      v-for="(value,key,index)in obj"
    • 4、遍历的时候都加上 :key来区分不同的数据,可以提高vue渲染的效率。

    ⑥、判断与显示:v-if 和 v-show

    • v-if:顾名思义,条件判断。当得到的结果为ture时,所在的元素才会被渲染。
    • v-show:得到的结果为true时,所在的元素才会被显示。(相当于设置了display:none)

    1、经常与v-if一起使用的还有:v-else、v-else-if。
    2、v-if与v-for搭配使用时,v-if的优先级是低于v-for的。也就是v-for先遍历,拿到遍历的对象再根据v-if判断。

    4)、计算属性

    某些结果是基于之前的数据实时计算出来的,这种情况我们可以利用计算属性来完成。

    计算属性computed是vue实例中的一个属性,所有需要动态计算的属性,都可以在写在这里。

    它的特点是:该属性依赖的任意一个值发生变化,都会触发它的重新计算。

    5)、侦听器

    侦听器(watch),也是vue实例的一个属性。watch可以让我监控一个值的变化,从而做出相应的反应。

    6)、过滤器

    过滤器(filters)也是vue实例的一个属性,它是一个方法,它可以把要过滤的值当做参数传入进来,进行逻辑处理。

    过滤器常用来处理文本格式的操作。过滤器可以用在2个地方:

    • ① 双花括号插值
    • ② v-bind表达式

    过滤器如果写在vue实例里面,则是一个局部过滤器,它只可以在当前的vue实例中可以使用。如果要创建全局的过滤器写法是: Vue.filter(..);

    7)、组件化

    在项目开发过程中,往往在不同的页面中,会使用相同的部分,为了让这些重复的部分方便复用,我们就可以把它作为组件。

    在vue里,所有的vue实例都是组件。我肯可以通过组件之间的灵活组合,完成更强大的功能。

    例如:你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其他的像导航链接、博文之类的组件。

    ①、全局声明一个组件:

    Vue.component('my-component-name', {
      // ... 选项 ...
    })
    

    这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。比如:

    Vue.component('component-a', { /* ... */ })
    Vue.component('component-b', { /* ... */ })
    Vue.component('component-c', { /* ... */ })
    
    new Vue({ el: '#app' })
    <div id="app">
      <component-a></component-a>
      <component-b></component-b>
      <component-c></component-c>
    </div>
    

    在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。

    ②、局部声明一个组件:

    全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

    在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

    var ComponentA = { /* ... */ }
    var ComponentB = { /* ... */ }
    var ComponentC = { /* ... */ }
    

    然后在 components 选项中定义你想要使用的组件:

    new Vue({
      el: '#app',
      components: {
        'component-a': ComponentA,
        'component-b': ComponentB
      }
    })
    

    对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。

    注意局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:

    var ComponentA = { /* ... */ }
    
    var ComponentB = {
      components: {
        'component-a': ComponentA
      },
      // ...
    

    或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:

    import ComponentA from './ComponentA.vue'
    
    export default {
      components: {
        ComponentA
      },
      // ...
    }
    

    注意在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:

    用在模板中的自定义元素的名称
    包含了这个组件选项的变量名

    说明: 组件的data() 是一个方法的返回。为什么呢?因为这样,我们每声明一个组件、每使用一个组件,它的数据都是调用这个方法而返回的一个新对象。那么每一个组件的数据,统计都是独立统计的。而如果返回以前的data的话,那么任何一个组件返回的对象都是同一个实例,那么就导致一处修改其他地方也会跟着修改,这样就达不到组件复用的效果了。

    总结:

    • 组件其实也是一个vue实例,因此它在定义时也会接收:data、methods、生命周期函数等。
    • 不同的是,组件不会与页面元素进行绑定,否则就无法复用了。因此没有#el元素。
    • 但是组件渲染需要html模板,所以增加了template属性,值就是html模板。
    • 全局组件定义完毕,任何vue实例都可以直接在html中通过组件名来使用该组件。
    • data必须是一个函数,不再是一个对象。

    8)、生命周期钩子函数

    每个vue实例在被创建时都呀经历一系列的初始化过程:创建实例、装载模板、渲染模板等等。

    为了简化开发,vue在生命周期中的每个状态都设置了钩子函数(也是监听函数)。每当vue实例处于不同的生命周期时,对应的生命周期函数就会被触发。

    测试各个生命周期函数的执行时机:

    created 钩子可以用来在一个实例被创建之后执行代码:

    new Vue({
      data: {
        a: 1
      },
      created: function () {
        // `this` 指向 vm 实例
        console.log('a is: ' + this.a)
      }
    })
    // => "a is: 1"
    

    在实例生命周期的不同阶段被调用,如 mounted、updated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例

    不要在选项属性或回调上使用箭头函数,
    比如 created: () => console.log(this.a) 或vm.$watch('a', newValue => this.myMethod())。
    因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,
    经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

    9)、vue的Live Template

    <template>
        <div></div>
    </template>
    
    <script>
        //这里可以导入其他文件,如:组件、工具js、第三方插件js、json文件、图片文件等
        //例如:import [组件名称] from [组件路径];
    
        export default {
            //import引入的组件需要注入到对象中才可以使用
            components: {},
            //父子组件传递数据
            props: {},
            data(){
                //这里存放数据
                return {};
            },
            //计算属性,类似于data概念
            computed: {},
            //侦听器,监听data中的数据变化
            watch: {},
            //方法集合
            methods: {
    
            },
            //生命周期 - 创建完成(可访问当前this实例)
            created() {},
            //生命周期 - 挂载完成(可访问DOM元素)
            mounted(){
    
            },
            //生命周期 - 创建之前
            beforeCreated(){},
            //生命周期 - 挂载之前
            beforeMount(){},
            //生命周期 - 创建之前
            beforeCreated(){},
            //生命周期 - 更新之前
            beforeUpdate(){},
            //生命周期 - 更新之后
            updated(){},
            //生命周期 - 销毁之前
            beforeDestroy(){},
            //生命周期 - 销毁完成
            destroyed(){},
            //如果页面有keep-alive缓存功能,这个函数a会触发
            activated(){},
    
        }
    
    </script>
    
    <style lang="scss" scoped>
    /*@import url(); 引入公共的css类*/
    
    </style>
    
    
  • 相关阅读:
    判断无向图G是否连通
    图的深度优先搜索与广度优先搜索
    整数变换问题
    按层次遍历二叉树
    交叉链表
    二元查找树转换成一个排序的双向链表
    简单计算器的实现
    二叉树宽度的计算
    BMP文件的读取与显示
    约瑟夫环问题
  • 原文地址:https://www.cnblogs.com/zhaoxxnbsp/p/12787914.html
Copyright © 2011-2022 走看看