Vue基础学习

Vue

一、入门

1.1 概念

个人BB:
这是一份去年其实就写完的Vue入门基础,当时是跟着官网把vue基本的内容全部自己写了一遍,以求更好的掌握,今年才真的在项目上实际使用Vue,也知道这份入门也就真的只有入门的程度。
今年实际写Vue项目之后,其实出了不少问题,我把之间没看过的vuex和vrouter看完了,又重新翻了一遍vue的api文档,去了解了深入响应式原理。又去看了现在常用的es6语法。觉得自己又能写出不少东西了,而且也想要求自己写一些东西。
做项目尚有文档产出,何况是学习呢。
下面有个项目可能会比较忙,但后续估计会更新uni-app的一些学习和项目的一些记录和心得

Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。

Vue 只关注视图层, 采用自底向上增量开发的设计。

Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

1.2 优点

轻量级,体积小,开源、吸取了其他两个框架的优点、拥有计算属性。

1.3 入门案例

1.3.1 IDEA安装Vue插件

在这里插入图片描述

1.3.2 代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<h3 id="name">{{message}}</h3>
</body>
<script>
    var vm=new Vue({
        el:'#name',
        data:{
            message:"回家睡觉"
        }
    });
</script>
</html>
1.3.3 结果

在这里插入图片描述

1.3.4 意义

看起来平淡无奇,但这本身是一种MVVM(Model-View-ViewModel)模式的实现,让视图与业务逻辑分开。

好处:

低耦合,高重用度、独立开发、可测试

也是一种数据双向绑定的实现。

直观体验,终于不刷新也可以改变页面数据了!

1.4 生命周期

在这里插入图片描述

二、语法

2.1 指令

在Vue中所有指令都以v-开头

自定义属性

2.2 v-html

v-html和{{}}作用一样

<div id="app">
    <div v-html="message"></div>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: '<h1>不转义直接输出</h1>'
  }
})
</script>

2.3 v-bind

2.3.1 绑定对象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<input v-bind:value="message" id="name"/>
</body>
<script>
    var vm=new Vue({
        el:'#name',
        data:{
            message:"回家睡觉"
        }
    });
</script>
</html>
2.3.2 绑定属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="name" v-bind:class="div"></div>
</body>
<script>
    var vm=new Vue ({
        el: '#name',
        data: {
            div: "div1"
        }
    });
</script>
<style>
    .div1 {
        border: 2px solid red;
        border-radius: 5px;
        width: 500px;
        height: 50px;
    }
</style>

2.3.3绑定style
<div v-bind:style="styleObject">绑定样式对象</div>'
<!-- CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) -->
<div v-bind:style="{ color: activeColor, fontSize: fontSize,background:'red' }">内联样式
</div>
<!--组语法可以将多个样式对象应用到同一个元素 -->
<div v-bind:style="[styleObj1, styleObj2]"></div>
<script>
	new Vue({
         el: '#app',
         data: {
            styleObject: {
                color: 'green',
                fontSize: '30px',
                background:'red'
                },
            activeColor: 'green',
            fontSize: "30px"
                },
        styleObj1: {
            color: 'red'
        },
        styleObj2: {
            fontSize: '30px'
        }
</script>
2.3.4绑定对象和绑定数组的区别

绑定对象的时候,对象的属性即要渲染的类名,对象的属性值对应的是 data 中的数据
绑定数组的时候数组里面存的是data 中的数据

2.4 v-cloak

作用比较简单,当页面加载比较慢时,页面会出现vue源码,所以用v-cloak设定样式,页面加载完再移除样式,

大概只有好看的作用

<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    <style type="text/css">
        [v-cloak]{
            display: none;
        }
    </style>
<body>
<div id="app">
    <div v-cloak >{{msg}}</div>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'Hello Vue'
        }
    });
</script>
</body>

2.5 v-text

和v-html差不多,但没有加载过慢的问题,单向绑定,标签里的值改变,vue里的值不会表

