vue总结

vue基础

vue 是一个MVVM框架,model-view-viewModel,是一个MVC的前端版本
viewModel是一个控制器的角色,在他里面实现逻辑运算等,这样就可以把Model层和View层高度分离
View:视图,用于封装和展示数据以及效果,其实就是html结构
Model层:数据模型,用于封装数据以及数据运行的业务逻辑

----使用vue的方法
1.通过script 引入vue文件
2.可以通过vue-cli 创建vue项目,进行开发

----解构出来一个创建应用的方法

const {createApp}=Vue;

----创建应用

createApp({
    // 设置数据
    // data函数中存放当前页面中所有的数据,如果需要声明数据,必须声明在data中
    // data是一个方法,返回值是一个对象,data必须有返回值,否则报错
    data(){
        return{
            str:'创建应用'
        }
    }
}).mount('#app');

.mount(‘#app’); 把应用挂载到 id=app 的div上

插值表达式 {{ }}

{{ }} :插值表达式,在他的里面可以执行vue的变量,表达式,也可以执行函数
插值表达式实际上是一个js的域,在插值表达式中可以执行简单的js语句,并且把执行结果返回到插值表达式所在dom结构的位置上

----插值表达式的缺点:初次加载的时候文本闪烁
解决方法
1.把vue文件引入到head中,不建议使用
2.使用指令 v-cloak 来隐藏数据没有加载完成的dom结构,这样可以解决页面开始时的闪烁问题。该指令的运行方式是,首先隐藏没有编译成功的dom结构,等到dom编译成功之后,会自动把隐藏的方式去掉

<p v-cloak>{{ 1+1 }}</p>

{{}}插值表达式不能直接绑定属性的值
也可以使用指令 v-html 、v-text 绑定数据

属性绑定

在vue中,可以使用 v-bind来绑定属性
语法是:
v-bind:属性名=‘属性值/变量名’
简写方式
:属性名=‘属性值/变量名’

绑定style和class

----绑定style

        <h2 :style="{ color:'#04be02',fontSize:'30px'}">{{str}}</h2>
        //以下:style="style" 引号中的style需要在data中声明
        <div :style="style"></div>
        <div :style="'font-size:20px;color:#f00;'">人之初性本善</div>
        <div :style="[ {color:'#04be02'},{fontSize:'30px'} ]">多行不义必自毙</div>

----绑定class

<div class="abc">柳宗元</div>
<div :class="'abc aa'">曾巩</div>
<!-- 使用数组形式绑定class -->
<div :class="['abc','aa']">韩愈</div>
<!-- 使用对象形式绑定class,属性名为class名,属性的值是一个bol值,如果bol值为true,则绑定该class名,否则不绑定 -->
<div :class="{'abc':3>4,'aa':3<4}">苏轼</div>

总结:style和class的绑定都支持数组形式和对象形式

事件绑定

绑定事件使用
v-on:事件名=“表达式/方法名”
方法名的参数问题,如果没有参数,可以不用加()
事件绑定指令的简写
@事件名=“表达式/方法名”

<button v-on:click="num++">点击++</button>

----事件的修饰符

vue提供了事件修饰符,用来提高开发效率
@事件名.修饰符.修饰符.修饰符…=触发方法

stop 阻止事件冒泡
prevent 阻止默认事件
once 只触发一次
self 当event.target是当前绑定元素的时候触发
capture 事件捕获的时候触发
passive 触发滚动事件的默认行为

----按键的修饰符

按键修饰符,当按下或者抬起对应修饰符的按键时触发事件,
.enter
.tab
.delete (捕获“Delete”和“Backspace”两个按键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
.exact 非系统键

数据的双向绑定

在表单元素中,使用v-model实现数据的双向绑定
双向绑定:简言之就是数据在视图层的更改,会立即体现在model层,反之在model层的改变也会立即体现在视图层

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数据的双向绑定</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="val"/>
        <p>{{val2}}</p>
    </div>
</body>
</html>
    <script src="../vue.js"></script>
   <script>
createApp({
    data(){
        return{
            val:'人之初性本善',
        }
    }
}).mount('#app');
 </script>

当用户在表单元素中输入内容时,v-model 会自动更新绑定的数据。
数据的变化也会反映在表单元素上。

常用指令

v-show 指令,如果他的值时true,则他所绑定的元素显示,如果为false,他所绑定的元素会自动添加一个display:none,元素隐藏,v-show改变的是css样式,属于元素重绘
v-if 指令,如果他的值是true,则他所绑定的元素从dom树对应的位置渲染,如果为false,所绑定的元素从dom树中删除,v-if改变的是dom树的结构,属于元素重排
v-else 需要结合v-if使用,用法同js的if-else
v-else-if 需要结合v-if使用,用法同js的if-else if

v-for 结合 template 标签(组件)循环数据(template 标签不会被渲染到页面上,一般用来实现数据绑定的功能)
v-for=“形参 in 数组/对象”
如果需要下标或者对象的属性名 v-for=“(形参,下标形参/属性名形参) in 数组/对象”
v-for的key属性
使用v-for的标签元素,都需要绑定一个key属性,属性的值一般都是要循环对象中的唯一值,例如id,
使用key属性的目的是,使已经渲染过的列表内容不再重新渲染,提高列表的渲染效率,注意index虽然可以设置key值,但是由于index的值会发生变化,这样会导致列表重新渲染,因此慎用

v-pre 他所绑定的元素不进行vue的编译,原样输出

v-once 他所绑定的元素只渲染一次,忽略之后所有的更新

v-memo 实现组件内容的缓存,如果他所绑定的值不发生改变,那么他绑定的元素内部不会根据数据的改变而重新渲染

自定义指令

createApp({
    data(){
        return{}
    },
    // 自定义指令
    directives:{
        /*
        aa 是指令名,
        参数
            el 表示的是自定义指令绑定的元素
            binding 是一个对象,包含的属性
                value 表示的是指令的值
                name 表示的是指令的名字
                oldValue 指令绑定的数据或者元素内部发生改变的时候,改变前的值仅在beforeUpdate和updated钩子函数中有值
        */ 
        aa(el,binding){
            console.log(el,binding);
        },
        // 配置指令
        abc:{
            created(el,binding){
                console.log('created',el,binding);
            },
            mounted(el,binding){
            },
            updated(el,binding){
                console.log('更新了',binding.oldValue);
            }
        }
    }
}).mount('#app');

计算属性

如果在插值表达式中直接渲染数据,非常方便,但是如果有比较复杂的逻辑运算,插值表达式的渲染效率就会受到影响,并且不利于后期维护,因此可以把比较复杂的运算逻辑放到计算属性

----计算属性的优点
1.数据没有发生变化的时候,优先读取缓存在computed中经过逻辑运算操作的数据,把数据渲染在dom树中,并且不用考虑methods和watch中数据的变化
计算属性值会基于其响应式依赖被缓存
2.他有get方法和set方法,可以进行灵活设置
get 在获取的时候被触发,如果没有set,则默认是get
set 在数据设置的时候被触发

   <script>
createApp({
    data(){
        return{}
    },
    computed:{
     changeStr(){
            return this.str.split('').reverse().join('');
        },
        numArr(){
            return this.arr.filter(item=>{
                return item%2==0
            });
        },
    }
}).mount('#app');
 </script>

每一个计算属性,实质上都包含get和set两个方法,默认是get方法
在计算属性的get方法中,不要异步请求数据(ajax),或者操作dom

    给计算属性设置值的时候,执行的是set方法
    从计算属性获取值的时候,执行的是get方法

侦听器

如果需要根据数据的变化来执行操作,可以使用数据侦听器 watch

   <script>
createApp({
    data(){
        return{}
    },
    /*
        书写侦听器的方法,方法名就是侦听器侦听data数据中数据的属性名,该方法具有两个参数
        第一个参数是数据当前的值(新值),第二个参数是数据变化之前的值(旧值)
        */ 
    watch:{
    	val(newVal,oldVal){
            console.log(newVal,oldVal);
        },
        // 设置侦听器的深度监听
        obj:{
            // 设置监听的回调方法
            handler(newVal,oldVal){
                console.log(newVal,oldVal);
            },
            // 设置立即监听
            deep:true,
            // 设置加载立即监听
            immediate:true
        },
    }
}).mount('#app');
 </script>

也可以设置外部的侦听器

// 可以设置外部的侦听器
app.$watch('name',(newVal,oldVal)=>{
    console.log(newVal,oldVal);
});

生命周期

vue的生命周期主要经历了如下几个阶段,分别是 beforeCreate,created,beforeMount,mounted,beforeUpdate,update,beforeUnmount,unmounted ,主要由这八个阶段组成。

let app=createApp({
    data(){
        return{
            str:'中午吃啥',
            num:100,
            arr:['郑州大学','西亚斯学院','郑州科技学院']
        }
    },
    // 在组件实例初始化完成之后立即调用。此刻其他的属性和方法均没有执行或者编译。当这个钩子被调用时,以下内容已经设置完成:响应式数据(data函数)、计算属性、方法和侦听器。然而,此时挂载阶段还未开始,因此 $el 属性仍不可用。

    beforeCreate() {
        console.log(this.str);
    },
    /*
    在组件实例处理完所有与状态相关的选项后调用。当这个钩子被调用时,以下内容已经设置完成:响应式数据(data函数)、计算属性、方法和侦听器。然而,此时挂载阶段还未开始,因此 $el 属性仍不可用。此时不能操作dom
    */ 
    created(){
        console.log('created',this.str);
    },
    /*
    vue的组件模板,如果在实例中设置了有组件的模板,则会替换掉挂载的dom元素,并且模板的第一层需要是一个完整的dom元素(vue2版本)
    */ 
    // template:`
    //     <h3>{{num}}</h3>
    //     <h2>{{str}}</h2>
    // `

    /*
    在组件被挂载之前调用。此刻还没有挂载任何模板,因此还无法操作dom
    */ 
    beforeMount(){
        console.log('beforeMount');
        let abc=document.querySelector('#abc');
        console.log(abc);
        this.num+=100;
    },
    /*
    在组件被挂载之后调用。此时所有的模板内容都已经被挂载,可以操作组件中所有的dom
    常用此钩子函数来进行 加载立即执行的操作
    */
    mounted(){
        console.log('mounted');
        this.show();
    },
    methods:{
        show(){
            let abc=document.querySelector('#abc');
            console.log(abc);
            abc.style.border='1px #f00 solid'
        },
        add(){
            this.arr.push('河南建筑职业技术学院');
        },
        die(){
            // 卸载vue实例
            app.unmount();
        }
    },
    /*
    beforeUpdate钩子 数据更新前触发,显示的数据是更新后的数据
    但是如果改变了dom结构,那么该函数中的dom结构是更新前的内容
    */ 
    beforeUpdate() {
        let list=document.getElementById('list');
        console.log('beforeUpdate',this.num,list.innerHTML);
    },
    /*
    updated钩子 数据更新后触发,显示的数据是更新后的数据
    但是如果改变了dom结构,那么该函数中的dom结构是更新后的内容
    */ 
    updated() {
        let list=document.getElementById('list');
        console.log('updated',this.num,list.innerHTML);
    },
    // 组件卸载之前触发
    beforeUnmount(){
        console.log('beforeUnmount');
    },
    // 组件卸载之后触发
    unmounted(){
        console.log('unmounted');
    }
});
// 挂载
app.mount('#app');

组件基础

组件,将来项目开发的时候使用的都是组件,组件具有极高的复用性

----注册组件
外部组件关键字是 component,在实例内部注册组件,属性名为 components
app.component(组件名,组建的配置)
1.命名不能和原生html冲突
2.可以使用驼峰,使用驼峰的时候,在视图模板中书写,驼峰的大写字母可以变为段横杠-,例如abCd,使用的时候写为
3.推荐使用 w3c的命名规则:aa-bb

createApp({
	data(){},
	components:{
	        // 驼峰,使用的时候需要my-show
        'myShow':{
            // 配置模板
            template:'<p class="abc">最喜小儿无赖-{{name}}</p>',
            data(){
                return{
                    name:'孙仲谋'
                }
            }
        },
        // w3c 推荐
        'my-run':{
            template:'#run',
            data(){
                return{
                    name:'原神'
                }
            }
        }
	}
})

组件外部配置

在createApp中

    components:{
        abc:abc
    }

在组件abc中

    components:{
        aa:{
            template:'<h4>组件内部的内容-郑科</h4>'
        }
    }

使用的时候在html外部

<template id="abc">
    <h1>我在郑州很想你{{num}}</h1>
</template>

在html中使用标签

    <div id="app">
        <abc></abc>
        <abc></abc>
    </div>

-----组件的属性

components:{
        show:{
            template:'#show',
            // 给组件设置属性,属性名设置在一个数组中,简写
            // props:['abc','aa','obj']
            // 设置属性的具体类型,设置属性的多样性
            props:{
                abc:{
                    // 设置属性abc的值必须是一个字符串
                    type:String,
                },
                aa:{
                    type:String,
                    // 设置为必写属性
                    required:true,
                    // 设置属性的默认值,当属性没有值的时候默认显示的内容
                    default:'中午吃啥'
                },
                obj:{
                    type:Object,
                    // 设置默认值,对象类型的默认值是一个函数,返回一个默认对象
                    default(){
                        return{
                            name:'燕青',
                            age:20
                        }
                    }
                }
            }
        }
    }

组件的传值

组件中通过 this. r e f s 获取所有携带 r e f 属性的子组件实例, t h i s . refs 获取所有携带ref属性的子组件实例,this. refs获取所有携带ref属性的子组件实例,this.refs 是一个集合
this.$refs.aa 就可以获取 ref=“aa” 的组件实例

----子传父

使用 e m i t ( ) 触发自定义事件,并且可以传递参数子组件中的操作 t h i s . emit()触发自定义事件,并且可以传递参数 子组件中的操作 this. emit()触发自定义事件,并且可以传递参数子组件中的操作this.emit(‘event-name’,args参数);

然后把event-name 绑定到子组件上
<son @event-name=“父组件的接收方法”>

过程:
子组件中执行 this. e m i t ( ) ,触发了绑定在子组件上的 e v e n t − n a m e ,然后执行父组件的接收方法,父组件的接收方法接收一个默认的参数,参数的值是子组件中的 t h i s . emit(),触发了绑定在子组件上的event-name,然后执行父组件的接收方法,父组件的接收方法接收一个默认的参数,参数的值是子组件中的this. emit(),触发了绑定在子组件上的eventname,然后执行父组件的接收方法,父组件的接收方法接收一个默认的参数,参数的值是子组件中的this.emit传递的参数,这样通过参数的形式,把数据从子组件传递给父组件

$parent 获取当前组件的父组件,如果没有父组件,则返回null
$root 获取当前组件的根组件,如果当前组件没有父组件,则返回当前组件

----非父子关系的传值

外部引入 mitt 插件 的js

<script src="https://unpkg.com/mitt/dist/mitt.umd.js"></script>

引入mitt实例

// 引入mitt实例
let bus=mitt();

在父组件中声明两个子组件

    components:{
        son1:son1,
        son2:son2
    }

在外部声明两个组件

// 声明两个组件
let son1={
    template:'#son1',
    data(){
        return{
            msg:'假行僧'
        }
    },
    methods: {
        pass(){
            // 执行 mitt 实例中的 emit() 方法,来触发并且传递参数
            bus.emit('abc',this.msg);
        }
    },
};

let son2={
    template:'#son2',
    data(){
        return{
            info:'一块红布'
        }
    },
    mounted(){
        // 执行 mitt 实例中的 on() 方法,来监听 自定义事件是否被触发,如果被触发,则执行回调函数,回调函数默认传入一个参数,该参数的值即为 通过 emit 触发事件传递的数据
        bus.on('abc',data=>{
            this.info=data;
        })
    }
};

provide和inject传值

配置直接传入后代的值

    provide:{
        msg:'却惹三千烦恼丝'
    },

如果直接获取data中的数据作为传递到后代组件的数据,则使用函数的形式返回数据

 provide(){
        return{
            msg:this.str
        }
    },

在外部声明组件,通过inject接收数据

let sun={
    template: '#sun',
    // 通过 inject 直接接收 provide 传递的数据
    inject:['msg']
};

动态组件

动态组件 使用标签 component
该组件具有一个 is 属性,is 属性的值是 要渲染组件的名字,即为 is 属性的值是哪一个组件名,component 标签就会渲染哪一个组件

缺点:component 可以动态的渲染组件的内容,但是每一次切换,都会重新渲染组件内容,降低渲染效率

使用 keep-alive 标签(组件),可以缓存曾经渲染过的组件,从而提高渲染效率

插槽

插槽 指的是 写入自定义组件中包裹的内容,一般都是html结构或者自定义组件
插槽的出口,在自定义组件内部设置一个 slot 标签,表示插槽的出口,将来插槽的内容会渲染在 slot 所在的位置

如果需要不同的插槽内容渲染在组件中不同的位置,那么就需要使用具名插槽,具名插槽的名字设置方式是:
1.在插槽的内容部分,设置v-slot:插槽名 来包裹需要渲染在具体位置的html结构
2.在自定义组件中,设置 slot 在对应的位置,并且slot的name属性值是设置的插槽名

注意 v-slot 可以简写成 #插槽名

使用指令 v-slot 绑定的插槽名字,可以是一个变量
v-slot:[变量名] #[变量名]

过度动画

----设置过度的流程
1.把需要使用过渡动画的元素使用 transition 组件包裹起来
2.给 transition 组件设置一个name属性
3.通过 name 属性的值设置过渡动画
4.通过 v-if 或者 v-show 控制元素的显示和隐藏

transition-group 组件,常用来操作一系列数据,他具有一个tag属性,可以把当前的transition-group组件渲染为 tag 属性设置的html标签

----过度动画的应用场景
1.结合v-if使用
2.结合v-show使用
3.结合 路由切换 使用

简单路由

router-view 组件,通过router-view组件来设置路由的出口,路由匹配到地址栏中的路由地址,会把和该地址对应的组件内容渲染到 router-view 组件中来

1.需要引入vue和router的js
2.设置路由配置

const routes =[
    {
        path:'/', //配置路由地址
        component:Index //根据路由地址的变化,渲染的组件内容
    },
    {
        path:'/list',
        component:List
    }
];

3.设置路由实例对象

let router=VueRouter.createRouter({
    // 设置路由的显示方式
    history: VueRouter.createWebHashHistory(),
    // 在实例中配置
    routes
});

4.在app中配置路由
5.设置路由

app.use(router);

6.在html中使用

<div id="app>
<!-- vue-router中使用 router-link 来设置路由的导航,通过他的to属性来配置路由的地址,每一个 router-link 组件最后会被渲染成一个a标签 -->

        <router-link to="/">首页</router-link> 
        <router-link to="/list">列表页</router-link>
         <router-view></router-view>
         
          <!--router-view 组件,通过router-view组件来设置路由的出口,路由匹配到地址栏中的路由地址,会把和该地址对应的组件内容渲染到 router-view 组件中来-->
</div>
  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值