vue基础

一、前端框架是什么?

是js的工具集合,而不是HTML和CSS的工具集;前端发展好,是因为js决定了前端的发展前景

例如HTML5也需要借助于JS,只有把JS基础学好才能构建更好的前端项目。

 

二、为什么要用框架呢?

1、前端框架的基础都是JS,更好开发项目

遵循限定的条件,例如jQuery的$的规则,有更好的维护性、升级性和复用性,这些条件或者规则起个名叫:架构或者模式。现在的框架都是基于一个架构/模式的,例如MVVM、MVC、MVP模式等等,这些模式就是我们去使用框架的原因,可以更好开发项目的原因

2、更快开发项目

jQuery或者Vue都是组件化开发,其实组件化开发就是我们开发的必然。开发时很多组件是重复的,例如导航栏每次开发就浪费时间了。那么经常使用的东西把他封装成一个组件,下次再开发的时候直接拿来使用,直接调用组件,传参就行了,把时间放在核心业务上,把核心业务做好才能体现价值,这就是为什么要使用框架,更好更快开发项目

 

三、不要盲目使用框架

1、框架复杂度(学习成本,按照规则写代码,要学,学完规则后才能写)

2、应用复杂度(简单项目还是复杂项目,单页还是多页等等)

3、如果应用特别简单,没必要使用框架,使用原生就行了

 

四、三大主流框架

Vue Angular React

Angular---谷歌开发

    问题:经常修改API和Tyscript

    优势:开发思想好,依赖注入

    Angular1---PC端,很重

    Angular4、5---移动端

    Tyscript语法,在js上又封装一层

React---FaceBook开发

    优势:虚拟DOM---JS渲染快,DOM渲染慢,如果把DOM渲染变成JS渲染

    问题:学习成本高,JSX 语法,把所有HTML和CSS都写在JS里面了

Vue---国产

    优势:结合Angular和React的思想开发,有组件化、依赖注入、虚拟DOM、书写方法和以前一样,学习成本不高,兼容Tyscript,自由度高

   

五、Vue官网

1、渐进式JavaScript 框架:https://cn.vuejs.org/

2、Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器

3、Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库:http://element.eleme.io/#/

4、大型项目需要:Vuex状态管理:https://vuex.vuejs.org/zh-cn/

5、生态系统:https://github.com/vuejs/vue

6、单页面应用:vue-routerhttps://github.com/vuejs

7、论坛:https://forum.vuejs.org/

8、论坛上不想等待的话有聊天室:https://discordapp.com/invite/HBherRA

 

六、Vue小例子

例1