和v-html区别,v-html不会转义字符,标签会生效,v-text输出转义后的字符

<body>
<div id="app">
    <div v-text="msg" ></div>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '张三<br/>李四'
        }
    });
</script>
</body>

在这里插入图片描述

2.5 v-pre

显示原始信息,不对这个元素进行编译。

可以加快静态资源的渲染。

<span v-pre>{{ this will not be compiled }}</span>
    <!-- 显示的是{{ this will not be compiled }} -->
<span v-pre>{{msg}}</span>
    <!-- 即使data里面定义了msg这里仍然是显示的{{msg}} -->
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'Hello Vue.js'
        }
    });
</script>

2.6 v-on

绑定事件

形式可以简写如:v-on:click =@click

可以在methods里写复数个方法

如果直接绑定函数名,默认传入事件参数

如果多个参数,事件参数必须在最后一个,名称必须为$event。

<body>
<div id="app">
    <button v-bind:class="div" @click="up">{{msg}}</button>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 1,
            div:"bbs"
        },
        methods:{
            up:function () {
                alert("函数执行");
            }
        }
    });
</script>
<style>
    .bbs{
        width: 200px;
        height: 200px;
        border: 2px solid ;
    }
</style>
</body>

2.7 v-once

一次性插入数据,只在第一次生效,以后改变绑定数据,也不会生效

<!-- 即使data里面定义了msg 后期我们修改了 仍然显示的是第一次data里面存储的数据即 Hello Vue.js -->
<span v-once>{{ msg}}</span>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'Hello Vue.js'
        }
    });
</script>

2.8 v-model

数据双向绑定

当数据发生变化时,视图变化,视图改变时,数据也随之变化

<body>
<div id="app">
    <div >{{msg}}</div>
    <input v-model="msg" />
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '1'
        }
    });
</script>
</body>

2.9 v-if

判断,基础

<body>
<div id="app">
    <p v-if="msg">如果条件成立,就显示这条</p>         <!--输出-->
    <p v-if="msg!=false">如果条件成立,也输出这条</p>  <!--输出-->
    <p v-else-if="msg===false">这条还可以这么写</p>   <!--不输出-->
    <p v-else>其他情况下输出这条</p>                  <!--不输出-->
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg:true
        }
    });
</script>
</body>

2.10 v-show和v-if的区别

v-show和v-if看起来相似,其实有着本质区别

**v-show本质就是标签display设置为none,控制隐藏
**v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
v-if是动态的向DOM树内添加或者删除DOM元素
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件

2.11 v-for

循环,核心

不推荐同时使用 v-if 和 v-for**
当 v-if 与 v-for 一起使用时, v-for 具有比 v-if 更高的优先级。**

<body>
<ul id="example-1">
    <!-- 循环结构-遍历数组
    item 是我们自己定义的一个名字 代表数组里面的每一项
    items对应的是 data中的数组-->
    <li v-for="item in items">
        {{ item.message }}
    </li>
</ul>
<script>
    new Vue({
        el: '#example-1',
        data: {
            items: [
                { message: 'Foo' },
                { message: 'Bar' }
            ]
    }
    })
</script>
</body>
<body>
    <!-- 循环结构-遍历对象
  v 代表 对象的value
 k 代表对象的 键
 i 代表索引
 --->
    <ul id="example-1">
        <div   v-if='v==13' v-for='(v,k,i) in obj'>{{v + '---' + k + '---' + i}}</div>
    </ul>

    <script>
        new Vue({
            el: '#example-1',
            data: {
                items: [
                    { message: 'Foo' },
                    { message: 'Bar' }
                ],
                obj: {
                    uname: 'zhangsan',
                    age: 13,
                    gender: 'female'
                }
            }
        })
    </script>
</body>

2.12 事件修饰符

Vue将操作Dom封装,使用事件修饰符来完成一些常用行为。

<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面,阻止默认事件-->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 即阻止冒泡也阻止默认事件 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
//使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。
//因此,用 v-on:click.prevent.self 会阻止所有的点
//击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

