vue整理(1)

161 阅读8分钟

Vue介绍

Vue是一个构建用户界面(UI)的JS库, 是一个构建数据驱动的渐进式框架,Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。基于MVVM (Model View VievModel)设计模式书写。 Vue只关注视图层,可以快速创建用户界面。

Vue特点
(1)体积小: gzip压缩后33K,并且不依赖其他基础库。
(2)更高的运行效率:基于虚拟DOM,一种可以预先通过JS(在内存中)进行各种运算,把最终的DOM操作计算出来并优化的技术啊。由于这种对DOM操作的预处理操作,并没有真是操作DOM,所以叫做虚拟DOM。 (3)双向数据绑定

Vue项目环境搭建

Vue是一个 JavaScript 框架。它是一个以 JavaScript 编写的库。 Vue是以一个 JavaScript 文件形式发布的,可通过 script 标签添加到网页中:
(1)CDN 引入

<script src="https://cdn.bootcss.com/vue/2.3.3/vue.js"></script>

CDN:全称是Content Delivery Network,即内容分发网络。CDN的通俗理解就是网站加速,可以让客户端快速度访问资源。
(2)使用vue官方脚手架(vue-cli)
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,是一个官方脚手架,可以帮助我们快速创建vue项目工程目录。
vue-cli安装&使用步骤

1、全局安装vue-cli
>> yarn global add @vue/cli   

2、创建项目
>> vue create 项目名     

3、进入项目目录,启动项目
>> yarn serve

项目目录详解

一级目录:
 node_modules       //>> 依赖的第三方模块
 public             //>> vue服务器静态文件目录,只有唯一的一个index.html
 src               //>> 我们的开发目录,最重要的目录,源文件(我们写的代码)目录
 .gitignore         //>> git忽略列表
 babel.config.js    //>> es6编译配置
 package-lock.json  //>> 包描述文件(记录更详细,记住当时的版本信息)
 package.json       //>> 包描述文件
 README.md          //>> 说明文档
 
 二级目录:
src:
    assets          //>> 静态资源 styles images fonts
    components      //>> 组件,是.vue的文件,主要是公用的小组件
    views           //>> 页面级别的组件
    App.vue         //>> 整个应用的顶级组件.
    main.js         //>> 入口文件

组件

所谓组件,即封装起来的具有独立功能的UI部件
组件特点:可重用、可组合、易维护
单文件组件
一个 XXX.vue文件就是一个单文件组件,功能逻辑独立,由 template、script、style三部分组成。
注意:style标签上可以通过 lang =”less”选择预处理语言(有些需要安装对应的loader模块)。 style标签上可以通过 scoped,让样式私有化。
使用自定义组件
使用自定义组件分为三个步骤: 1.引入组件 (引入一个已经写好的xxx.vue组件) 2.注册组件 (在components里面注册) 3.使用组件 (通过标签名使用)

Mustach表达式

语法: {{ 表达式 }},{{}} 里面可以写变量也可以写 表达式 ,也可以简单的运算,注意: 表达式必须能输出唯一结果,不能写if else条件等其他JavaScript代码。可以写三目运算。

指令

指令是写在标签上的一种自定义属性,主要是把vue实例中的数据,输出到html中。
常用指令
v-text 和 v-html: 都可以把数据渲染到一对标签中间,但是v-text不能识别html标签,v-html可以解析html标签。
v-show和v-if:v-show通过控制css的display属性,来控制显示和隐藏,v-if删除或重建DOM。区别: 如果是频繁的切换显示隐藏,就是用v-show;v-if频繁操作dom,性能低。
作用: 控制页面内容显示隐藏(常见:v-show显示/隐藏切换频繁,v-if显示/隐藏切换不频繁,但对隐藏安全要求较高)。
v-if 和 v-else-if 和 v-else:这几个指令需要配合使用,逻辑和js中的条件判断语句一致,会从上往下,找到满足条件的第一个表达式,渲染该DOM.(指令元素间,必须紧密相间)
作用: 用于页面结构中的逻辑判断。(常见:根据场景的不同,制定不同的显示规则)
v-for 循环:循环数组和对象
循环数组:v-for=”(元素的值, 元素的索引) in 数组”
循环对象:v-for=”(元素的值, 键名,元素的索引) in 对象”
作用: 用于根据模板,批量生产显示内容。(常见:数据列表)
v-model: 只能使用于表单,让表单和数据双向绑定。 适用的标签: input(输入框 单选框 多选框) select textarea
作用: 用于获取用户输入表单的值(常见:表单数据获取)
v-bind :给属性绑定动态数据
语法: <标签 v-bind:属性=”表达式” ></标签>
简写: <标签 :属性=”表达式” ></标签>
1)v-bind绑定style 语法: <标签 :style=”{ color: ‘red’, backgroundColor: ‘green’ }” ></标签>

    <div id='app'>
        <div :style="{color:red}">111</div>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.3.3/vue.js"></script>
    <script>
        let app = new Vue({
				el: '#app',
				data: {
					message: 'hello',
                                        num:1,
                                        red:"yellow"
				}
			})