<div id="app">
        <h1>1、vue给我们用的第一种语法是{{}}</h1>
        信息:{{ msg }}<br />
        <!--模板语法,里面是js的变量,可写表达式:例如:age * 2-->
        年龄:{{ age }}<br />
        年龄:{{ age*2 }}<br />
        年龄是否大于60岁:{{ age > 60 ? '老人' : '青年'}}<br />
        第一个和最后一个名字:{{ firstName + " " + lastName }}<br />
        类数组:{{ fullName.split(" ") }}<br />
        类数组第2位:{{ fullName.split(" ")[1] }}<br />
        方法this实现:{{ getFullName1() }}<br />
        方法传参:{{ getFullName2(firstName,lastName) }}<br />
    </div>
    <script type="text/javascript">
        var app = new Vue({
            el: "#app" ,//属性
            data: {
                msg: "Hello World",
                age: 20,
                lastName: "an",
                firstName: "lin",
                fullName: "lin an"
            },
            methods: {//方法,vue给我们提供好的
                getFullName1: function () {
                    return this.firstName + " " + this.lastName
                    //第1种,利用this
                    //this就是代表app实例,app实例把app上面的属性全部挂在app最顶层,我们就能通过this.去获取到firstName和lastName
                },
                getFullName2: function (first,last) {
                    return first+ " " + last
                    //第2种:传参
                },
                getFullName3: (first,last) => {
                    return console.log(this.lastName);//这里的this就不是我们想要的
                    //第3种:es6 箭头函数
                    //不能用箭头函数
                }
            }
        })
        //app才是vue的实例
        //app.msg可获取数据
        //传的参数是一个对象
        //通过new vue创建实例,并且控制了el后面属性选择的HTML代码,然后可以往这段HTML代码里去填充一个{{}}的语法
        //{{}}的语法可以写一个js表达式,js表达式可以输出data里面的数据,并且可以对这个数据进行加工,假如说现在的一个数据非常复杂,假如需要一些逻辑判断和循环,
        //我们可以写一个方法,那一个方法是怎么实现的呢?
        //写一个方法和写一个变量是一样的,如果想定义一个数据定义一个变量的话,必须写在data的数据上面去
        
        //假如在方法里面传参,可以通过this获取,也可以通过{{}}模板语法传把firstName参进去,firstName会去vue的data里面去取数据,只是利用函数调用的一个参数的形式传进去,那定义函数的时候就要写形参
        //定义函数的时候要注意一个问题,如果es6定义了一个函数,箭头函数,箭头函数是没有this指向的,this指向是借助调用他那个作用域的this指向在vue底层操作不知道哪里去调用getFullName3,不知道的话他的this指向就会指向window,因为会有一个undefined
    </script>


    例2
    <div id="app2">
        <h1>2、vue给我们用的第二种语法是一个指令</h1>
        <a v-bind:href="url">百度</a><br />
        如果直接使用{{url}},那么会报错,要使用vue的,因为赋值的时候还是{{url}},href是一个属性,后面一定是一个字符串,后面解析成字符串,而不是解析成vue的语法,需要借助vue的指令,告诉我们这段DOM去做什么,现在绑定一个数据到属性上面去。<br />
        v-bind:想绑定什么样的属性;后面等于一个表达式,表达式里面写想写的数据<br />
        vue的指令,告诉我们这段DOM去做什么<br />
        vue的指令语法:<br />
        v-指令名字+:+指令的参数 = 指令的表达式<br />
        例如:v-bind:href="url"<br />
        
    </div>
    <script type="text/javascript">
        var app2 = new Vue({
            el: "#app2",
            data: {
                url: "http://www.baidu.com"
            }
        })
    </script>
    
    例3
    <div id="app3">
        <h4>需求1:输出一个电影的名字和上映日期</h4>
        电影名字:
        上映日期:
        <h4>需求2:判断一部电影是不是新电影,>2000年的就是新电影 不然就是旧电影</h4>
        这部电影是 {{ getMovie() }} 电影
        <h4>电影的名字title的绑定</h4>
        <div v-bind:title = "movieTitle">
            hover me
        </div>
    </div>
    <script type="text/javascript">
        var app3 = new Vue({
            el: "#app3",
            data: {
                movieTitle: "红海行动",
                movieDate: "2018"
            },
            methods: {
                getMovie: function () {
                    return this.movieDate > 2000 ? '新' : '旧'
                }
            }
        })
    </script>

 

 例4

