• 欢迎光临~

Vuejs入门 ①

开发技术 开发技术 2022-05-19 次浏览

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,保证视图和数据的一致性,这种轻量级的架构让前端 开发更加高效、便捷

Vuejs入门  ①

 

 

 

快速入门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生命周期

Vuejs入门  ①

 

 

 Vuejs入门  ①

 

 

 

 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:测试结果。

Vuejs入门  ①

 

 

 

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

 

具名插槽

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:测试结果。

Vuejs入门  ①

 

 

 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>

Vuejs入门  ①

 

 

插槽作用域

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>

Vuejs入门  ①

 

程序员灯塔
转载请注明原文链接:Vuejs入门 ①
喜欢 (0)