VUE2~3初步探索

    对应模式:MVVM(以异步通信为主) : Model, View, ViewModel。

Vue:采用插值语法。

Vue对应的cdn为下:

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

    内置指令

v-pre:使Vue跳过解析。

v-once:只会读取一次数据,且v-once没有值。

v-cloak: 当网速过慢时,可以使未经解析的模板不显示在页面上。

[v-cloak]{
    display: none;
}

<p v-cloak>{{data}}</p>

v-html:类似v-text,但是v-html支持结构的解析,也就是可以解析标签字符串。

v-text:向其所在的标签插入文本。(会替换掉标签中的内容,所以在标签中写内容是无效的)

v-bind:title : 可以将vue中的值显示在对应的字体上。(鼠标悬停在字体上时显示数据)

v-if ,v-else : 判断。

v-for : v-for="(item, index) in item"。(类似python的循环, item表示遍历到的项,index表示下标),且必须给每个item配置一个:key,如果没有写key的话,v-for会将遍历时的index作为:key的值。(类似SQL中的主键)

v-bind:"data" : 表示动态绑定,value为""中data的运行结果。

key的作用:

使用:key时的特殊例子:

使用数组的index作为唯一标识时,使用头插法的话会打乱原本的顺序,从而影响效果。

 而在使用id作为唯一标识时,就不会影响效果了。

v-model :实现双向绑定。(此方法只适用于表单元素上,也就是只适用于输入类元素上)

:style:绑定style,且对应的值是对象形式的。

v-show:条件渲染。(true表示显示,false表示不显示),且v-show不能配合template使用。

双向绑定<input type="text" v-model:value="name"/>
        双向绑定<input type="text" v-model="name"/>
//两者是等价的,可以省略绑定的参数名

el:的替代写法为下:

var v = new Vue();
v.$mount("#id");

 data:的替代写法为下:

data: function(){
    return {
    name: value
}
}

    自定义指令 

例子为下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.6/dayjs.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
    <div id="root">
      
    <p>{{n}}</p>
    <button @click="add">n++</button>
    <p v-big="n"></p>
    </div>
</body>
<script>
   var vm = new Vue({
       el: '#root',
       data: {
           n: 0
       },
       methods: {
         add(){
             this.n++
         }
       },
       directives:{
        big(el, binding){
            //el表示标签,binging表示绑定的值对象
            el.innerText = binding.value * 10
        }
       }
   })
</script>
</html>

自定义指令被调用的情况:

  • 指令与元素成功绑定时。
  • 指令所在的模板重新被解析时。

自定义局部指令的格式为下:

 directives:{
        fbind: {
            //指令和元素绑定成功时调用
            //默认时就表示以个bind函数
            bind(el, binding){
                el.value = binding.value
            },
            //指令所在元素被插入页面时调用
            inserted(el, binding){
                el.focus()
            },
            //指令所在的模板被重新解析时调用
            update(el, binding){
                el.value = binding.value
            }
        }
       }

如果使用简写方式的话就等于只写了bind()和update()。 

 自定义全局指令的格式为下:

Vue.directive('指令名',{
    //函数体
    bind(){
    }
    inserted(){
    }
    update(){
    }
})

注意点:

    Vue主键

对应的例子为下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--v-bind:data="item":将item绑定给data,就是传递数据-->
<div id="app">
    <hfw v-for="item in item" v-bind:data="item"></hfw>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
<!--组件定义-->
    Vue.component("hfw",{
//data表示对应的参数名,不要使用驼峰命名法,会报错,hfw表示对应的标签名
        props: ['data'],
        template: '<li>{{data}}</li>'
    });
    var vm = new Vue({
        el: "#app",
        data: {
            item: ["java", "c++", "python"]
        }
    });
</script>
</body>
</html>

    <hfw v-for="item in item" v-bind:data="item"></hfw>类似中间商。

template:表示模板,且在代码执行时会脱去。

    defineProprety() 

作用:个对象添加新的属性。(新添加的属性不会参与遍历)

例子为下:

var data = {
            name: '张三',
            sex: '男',
        }
        Object.defineProperty(data, 'age',{
            value: 19
//想要被枚举的话就加下面的条件
enumerable: true;
//想要可以修改的话,就加下面的条件
writable: true;
//可以属性是否可以被删除
configurable: true;
        });
        console.log(data);

为了让Vue中的数据得到数据代理,所以我们不能直接使用defineProperty(),而是用Vue.set(target, key, value)或者使用vm.$set(target, key, value)。

重点: Vue.set(target, key, value)和vm.$set(target, key, value)中的target不允许为vm或vm.data,只能是vm.data中的对象。

    事件修饰符(修饰符可以连续写)

    计算属性