2.13 按键修饰符

就是以前的监听事件

常用的按键修饰符
.enter => enter键
.tab => tab键
.delete (捕获“删除”和“退格”按键) => 删除键
.esc => 取消键
.space => 空格键
.up => 上
.down => 下
.left => 左
.right => 右
<body>
<div id="app">
    <div>
        <button v-on:keyup.enter="handle1">点击2</button>
    </div>
</div>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            num: 0
        },
        methods: {
            handle1: function(event) {
                console.log("你按下了enter键")
            }
        }
    });
</script>

2.14 自定义按键修饰符别名

在vue中可以通过 config.keyCodes 修改按键别名 。

<body>
<div id="app">
    <div>
        <button v-on:keyup.f="handle1">按f</button>
    </div>
</div>
<script type="text/javascript">
    Vue.config.keyCodes.f=70;
    var vm = new Vue({
        el: '#app',
        methods: {
            handle1: function(event) {
                alert("你确定要进入坦克?")
            }
        }
    });
</script>
</body>

2.15 自定义指令

自定义指令和自定义组件差不多。

2.15.1 全局指令
<body>
    <input id="app" v-focus>
<script>
  Vue.directive('focus',{
      inserted: function(el) {
          el.focus();
      }
  });
  var vm=new Vue({
      el:'#app'
  });
</script>
</body>
2.15.2 全局指令带参数
<body>
    <input id="app" v-focus="msg">
<script>
  Vue.directive('focus',{
      bind:function (el,binding) {
          el.style.backgroundColor=binding.value.color;
      }
  });
  var vm=new Vue({
      el:'#app',
      data: {
          msg: {
              color: 'blue'
          }
      }
  });
</script>
</body>
2.15.3 局域自定义指令

用法与全局差不多

定义在directives中

局域自定义指令优先级大于父类优先级

三、属性

3.1 组件注册

在Vue中可以自定义组件模板,是十分方便的一个功能

组件参数的data值必须是函数同时这个函数要求返回一个对象
组件模板必须是单个根元素
组件模板的内容可以是模板字符串

自定义组件必须使用短横线

<body>
<div id="app">
    <span>{{msg}}</span>
    <a-mu></a-mu>
</div>
<script>
    Vue.component('a-mu',{
         template: '<div>这是一个默认模板</div>'
    });

    var vm=new Vue({
        el:'#app',
        data: {
            msg: '测试数据'
        }
    })
</script>
</body>

3.1.1组件中可传的参数

    Vue.component('button-counter', {
        // 1、组件参数的data值必须是函数
        // 同时这个函数要求返回一个对象
            data: function(){
                return {
                    count: 0
                }
            },
        // 2、组件模板必须是单个根元素
        // 3、组件模板的内容可以是模板字符串
            template: `
            <div>
                <button @click="handle">点击了{{count}}次</button>
                <button>测试123</button>
                # 6 在字符串模板中可以使用驼峰的方式使用组件
                <HelloWorld></HelloWorld>
            </div>
            `,
            methods: {
                handle: function(){
                    this.count += 2;
                }
            }
            })
    var vm = new Vue({
        el: '#app',
        data: {
        }
    });

3.2数据绑定

<body>
<div id="app">
    <amu v-bind:message="msg" ></amu>
</div>
<script>
    Vue.component('amu',{
         props:['message'],
         template: '<div>{{message}}</div>'
    });

    var vm=new Vue({
        el:'#app',
        data: {
            msg: '测试数据'
        }
    })
</script>
</body>

3.3 计算属性 Computed

3.3.1回调函数

自己定义

没有调用

最后执行

  • 模板中放入太多的逻辑会让模板过重且难以维护 使用计算属性可以让模板更加的简洁

  • 计算属性是基于它们的响应式依赖进行缓存的

  • computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变

    化则我们监控的这个值也就会发生变化

    响应式依赖进行缓冲,就是Message改变后,页面不刷新也不改变。

    这么做的原因是 性能比较高,如果每次 都改变的话,每次都要计算。

    如果不需要缓冲,就可以写成方法。