2)v-bind绑定class:语法:<标签 :class=”{ 类名1: flag1, 类名2: flag2 }” ></标签> 注意:flag是true,就有这个类,是false,就没有这个类

    <style>
        .red{
            color: red;
        }
        .yellow{
            color: yellow;
        }
    </style>
</head>
<body>
    <div id='app'>
        <div :class="{red:flag,yellow:!flag}">111</div>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.3.3/vue.js"></script>
    <script>
        let app = new Vue({
				el: '#app',
				data: {
					flag:false
				}
			})
    </script>

一些很少用的指令:
v-pre:不编译Mustache模板表达式,直接当成普通的字符串输出;
v-cloak:隐藏Mustache表达式,直到有数据后,才显示出来;
v-once:只渲染1次,后续数据改变,不会重新渲染。

事件处理
基础语法:
v-on: 事件名;@事件类型=”函数名”; @事件类型=”函数名(参数)”

计算属性

计算属性computed也是vue的一个配置选项,写法和methods一样,把复杂的计算逻辑都写在计算属性函数中,返回结果,通过函数的名字,可以直接使用该函数的返回结果。
computed特点和methods的区别 :1.写法上一样,都是一个方法,但是computed必须返回一个结果。computed有依赖缓存,如果依赖的数据没有发生改变,会直接使用使用缓存的结果,不会重新计算,只有依赖的数据发生了改变才会重新计算,性能高!而methods每次都会重新计算执行一遍。

vue 组件属性命名冲突处理策略

props ==> methods ==> data ==> computed ==> watch

过滤器filters

过滤器filters写法和methods一样,主要是在数据输出到页面之前,进行显示格式处理。
过滤器写法和computed一模一样,有一些区别:
1.过滤器,函数会接收一个参数,函数必须有返回值,对传入数据进行处理
2.过滤器,无缓存机制,调用次数,取决于页面中有所多少过滤器
3.过滤器,被作为一个特殊方法处理.

<div id='app'>
        <div >{{sex|changesex}}</div>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.3.3/vue.js"></script>
    <script>
        let app = new Vue({
				el: '#app',
				data: {
					sex:0
				},
                                filters:{
                                    changesex(sex){
                                        if(sex){
                                            return "男"
                                        }else{
                                            return "女"
                                        }
                                    }
                                }
			})
侦听器Watch

侦听器watch写法和computed一样,主要是捕获指定数据的变化,进行相关的操作。
侦听器写法和computed一模一样,有一些区别:
1.侦听器,函数会接收两个参数(),内部可以根据新值进行处理,函数无需返回值,
2.侦听器,自定捕获数据的变化,并作出响应。变化一次,执行一次。
3.侦听器,被作为一个监听方法处理.

    <div id='app'>
        <div >{{sex}}</div>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.3.3/vue.js"></script>
    <script>
        let app = new Vue({
				el: '#app',
				data: {
					sex:0
				},
                created(){
                    setTimeout(()=>{
                        this.sex=1
                    },3000)
                },
                watch:{
                    sex(newval,oldval){
                        console.log("newval",newval);  //1
                        console.log("oldval",oldval);  //0
                    }
                }
			})
Vue生命周期

Vue生命周期总共分为4大阶段创建前/后、载入前/后、更新前/后、销毁前/后共8个方法。

创建前: :
 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化;
创建后 :
在created阶段,vue实例的数据data有了,el还没有。
*创建阶段:主要是处理数据(主要:对数据进行挟持,把data对象上的数据挂到了this实例上)!!
挂载前:
在beforeMount阶段,vue实例的$el和data都初始化了,但还没有挂载之前都是虚拟的dom阶段,data还未替换;
挂载后:
在mounted阶段,vue实例挂载完后,data成功渲染。
*挂载阶段:主要是合成数据和视图模板,先在内存完成虚拟dom解析,最后一次dom操作直接更新到页面。
更新前:
beforeUpdate,当data变化后,这时视图尚未改变,依旧可以获得改变前的DOM内容
更新后:
updated,当data变化后,页面视图已经更新完毕,可以获得最新的DOM信息
*更新阶段:主要是完成对视图的动态修改。
销毁前:
beforeDestroy,实例销毁之前调用。在这一步,实例仍然完全可用。这时data的改变不会再触发周期函数,说明此时vue实例已经结束了事件监听以及和dom的绑定,但是dom结构依然存在。
销毁后:
destroyed,Vue 实例销毁后调用。这时Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
*销毁阶段:主要是完成对组件的回收。

发送异步请求一般是在created阶段,mounted阶段操作dom,beforeDestroy阶段清除定时器。

前端路由Vue-router

