vue.js

作者: Bonucci | 来源:发表于2019-05-25 12:02 被阅读0次

    [vuejs挂载点,模板与实例的关系]

    <body>
      <div id='root'>
        <h1>{{msg}}</h1>
      </div>
      <script>
        new Vue({
          el:'#root',
          data:{
            msg:'hello world'
          }
        })
      </script>
    </body>
    

    挂载点:element对应的标签

    上面的html中{{msg}}去掉

    <div id='root'></div>
    

    这个标签就称之为vue实例的挂载点,因为下面的el,也就是element正好与上面的标签的id对应的上

    模板:挂载点内部的内容

    <h1>{{msg}}</h1>
    

    这个就是模板,模板也可以有多种方式

    new Vue({
      el:'#root',
      template:'<h1>{{msg}}</h1>',
      data:{
        msg:'hello world'
      }
    })
    

    这种写在实例里面也可以,所以模板就是挂载点内部的内容,模板可以写在挂载点内部,也可以写在实例里面template属性里面

    首先我们知道vue中有很多自定义指令,以v- 开头,例如:v-text,v-bind,v-model, v-if,等

    在这些指令中,部分指令之间是很容易被混淆,所以今天决定自己总结一下以下几个相似指令之间的异同:

    
    
    <!--区别:v-text打印出来包含标签 v-html不包含标签-->
    
    <div class="root" v-text="number"></div>
    
    <div class="root1" v-html="number"></div>
    
    <!--点击事件用v-on方法-->
    
    <div id="root" v-on:click="tomyclick">{{number}}</div>
    
    <!--点击事件用@方法-->
    
    <div id="root1" @click="tomyclick">{{number}}</div>
    
    <script>
    
    new Vue({
    
            el:".root",
    
            data:{
    
                    number:"<h1>这是v-text方法</h1>"
    
          },
    
    })
    
     
    
    new Vue({
    
            el:".root1",
    
            data:{
    
                    number:"<h1>这是v-html方法</h1>"
    
            },
    
    })
    
     
    
    new Vue({
    
            el:"#root",
    
            data:{
    
                    number:"这是v-on:click方法"
    
            },
    
            methods:{
    
                    tomyclick : function(){
    
                    this.number = "点击之后的效果用v-on方法"
    
          }
    
    }
    
    })
    
     
    
    new Vue({
    
             el:"#root1",
    
            data:{
    
                      number:"这是v-on:click方法"
    
            },
    
            methods:{
    
                  tomyclick : function(){
    
                          this.number = "点击之后的效果用@方法"
    
                  }
    
            }
    
    })
    
    </script>
    
    </body>
    
    
    image.png image.png image.png

    1、属性绑定

    v-bind :

    
    <div id="root">
            <div v-bind:title="title">hello world</div>
    </div>
    <script>
        new Vue({
            el:"#root",
            data:{
               title:"this is hello world"
            }
        })
    </script>
    

    v-bind可以缩写为“:”

    即<div v-bind:title="title">hello world</div>可以写为
    <div :title="title">hello world</div>
    

    单向绑定:数据决定页面的显示,但页面不能决定数据的内容

    双向绑定:数据决定页面的显示,但页面也能修改数据的内容

    用v-model实现双向绑定

    
    <div id="root">
        <input type="text" v-model:value="content">//当修改input的值时,content的值也会做相应修改
        <div>{{content}}</div>
    </div>
    <script>
        new Vue({
            el:"#root",
            data:{
                content: "this is content"
                 },
           
        })
    </script>
    
    
    image.png

    2、vue中的计算属性和侦听器

    2.1计算属性computed:一个属性通过其他属性计算而来

    fullName由firstName和lastName计算而来.

    当firstName和lastName不发生变化时,fullName不会重新计算而是调用缓存值,提高了程序效率。

     <div id="root">
            姓:<input type="text" v-model:value="firstName">
            名:<input type="text" v-model:value="lastName">
            <div>{{fullName}}</div>
            <div>{{count}}</div>
        </div>
        <script>
            new Vue({
                el: "#root",
                data: {
                    firstName: '',
                    lastName: '',                
                },
                //计算属性
                computed:{ 
                    fullName: function () {
                        return this.firstName+" "+this.lastName
                    }
                },                     
            })
        </script>
    
    
    image.png

    2.1侦听器watch:监听某个数据的变化,一旦数据发生变化,就可以在侦听器中进行逻辑计算

    
    <div id="root">
            姓:<input type="text" v-model:value="firstName">
            名:<input type="text" v-model:value="lastName">
            <div>{{fullName}}</div>
     
        </div>
        <script>
            new Vue({
                el: "#root",
                data: {
                    firstName: '',
                    lastName: '',
                    fullName: ''
                },           
                watch:{
                    firstName:function () {
                        this.fullName=this.firstName+" "+this.lastName;
                    },
                    lastName: function () {
                        this.fullName=this.firstName+" "+this.lastName;
                    }
                }
            })
        </script>
    
    
    image.png

    计算属性computed的getter和setter:

    
    <div id="root">
        {{fullName}}
    </div>
    <script>
        var vm=new Vue({
            el: "#root",
            data: {
                firstName: 'Dell',
                lastName: 'Lee',
                fullname: 'Dell Lee'
            },
            computed:{
                fullName:{
                    get: function () {
                        return this.firstName+" "+this.lastName
                    },
                    set: function (value) {
                        var arr=value.split(" ");
                        this.firstName=arr[0];
                        this.lastName=arr[1];
                    }
                }
            }
         
        })
    
    image.png

    [vuejs里面v-if,v-show和v-for]

    <div id='root'>
      <div v-if='show'>helle world</div>
      <button @click='handleClick'>toggle</button>
    </div>
    <script>
      new Vue({
        el:'#root',
        data:{
          show:true
        },
        methods:{
          handleClick:function(){
            this.show = !this.show;
          }
        }
      })
    </script>
    

    v-if,里面这个show是个变量,如果是true就是显示,如果是false就不显示,这里是移除了dom

    <div id='root'>
      <div v-show='show'>helle world</div>
      <button @click='handleClick'>toggle</button>
    </div>
    <script>
      new Vue({
        el:'#root',
        data:{
          show:true
        },
        methods:{
          handleClick:function(){
            this.show = !this.show;
          }
        }
      })
    </script>
    

    v-show,把v-show替换掉v-if,表现形式一样,但是和v-if不同的是,v-show只是将dom隐藏,显示,并没有移除dom,只是把display的样式变了

    如果显示的频率大,v-show比v-if要性能高一些,因为不会去销毁dom,和创建dom,如果显示的频率不是那么大,只要一次显示隐藏,那么v-if是更好的选择

    <div id='root'>
      <ul>
        <li v-for='item of list' :key='item'>{{item}}</li>
      </ul>
    </div>
    <script>
      new Vue({
        el:'#root',
        data:{
          list:[1,2,3]
        }
      })
    </script>
    

    当你给元素标签加key值得时候, vue会知道它是页面上唯一的一个元素,如果两个key不一样,vue不会复用


    v-for,当某个数据需要循环显示的时候,可以用v-for,这里需要注意加:key,可以提升性能,但是这个item变量要是唯一的,如果数组是[1,1,3],这个item就不能作为key值,需要将
    v-for='item of list'
    改成
    v-for='(item,index) of list',
    将索引index作为key值,这样是唯一的,但是index作为key值,在对列表排序等操作的时候可能存在问题
    一个简单的todolist

    <script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
    <div id="root">
        <div>
            <input v-model = "inputValue"/>
            <button @click = "handleSubmit">提交</button>
        </div>
    
        <ul>
            <li v-for = "(item , index) of list" :key = "index">{{item}}</li>
    
        </ul>
    
    </div>
    <script>
        new Vue({
            el:"#root",
            data:{
                inputValue:'999',
                list:[]
            },
            methods:{
                handleSubmit:function(){
                    this.list.push(this.inputValue),
                    this.inputValue = ''
              }
            }
    
        })
    </script>
    

    运用组件化的概念进行整改

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>vue学习</title>
    
    <script type="text/javascript" src="./vue.js"></script>
    </head>
    <body>
        <div id = "app">
            <input type="text" v-model = "interValue"/>
            <button v-on:click = "handleBtnClick">提交</button>
            <ul>
                <!-- <li v-for = "item in list">{{item}}</li> -->
                <todo-item v-bind:content="item" v-for = "item in list"></todo-item>
            </ul>
            </button>
        </div> 
        <script>
    
            Vue.component("TodoItem",{
                props : ["content"],
                template : "<li>{{content}}</li>",
            })
    
            var app = new Vue ({
                el : '#app',
                data :{
                    
                    list : [],
                    interValue : '' 
                    
                },
                methods : {
                    handleBtnClick : function(){
                        this.list.push(this.interValue)
                        this.interValue = ''
                    }
                }
            })  
    
            setTimeout(function()  {
                app.$data.content = '我要改变'
                // app.content = '我要改变';
    
            }, 2000)
        </script>
    </body>
    </html>
    

    需要注意四点就是
    1.Vue.component 这样使用的是全局组件
    2.TodoItem 到节点运用就成了todo-item
    3.v-bind:content="item" 父组件把值传给子组件

    1. props : ["content"]这样接受

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>vue学习</title>
    
    <script type="text/javascript" src="./vue.js"></script>
    </head>
    <body>
        <div id = "app">
            <input type="text" v-model = "interValue"/>
            <button v-on:click = "handleBtnClick">提交</button>
            <ul>
                <!-- <li v-for = "item in list">{{item}}</li> -->
                <todo-item v-bind:content="item"
                v-bind:index="index"
                 v-for = "(item, index) in list"
                 @delete = "handleItemDelete"
                 ></todo-item>
            </ul>
            </button>
        </div> 
        <script>
    
            // Vue.component("TodoItem",{
            //     props : ["content"],
            //     template : "<li>{{content}}</li>",
            // })
            var TodoItem = {
                props : ["content","index"],
                template : "<li @click = 'handleItemClick'>{{content}}</li>",  
                methods : {
                    handleItemClick : function(){
                        this.$emit('delete',this.index)
                    },
                }
            }
    
            var app = new Vue ({
                el : '#app',
                components :{
                    TodoItem : TodoItem,
                },
                data :{
                    
                    list : [],
                    interValue : '' 
                    
                },
                methods : {
                    handleBtnClick : function(){
                        this.list.push(this.interValue)
                        this.interValue = ''
                    },
                    handleItemDelete : function(index){
                        this.list.splice(index,1)
                    }
                }
            })  
    
            setTimeout(function()  {
                app.$data.content = '我要改变'
                // app.content = '我要改变';
    
            }, 2000)
        </script>
    </body>
    </html> 
    

    需要注意四点就是
    1var TodoItem 这样使用的是局部组件,创建了一对象
    2.components :{
    TodoItem : TodoItem,
    },
    把局部组件注册到根实例里面。
    3.template : "<li @click = 'handleItemClick'>{{content}}</li>", 这里是列表cell添加点击事件
    4.@delete = "handleItemDelete" 这里父组件在创建子组件的时候进行监听

    1. this.emit('delete',this.index) 子组件像父组件传递被删除的信号 6.this.list.splice(index,1)从下标进行删除1 7.v-bind:index 可以简写为 :index 8.v-on:click 可以简写为 @click 9,凡是以开头的都是vue的实例属性跟实例方法

    生命周期函数就是vue的实例在某一个时间点会自动执行的函数。生命周期函数并不在methosd,单独写在实例里。
    init-->beforeCreate -->created--> beforeMount -->mounted -->beforeDestroy -- >destroyed


    image.png
    image.png image.png

    大图解析,


    image.png

    v-xxx=""后面的字符串是js表达式。可以+操作


    var vm = new Vue({
        el: '#example',
        data: {
            message: 'Hello'
        },
        computed: {
            reversedMessage: function () {
                // `this` 指向 vm 实例
                return xxxx
            }
        }
    });
    

    关于计算属性优点就是他能缓存,提高性能,页面重新渲染的,计算属性依赖的值给没有发生改变,这个时候计算属性就不会计算,提高性能.用方法的形式也可以实现计算的结算,但是页面只要渲染方法就会调用,用监听器也可以实现这个功能,也会有缓存。


    image.png
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta content="text/html; charset=utf-8" />
        <title>Vue</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="root">{{fullName}}</div>
    
        <script>
            var vm = new Vue({
                el : '#root',
                data :{
                    firstName : 'Dell',
                    lastName : 'Lee'
                },
                computed :{
                    fullName : {
                        get :function (){
                            return this.firstName + " " +this.lastName
                        },
                        set :function(value){
                            console.log(value);
                            var array = value.split(" ");
                            this.firstName = array[0];
                            this.lastName = array[1];
                        }
                    }
    
                }
    
            })
        </script>
    </body>
    </html>
    

    计算属性跟set跟get方法


    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta content="text/html; charset=utf-8" />
        <title>Vue</title>
        <script src="./vue.js"></script>
        <style>
            .acivated{
                color: red
            }
        </style>
    </head>
    <body>
    
        <div id="root" :class = "[acivated]" @click = "handleClick">{{content}}</div>
        <script>
            var vm = new Vue({
                el : '#root',
                data : {
                    content : '我是内容',
                    acivated : ''
                },
                methods : {
                    handleClick : function(){
                        this.acivated = this.acivated === "acivated" ? "" : "acivated";
                    }
                }
            })
        </script>
    </body>
    </html>
    

    知识点
    1.:class = "[acivated]" 这里主要是表示class这块的东西,这是一个数组可以添加多个,样式就有这个数组里面的东西决定。


    image.png

    同样的东西,这里是style的用法,可以在 :style = "[styleObj {fontSize : '20px'}]"



    如果是按照数组下标的方法进行操作数组,页面没有及时渲染,想要及时渲染,要用系统提供的七个方法。
    push pop shift unshift splice sort reverse

    当然你也可以直接替换数据的引用地址,这样也能改变渲染。

    还有一个方法就是用set修改,也可数据改变之后页面也改变

    Vue.set(vm.userInfo,1,5)


    一个比较重要的模板占位符 template 可以包裹 元素,但是 渲染的时候并不会真正的渲染到页面中。


    image.png image.png

    直接修改vm.userInfo.name = "Dell Lee"可以在页面中立刻渲染
    但是想添加 vm.userInfo.address = "beijing" 这样数据是添加进去了,但是不能立即渲染。
    想立即改变要直接改变数据引用地址,就是直接改好数据,直接把引用引到新数据下面。
    其实用set方法修改,也能让数据改变之后页面也立刻改变。
    例如 Vue.set(vm.userInfo,"address","beijing")

    vue遇到问题解析
    1.有些时候自定义的标签在使用起来发现出问题了,table--> tbody -->tr就是tbody下面必须是tr标签,要不就就会出问题,这个时候要做的是用 is=“”来处理


    image.png

    2.子组件的data必须是一个函数不能是一个对象.


    image.png
    3,添加ref 添加引用,便于操作dom节点
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta content="text/html; charset=utf-8" />
        <title>Vue</title>
        <script src="./vue.js"></script>
    </head>
    <body>
    
        <div id="root">
            <couter ref = "one" @change = "handeleChange"></couter>
            <couter ref = "two" @change = "handeleChange"></couter> 
            <div>{{total}}</div>  
        </div>
        <script>
            Vue.component('couter',{
                template : '<div @click = "handleClick">{{number}}</div>',
                data :function(){
                    return {
                        number : 0
                    }
                },
                methods :{
                    handleClick : function(){
                        this.number ++;
                        this.$emit('change')
                    }
                }
    
            })
    
    
            var vm = new Vue({
                el : '#root',
                data : {
                    total : 0
                },
                methods : {
                    handeleChange : function(){
                        this.total = this.$refs.one.number + this.$refs.two.number
                    }
                }
            })
        </script>
    </body>
    </html>
    

    涉及到父子组件传值的概念
    单向数据流:父组件给子组件传递参数,传递过得参数可以随意修改,但是子组件不能修改父组件传递过来的内容。原因传递过来的数据如果是引用数据类型的数据,如果你修改了 数据就是修改了原始数据。

    校验器


    image.png

    @click.nataive 这个就是监听的原生的click事件,并非自定义的

    非父子组件进行传值


    image.png

    created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
    mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
    var this_ = this 是因为作用域发生了变化,有一个function,this变成了function了
    ,要保存一下


    插槽语法,方便插入dom元素,还可以定义默认内容 ,还能给插槽给一个name,这样可以对应,根据name变换插槽


    image.png

    动态组件

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 动态组件</title>
    <script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
        <button @click='toShow'>点击显示子组件</button>
        <!----或者<component v-bind:is="which_to_show" keep-alive></component>也行----->
        <keep-alive>
        <component v-bind:is="which_to_show" ></component>
        </keep-alive>
    </div>
     
    <script>
     
    // 创建根实例
    new Vue({
      el: '#app',
      data:{
          which_to_show:'first'
      },
        methods:{
            toShow:function(){
                var arr = ["first","second","third"];
                var index = arr.indexOf(this.which_to_show);
                if(index<2){
                    this.which_to_show = arr[index+1];
                }else{
                    this.which_to_show = arr[0];
                }  console.log(this.$children); 
            }
        },
        components:{
            first:{
                template:'<div>这是子组件1<div>'
            },
            second:{
                template:'<div>这是子组件2<div>'
            },
            third:{
                template:'<div>这是子组件3<div>'
            },
        }
    })
    </script>
    </body>
    </html>
    
    
    
    image.png

    v-once 指令,可以让把组件第一次被渲染之后会放到内存里面


    image.png image.png
    image.png

    这个东西很有意思,这边整体解释一下动画的东西,首先就是fade-enter 跟fade-enter-active在动画开始的第一帧就已经存在,然后第二帧的时候 fade-enter 被干掉,增加fade-enter-to ,到结束之后这个时候fade-enter-active,fade-enter-to被干掉。与opacity:0这个被去掉,恢复原有的默认属性,为1.此时,监听到opacity变化,fade-enter-active开始运行,会做一个渐变。

    相关文章

      网友评论

          本文标题:vue.js

          本文链接:https://www.haomeiwen.com/subject/bxuazqtx.html