<body>
<div id="app">
    <div>{{message}}</div>
    <div>{{reserveMessage}}</div>
</div>
<script>
    var  vm= new Vue({
        el:'#app',
        data: {
            message:'这是一条测试数据'
        },
        computed:  {
            reserveMessage: function () {
               return this.message.split('').reverse().join('');
            }
        }
    });
</script>
</body>

getter:get 显示

setter:set 监视双向绑定,数据回写

3.4 watch 侦察属性

  • watch里面都是data里面的属性
  • 如果异步或者开销比较大的操作
  • 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听
<body>
<div id="demo">{{ fullName }}</div>
<script>
    var vm = new Vue({
        el: '#demo',
        data: {
            firstName: 'Foo',
            lastName: 'Bar',
            fullName: 'Foo Bar'
        },
        watch: {
            firstName: function (val) {
                this.fullName = val + ' ' + this.lastName
            },
            lastName: function (val) {
                this.fullName = this.firstName + ' ' + val
            }
        }
    })
</script>
</body>

3.5 过滤器 filter

  • Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。
  • 过滤器可以用在两个地方:双花括号插值和v-bind表达式。
  • 过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示支持级联操作
  • 过滤器不改变真正的 data ,而只是改变渲染的结果并返回过滤后的版本全局注册时是filter,没有s的。
  • 而局部过滤器是filters,是有s的

和directive差不多有 全局fitler和局域fitler

可以使用多个filter,使用 | 分割。

<body>
<div id="example-1" class="demo">
    <input type="text" v-model="message">
    <p>{{ message | capitalize }}</p>
</div>
</div>
<script>
    new Vue({
        el: '#example-1',
        data: function () {
            return {
                message: 'john'
            }
        },
        filters: {
            capitalize: function (value) {
                if (!value) return ''
                value = value.toString()
                return value.charAt(0).toUpperCase() + value.slice(1)
            }
        }
    });
</script>
</body>

3.6 组件插槽

匿名插槽,数据在插槽里

当组件渲染的时候,这个 元素将会被替换为“组件标签中嵌套的内容”。

插槽内可以包含任何模板代码,包括 HTML

就是在组件里嵌套别的组件,还可以进行数据绑定等操作,让vue更加灵活

必须在组件里实现声明有插槽,不然不能用

<alert-box ID="slots-demo">
    Something bad happened.
</alert-box>
<script>
    Vue.component('alert-box', {
        template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
    })
    new Vue({ el: '#slots-demo' })
</script>
<style>
.demo-alert-box {
    padding: 10px 20px;
    background: #f3beb8;
    border: 1px solid #f09898;
 }
</style>
</body>

具名插槽

用 name指定slot的名字

渲染顺序取决于模板的顺序,而不是组件中的顺序。

使用插槽绑定数据,说实话,以我的角度看 比较烦

<body>
<alert-box ID="slots-demo">
   <up-half slot="up-half" :title="title"></up-half>
    <down-half slot="down-half" :message="message"></down-half>
</alert-box>
<script>
    Vue.component('alert-box', {
        template: `
    <div class="demo-alert-box">
      <slot name="up-half"></slot>
      <slot name="down-half"></slot>
    </div>`
    })
    Vue.component('up-half',{
        props:['title'],
        template:
          '<div>{{title}}</div>'
    });
    Vue.component('down-half',{
        props:['message'],
        template:
            '<div>{{message}}</div>'
    })
    new Vue({
        el: '#slots-demo',
        data: {
            title: '标题',
            message: '内容'
        }
    })
</script>
<style>
.demo-alert-box {
    padding: 10px 20px;
    background: #f3beb8;
    border: 1px solid #f09898;
 }
</style>
</body>

3.7 自定义事件

3.7.1 只自定义一个时间名
<div id="app">
    <p>{{msg}}</p>
 <out-alert v-on:plus="outalert" ></out-alert>