computed : 储存计算属性,且在计算属性中的get()方法存在缓存机制。

get()的调用机制:初次调用计算属性时会调用get(),在所依赖数据发生改变时会再次调用。

在计算属性确定不会被更改时,我们可以采用简写的方式。

computed: {
    data: function{
    //此函数就为get();
    }
}

set():不是必须的,但是如果此消息在后续会被更改的话,就必须写set方法。

计算属性例子:列表过滤

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
    <div id="root">
        请输入名字: <input type="text" v-model="keyword"/>
        <button @click="sortData = 1">年龄升序</button>
        <button @click="sortData = 2">年龄降序</button>
        <button @click="sortData = 0">年龄原顺序</button>
        <ul>
            <li v-for="person in filterpersons" :key="person.id">
                {{person.name}}--{{person.age}}--{{person.sex}}
            </li>
        </ul>
    </div>
</body>
<script>
   new Vue({
       el: '#root',
       data: {
           keyword: '',
           sortData:0,
           persons: [
               {id: 001, name: '黄飞武',age: 18, sex: '男'},
               {id: 002, name: '黄武',age: 13, sex: '女'},
               {id: 003, name: '黄飞',age: 49, sex: '女'},
               {id: 004, name: '飞武',age: 11, sex: '男'}
           ]
       },
       computed: {
           filterpersons(){
               var arr =  this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyword) !== -1
               })
                //a,b表示数组项
               if(this.sortData == 1){
                    arr.sort((a, b)=>{//递增
                     return a.age - b.age
                    })
               }else if(this.sortData == 2){
                arr.sort((a, b)=>{//递减
                     return b.age - a.age 
                    })
               }
               return arr
           }
       }
   })
</script>
</html>

    监视属性

watch: 用于监视数据。

  methods: {
       watch: {
                ishot: {
                     //初始化时就让handler调用一下
                    immediate: true
                    //当ishot发生改变时就会调用
                    handler(newValue, oldValue){

                    }
                }
            }
}

//方法二
vm.$watch('ishost', {
                ishot: {
                    immediate: true
                    //当ishot发生改变时就会调用
                    handler(newValue, oldValue){

                    }
                }
})

注意点:

  • 监视的属性必须存在,才能进行相关的操作。
  • 当监视的属性发生变化时,回调函数自动调用,进行相关的操作。
  • 监视的两种方法:new Vue时传入watch配置,通过vm.$watch监视。   

深度监视 : 监视多级结构中某个属性的变化。(使用方法为下)

//在对应的监视器上加上此代码
deep: true

 深度监视注意点:

  • Vue中的watch默认不监测对象内部中值的改变(一层)
  • 配置deep: true可以监测对象内部值的变化。
  • Vue自身可以监测对象内部的值的改变,但Vue提供的watch默认不可以。
  • 使用watch时根据数据的具体结构,决定是否采用深度监视。

监视属性的简写方法为下:

watch: {
        dataName(newValue, oldValue){
            //方法体
            }
  }

此简化方法的使用情况:只适用于修改对应属性值时。 

监视属性和计算属性的区别: 监视属性可以开启异步任务,而计算属性不可以开启异步任务。(如:setTimeout)

计算属性必须返回值,而异步任务不能使数据return给外部的同步函数,所以计算属性不能使用异步操作。

区别:

  • computed能完成的功能,watch都可以完成。
  • watch能完成的功能,computed不一定可以完成,例如:watch可以进行异步操作。
  • 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
  • 所有不被Vue所管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数。
  • 这样this的指向才是vm或组件实例对象。

setTimeout的this是window。 

    数据监视

    收集表单数据

注意点:

    过滤器 

过滤器中存放对应的函数。

过滤器的格式为下:

{{对应参数 | 对应的过滤器函数}}

过滤器在Vue中的创建:

var vm = new Vue({
       filters: {
            timeFormater(value){
                return dayjs(value).format('YYYY-MM-DD HH:mm:ss')
            }
       }
   })

过滤器函数的第一个参数为管道符前面的参数 ,即使你没有写参数,它也会传管道符前面的参数给过滤器对应的函数。

    过滤器函数的特点: 过滤器函数可以进行串联使用,且函数之间用管道符间隔,作用顺序为从前往后传递。

   注册全局过滤器格式为下:

Vue.filter('对应的过滤器函数名',function(){
    //对应的函数体
})

且全局过滤器必须写在new Vue()的前面。

    网络通信(Axios异步通信)

Axios的特性:

  • 从浏览器中创建 xmlHttpRequest。
  • 从 node.js创建http请求。
  • 支持Promise API [js中链式编程]
  • 转换请求数据和响应数据。
  • 取消请求。
  • 自动转换为JSON数据。
  • 客户端支持防御XSRF(跨站请求伪造)