前端路由定义了地址和组件的一一对应关系(一个url地址,对应一个页面级别的组件)
前端路由优点:
1.路由处理速度较快,不用每次都通过服务返回。 2.前端拥有更多的主动权。
缺点:
1.使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。
2.单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置。
在路由文件router.js里面,配置路由和组件的映射关系,每一个路由映射一个组件.
路由的配置有2种
直接引入

import Home from './views/Home.vue'
const routes = [ 
{
path'/home',
name'home',
componentHome
}]

按需加载

{
path: '/about',
name: 'about',
//路由级别代码分割
//这会为该路由生成一个单独的块(about.[hash].js)
//当访问路由时,延迟加载。
component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
}

使用
在App.vue里面,添加一个路由出口,使用来挂载所有的路由组件。会根据当前路由动态渲染不同的页面组件

路由导航

Vue-router里面有内置的组件可以实现跳转,他会被渲染成一个a标签

路由嵌套

在某些场景中,页面只需要做局部更新。在路由中再定义子路由,叫做路由嵌套。内部使用children属性来定义。

    var router = new VueRouter({
        routes:[
            {path:"/",component:index},
            {path:"/product",component:product},
            {path:"/about",component:about,
                children: [
                    {path : "" , component :us},
                    {path : "company" , component :company},
                ]
            }
]});
路由中的全局对象

$router-全局路由对象

    this.$router.push(): 跳转到不同的url,但这个方法会向history栈添加一个记录,点击后退会返回到上一个页面。
    this.$router.replace():替换当前路由,不会向history栈添加一个记录,无法通过history返回到上一个页面。

$route-获取当前页面路由信息

    this.$route.path : 获取当前页面对应的路由地址

组件通信

(1)父组件传给子组件
    1. 父组件使用v-bind绑定动态数据到子组件的标签上。
   <子组件标签 :属性名=“动态数据”></子组件标签>

 2. 子组件通过props接收。
   export default {
       props: [“属性名”]
}

 3. props接收的对象写法/类型校验/默认值。
    export default {
      props: {
            属性名:{
              type: String// 类型可以是Number/Object/Boolean/Array/Date/Funcion
              default: ‘默认值’ // 对象或数组需要写函数。
              //默认值为对象
              default: () => ({})
              //默认值为数组
              default: () => ([])
            }
        }
    }
(2)子组件传递给父组件
    子组件通过 this.$emit() 把数据传递出去
    this.$emit(“自定义事件”, 要传递出去的数据)

    父组件通过在子组件标签上v-on绑定自定义事件接收数据
    <子组件标签 @自定义事件=”函数名”></子组件标签>
   
    methods: {
       函数名( sonData ) {
            // sonData就是子组件传递出来的数据。
    }
}
(3)任意组件之间传递数据(跨级组件)
任意组件之间传递数据,需要通过一个空的vue实例,步骤如下:
1)在入口文件main.js中,创建一个空的vue实例,挂载在Vue的原型上
Vue.prototype.$bus = new Vue();
2)通过emit方法把数据传递出去。
this.$bus.$emit(‘自定义事件’, 要传递出去的数据) 
3)在生命周期created中,通过$on监听自定义事件的方式,接收数据。
 created ( ) {
    this.$bus.$on(‘自定义事件’, function ( data ) { 
     // data就是从传递过来的数据
})}
slot插槽

插槽就是在子组件中预留位置(插槽),父组件在使用子组件标签的时候,可以把内容插入进去。
(1)默认slot:一个没有名字的插槽,就是默认插槽

    子组件
    <!-- 默认插槽: name=default不写 -->
      <slot>默认header</slot>
     <子组件>
      <!-- 这里写的所有内容 都会被插入默认插槽中 -->
     </子组件>

(2)具名slot:一个具有名字的插槽,就是具名插槽

     子组件
      <slot name="header">默认header</slot>
      <slot name="main">默认main</slot>
      <slot name="footer">默认footer</slot>
    父组件
     <子组件>
        <!-- 具名插槽: 找到slot的值对应的这个名字的插槽,把内容插入 -->
        <h1 slot="header">Header</h1>
        <h1 slot="main">main</h1>
        <h1 slot="footer">footer</h1>
     </子组件>

(3)作用域slot

子组件中的数据,通过v-bind绑定到插槽上:
<slot :num="num" :msg="msg" name="main">默认main</slot>
父组件中,通过作用域插槽使用数据:
<h1 slot="main" slot-scope="scope">main main mian: {{ scope.msg }} === {{ scope.num }}</h1>
v-slot
注意:
1.v-slot的缩写是#。
2.需要使用template包裹
v-slot是2.6.x新增的指令,用于取代以上三种写法。
    <Layout>
      <template #header>
        <h1>Header</h1>
      </template>
      <template #main="scope">
        <h1>Main</h1>
        {{ scope }}
        {{ scope.num }}
        {{ scope.msg }}
      </template>
      <template #footer>
        <h1>Footer</h1>
      </template>
    </Layout>