Vuejs入门 ①

Vuejs入门 ①

Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑 定和组合的视图组件。它不仅易于上手,还便于与第三方库或既有项目整合。

了解MVVM模式

MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为 抽象化,让我们将视图 UI 和业务逻辑分开 MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model) Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM, 也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端 开发更加高效、便捷

快速入门Demo

<!DOCTYPE html><html><head><meta charset="utf-8" />  <title>快速入门</title><script src="js/vuejs-2.5.16.js"></script>  </head><body><div id="app">  {{message}}</div><script>  new Vue({      el:'#app', //表示当前vue对象接管了div区域      data:{        message:'hello world' //注意不要写分号结尾    }  });</script></body></html>

插值表达式

数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值,Mustache 标签将会被替代为对应数据对 象上属性的值。无论何时,绑定的数据对象上属性发生了改变,插值处的内容都会更新。

Vue.js 都提供了完全的 JavaScript 表达式支持

{{ number + 1 }}{{ ok ? 'YES' : 'NO' }}

这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个 表达式,所以下面的例子都不会生效。

<!-- 这是语句,不是表达式 -->{{ var a = 1 }}<!--控制也不会生效,请使用三元表达式 -->{{ if (ok) { return message } }}

VueJS 常用系统指令

    1. v-on 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码

v-on:click

<!DOCTYPE html><html><head>    <meta charset="utf-8" />        <title>事件处理 v-on示例1</title><script src="js/vuejs-2.5.16.js"></script><script src="js/vuejs-2.5.16.js"></script></head><body><div id="app">       {{message}}      <button v-on:click="fun1('good')">点击改变</button></div><script>    new Vue({    el:'#app', //表示当前vue对象接管了div区域    data:{        message:'hello world' //注意不要写分号结尾    },    methods:{        fun1:function(msg){            this.message=msg;}}});</script></body></html>

    2. v-bind 插值语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind指令

<!DOCTYPE html><html><head><meta charset="utf-8" /><title>v-bind</title><script src="js/vuejs-2.5.16.js"></script></head><body><div id="app"><font size="5" v-bind:color="ys1">传智播客</font><font size="5" :color="ys2">黑马程序</font><hr><a v-bind={href:"http://www.itcast.cn/index/"+id}>itcast</a></div><script>  new Vue({  el:'#app', //表示当前vue对象接管了div区域  data:{  ys1:"red",  ys2:"green",  id:1}});</script></body></html>

v-bind简写方式

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

    3. v-model

<!DOCTYPE html><html><head><meta charset="utf-8" /><title>v-model</title><script src="js/vuejs-2.5.16.js"></script></head><body><div id="app">姓名:<input type="text" id="username" v-model="user.username"><br>密码:<input type="password" id="password" v-model="user.password"><br><input type="button" @click="fun" value="获取"></div><script>new Vue({  el:'#app', //表示当前vue对象接管了div区域  data:{    user:{username:"",password:""}      },  methods:{    fun:function(){      alert(this.user.username+" "+this.user.password);      this.user.username="tom";      this.user.password="11111111";}}});</script></body></html>

    4. v-for

操作array

<!DOCTYPE html><html><head>    <meta charset="utf-8" />    <title>v-model</title>    <script src="js/vuejs-2.5.16.js"></script></head><body><div id="app">    <ul>        <li v-for="(item,index) in list">{{item+" "+index}}</li>    </ul></div><script>    new Vue({        el:'#app', //表示当前vue对象接管了div区域        data:{            list:[1,2,3,4,5,6]        }    });</script></body></html>

操作对象

<!DOCTYPE html><html><head>    <meta charset="utf-8" />    <title>v-for示例1</title>    <script src="js/vuejs-2.5.16.js"></script></head><body><div id="app">    <ul>        <li v-for="(value,key) in product">{{key}}--{{value}}</li>    </ul></div><script>    new Vue({        el:'#app', //表示当前vue对象接管了div区域        data:{            product:{id:1,pname:"电视",price:6000}        }    });</script></body></html>

操作对象数组

<!DOCTYPE html><html><head>    <meta charset="utf-8" />    <title>v-for示例1</title>    <script src="js/vuejs-2.5.16.js"></script></head><body><div id="app">    <table border="1">        <tr>            <td>序号</td>            <td>名称</td>            <td>价格</td>        </tr>        <tr v-for="p in products">            <td>                {{p.id}}            </td>            <td>                {{p.pname}}            </td>            <td>                {{p.price}}            </td>    </tr>    </table></div><script>    new Vue({        el:'#app', //表示当前vue对象接管了div区域        data:{            products:[{id:1,pname:"电视机",price:6000},{id:2,pname:"电冰箱",price:8000},                {id:3,pname:"电风扇",price:600}]        }    });</script></body></html>

    5.v-if与v-show

v-if是根据表达式的值来决定是否渲染元素

v-show是根据表达式的值来切换元素的display css属性

<!DOCTYPE html><html><head>    <meta charset="utf-8" />    <title>v-if与v-show</title>    <script src="js/vuejs-2.5.16.js"></script></head><body><div id="app">    <span v-if="flag">传智播客</span>    <span v-show="flag">itcast</span>    <button @click="toggle">切换</button></div><script>    new Vue({        el:'#app', //表示当前vue对象接管了div区域        data:{            flag:false        },        methods:{            toggle:function(){this.flag=!this.flag;            }        }    });</script></body></html>

VueJS生命周期

vue在生命周期中有这些状态, beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed。Vue 在实例化的过程中,会调用这些生命周期的钩子

,给我们提供了执行自定义逻辑的机会。那么,在这些vue钩子 中,vue实例到底执行了那些操作,我们先看下面执行的例子

<!DOCTYPE html><html><head>    <meta charset="utf-8" />    <title>生命周期</title>    <script src="../js/vue.js"></script></head><body><div id="app">    {{message}}</div><script>    var vm = new Vue({        el: "#app",        data: {            message: 'hello world'        },        beforeCreate: function() {            console.log(this);            showData('创建vue实例前', this);        },        created: function() {            showData('创建vue实例后', this);        },        beforeMount: function() {            showData('挂载到dom前', this);        },        mounted: function() {            showData('挂载到dom后', this);        },        beforeUpdate: function() {            showData('数据变化更新前', this);        },        updated: function() {            showData('数据变化更新后', this);        },        beforeDestroy: function() {            vm.test = "3333";            showData('vue实例销毁前', this);        },        destroyed: function() {            showData('vue实例销毁后', this);        }    });    function realDom() {        console.log('真实dom结构:' + document.getElementById('app').innerHTML);    }    function showData(process, obj) {        console.log(process);        console.log('data 数据:' + obj.message)        console.log('挂载的对象:')        console.log(obj.$el)        realDom();        console.log('------------------')        console.log('------------------')    }    vm.message="good...";    vm.$destroy();</script></body></html>

vue对象初始化过程中,会执行到beforeCreate,created,beforeMount,mounted 这几个钩子的内容

  • beforeCreate :数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象
  • created :数据已经绑定到了对象实例,但是还没有挂载对象
  • beforeMount: 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的 el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创 建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点
  • mounted: 将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们 就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并 进 行各种操作
  • 当我们的data发生改变时,会调用beforeUpdate和updated方
    • beforeUpdate :数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还 没有发生改变
    • updated: dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到 dom上面,完成更新
  • beforeDestroy,destroed : 实例的销毁,vue实例还是存在的,只是解绑了事件的监听还有watcher对象数据 与view的绑定,即数据驱动

  

VueJS ajax

1 vue-resource

vue-resource是Vue.js的插件提供了使用XMLHttpRequest或JSONP进行Web请求和处理响应的服务。 当vue更新 到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios

2 axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中

在线CDN 引入

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

使用Demo

创建一个json文件模拟请求返回数据

{   "extends1": "dtslint/dtslint.json",  "rules1": {    "nounnecessarygenerics": false  }}

使用示例

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title><!--    <style>--><!--        [v-clock]{--><!--            display: none;--><!--        }--><!--    </style>-->  解决闪屏问题    <script src="../js/vue.js"></script>    <script src="../js/axios.min.js"></script></head><body>    <div id="vue">        {{info.extends1}}<br>        {{info.rules1}}    </div>    <script type="text/javascript">        var vm=new Vue({            el:'#vue',            data(){                return{                    info:{                        extends1:null,                        rules1:{                            nounnecessarygenerics:null                        }                    }                }            },            mounted(){                axios.get('../js/tslint.json').then(response=>{                    this.info=response.data;                    console.log(response.data);                })            }        });    </script></body></html>

注意:此处的data为一个方法,不再是之前的data。

计算属性:

计算属性的重点突出在属性两个字上面(属性是名词),首先它是个属性,其次是这个属性有计算的能力。这里的计算就是个函数,简单点说,它就是一个能够将计算结果缓存起来的属

性,(将行为转换成了静态的属性),仅此而已;可以想象为缓存!!

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title>    <script src="../js/vue.js"></script>    <script src="../js/axios.min.js"></script></head><body><div id="vue">    <p>{{currentTime1()}}</p>    <p>通过属性调用:{{cuttrentTime2}}</p></div><script type="text/javascript">    var vm=new Vue({        el:'#vue',        data:{            message:"hasagei"        },        methods:{            currentTime1:function (){                return Date.now();  //返回一个时间戳            }        },        computed:{    //计算属性            cuttrentTime2:function (){  //与methods中的方法名不能重名  重名之后只会调用Methods中的方法
          this.message; return Date.now(); //返回一个时间戳 } } });</script></body></html>

说明:

  • methods:定义方法,调用方法时使用currentTime1(),需要带括号
  • computed:定义计算属性,调用属性使用currentTime2,不需要带括号;this.message是为了能够让currentTime2观察到数据变化为变化
  • 如果再方法中的值发生了变化,则缓存就会刷新!可以在控制台中使用vm.message="xxxx",改变下数据的值,在观察结果

结论:

  调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑讲这个结果缓存起来,

采用计算属性可以很方便的做到这点,计算属性主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;

vue中的slot(插槽)

默认插槽

1:定义插槽。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title>    <script src="../js/vue.js"></script>    <script src="../js/axios.min.js"></script></head><body><div id="vue">    <ksd-button>注册</ksd-button>    <ksd-button>登录</ksd-button>    <ksd-button><span style="font-weight: bold">保存</span></ksd-button></div><script type="text/javascript">    Vue.component('ksd-button',{        template:`<button><slot></slot></button>`    });    var vm=new Vue({        el:'#vue',        data:{            message:"hasagei"        }    });</script></body></html>

2:使用插槽。

<div id="app">    <ksd-button>注册</ksd-button>    <ksd-button>登录</ksd-button>    <ksd-button><span style="font-weight: bold">保存</span></ksd-button></div>

3:测试结果。

结论:插槽相当于占位符。

具名插槽

1:定义插槽。

<script type="text/javascript">    Vue.component("KsdLayout", {        template: `<div class="container">                       <header><slot name="header"></slot></header>                       <main><slot name="main"></slot></main>                       <footer><slot name="footer"></slot></footer>                   </div>`    });    var vm=new Vue({        el:'#vue',        data:{            message:"hasagei"        }    });</script>

2:定义样式。

<style>    * { margin: 0; padding: 0; }    .container { max-width: 1200px; margin: 0 auto; color: #fff; text-align: center; }    header { height: 50px; background: #000; }    main { height: 150px; background: red; }    footer { height: 50px; background: green; }    .container * { margin: 10px; }</style>

3:使用插槽。

<div id="vue">    <ksd-layout>        <template v-slot:header><h1>我是头部</h1></template>        <template v-slot:main><h1>我是内容</h1></template>        <template v-slot:footer><h1>我是底部</h1></template>        <template v-slot:default><h1>我是默认</h1></template>    </ksd-layout>    <ksd-layout>        <template #header><h1>我是头部</h1></template>        <template #main><h1>我是内容</h1></template>        <template #footer><h1>我是底部</h1></template>        <template #default><h1>我是默认</h1></template>    </ksd-layout></div>

template 作用 template 是 vue 提供的一个虚拟标签,这个标签不会进行渲染,只是起到一个临时使用和隔离块的作用,比如插槽的模板的隔离,v-for 和 v-if 同时使用的问题,表格树 tree,递归组件

默认插槽与具名插槽结合使用

1:定义插槽。

 Vue.component("KsdLayout", {        template: `<div class="container">                       <header><slot name="header"></slot></header>                       <main><slot name="main"></slot></main>                       <footer><slot name="footer"></slot></footer>                       <footer><slot></slot></footer>                   </div>`    });    Vue.component("KsdHeader", {        template: `<header><slot name="header">我是头部组件</slot></header>`,    });

2:使用插槽

    <ksd-layout>        <template #header><h1><ksd-header></ksd-header></h1></template>        <template #main><h1>我是内容</h1></template>        <template #footer><h1>我是底部</h1></template>        <template #default>            <div><h1>1</h1></div><div><h1>2</h1></div>            <div><h1>3</h1></div><div><h1>4</h1></div>        </template>    </ksd-layout>

3:测试结果。

4:如果在组件中,没有定义默认插槽,那么组件中没有被具名包裹的元素,全部都会被 vue 抛弃掉。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title>    <script src="../js/vue.js"></script>    <script src="../js/axios.min.js"></script>    <style>        * { margin: 0; padding: 0; }        .container { max-width: 1200px; margin: 0 auto; color: #fff; text-align: center; }        header { height: 50px; background: #000; }        main { height: 150px; background: red; }        footer { height: 50px; background: green; }        .container * { margin: 10px; }        h1{color: red}    </style></head><body><div id="vue">    <ksd-layout>        <template #header><h1><ksd-header></ksd-header></h1></template>        <template #main><h1>我是内容</h1></template>        <template #footer><h1>我是底部</h1></template>        <div><h1>1</h1></div><div><h1>2</h1></div>        <div><h1>3</h1></div><div><h1>4</h1></div>    </ksd-layout><!--    <ksd-layout>--><!--        <template #header><h1>我是头部</h1></template>--><!--        <template #main><h1>我是内容</h1></template>--><!--        <template #footer><h1>我是底部</h1></template>--><!--        <template #default><h1>我是默认</h1></template>--><!--    </ksd-layout>--></div><script type="text/javascript">    Vue.component("KsdLayout", {        template: `<div class="container">                       <header><slot name="header"></slot></header>                       <main><slot name="main"></slot></main>                       <footer><slot name="footer"></slot></footer><!--                       <footer><slot></slot></footer>-->                   </div>`    });    Vue.component("KsdHeader", {        template: `<header><slot name="header">我是头部组件</slot></header>`,    });    var vm=new Vue({        el:'#vue',        data:{            message:"hasagei"        }    });</script></body></html>

插槽作用域

1:定义插槽。

<script>    var app = Vue.createApp({        data() {            return {                loginText: "登录",                regText: "注册"            }        },        methods: {        }    });    app.component("KsdButton", {        template: `<button><slot :btns="buttons"></slot></button>`,        data() {            return {                buttons: {                    loginText: "登录",                    regText: "注册"                }            }        }    });    app.mount("#app");</script>

2:把组件中的 data 值返回给组件的调用者进行使用。

<div id="app">    <ksd-button #default="{btns}">{ {btns.loginText} }</ksd-button>    <ksd-button #default="{btns}">{ {btns.regText} }</ksd-button>    <ksd-button><span style="font-weight: bold;">保存</span></ksd-button></div>

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部