Axios对应的cdn为下:

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

Axios例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <div>{{info.name}}</div>
    <div>{{info.address}}</div>
    <a v-bind:href="info.url">点我</a>
</div>
    <script src="http://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data(){
          return{
              info:{
                  name: null,
                  address: {
                      street: null,
                      city: null,
                      country: null
                  },
                  url: null
              }
          }
        },
        mounted(){//钩子函数,链式编程,程序执行时插入执行
            axios.get("../data.json").then(response=>(this.info=response.data));
        }
    });
</script>
</body>
</html>

对一个的data.json为下:

{
  "name":"java",
  "url": "http://baidu.com",
  "page": 1,
  "isNonProfit":true,
  "address": {
   " street": "含光门",
    "city":"陕西西安",
    "country": "中国"
  },
 " links": [
    {
     " name":" B站",
      "url":" https://www.bilibili.com/"
    },
    {
      "name": 4399,
      "url": "https://www.4399.com/"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}

    计算属性

computed:在其中编写对应的函数,该函数在调用时不需要加括号,而methods中定义的方法,在调用函数时需要加上括号。

计算属性的特点: 类似缓存方法,如果对应的参数不变的话,且调用过对应的函数时,就会返回上次计算出的结果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<body>
<!--view层,模板-->
<div id="vue">
    <todo>
        <todo-title slot="todo-title" v-bind:title="title"></todo-title>
        <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下为简写-->
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item" ></todo-items>
    </todo>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    Vue.component('todo',{
        template:'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
            </ul>\
            </div>'
    });
    Vue.component('todo-title',{
        props:['title'],
        template:'<div>{{title}}</div>'
    });
    //这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
    Vue.component("todo-items",{
        props:["item"],
        template:"<li>{{item}}<button>删除</button></li>"
    });
    var vm = new Vue({
        el:"#vue",
        data:{
            title:"cvzhanshi study java",
            todoItems:['test1','test2','test3']
        }
    });
</script>
</body>
</html>
slot对应的name表示插槽对应的名字。

    点击事件

@click : 用于按钮的触发事件,且@click可以等于一个完整的函数也可以是一个简单的语句。(@click只会在vm中查找对应的函数,并不会在window中查找)

    生命周期 

mounted:表示挂载,且在把真实的dom放入页面后(完成挂载),会去调用mounted中的函数。

生命周期视图:https://cn.vuejs.org/images/lifecycle.png 

注意点:

     组件

 cv的__proto__不是指向object,而是指向Vue,这是Vue强制指向的,所以在cv中查找某个属性时,不存在时就会到Vue中查找,最后在通过Vue的__proto__再找到Object。(vueComponent.prototype.__proto === Vue.prototype的值为true)

    .Vue文件的格式

<template>
    <!-- 组件的结构 -->
</template>

<script>
    // 脚本
</script>

<style>
    /* 组件的样式 */
</style>

在编写完.vue文件后,我们要将文件进行暴露。

暴露方法有: 分别暴露(直接将数据分别暴露),统一暴露(export{数据,数据,数据}),默认暴露(export  default 数据)

    脚手架

配置步骤:

 render: 渲染功能,使app放入到对应的容器中。

脚手架中的规则:

    props

props:表示组件中存在的参数,可以通过标签来赋值。(传入的属性值不可修改)

格式为下:

props: ['name', 'address'],//简单写法
    props:{//完整写法
        name: String,
        age: Number,
        address: String
    }
    props: {//最完整写法
        name: {
            type: String,
            required: true//是否必要
        },
        age: {
            type: Number,
            default: 99//默认值
        },
        address: {
            type: String,
            required: false
        }
    }

      mixin

mixin:表示多个组件共用一个配置。(mixin的配置文件使用js编写)

目的: 提高代码的复用性。

如果原来就存在某个键,而混合又传入了个相同名字的键,我们就以原来的键为最后结果,但是如果是生命周期的钩子函数,那么就会全部执行。

格式为下:

 mixins: [.., .., ..]

mixins:要用数组表示,因为其可能存在多个。

    nanoid

nanoid:用于创建唯一的id。

下载方式为下:

npm i nanoid

    Confirm()

Confirm的用法:会显示一个弹窗,此弹窗会有确定和取消按钮,分别返回ture和false。

    Todo-List(练习)

对应的Todo-List为下链接:

http://链接:https://pan.baidu.com/s/1131bPmPc4BYZMOnom6EOFg

提取码:6666

    浏览器本地存储

    localStorage

方法:通过window.localStorage,调用setItem(添加数据,参数为key), getItem(查询数据),removeItem(删除对应的数据,参数为key),clear(清空全部的数据)

特点: 在浏览器关闭后,localStorage还会存在,localStorage会存在缓存中,只有当用户主动清空缓存后才会消失。

sessionStorage

方法: 和localStorage的方法相同。

特点:在浏览器关闭后,sessionStorage会马上消失。

    自定义事件

通过v-on 绑定对应的事件,而被绑定事件的主键上,我们可以通过this.对应的事件,来获取自定义事件,为了能够触发事件,我们就可以使用this.$emit('自定义事件',传递对应的参数)来触发自定义事件。(传递对应的参数是可选项,传递对应的参数会传递给自定义事件中对应的函数)

第二种写法:在对应的标签中使用ref,通过this.$refs.对应的子组件从而获取对象,通过者对象进行绑定事件($on('对应的事件名',对应的函数), this为触发事件的组件)。

解除绑定: this.$off('对应的事件名'),如果是解绑多个事件的话,我们就可以将$off()中的参数用数组表示。

在组件中使用原生的事件,需要在@原生事件后加上 .native。(例子: @click.native="")

    过度效果

例子为下:

<template>
  <div>
      <button @click="isShow=!isShow">显示/隐藏</button>
      <transition>
          <h1 v-show="isShow" >你好!</h1>
      </transition>
  </div>
</template>

<script>
export default {
    name: 'test',
    data(){
        return {
            isShow: true
        }
    },

}
</script>

<style scoped>
    h1{
        background-color: orange;
    }
    .v-enter-active{
        animation: hfw 1s;
    }
    .v-leave-active{
        animation: hfw 1s reverse;
    }
    @keyframes hfw {
        from{
            transform: translateX(-100%);
        }
        to{
            transform: translateX(0px);
        }
    }
</style>

如果用实现多个过度动画的话,我们就想要为<transition>的name赋值。

如果进行了此操作我们就需要将进/出类更新名字。

格式: .(对应的新名字)-enter-active,.(对应的新名字)-leave-active。

appear:此属性为<transition>中的属性,:appear="true"表示出现时有过度动画,:appear="false"表示出现时没有过度动画。

如果要实现两个相同的过度效果就需要使用<transition-group>,且每个项都要有key值。

animate的使用

对应的下载方法

npm install animate.css --save

引入方式:

import 'animate.css'

例子为下:

<template>
  <div>
      <button @click="isShow=!isShow">显示/隐藏</button>
      <transition-group 
      name="animate__animated animate__bounce"
       appear
       enter-active-class="animate__jello"
       leave-active-class="animate__backOutRight">
          <h1 v-show="isShow" :key="1">你好!</h1>
          <h1 v-show="!isShow" :key="2">你不好!</h1>
      </transition-group>
  </div>
</template>

<script>
import 'animate.css'
export default {
    name: 'test',
    data(){
        return {
            isShow: true
        }
    },

}
</script>

<style scoped>
    h1{
        background-color: orange;
    }
</style>

    axios的引用

下载axios库

npm i axios

axios的格式为下:

axios.get('www.4399.com').then(
					response => {
						console.log("请求成功!", response.data)
					},
					error => {
						console("请求失败了", error。message)
					}
				)
//获取的数据需要使用,否则会爆红

跨域问题: 用于获取的数据源的端口号为5000(例子),而ajax的请求为8080(例子),两者的端口号不相同,从而引起跨域。

解决方法: 

方法1:

使用 vue.CLI(代理服务器)

在vue.config.js中配置。

module.exports = {
  devServer: {
    proxy: 'http://localhost:4000'
    //4000表示对应的数据源端口
  }
}

且在ajax中的请求端口为发起请求的前端端口。

缓存机制: 如果在vue中public文件夹中存在请求所需要的数据,那请求请求就不会继续执行了,其会直接返回public文件夹中对应的数据。

缺点:在vue.config,js中只能配置一个端口号,其用于缓存机制会导致无法请求得到真正的数据。

方法2:

  module.exports = {
    devServer: {
      proxy: {
        '对应的前缀名,跟在端口号后面,这样就可以控制是否走代理服务器,就不会受到缓存的影响':{
            target:"www.4399.com",
            pathRewrite:{'^/atguigu':''},//此属性表示代理服务器传给后端时的url不回带有/atguigu
            ws: true,//Websocket
            changeOrigin: true // 是否对应后端服务器撒谎,true为撒谎,false为实话实说
          },

          '对应的前缀名2,跟在端口号后面,这样就可以控制是否走代理服务器,就不会受到缓存的影响':{
            target:"www.4399.com",
            pathRewrite:{'^/atguigu':''},//此属性表示代理服务器传给后端时的url不回带有/atguigu
            ws: true,//Websocket
            changeOrigin: true // 是否对应后端服务器撒谎,true为撒谎,false为实话实说
          }
      }
    }
  }

 此方法弥补了方法一的缺陷。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值