</div>
<script>
    Vue.component('out-alert',{
        template: `
    <button v-on:click="$emit('plus')">
     help me!
    </button>
   `
    })
    var vm=new Vue({
        el: '#app',
        data: {
            msg: 0
        },
        methods: {
            outalert: function () {
                   this.msg+=1;
            }
        }
    });
</script>
3.7.2 配合额外参数
<body>
<div id="app">
    <p>{{msg}}</p>
 <out-alert v-on:plus="outalert" ></out-alert>
</div>
<script>
    Vue.component('out-alert',{
        data: function(){
            return{
                count: 0
            }
        },
        template: '<button v-on:click="pluscount">{{count}}</button>',
        methods: {
            pluscount: function () {
                 //this.count+=1;
                 //自定义事件
                 this.$emit('plus')
            }
        }
    })
    var vm=new Vue({
        el: '#app',
        data: {
            msg: 0
        },
        methods: {
            outalert: function () {
                   this.msg+=1;
            }
        }
    });
</script>
</body>

四、异步通信

4.1 axios框架

实现基本的get、put、post、delete请求

主要就是从指定路径拿到返回相应携带数据,然后then里面放后续操作,catch里面放失败的处理

<body>
<div id="app">
    {{ info }}
</div>
<script type = "text/javascript">
    new Vue({
        el: '#app',
        data () {
            return {
                info: null
            }
        },
        mounted () {
            axios
                .get('http://localhost:63342/vuetest/first-Vue/static/data.json')
                .then(response => (this.info = response))
                .catch(function (error) { // 请求失败处理
                    console.log(error);
                });
        }
    })
</script>
</body>

4.2 axios 全局配置

# 配置公共的请求头
axios.defaults.baseURL = 'https://api.example.com';
# 配置 超时时间
axios.defaults.timeout = 2500;
# 配置公共的请求头
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
# 配置公共的 post 的 Content-Type
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

4.3 axios拦截器

在我看来等同于预处理或者后处理

请求拦截器
请求拦截器的作用是在请求发送前进行一些操作
例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易

响应拦截器
响应拦截器的作用是在接收到响应后进行一些操作
例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页

# 1. 请求拦截器
axios.interceptors.request.use(function(config) {
console.log(config.url)
# 1.1 任何请求都会经过这一步 在发送请求之前做些什么
config.headers.mytoken = 'nihao';
# 1.2 这里一定要return 否则配置不成功
return config;
}, function(err){
#1.3 对请求错误做点什么
console.log(err)
})
#2. 响应拦截器
axios.interceptors.response.use(function(res) {
#2.1 在接收响应做些什么
var data = res.data;
return data;
}, function(err){
#2.2 对响应错误做点什么
console.log(err)
})

4.4 async和await

async作为一个关键字放到函数前面
任何一个 async 函数都会隐式返回一个 promise

await 关键字只能在使用 async 定义的函数中使用
await后面可以直接跟一个 Promise实例对象
await函数不能单独使用

# 1. async 基础用法
# 1.1 async作为一个关键字放到函数前面
	async function queryData() {
# 1.2 await关键字只能在使用async定义的函数中使用 await后面可以直接跟一个 Promise实例对象
var ret = await new Promise(function(resolve, reject){
setTimeout(function(){
resolve('nihao')
},1000);
})
// console.log(ret.data)
return ret;
}
# 1.3 任何一个async函数都会隐式返回一个promise 我们可以使用then 进行链式编程
queryData().then(function(data){
console.log(data)
})
#2. async 函数处理多个异步函数
axios.defaults.baseURL = 'http://localhost:3000';
async function queryData() {
# 2.1 添加await之后 当前的await 返回结果之后才会执行后面的代码
var info = await axios.get('async1');
#2.2 让异步代码看起来、表现起来更像同步代码
var ret = await axios.get('async2?info=' + info.data);
return ret.data;
}
queryData().then(function(data){
console.log(data)
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值