<div id="app4" class="mar-b-30">
        <h4 class="mar-b-10">点击事件 v-on:click="showsome"</h4>
        <button v-on:click="showsome">第一种点击方式!</button>
        <button v-on:click="showsome(1000,$event)">第二种点击方式!</button>
        <h5 class="mar-t-30 mar-b-10">阻止事件冒泡-事件修饰符.stop</h5>
        <div v-on:click="showsome(10,$event)">
            <button v-on:click.stop="showsome(1000,$event)">点击事件冒泡!</button>
        </div>
        <h5 class="mar-t-30 mar-b-10">阻止默认事件-事件修饰符.prevent</h5>
        <a href="http://www.baidu.com" v-on:click.prevent="showsome" class="btn">阻止默认事件,阻止默认跳转行为</a>
        <div class="mar-t-10">
            <a href="http://www.baidu.com" v-on:click.prevent class="btn">阻止默认事件,没有弹窗</a>
        </div>
    </div>
    <script type="text/javascript">
        var app4 = new Vue({
            el: "#app4",
            data: {},
            methods: {
                showsome: function (msg,event) {
                    console.log(msg);
                    alert("阻止事件冒泡-事件修饰符.stop")
                }
            }
        })
    </script>
    

 例5

    <div id="app5" class="mar-b-30">
        <h3 class="mar-b-10">按键修饰符</h3>
        <h4 class="mar-b-10">按键修饰符-.enter.space.esc.13(键盘号码),可以链式调用的</h4>
        <h4 class="mar-b-10">系统修饰符-.shift//系统规定,shift必须和其他键一起按</h4>
        <input type="text" v-on:keyup.enter.space="keyup" name="" id="" value="" />
        <input type="text" v-on:keyup.shift="shift" name="" id="" value="shift必须和其他键一起按" />
        <button v-on:click.shift="shift">按住shift+鼠标左键</button>
        <button v-on:click.meta="meta">window键盘或者苹果的command</button>
    </div>
    <script type="text/javascript">
        var app5 = new Vue({
            el: "#app5",
            methods: {
                keyup: function(){
                    /*if(event.which == 13){
                        alert("按键了")//这是原生js的按enter键就弹出方法
                    }*/
                    alert("按键了")
                },
                shift: function(){
                    alert("shift必须和其他键一起按")
                },
                meta: function(){
                    alert("window键盘或者苹果的command")
                }
            }
        })
    </script>
    

 

 例6
    <div id="app6">
        <h4 class="mar-b-10">按键修饰符例子</h4>
        需求1:输入什么,输出什么,双向数据绑定<br />
        <input type="text" v-on:keyup = "changeName"/>
        <div>output: {{name}}</div><br />
        需求2:和刚刚一样的,如果改变第二个输入框,但只要输入一个空格或者enter键盘才能把第一个输入的变量改变了
        <br />
        <input type="text" v-on:keyup.enter.space = "name = $event.target.value"/><br />
        可以写简单的函数表达式或者语句
        在HTML模板中通过name获取this里面的值
        通过name获取this里面的name,当前input里面的值,通过事件对象获取,在HTML模板中怎么获取事件对象呢,vue给我们了一个方法$event.target.value

        <div>output: {{name}}</div><br />
        需求3:把form表单的默认提交的事件取消掉<br />
        <form action="" v-on:submit.prevent="submitDefault">
            <input type="submit"/>
        </form>
    </div>
    <script type="text/javascript">
        var app6 = new Vue({
            el: "#app6",
            data: {
                name: "hello"
            },
            methods: {
                changeName: function(event){
                    //获取input的name的话,可以使用原生的一个事件,event,系统默认会把默认的event传进来
                    this.name = event.target.value;
                    //如果想在methods里面获取数据的话,必须通过this.name指的是当前vue实例,因为他在底层会做一个数据绑定,作用域vue最顶层,可以通过this.name获取值
                },
                submitDefault: function(){
                    alert("阻止了表单提交")
                }
            }
        })
    </script>

 


    <div id="app7" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">双向数据绑定的例子</h4>
        <input type="text" v-bind:value = " value " v-on:input = " input "/>
        <div>这里是输入框的输出值:{{ value }}</div>
        <div>文本框,v-bind指令可以把js数据输入到DOM属性上,直接书写{{}}的话属性会变成字符串,所以是 v-bind:value(绑定哪个属性)</div>
        <div>文本框,v-on:click事件</div>
    </div>
    <script type="text/javascript">
        var app7 = new Vue({
            el: "#app7",//对象传,vue控制哪段html
            data: {
                value: "双向数据绑定的例子"
            },
            methods: {
                input: function(event){
                    this.value = event.target.value
                    //数据变成我们输入的东西
                    //input函数会借助参数,是一个事件对象event
                    //this获取data里面的数据,data里面的数据在vue的底层会把他挂载到vue的实例的最顶层上去
                }
            }
        })
    </script>
    
    
    <div id="app8" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">简化app7的双向数据绑定</h4>
        <h5>双向数据绑定:首先把value输入到input框的value属性上面去了,用value把input框初始化了,并且我们写了一个事件,
            事件的作用是改变HTML模板从而改变js里面代码,其实v-bind和v-on可以一起结合起来去看,
            怎么结合呢,v-bind是把js里面的数据给输出到了DOM节点上去,那v-on就是DOM节点上的一些改变,
            相当于用户操作的是一个用户节点,在input里面输入, 操作DOM节点从而改变js里面的数据,
            他两是一个相反的过程,如果两步都实现,这就是双向数据绑定,如果按照app7这样写会很麻烦,如果想有一个简单简便的写法,
            因为这样的一个需求在我们日常开发中也是很多的,那么就有一个指令叫v-model 后面绑定的就是数据,这就实现了刚才app7的两步,
            methods方法也就不需要了,<br />
            第一步就是把value绑定到input的value的属性上去,所以初始化值就是:“简化双向数据绑定的例子”<br />
            第二步,就是每改变input的DOM上输入的值,就会把{{}}中的value的值改变,也就是利用v-model的指令实现了两步操作,一个叫v-bind,一个是v-on<br /> 
            使用了v-model的话,在input里面再写一个value的话就不好使了。会把value覆盖了<br />
            v-model也有修饰符,v-bind绑定一个事件的时候,都已经提到,修饰符可以让你更方便做常做的事情,例如事件修饰符.prevent就可以阻止默认事件<br />
            .stop就能阻止事件冒泡,例如按键的时候,想输入特定的按键才会触发事件,例如.enter就是通过按一个enter键,才会触发这个事件,还有一些系统按键的修饰符,
            contrl,shift键等等<br />
            还有一些苹果的command键,window上的window键            
        </h5>
        <input type="text" v-model = " value "/>
        <div>这里是输入框的输出值:{{ value }}</div>
        <div>v-mode = " 简化双向数据绑定的例子 "</div>
    </div>
    <script type="text/javascript">
        var app8 = new Vue({
            el: "#app8",//对象传,vue控制哪段html
            data: {
                value: "简化双向数据绑定的例子"
            }
        })
    </script>
    
    <div id="app9" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">v-model事件修饰符.trim</h4>
        <input type="text" v-model.trim = " value "/>
        <div>这里是输入框的输出值:{{ value }}</div>
        <h5>
            v-model.trim = " " .trim修饰符<br />
            js里的trim的作用是把首尾的空格去掉<br />
            现在如果加上v-model的事件修饰符.trim,那么,当文本中有包含2个空格以上的时候,在value中就只显示一个空格<br />
        </h5>
    </div>
    <script type="text/javascript">
        var app9 = new Vue({
            el: "#app9",
            data: {
                value: "v-model事件修饰符"
            }
        })
    </script>
    
    <div id="app10" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">v-model事件修饰符.number</h4>
        <input type="text" v-model.number = " value "/>
        <div>这里是输入框的输出值:{{ value }}</div>
        <h5>
            v-model.number = " " .number修饰符<br />
            .number修饰符会把{{ value }}上面输出的所有数据全部变成一个数字<br />
            如果没有加上.number修饰符-----检查输出的20 是不是字符串还是数字,可以使用typeof返回的是:{{ typeof value }}类型<br />
            但是当我们清掉input里面的数据的话,再输入就变成string类型了,因为我们在input里面输入的东西全部都是srting字符串,所以返回字符串。<br />
            如果加上.number修饰符-----那么类型就始终都是number,因为会自动把输出的改成数字。
        </h5>
    </div>
    <script type="text/javascript">
        var app10 = new Vue({
            el: "#app10",
            data: {
                value: 20
            }
        })
    </script>
    
    <div id="app11" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">v-model事件修饰符.lazy</h4>
        <input type="text" v-model.lazy = " value "/>
        <div>这里是输入框的输出值:{{ value }}</div>
        <h5>
            v-model.lazy = " " .lazy修饰符<br />
            如果没有加.lazy修饰符,那么我们双向数据绑定时候,每在input输入时,都会改变大括号里的value值<br />
            如果加.lazy修饰符,那么数据将会在鼠标移出输入框的时候才会改变<br />
            js可以改变dom,dom可以改变数据-----双向数据绑定
        </h5>
    </div>
    <script type="text/javascript">
        var app11 = new Vue({
            el: "#app11",
            data: {
                value: "如果加.lazy修饰符,那么数据将会在鼠标移出输入框的时候才会改变"
            }
        })
    </script>
    
    <div id="app12" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">HTML操作</h4>
        <div>输出值:{{ html }}</div>
        <div>会重新渲染:{{ message }}</div>
        <div v-once>加了v-once不会重新渲染:{{ message }}</div>
        <button v-on:click = "message = '123'">点击我,改变上一行,响应式的数据绑定</button>
        数据会重新渲染,DOM也会重新渲染,
        <h5>
            数据一般是字符串格式,如果想把数据渲染成DOM节点的话?想把DOM节点输出到双括号中<br />
            输出的是字符串,有两个好处<br />
            1、防止跨域脚本攻击-------假如说在HTML中输出的是一个DOM节点,如果直接按照DOM节点输出的话,假如说有一个黑客把这个页面拦截了,HTML和JS都是以明码的方式给你的,就可以把服务器的js和HTML全部下载到本地浏览器运行。那既然是一个明码的方式,读取到你的js里面知道你是Vue去写的,并且知道你的HTML里面的数据是DOM节点,完全可以把DOM节点换成script标签,换成script标签之后,在本地浏览器里面一运行script把你本地的信息全部发送发到他的服务器里面去,这就是xss跨域的脚本工具,所以说使用DOM是很危险的行为<br />
            2、防止用户随意更改DOM-----如果用户,利用input框输入一个DOM节点,那用户可以随意地更改你页面里面的东西,比如说这个页面是不可控的,你不知道用户会把你页面变成什么样子,这样的行为也是不好的<br />
            所以把输出的变成是默认的字符串<br />
            解决问题:-----通过指令<br />
            <div v-html = "html"></div>
            如果使用了v-html,既然他的默认行为就是想让你去输出字符串,就一定一定要注意数据是安全的,不能让用户去随意修改,而且必须是隐藏好的,不能有一个轻易的脚本跨域攻击。一定要慎重选用
            如果说我们现在有一个数据绑定,有个数据,我们每一次改变数据,HTML都统一渲染,那假如说就想只渲染初始化,剩下的如果我们改变了数据,我们不想在渲染了,也用到一个指令<strong>v-once</strong><br />
        </h5>
    </div>
    <script type="text/javascript">
        var app12 = new Vue({
            el: "#app12",
            data: {
                html: "<h1>hello</h1>",
                message: "linsheng"
            }
        })
    </script>
    
    <div class="app13" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">指令v-if用于条件判断的</h4>
        <div>
            <div>如果大于10,显示有现货,如果小于10,显示所剩不多,如果0,显示没库存</div>
            <p v-if = " items > 10">输出:{{ items }}个有现货</p>
            <p v-else-if = " items > 1">输出:所剩不多了,快点买</p>
            <p v-else>输出:没库存了</p>
        </div>
        <h5>
            可能有很多DOM节点。在不同条件下只渲染一部分DOM节点,假如说有一个input,input右边可能有一个DOM节点,来显示输入的用户名是否正确,如果正确,DOM节点是正确,否则相反,可能写了两个DOM节点,一个是正确,一个是错误的,只不过根据用户输入的正确或者错误给不同的DOM渲染出来,现在用Vue实现<br />
        </h5>
    </div>
    <script type="text/javascript">
        var app13 = new Vue({
            el: ".app13",
            data: {
                items: 5
            }
        })
    </script>

 


    <div id="app14" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">正常的话,渲染出的是linjian,那当网络不正常,DOM结构加载完之后,下面的vue.js还没加载过来或者被阻塞了,即vue实例创建失败,返回的就是{{ message }}</h4>
        <div>
            <div>
                刷新页面后等待3秒后出现信息:{{ message }}
            </div>
            <div v-clock>
                <h4>直接就写v-clock就行了,就是当加载完vue实例,把他变成HTML模板之后,即加载完DOM后,v-clock指令就消失了</h4>
                刷新页面后等待3秒后出现信息:{{ message1 }}
            </div>
            <h5></h5>
        </div>
        <!--<script src="resources/js/vue.js"></script>-->
    </div>
    <script type="text/javascript">
        //模拟一个异步,模拟的意义就是,等vue加载完之后才会执行3秒之前都是{{}}的形式,3秒之后就刷新数据了
        setTimeout(function(){
            var app14 = new Vue({
                el: "#app14",
                data: {
                    message: "linjian",
                    message1: "11111111111",
                }
            })
        },3000);
    </script>
    
    
    <div id="app15" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">所有的DOM操作都能用vue去做,vue用的是vue指令实现</h4>
        <h4 class="mar-b-10">循环:v-for=""</h4>
        <h4 class="mar-b-10"><strong>语法:v-for="别名 in 表达式"</strong>,别名是任意起的一个变量名,例如现在的movies</h4>
        <h4 class="mar-b-10">v-for="title in movies",意思就是循环下面的数组,有多少个就循环多少次,每一次循环都有个变量,如title,就是变量的别名</h4>
        <div class="mar-b-10">
            <div><strong>案例1、循环一个数组的方法------------------------下面输出的是电影列表</strong></div>
            <ol>
                <li v-for="title in movies">{{ title }}</li>
            </ol>
        </div>
        <div class="mar-b-10">
            <div><strong>案例2、循环一个数组------------------------需要知道数组的索引是什么</strong></div>
            <h4 class="mar-b-10"> v-for="(title,index) in movies",后面使用小括号加索引index,其中的index也是我们给的变量,些什么后面就用什么</h4>
            <ol>
                <li v-for="(title,index) in movies">{{ title }}({{ index }})</li>
            </ol>
        </div>
        <div class="mar-b-10">
            <div><strong>案例3、循环一个复杂的数组,输出一个员工列表和职位,通过对象的属性来处理</strong></div>
            <div class="mar-b-10"><strong>其中公司名就是告诉我们,v-for="" 里面也能使用正常的数据绑定</strong></div>
            <table border="">
                <thead>
                    <tr>
                        <th>员工姓名</th>
                        <th>员工职位</th>
                        <th>所在公司</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="person in persons">
                        <td>{{ person.name }}</td>
                        <td>{{ person.title }}</td>
                        <td>{{ company }}</td>
                    </tr>
                </tbody>
            </table>
            <h4>有索引的案例</h4>
            
            <table border="" class="mar-b-10">
                <thead>
                    <tr>
                        <th>员工姓名</th>
                        <th>员工职位</th>
                        <th>所在公司</th>
                        <th>索引</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(person,index) in persons">
                        <td>{{ person.name }}{{index}}</td>
                        <td>{{ person.title }}{{index}}</td>
                        <td>{{ company }}</td>
                        <td>{{index}}</td>
                    </tr>
                </tbody>
            </table>
            
            <h4><strong>案例4、循环对象,v-for=""的特殊用法,只用name的话循环出来的是所有对象的属性值,如果要对象的属性名,(name, prop),prop就是属性名</strong></h4>
            <div v-for="name in person" class="mar-b-10">
                {{ name }}
            </div>
            
            <h4>键值对的方式输出</h4>
            <div v-for="(name,prop) in person">
                {{ prop }} : {{ name }}
            </div>
            <h4 class="mar-t-10">键值对的方式输出--------带索引值</h4>
            <div v-for="(name,prop,index) in person">
                {{ prop }} : {{ name }}({{index}})
            </div>
            
            <h4><strong>案例5、v-for数字循环,输出的是1-3,v-for="n in 3"</strong></h4>
            <div class="mar-b-10"><div v-for="n in 3">没有索引值的循环{{ n }}</div></div>
            <div v-for="(n,index) in 3">有索引值的循环{{ n }},当前索引值是:{{ index }}</div>
            
            <h4><strong>案例6、v-for字符串循环,输出的是每个字符串,v-for="s in 'lin'"</strong></h4>
            <div class="mar-b-10"><div v-for="s in 'lin'">{{ s }}</div></div>
            <div v-for="(s,index) in 'lin'">{{ s }},当前索引值是:{{ index }}</div>
            
            <h4 class="mar-t-10"><strong>v-for=""使用注意事项------循环一个数组需要注意的地方</strong></h4>
            <h4 class="mar-b-10">数组是一个引用值,引用值指向内存空间,假如把numbers里面的2变成10,但还是以前的那个地址,那个内存空间,并没有变地址,那vue通过,object.property进行数据绑定,内存地址没变,就不会触发vue的set,就不会触发DOM节点的渲染,所以现在看起来还是以前的数,2.数组的值改变了,但是索引没有改变,因此,就不会重新渲染我们的DOM节点</h4>
            <ul>
                <li v-for="n in numbers">{{ n }}</li>
            </ul>
            <button v-on:click="changeNumber" class="mar-b-10">点击修改第2个数变成10,发现没变</button>
            
            <h4 class="mar-b-10">点击修改第2个数变成10,非要改变,就要用vue内部的set方法实现,如果以set方法进行设置,就会对DOM节点进行渲染。这个就是vue的内部机制,也是js的一个缺陷,无法检测数组里面元素的变化,因为只是检测内存地址的变化,如果地址没有变化,就认为没有变化。</h4>
            <h4>Vue.set(想设置谁,索引,设置值)有三个参数,如:Vue.set(this.numbers,1,10)</h4>
            <ul>
                <li v-for="n in numbersOk">{{ n }}</li>
            </ul>
            <button v-on:click="changeNumberOk">点击修改第2个数变成10,非要改变</button>
            
            <h4 class="mar-b-10 mar-t-10"></h4>
            <h4 class="mar-b-10">push方法添加一组数据,按照上面的例子,一直往数据添加数据,vue能检测到数组内部的变化,并且把他渲染出来,重新渲染DOM。就是vue底层的操作:把js底层的push方法进行了重写,虽然看到的是push方法,但是跟我们看到的数组方法的push方法已经不一样了,使用了观察者模式</h4>
            <h4 class="mar-b-10"><strong>v-for运行机制:模板复用机制</strong></h4>
            <h4>直接把上一个模板拿过来接着使用,就不用重新渲染DOM了,从而节省性能,但是会有bug</h4>
            <h4>重写的数组方法有:push,por,shift,unshift,sort,reverse,splice</h4>
            <ul class="mar-b-10">
                <li v-for="item in listItem">
                    {{item.id}}、
                    {{item.name}}
                    {{item.time}}
                </li>
            </ul>
            <button v-on:click="addGroup">点击我添加一组数据</button>
            <button v-on:click="reverse">reverse把数组倒置</button>
            
            <h4 class="mar-b-10 mar-t-10"><strong>下面这个例子会有问题了,点击后倒置,只有前面的会倒置,后面的input框没有倒置了,因为现在用的是同一套模板,三个input框识别成了一个,所有的都是一样的input框,就不用DOM渲染,也就不会倒置,过滤掉了</strong></h4>
            <h4>如果现在想让他进行渲染,可以给一个key值,告诉模板这个input框是独一无二的,不是一样的。v-bind:key="item.id"</h4>
            <h4>那么第一个模板的key是1,第二个是2。。。。并且提到了2点:</h4>
            <h4>第一点:v-for是需要知道数组或者对象里面的name元素的变化不会引起DOM渲染,如果我们想要让DOM进行渲染,就用Vue.set()设置属性或者重写后的数组方法去写</h4>
            <h4>第二点:v-for=""进行了循环,用了一个模板复用的思想,比如说所有模板是一样的话,就不会重新渲染DOM,如果想让他每次改变DOM都让他从新渲染DOM的话,就给一个独一无二的key值,vue就知道这些是不一样的,就会重新渲染DOM节点</h4>
            <ul class="mar-b-10">
                <li v-for="item in listItem" v-bind:key="item.id">
                    {{item.id}}、
                    {{item.name}}
                    {{item.time}} <input type="text" />
                </li>
            </ul>
        </div>
    </div>
    <script type="text/javascript">
        var app15 = new Vue({
            el: "#app15",
            data: {
                numbers: [1,2,3,4],
                numbersOk: [0,1,2,3],
                movies: ["黑豹","复仇者联盟","至暗时刻"],
                persons: [{
                    name: "林",
                    title: "web前端"
                },{
                    name: "张",
                    title: "UI设计"
                },{
                    name: "赵",
                    title: "Java后台"
                }],
                company: "阿里巴巴",
                person: {
                    lastName: "林",
                    firstName: "先生",
                    age: 10
                },
                listItem: [{
                    id: 1,
                    name: "林",
                    time: 2016
                },{
                    id: 2,
                    name: "钱",
                    time: 2017
                },{
                    id: 3,
                    name: "孙",
                    time: 2018
                }]
            },
            methods: {
                changeNumber: function(){
                    this.numbers[1] = 11
                    alert("应该弹出来是一个"+ this.numbers[1] + "但却没有修改成功,因为是引用值")
                },
                changeNumberOk: function(){
                    Vue.set(this.numbersOk , 1 , 10);
                    alert("应该弹出来是一个"+ this.numbersOk[1])
                },
                addGroup: function(){
                    this.listItem.push({
                        id: 4,
                        name: "周",
                        time: 2019
                    })
                },
                reverse: function(){
                    this.listItem.reverse()
                }
            }
        })
    </script>
    
    <div id="app16" class="mar-t-30 mar-b-30">
        <h4 class="mar-b-10">案例7、</h4>
        <h4 class="mar-b-10">
            <p>1、双向数据绑定案例</p>
            <input type="text" v-model="textInput"/>
            <p>{{ textInput }}</p>
            在这要注意,这里如果是input或者password框,就绑定到value上面去。去过是复选框上的话,就绑定check上。如果是check是true是选中状态,否则就是未选中状态
        </h4>
        
        <div class="mar-b-10">
            <div>2、v-if v-else-if else用法案例</div>
            <p v-if="numbers > 5">你的数字大于5</p>    
            <p v-else-if="numbers > 3">你的数字大于3</p>    
            <p v-else>你的数字小于3</p>    
        </div>
        <div class="mar-b-10">
            <h2><strong>3、v-for=""循环里面再循环</strong></h2>
            <ol>
                <li v-for="box in subs">
                    {{ box.name }}
                    <ul>
                        <li v-for="arr in box.sub">{{ arr }}</li>
                    </ul>
                </li>
            </ol>
        </div>
    </div>
    <script type="text/javascript">
        var app15 = new Vue({
            el: "#app16",
            data: {
                textInput: "这个是一个双向数据绑定的案例",
                numbers: 8,
                subs: [{
                    name: "HTML",
                    sub: ["div","p","a"]
                },{
                    name: "Css",
                    sub: ["css1","css2","css3"]
                },{
                    name: "Javascript",
                    sub: ["Jquery","Vue","Angular"]
                }]
            }
        })
    </script>

v-bind
缩写::
预期:any (with argument) | Object (without argument)
参数:attrOrProp (optional)
修饰符: 
.prop - 被用于绑定 DOM 属性。
.camel - (2.1.0+) 将 kebab-case 特性名转换为 camelCase.
.sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
用法: 
动态地绑定一个或多个特性,或一个组件 prop 到表达式。 
在绑定 class 或 style 特性时,支持其它类型的值,如数组或对象。
在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。 
没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。

v-bind缩写:  :  如 :src="item.imgPath" ==> v-bind:src="item.imgPath"


v-on
缩写:@
预期:Function | Inline Statement | Object
参数:event
修饰符: 
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
用法: 
绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。 
从 2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。 
用在普通元素上时,只能监听 原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。 
在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event 属性:v-on:click="handle('ok', $event)"

转载于:https://my.oschina.net/parchments/blog/1793096

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值