vue基础,加少量的webpack,以及脚手架搭建vue项目

这是我学习vue基础时候的笔记,在b站上跟着敲的,一开始是有道云笔记的形式,为了上传到博客整理了两个小时改成了markdown的形式,喜欢的点个赞,谢谢。

文章目录

一. vue基本使用

1. 实例参数分析

el:元素的挂载位置(值可以是css选择器或者DOM元素) data:模型数据(值的一个对象)

2. 插值表达式用法 将数据填充到HTML标签中

插值表达式支持基本的计算操作

3. vue代码运行原理

分析概述编译过程中的概念(vue语法->原生语法)

4. 代码举例

<body>
        <div id="box">
            <div >
                {{1+2}}
            </div>
            <div >
                {{msg}}
            </div>
        </div>
        <script type="text/javascript" src="vue.js"></script>
        <script type="text/javascript">
            var vm = new Vue({
                el:'#box',
                data:{
                    msg:'helloWorld'
                }
                
            })     
        </script>
 </body>

二. Vue模板语法

1. 插值表达式{{}},可用来显示数据,计算数据

2. 指令

  • 指令的本质就是自定义属性
  • 指令的格式:以v-开始(如v-cloak)

v-cloak的用法

插值表达式存在闪动(插值表达式里面的vue代码显示出来,再渲染出了页面)的问题,使用v-cloak可以解决,解决原理:先隐藏,替换好值后再显示

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            [v-cloak]{
                display: none;
            } 
        </style>
    </head>
    <body>
        <div id="box">
            <!-- 可以完全编译好后再显示,插值不会出现闪动现象(先显示了vue的内容,再显示html的) -->
            <div v-cloak>
                {{1+2}}
            </div>
            <div v-cloak>
                {{msg}}
            </div>
        </div>
        <script type="text/javascript" src="vue.js"></script>
        <script type="text/javascript">
            var vm = new Vue({
                el:'#box',
                data:{
                    msg:'hello vue'
                }
            });
            
        </script>
    </body>
</html>

3. 数据绑定

3.1 v-text填充纯文本

3.2 v-pre 显示原始内容

3.3 v-html插入html片段

            <div v-text="msg2">
                <!-- 显示插入文本 hello vue -->
            </div>
            <div v-pre>  
            <!-- 显示原始的内容 {{msg}}-->
                {{msg}}     
            </div>
            <div v-html="msg1">
                <!-- 插入html语句 显示带标签h1效果的内容 -->
            </div>
            
            var vm = new Vue({
                el:'#box',
                data:{
                    msg:'hello vue',
                    msg1:'<h1>HTML',
                    msg2:"hello vue"
                }
            });

4. 数据响应式

当vue对象里的data被修改时,页面也会发生改变

v-once

应用于显示的信息后续不需要修改时,可加这个属性,这样可以提高性能

<div v-text="msg2" v-once>
                <!-- 插入文本 -->
</div>

5. 双向数据绑定

5.1 双向数据绑定

5.2 MVVM设计思想

  • M(model)(对象,模型)
  • V (view)(DOM,视图)
  • vm(view-model)(vue) v->M需要vm使用DOM
  • Listeners,vm->v需要vm使用Bindings, 从视图到模型用的是事件监听,从模型到视图用的是数据绑定

在这里插入图片描述

6. 事件绑定

6.1 v-on:指令

  • v-on指令用法 加1
  • v-on简写形式 <button type=“button” @click=“handle”>加1
  • 事件函数的调用方法
    • 直接函数名称 <button type=“button” @click=“handle”>加1
    • 调用函数 <button type=“button” @click=“handle()”>加1
  • 事件函数参数传递
    • 普通参数和事件对象<button type=“button” @click="handle(“a”,“b”, e v e n t ) " 事 件 对 象 参 数 只 能 是 event)"事件对象参数只能是 event)"event
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="box">
            <div >
                {{msg}}
            </div>
            <div>{{num}}</div>
            <button type="button" @click="handle">加1</button>
            <button type="button" @click="handle2(1,3,$event)">加法运算</button>

        </div>
        <script type="text/javascript" src="vue.js"></script>
        <script type="text/javascript">
            var vm = new Vue({
                el:'#box',
                data:{
                    msg:'hello vue',
                    num:0
                },
                methods:{
                    handle:function(){
                        this.num++;
                    },
                    handle2:function(a,b,event)         
                    {
                        console.log(event.target.innerHTML);
                        var sum=a+b;
                        console.log('a+b='+sum);
                    }
                }
            });
        </script>
    </body>
</html>

事件修饰符(可以连写,要注意顺序)

  • .stop-调用 event.stopPropagation()。阻止冒泡事件发生
  • .prevent - 调用 event.preventDefault()。阻止默认事件发生
  • .capture - 添加事件侦听器时使用 capture 模式。
  • .capture - 添加事件侦听器时使用 capture 模式。
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调。
  • .left - (2.2.0) 只当点击鼠标左键时触发。
  • .right - (2.2.0) 只当点击鼠标右键时触发。
  • .middle - (2.2.0) 只当点击鼠标中键时触发。
  • .passive - (2.3.0) 以 { passive: true } 模式添加侦听器
                <button type="button"  v-on:click.stop="handle1">加1</button>
                <!-- .stop阻止冒泡 -->
                <a href="http://www.baidu.com" @click.prevent='handle2'>百度
                <!-- .prevent阻止默认事件,a标签不会跳转 -->
                </a>

按键修饰符

  • v-on:keyup.delete=’ ’
  • v-on:keyup.enter = ‘’
  • config.keyCodes 对象自定义按键修饰符别名:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">


    </style>
</head>

<body>
    <div id="box">
        用户名:<input type="text" name="" id="" value="" v-model='user' v-on:keyup.delete="clear"><br>
        密码:<input type='password' name="" id="" value="" v-model='pwd' v-on:keyup.enter="Submit">
        <br />
        密码:<input type='password' name="" id="" value="" v-model='pwd' v-on:keyup.aaa="handle1">

        <input type="submit" id="" name="" value="登陆" @click="handle1" />

    </div>
    <script src="vue.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
    // 自定义按键修饰符:名字可以随便,对应按键的code值
        Vue.config.keyCodes.aaa = 65
        var vm = new Vue({
            el: '#box',
            data: {
                user: '',
                pwd: ''
            },
            methods: {
                handle1: function (event) {
                    console.log(this.user, this.pwd)
                    console.log(event.keyCode);
                },
                Submit: function () {
                    console.log(this.user, this.pwd)
                },
                clear: function () {

                    this.user = ' ';
                }
            }
        })
    </script>
</body>
</html>

7.属性绑定

7.1 v-bind:指令 缩写:

v-model底层原理本质

v-bind:value=‘msg’,v-on:input’‘msg=$event.target.value’

<body>
        <div id="box">
                <a :href="url">百度</a>
                <button type="button" @click="change">改变</button>
        </div>
    
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var vm = new Vue({
                el:'#box',
                data:{
                    url:'http://www.baidu.com'
                },
                methods:{
                    change:function(){
                        this.url='https://www.bilibili.com/video/av50680998/?p=213'
                    }
                }
            })
        </script>
</body>

8.样式绑定

class样式处理

  • 对象语法 :class = “{active:isactive,error:iserror}”
  • 数组语法:class = “[a,b]”
    简写 :class = “a”,默认的class = “xxx” 会保留

style样式处理

  • 对象语法:style="{color:activeColor,fontSize:fontsize}"
  • 数组语法:style= “[a,b]”
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            .active{
                border: 1px solid red;
                width: 100px;
                height: 100px;
            }
            .error{
                background-color: yellow;
            }
            .test{
                color: #0000FF;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <div id="app"  v-bind:class="{active:isactive,error:iserror}">
                样式绑定
            </div>
            <div><button type="button" @click="handle">对象语法改变</button></div>
            <!-- 对象绑定和数组绑定结合使用 -->
        <div id="app2"  v-bind:class="[a,b,{test:istest}]">
            样式绑定
        </div>
        <div><button type="button" @click="handle2">数组改变</button></div>
        <!-- 简化操作 -->
        <div id="app3"  v-bind:class="arr">
            样式绑定
        </div>
        <div><button type="button" @click="handle3">数组简化操作</button></div>
        <div id="app4"  v-bind:class="obj">
            样式绑定
        </div>
        <div><button type="button" @click="handle4">对象简化操作</button></div>
        <div id="app5"  v-bind:style="{color:activeColor,fontSize:fontsize}">
            样式绑定
        </div>
        <div><button type="button" @click="handle5">style样式处理</button></div>
        <div id="app6"  v-bind:style="[basestyle,fugai]">
            样式绑定
        </div>
        </div>
        
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var vm = new Vue({
                el:'#box',
                data:{
                    activeColor:'red',
                    fontsize:'28px',
                    isactive:true,
                    iserror:true,
                    a:'active',
                    b:'error',
                    istest:true,
                    arr:['active','error'],
                    obj:{
                        active:true,
                        error:true,
                    },
                    basestyle:{
                        color:'blue',
                        fontSize:'30px',
                    },
                    fugai:{
                        border:'1px solid red',
                        color:'pink'
                    }
                },
                methods:{
                    handle:function(){
                        this.isactive=!this.isactive
                    },
                    handle2:function()
                    {
                        this.a='',
                        this.b=''
                    },
                    handle3:function()
                    {
                        Vue.set(this.arr,0,'')
                    },
                    handle4:function()
                    {
                        this.obj.active = !this.obj.active
                    },
                    handle5:function()
                    {
                        this.activeColor='blue';
                    }
                }
            })
        </script>
    </body>
</html>

9.分支循环

分支结构

  • v-if
  • v-else
  • v-else-if
  • v-show

v-if与v-show的区别

  • v-if控制元素是否渲染页面
  • v-show控制元素是否显示(已经渲染到页面)

循环结构

  • v-for遍历数组 v-for = “(item,index) in arr”
  • key的作用:帮助区分不同元素,提高性能
  • v-for遍历对象(v-for=’(value,key,index)’ in object )
  • v-if和v-for结合使用

三.vue常用特性

常用特性概述

  • 表单操作
  • 自定义指令
  • 计算属性
  • 过滤器
  • 侦听器
  • 生命周期

表单操作

基于vue的表单操作

  • input
  • textarea
  • select
  • radio
  • checkbox

表单域修饰符

  • number:转化为数值 如(v-model.number=’’)
  • trim:去掉开始和结尾的空格
  • lazy:将input事件切换为change事件

自定义属性directives

  • 自定义指令的语法规则(获取元素焦点)
  • 自定义指令用法(例子 v-focus)
  • 带参数的自定义指令(改变元素背景色)
  • 指令的用法(v-color=’{color:“orange”}’)
  • 局部指令(使用在组件内)
        <div id="app">
			<input type="text" v-color='msg'>
			<!-- 携带参数的 -->
			<input type="text"  v-focus>
		</div>


------------------------------------------


                directives:{
                    color:{
                        inserted: function(el,binding)
                        {
                            console.log(binding);
                            el.style.backgroundColor = binding.value.color;
                        }
                    },
                    focus:{
                        inserted:function(el)
                        {
                            el.focus()
                        }
                    }
                }

计算属性computed

应用于负责的计算,计算属性可以使模板更加简洁

                <div>{{rever}}</div>
                // 直接调用

--------------------------------                
                computed:{
                    rever:function()
                    {
                        return this.msg.split('').reverse('').join('');
                        //分割数据,然后反转,拼接
                    }
                }

计算属性和方法的区别

  • 计算属性使基于他们的依赖进行缓存(多次使用同一个计算属性只会计算一次)
  • 方法不存在缓存,每次调用都要重新执行

侦听器watch

  • 运用于数据变化时执行异步操作或开销较大的操作
  • 侦听器用法
 <div id="app">
            <span>用户名:</span>
            <span >
                <input type="text" v-model.lazy="uname">
            </span>
            <span>
                {{tip}}
            </span>
        </div>
        <script src="vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var vm = new Vue(
            {
                el:'#app',
                data:{
                    tip:'',
                    uname:''
                },
                methods:{
                    cheack:function(uname)
                    {
                            var that = this;
                            setTimeout(function(){
                                if(uname=='admin')
                                {
                                    that.tip = '用户名已存在'
                                }
                                else
                                {
                                    that.tip = '用户名可以使用'
                                }
                            },1000)
                    }
                },
                watch:{
                    uname:function(val)
                    {
                        this.cheack(val);
                        this.tip = '正在验证...'
                    }
                }
            })
        </script>

过滤器

过滤器的作用

格式化数据,比如将字符串格式化首字母大写,时间格式化

自定义过滤器(例子为全局定义) f第一个参数默认为你需要处理的数据

Vue.filter('过滤器名称', function(val){
    // 过滤器业务逻辑
})

过滤器的使用

<div>{{msg | upper}}</div>
<div>{{msg | upper | lower}}</div>
<div v-bind:id="id | formatId"></div>

局部过滤器(filters)

// 写在组件里
                filters:{
                    upper:function(val)
                    {
                        return val.charAt(0).toUpperCase() + val.slice(1);
                    }
                }

带参数的过滤器(第二个参数开始为传入)

{{msg | upper('arg1'))}}
Vue.filter('过滤器名称', function(val,arg1){ console.log(arg1) })

生命周期

主要阶段

  • 挂载(初始化相关属性)
    • beforeCreate 实例初始化后,数据观测和事件配置之前被调用
    • created 实例创建完成之后调用
    • beforeMount 挂载开始之前被调用
    • mounted:被心创建的vm。$el替换,并挂载到实例上去之后调用该钩子
  • 更新(元素或组件的变更操作)
    • beforeUpdat 数据更新时调用,发生在虚拟DOM打补丁之前
      -updated 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
      销毁(销毁相关属性)
    • beforeDestroy 销毁实例之前
    • destroyed 销毁后调用

四 补充数组相关的api

变异方法(修改原有的数据)

  • push() 数组最后添加内容
  • pop() 弹出数组最后一个 这两个为栈
  • shift() 头部弹出
  • unshift() 头部插入 这两个为队列
  • splice(index) 删除由index开始后面的元素
  • splice(index,num) 由index开始删除num个元素 - splice(index,index2,‘apple2’);由index开始删除,并在index处添加apple2
  • sort() 排序
  • reverse() 翻转

替换数组(生成新数组,原有数据不改变)

  • filter(fn) 过滤
  • concat()连接两个或多个数组。
  • slice(index,index2) index到index2中的元素形成新数组替换旧数组;

修改响应式数据

Vue.set(vm.item,indexOfitem,newValue)
第一个参数表示要处理的数组名,第二个要处理的数组的索引,第三个是数组的设置值

  • Vue.set(vm.list,2,‘lemon’)修改vm中list数组index为2的值为lemon
  • vm.$set(vm.list,1,‘lemon’)与上面相似
  • vm.$set(vm.list,‘sex’,‘man’)往list中添加sex属性并赋值man

五. 组件

全局组件注册语法

Vue.component(组件名称,{
data:组件数据(data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。)
template:'  '组件模板内容,
methods:{  }......
})


Vue.component('button-counter',{
                data:function(){
                    return {
                        count:0
                    }
                },
                template:`<div>
                <button @click="count++">点击了{{count}}次</button>
                <button>测试</button>
                </div>`
            })

组件用法

直接引入组件的名称作为标签,每个都是相互独立的,互不干扰

  <div>
        <button-counter></button-counter>
        <button-counter></button-counter>
    </div>

组件注册注意事项

  • data必须是一个函数
  • 组件模板内容必须时单个跟元素(模板里面一个div套着所有的内容)
  • 组件模板内容可以时模板字符串
    组件命名
  • 驼峰命名(如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,但是在普通标签模板中,必须使用短横线的方式使用组件,因为html不识别大小写)
  • 横杠(‘button-counter’)(推荐使用)

局部组件注册

           <div id="#app">
                   <hello-world></hello-world>
           </div>
            
              //局部组件注册
            var helloworld = {
                data:function()
                {
                    return {
                        msg:'helloworld'
                    }
                },
                template:'<div>{{msg}}</div>'
            }
            // 局部组件只能在注册他的父组件中使用
            var vm = new Vue(
            {
                el:'#app',
                data:{
                },
                components:{
                    'hello-world':helloworld,、
                }
                
            })

组件间数据交互

父组件向子组件传值

  1. 组件内部通过pros接收传递过来的值
Vue.component('brother-com',
            {
                // 父组件传过来的属性
                props:['title'],
                data:function()
                {
                        return {
                            test:'子组件的内容'   
                        }
                },
                template:`
                <div>{{test + '---' +title}}</div>`
            })
  1. 父组件通过属性将值传递给子组件
 <!-- 静态绑定 -->
            <brother-com title='来自父组件的值'></brother-com>
            <!-- 动态属性绑定 -->
            <brother-com :title='pmsg'></brother-com>
// 父组件
var vm = new Vue({
                el:'#app',
                data:{
                    pmsg:'来自父组件的内容'
                }
            })
  1. props属性名规则
  • 在props中使用驼峰形式,模板中需要使用短横线形式
  • 字符串形式的模板中没有这个限制
    props属性值类型(string,Number,Boolean,array,Object)

子组件向父组件传递数据

和事件委托差不多,子组件的事件委托给父组件,子组件调用申明方法,父组件监听到,父组件执行父组件对应的方法。
props传递数据原则:单向数据流(虽然可以直接改变props的属性值来修改父组件的

  1. 子组件通过自定义事件向父组件传递信息
Vue.component('brother-com',
            {
                props:['title','pnum','pmsgb','parr','pobj'],
                template:
                `
                <div>
                // 子组件模板通过$emit('事件名')定义事件
                    <button @click="$emit('change-fa',100)">点击改变字体大小</button>
                </div>
                `
            })
  1. 父组件监听子组件的事件\

事件对象参数 event 的处理。不加括号时,函数第一个参数为 event,加了括号后,需要手动传入 $event 才能获得事件对象。

<div id="app">
                <brother-com   @change-fa='handle($event)'  ></brother-com>
            </div
            
            // 父组件处理数据
            var vm = new Vue({
                el:'#app',
                data:{
                },
                methods:{
                    handle:function(val)
                    {
                        this.size +=val;
                    }
                }
            })
            

非父子组件间的传值

  1. 单独的事件中心管理组件间的通信 (单独new一个vue对象作为事件中心)
var  eventHub = new Vue()
  1. 设置监听事件($on)
 //2. 监听事件,可以提供给兄弟组件调用,可以自己用
                eHub.$on('tomFn', (val) => {
                    this.num++
                })
  1. 调用兄弟事件
// 调用兄弟组件的方法
                eHub.$emit('jerryFn',1)
  1. 销毁事件
// 销毁jerryfn
                    eHub.$off('jerryFn')
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id='app'>
			<div>父组件</div>
			<div>
				<button @click="handle">销毁</button>
			</div>
			<test-jerry></test-jerry>
			<test-tom></test-tom>
		</div>
		<script src="vue.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			//提供事件中心
			var hub = new Vue();
			Vue.component('test-tom',{
				data:function(){
					return {
						num:0
					}
				},
				template:`
				<div>
					<div>TOM:{{num}}</div>
					<div>
						<button @click='handle'>点击</button>
					</div>
				</div>
				`,
				methods:{
					handle:function()
					{
						//触发兄弟事件
						hub.$emit('jerry-event',2);
						
					}
				},
				mounted:function(){
					//监听事件,开启tom事件,可以提供给兄弟触发
					hub.$on('tom-event',(val)=>{
						this.num+=val;
					});
					
				}
			})
			Vue.component('test-jerry',{
				data:function(){
					return {
						num:0
					}
				},
				template:`
				<div>
					<div>jery:{{num}}</div>
					<div>
						<button @click='handle'>点击</button>
					</div>
				</div>
				`,
				methods:{
					handle:function()
					{
						//触发兄弟组件的事件
						hub.$emit('tom-event',1);
					}
				},
				mounted:function(){
					//监听事件,开启jerry的事件
					hub.$on('jerry-event',(val)=>{
						this.num+=val;	
					});
					
				}
			})
			var vm = new Vue({
				el:'#app',
				data:{
					
				},
				methods:{
					handle:function()
					{
						//销毁tom事件,这样兄弟jerry无法继续开始点击事件了
						hub.$off('tom-event')
					}
				}
			})
		</script>
	</body>
</html>

组件插槽的作用

父组件向子组件传递内容

<test>{{err}}</test> //err的值为slot的内容

Vue.component('test',{
                template:`
                <div>
                    <strong>ERROR:</strong>
                    // 子组件中放置slot作为插槽,父组件的内容在这里展示
                    <slot></slot>
                </div>
                
                `
            })

具名插槽

// 具名插槽的两种使用
<test>
// 有name的就对应name的位置地方
    <p slot='foot'></p>
    <p><p>
</test>

<test>
    <template slot = 'foot'>
        <p></p>
        <p><p>
    </template>

</test>
Vue.component('test',{
                template:`
                <div>
                    <strong>ERROR:</strong>
                    // 子组件中放置slot作为插槽,父组件的内容在这里展示
                    <slot></slot>
                    <slot name='foot'></slot>
                </div>
                
                `
            })

六前后端交互模式

接口调用方式

  • 原生ajax
  • 基于jQuery的ajax
  • fetch
  • axios

Promise用法

异步调用

  • 异步效果分析
    • 定时任务
    • ajax
    • 事件函数
  • 多种异步调用的依赖分析
    • 多次异步调用的结果顺序不确定
    • 异步调用结果如果存在依赖需要嵌套

Promise概述

Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。
使用promise的好处

  • 可以避免多层异步调用嵌套问题(回调地狱)
  • Promise对象提供简洁的API,使得控制异步操作更加容易

Promise基本用法

  • 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
  • resolve和reject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果
// 成功是调用resolve,失败时调用reject
            var p = new Promise(function(resolve,reject)
            {
                //这里用于实现异步任务
                setTimeout(function(){
                    var flag=false;
                    if(flag)
                    {
                        //正常情况
                        resolve('hello');
                    }
                    else
                    {
                        //异常情况
                        reject('出错了');
                    }
                },100);
            })
            p.then(function(data){//接收正常情况
                console.log(data)
            },function(info){//接收错误情况
                console.log(info)
            })

基于Promise处理ajax请求

function queryData(url)
            {
                 return new Promise(function(resolve,reject){
                    var xhr = new XMLHttpRequest();
                    xhr.onreadystatechange = function(){
                        if(xhr.readyState!=4)return;
                        //==4表示接收结果完毕,status==200表示处理的结果是正确的
                        if(xhr.readyState==4&&xhr.status==200)
                        {
                            //处理正常的情况
                            resolve(xhr.responseText);
                        }
                        else{
                            reject('服务器错误')
                        }
                    };
                    xhr.open('get',url);
                    xhr.send(null);
                });
            }

发送ajax请求

queryData('http://rap2api.taobao.org/app/mock/251796/crms/crmsAdmin/getUnList')
            .then(function(data){
                console.log(data);
                return queryData('http://rap2.taobao.org:38080/repository/get?id=:repositoryId')
                //直接返回了一个新的Promise对象
            })
            //这个data得到上一个异步的结果
            .then(function(data){
                return new Promise(function(resolve,reject)
                {
                    setTimeout(function(){
                        resolve(123);
                    },1000)
                })
            })
            //同理这个data得到上一个异步的结果,返回123
            .then(function(data){
                return 'hello'//返回了普通值,这个then会自动产生一个默认的promise对象,保证下一个then采取链式操作
            })
            .then(function(data){
                console.log(data) //hello
            })

then参数中的函数返回值

  1. 返回Promise实例对象
  • 返回的该实例对象会调用下一个then
  1. 返回普通值
  • 返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值

Promise常用的API

  1. 实例方法
  • p.then()得到异步任务的正确结果
  • p.catch()获取异常信息
  • p.finally()无论成功与否都会执行
  1. 对象方法
  • Promise.all()并发处理多个异步任务,所有任务都会执行完成才能得到结果
  • Promise.race()并发处理多个异步任务,只要有一个任务完成就能得到结果
         var a=querydata('http://rap2.taobao.org:38080/app/mock/241938/mock/19/api/admin/greenhouse/list/:id')
         var b=querydata('http://rap2.taobao.org:38080/app/mock/241938/mock/19/api/admin/greenhouse/list/:id')
         var c=querydata('http://rap2.taobao.org:38080/app/mock/241938/mock/19/api/admin/greenhouse/list/:id')
        // 得到一个数组
        // Promise.all([a,b,c]).then(function(data){
        //  console.log(data)
        // })
        //只打印最先返回的结果,但是其他异步的结果也在进行
        Promise.race([a,b,c]).then(function(data){
            console.log(data)
        })

接口调用fetch用法

 // fetch api 基本用法
            fetch('http://rap2.taobao.org:38080/app/mock/241938/mock/19/api/admin/greenhouse/list/2')
            .then(function(data){
                //text()方法属于fetchapi的一部分,它返回一个promise实例对象,用于后台返回的数据,字符串,想获取值需要转换成json
                // return data.text();
                // 返回的是对象
                return data.json();// ==JSON.parse(data)
            })
            //此处才是获取最终数据
            .then(function(data){
            //text方式需要转化成对象才能访问属性
                // var obj = JSON.parse(data);
                // console.log(obj)
                //json方式可直接属性
                console.log(data)
            })

请求参数

  1. 常用配置选项
  • method(string) :HTTP请求方法,默认为GET
  • body(Stirng);HTTP的请求参数
  • headers(Object):请求头,默认为{}
fetch('url',
        {methods:'post',
        // body:JSON.stringify({uname:'lisi',age:12})
        body:'uname=list&pwd=123'),
        headers:{'xxx':xxx}})
            .then(function(data){
                return data.text()
            })
            .then(ret=>{
                console.log(ret)
            })

axios

aixos基本特性

  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 自动转换json数据

基本用法

            axios.get('url')
            .then(function(ret){
                //data属性使固定的用法
                console.log(ret.data)
            })

axios的参数传递

  1. get传递参数(与delete一样)
  • 通过URL传递参数
  • 通过params选项传递参数
//通过url传递参数
            axios.get('url?id=123')
            .then(function(ret){
                //data属性使固定的用法
                console.log(ret.data)
            })
            axios.get('url/123')
            .then(function(ret){
                //data属性使固定的用法
                console.log(ret.data)
            })
            
            
            // 通过params
            axios.get('/adata',{
            params:{
                id:123,
                name:'ljx'
                }
            }).then(ret=>{
                console.log(ret.data)
            })

2.post参数传递(put类似)

  • 通过选项传递参数(默认传递的是json格式)
  • 通过URLSearchParams传递参数
        // 选项传递参数
            axios.post('/adata',{
             uname:'tom',
             pwd:123
            })
            .then(function(ret){
                console.log(ret.data)
            })
            
            var params = new URLSearchParams()
            params.append('uname','zhangsan')
            axios.post('/adata',params).then(ret=>{
                console.log(ret.data)
            })

axios响应结果

  • data:实际响应回来的数据
  • headers:响应头信息
  • status:响应状态码
  • statusText:响应状态信息

axios全局配置

axios.defaults.timeout = 3000 // 超时时间
axios.defaults.baseURL 默认地址
axios.defaults.headers[‘mytoken’] = ‘’ 设置请求头

拦截器

            //asios请求拦截器
            axios.interceptors.request.use(function(config){
                console.log(config.url)
                config.headers.mytoken='nihao'
                return cofig;
            },function(err){
                console.log(err)
            })
            //响应拦截器(设置好时调接口就能直接拿到data了,不再是数据对象)
            axios.interceptors.response.use(function(ret){
                //这里对返回的数据进行处理
                var data = res.data;
                return data;
            },function(err){
                console.log(err)
            })

async/await

基本用法

  • async/awai 是es7引入的新语法,可以更加方便进行异步操作
  • async关键字用于函数上(async函数的返回值是promise实例对象)
  • await关键字用于async函数当中(await可以得到异步的结果)

七路由

路由的基本概念与原理

  1. 后端路由
  • 概念:根据不同的用户URL请求,返回不同的内容
  • 本质:URL请求地址与服务器资源之间的对应关系
  1. spa(Single Page Application)
  • 后端渲染(存在性能问题)
  • Ajax前端渲染(前端渲染提高性能,但是不支持浏览器的前进后退操作)
  • Spa(Single Page Application)单页面应用程序:整个网站只有一个页面,内容的变化通过ajax局部更新实现,同时支持浏览器地址栏的前进和后退操作
  • SPA实现原理之一:基于URL地址的hash(hash的变化会导致浏览器记录访问历史的变化,但是hash的变化不会触发新的URL请求)
  • 在实现SPA过程中,最核心的技术就是前端路由
  1. 前端路由
  • 根据不同的用户事件,显示不同的页面的内容
  • 本质:用户事件与事件处理函数之间的对应关系

Vue Router

  • 支持hash模式或html5模式
  • 支持嵌套路由
  • 支持路由参数
  • 支持编程式路由
  • 支持命名路由

vue-router的基本使用

  1. 引入相关库
        <script src="./vue.js" type="text/javascript" charset="utf-8"></script>
        <script src="./vue-router.js" type="text/javascript" charset="utf-8"></script>
  1. 添加路由链接
            <!-- router-link是vue中提供的标签,默认会被渲染为a标签 -->
            <!-- to 属性默认会被渲染为href属性 -->
            <!-- to属性的值会被渲染为#开头的hash地址 -->
            <router-link to="/user">User</router-link>
            <router-link to="/register">Register</router-link>
  1. 添加路由填充位
            <!-- 路由占位符 -->
            <router-view></router-view>
  1. 定义路由组件
            const User = {
                template:'<h1>User组件</h1>'
            }
            const Register = {
                template:'<h1>Register组件</h1>'
            }
  1. 配置路由规则并创建路由实例
            //创建路由实例对象
            const router = new VueRouter({
                //所有路由规则
                routes:[
                    //需要被重定向的地址,redirect跳到新地址
                    {path:'/',redirect:'/register'},
                    {
                        path:'/user',component:User
                    },
                    {
                        path:'/register',component:Register
                    }
                ]
            })
  1. 把路由挂载到Vue跟实例中
            const vm = new Vue({
                el:'#app',
                data:{},
                //挂载路由实例对象
                router:router
            })

路由重定向

用户在访问地址A的时候,强制调转到地址c从而展示特定的组件页面

嵌套路由

  1. 嵌套路由功能分析
  • 点击父级路由链接显示模板内容
  • 模板内容又有子级路由链接
  • 点击子级路由链接显示子级模板内容
  1. 父级路由模板
  • 父级路由链接
  • 父组件路由填充位
            <router-link to="/user">User</router-link>
            <router-link to="/register">register</router-link>
            <router-view></router-view>
  1. 子路由模板
  • 子路由链接
  • 子路由
 const Register ={
                template:`
                <div><h1>register组件</h1>
                <hr/>
                <router-link to="/register/tab1">tab1</router-link>
                <router-link to="/register/tab2">tab2</router-link> 
                <router-view></router-view>
                </div>
                `,      
            }
  1. 嵌套路由配置
  • 父级路由通过children属性配置子级路由
                    {path:'/register',component:Register,
                    //通过children属性添加子路由
                    children:[
                        {path:'/register/tab1',component:Tab1},
                        {path:'/register/tab2',component:Tab2}]
                    }

动态路由匹配

动态路由匹配的基本用法(不太灵活)

            <router-link to="/user/1">User1</router-link>
            <router-link to="/user/2">User2</router-link>
            <router-link to="/user/3">User3</router-link>
            <router-link to="/register">register</router-link>
            <router-view></router-view>
            const User={
                //路由组件中通过$route.param 获取路由参数
                template:`<h1>User--用户id为:{{$route.params.id}}</h1>`   
            }
            //动态路径参数,以冒号开头
            routes:[{path:'/user/:id',component:User}]

路由组件传递参数

路由组件传递参数
$route与对应路由形成高度耦合,不够灵活,所以可以使用props将组件和路由解耦

  1. props值为布尔类型
    const router = new VueRouter({
        routes:[
        // 如果props设置为true,route.params将会被设置为组件属性
            {path:'user/:id',component:User,props:true}
        ]
    })
    const User = {
        props:['id'],// 使用props接收参数,例子中获取到的是id
        template:'<div>用户ID:{{id}}</div>' // 使用路由参数
    }

2.props的值为对象类型

const route = new VueRouter({
        routes:[
            // 如果props是一个对象,他会按原样设置成组件属性
            // 此时id只能通过$route.param来获取,props只有uname和age
            {path:'/user/:id',component:User,props:{uname:'lisi',age:12}}
        ]
    })
    const User = {
        props:['uname','age'],
        template:`<div>用户信息:{{uname,age}}`
    }

3.props的值为函数类型

const route = new VueRouter({
        routes:[
            // 如果props是一个函数,则这个函数接收route对象为自己的形参
            {path:'/user/:id',component:User,props:route=>({uname:'lisi',age:12,id:route.params.id})}
        ]
    }
        const User = {
            props:['uname','age','id'],
            template:`<div>用户信息:{{uname age id}}`
        }

命名路由

                <router-link :to="{name:'user',params:{id:2}}">User</router-link>
                const User = {
                    props:["id",'uname','age'],
                    template:`
                        <div>
                            <h1>User--用户id{{id}}姓名{{uname}}年龄{{age}}</h1>
                            <button @click='turn'>跳转到register</button>
                        </div>`,
                    methods:{
                        turn(){this.$router.push('/register')}
                    }
                }
                const Register = {
                        template:`
                        <div>
                        <h1>Register组件</h1>
                        <button @click='goback'>返回上一个页面</button>
                        </div>`,
                        methods:{
                            goback(){
                                this.$router.go(-1);
                            }
                        }
                    }
                
                routes:[
                    {
                        //命名路由
                        name:'user',
                        path:'/user/:id',
                        component:User,
                        props:route=>({name:'heihei',age:20,id:route.params.id})
                        
                    },

编程式导航

当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(…)。

声明式编程式
router.push(…)

编程式导航的基本用法

  • this.$router.push(‘hash地址’)
  • this.$router.go(n) 0刷新,1前进,-1后退

编程式导航的基本用法

this. r o u t e r . p u s h ( ′ h a s h 地 址 ′ ) t h i s . router.push('hash地址') this. router.push(hash)this.router.go(n) 0刷新,1前进,-1后退

// 字符串(路径名称)
router.push('/home')
// 对象
router.push({path:'/home'})
// 命名的路由(传递参数)
router.push({name:'/user',params:{userId:123}})
// 带查询参数 /user?userId=123
router.push({path:'/user',query:{userId:123}})

八模块化

模块化概述

传统开发的主要问题:

  • 命名冲突
  • 文件依赖
    通过模块化解决上述问题
  • 模块化就是把单独的一个功能封装到一个模块中,模块之间相互隔离,但是可以通过特定的接口公开内部成员,也可以依赖别的模块
  • 模块化的好处:方便代码的重用,从而提升开发效率,并且方便后期的维护

浏览器端的模块规范

  1. AMD
    require.js
  2. CMD
    sea.js
    落伍了,有更好的规范

服务器端模块化规范

  1. commonJS
  • 模块分为单文件模块与包
  • 模块成员导出:module.exports和exports
  • 模块成员导入:require(‘模块标识符’)

大一统的模块化规范-es6模块化

ES6模块化规范中定义

  • 每个js文件都是独立模块
  • 导入模块成员使用import关键字
  • 暴露模块成员使用export关键字
  1. Node.js中通过babel体验ES6模块化
    Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。下面列出的是 Babel 能为你做的事情:
  • 语法转换
  • 通过 Polyfill 方式在目标环境中添加缺失的特性 (通过 @babel/polyfill 模块)
  • 源码转换 (codemods)

安装下载

  • npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
  • npm install --save @babel/polyfill
  • 项目根目录创建文件 babel.config.js
  • babel.config.js文件内容如图
const  presets = [
    ["@babel/env",{
        targets:{
            edge:'17',
            firefox:'60',
            chrome:'67',
            safari:'11.1'
        }
    }]
]

module.exports = {presets}
  • 通过npx babel-node index.js执行代码

ES6模块化的基本语法

  1. 默认导出与默认导入
  • 默认导出语法 export defaulr 默认导出的成员
//默认导出
// 定义私有成员
let a = 10
let c = 20
function happy(){}
// 外界访问不到d,因为没有暴露出去

// 将本模块的私有成员暴露出去,供其他模块使用
export default{
    a,
    c,
    happy
}
  • 默认导入的语法 import 接收名称from’'模块表示符号 注意:每个模块中,只允许使用唯一的一次export default,否则报错
//导入模块成员 , 用m1接收
import m1 from './m1export.js'
console.log(m1)

2.按需导出与按需导入

  • 按需导出语法 export let s1=10
export let s1=10
export let s2=10
export function say = function(){}
  • 按需导入语法
import {s1,s2 }from './m1export.s'
//s1,s2必须要导入文件里有的

3.直接导入并执行模块代码 只想单纯执行某个模块中的代码,并不需要得到模块中向外暴露的成员时使用

//当前文件模块 m2.js
// 在当前模块中执行一个for循环操作
for(let i=0;i<3;i++){
    console.log(i)
}

// 其他文件导入
import './m2.js'

webpack

当前web开发面临的困境

  • 文件依赖关系错综复杂
  • 静态资源请求效率低
  • 模块化支持不友好
  • 浏览器对高级JavaScript特性兼容程度较低
  • 其他

webpack的基本使用

是一个前端项目构建工具(打包工具),提供友好的模块化支持,以及代码压缩混淆,处理js兼容问题,性能优化等

  1. 创建列表隔行变色项目
  • 新建项目空白目录,运行npm init -y命令,初始化包管理配置文件package.json
  • 新建src源代码目录
  • 新建src->index.html首页
  • 初始化首页基本结构
  • 运行npm install jquery -S 命令,安装jQuery
  • 通过模块化的形式,实现列表隔行变色的效果
  1. 在项目安装和配置webpack
  • 运行npm install webpack webpack-cli -D命令安装webpack相关包
  • 在项目根目录创建webpack.config.js的webpack配置文件
  • 在webpack的配置文件中,初始化一下基本配置
module.exports = {
    mode:'development' // mode用来指定构建模式,开发模式不会压缩代码
}
  • 在package.json配置文件中的script节点下,新增dev脚本如下:
"scripts":{
    "dev":"webpack" //script节点下的脚本,可以通过npm run dev运行
}

在终端运行npm run dev,启动webpack项目打包

3.配置打包的入口与出口
webpack 的默认约定:

  • 打包的入口文件为src ->index.js
  • 打包的输出文件为dist ->main.js
    如果需要修改打包的入口和出口,可以在webpack.config.js中新增如下的配置信息
const path = require('path')
module.exports = {
    mode : "development", // development production
    //__dirname 项目根路径+入口文件
    entry: path.join(__dirname,'./src/index.js'),
    output:{
        path:path.join(__dirname,'./dist'),// 输出文件的存放路径
        filename:'bundle.js' // 输出文件的名称
    }
}
  1. 配置webpack的自动打包功能
  • 运行npm install webpack-dev-server -D 命令,安装支持项目自动打包的工具
  • 修改package.json ->scripts中的dev命令如下:
"scripts":{
    "dev":"webpack-dev-server"//script节点下的脚本,可以通过npm run运行
}
  • 将src->index.html中,script脚本的引用路径,修改为"./bundle.js
  • 运行那个npm run dev命令,重新进行打包
  • 在浏览器中访问 http://localhost:8080地址,查看自动打包效果
    注意:
  • webpack-dev-server 会自动启动一个实时打包的http服务器
  • webpack-dev-server打包生成的输出文件,默认放到项目根目录中,而且是虚拟,看不到的
  1. 配置html-webpack-plugin生成预览页面
  • 运行npm install html-webpack-plugin -D 命令,安装生成预览页面的插件
  • 修改webpack.config.js文件头部区域,添加如下配置
// 导入生成预览页面的插件,得到一个构造函数
const HtmlWebpackPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlWebpackPlugin({
    template:'./src/index.html', // 指定用到的模板文件
    filename:'index.html' //指定生成的文件名称,存在内存中,目录上不显示
})
module.exports = {
    plugins:[htmlPlugin] //plugins数组是webpack打包期间会用到的一些插件列表
}
  • 修改webpack.config.js文件向外暴露的配置对象,新增配置节点
module.exports = {
    plugins:[htmlPlugin] //plugins数组是webpack打包期间会用到的一些插件列表
}
  1. 配置自动打包相关的参数
// package.json中配置
// --open 打包完成后自动打开浏览器页面
// --host 配置IP地址
// --port配置端口
"scripts":{
    "dev":"webpack-dev-server --open --host 127.0.0.1 --port 8888"
}

webpack中的加载器

  1. 通过loader打包非js模块 和node里的gulp差不多。
    在实际开发过程中,webpack默认只能打包处理以.js后缀名结尾的模块,其他非.js后缀名结尾的模块,webpack默认处理不了,需要调用loader加载器才可以正常打包
    loader加载器可以协助webpack打包处理待定的文件模块,如
  • less-loader可以打包处理 .less相关文件
  • sass-loader 可以打包处理.scss相关的文件
  • url-loader处理css中url路径相关的文件

webpack中的加载器的基本使用

  1. 打包处理css文件
  • 运行npm i style-loader css-loader -D 命令,安装处理css文件的loader
  • 在webpack.config.js中module->rules数组中,添加loader规则如下
// 所有第三方文件模块匹配规则
    module: {
        rules: [{
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
            //test表示匹配类型的文件,use表示调用的loader
            //注意:
            //use的顺序是固定的,必须先style-loader,再css-loader
            // 多个loader的调用顺序是从后往前调用
        ]
    }
  1. 打包处理less文件
  • 运行npm i less-loader less -D命令
  • 在webpack.config.js中module->rules数组中,添加loader规则如下
// 所有第三方文件模块匹配规则
    module: {
        rules: [{
                test: /\.less$/,
                use: ['style-loader', 'css-loader','less-loader']
            }
            //test表示匹配类型的文件,use表示调用的loader
            //注意:
            //use的顺序是固定的,必须先style-loader,再css-loader
            // 多个loader的调用顺序是从后往前调用
        ]
    }
  1. 打包处理scss文件
  • 运行npm i scss-loader node-sass -D命令
  • 在webpack.config.js中module->rules数组中,添加loader规则如下
// 所有第三方文件模块匹配规则
    module: {
        rules: [{
                test: /\.scss$/,
                use: ['style-loader', 'css-loader','scss-loader']
            }
        ]
    }
  1. 配置postCSS自动添加css兼容前缀
  • npm i postcss-loader autoprefixer -D
  • 在项目根目录创建postcss的配置文件 postcss.config.js
const autoprefixer = require("autoprefixer")
module.exports = {
    plugins:[autoprefixer]
}
  • 在webpack.config.js 的module->rules数组中,修改css的loader规则
// 所有第三方文件模块匹配规则
    module: {
        rules: [{
                test: /\.css$/,
                use: ['style-loader', 'css-loader','postcss-loader']
            }
        ]
    }
  1. 打包样式表中的图片和字体文件
  • 运行 npm i url-loader file-loader -D 命令
  • 在webpack.config.js的module->rules数组中,添加loader规则如下
    module: {
        rules: [{
                test: /\.jpg|png|git|bmp|ttf|eot|svg|woff|woff2$/,
                use: 'url-loader?limit=16940'
                // ?之后的是loader的参数项
                // limit用来指定图片的大小,单位是字节(byte),只有小于limit大小的图片才会杯转为base64图片,转成base64图片加载快点
            }
        ]
    }

  1. 打包处理js中高级语法 如class
  • 安装babel转换器相关的包 npm i babel-loader @babel/core @babel/runtime -D
  • 安装babel语法插件相关的包 npm i @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
  • 项目根目录,创建babel.config.js 并初始化配置
module.exports={
    presets:['@babel/preset-env'],
    plugins:['@babel/plugin-transform-runtime','@babel/plugin-proposal-class-properties']
}
  • 在webpack.config.js的module->rules数组中,添加loader规则
// exclude 为排除项,表示babel-loader不需要处理node_modules中的js文件
{
    test:/.js$/,use:'babel-loader',exclude:/node_modules|jquery-3.5.1.min.js/
    
}

Vue 单文件组件

一个vue单文件组件中,包含template,script,style。

webpack中配置vue组件的加载器

  • 运行npm i vue-loader vue-template-compiler -D
  • 在webpack.config.js配置文件中,添加vue-loader的配置项如下
const VueLoaderPlugin = requir('vue-loader/lib/plugin')
module.exports = {
    module:{
        rules:[
            //...其他规则
            {test: /\.vue$/,loader:'vue-loader'}
        ]
    },
    plugins:[
        // 其他插件
        new VueLoaderPlugin()
    ]
}

webpack项目中使用vue

  • 运行npm i vue -S 安装vue
  • 在src-index.js入口文件中,通过import Vue from 'vue’来导入vue构造函数
  • 创建vue的实例对象,并指定要控制的el区域
  • 通过render函数渲染App跟组件
//1. 导入vue构造函数
import Vue from 'vue'
//2 导入App跟组件
import App from './components/App.vue'

const Vm = new Vue({
    // 3. 指定vm实例要控制的页面区域
    el:'#app'
    // 通过render函数,吧指定的组件渲染导el区域中
    render: h=>h(App)
})

webpack打包发布

通过package.json 文件配置打包命令:

// 在package.json 文件中配置webpack打包命令
// 该命令默认加载项目根目录中的webpack.config.js配置文件
"scripts":{
    //用于打包的命令
    "build":"webpack -p",
    // 用于开发调试的命令
    "dev":"webpack-dev-server --open --host --127.0.0.1 --port 3000"
    
}

运行 npm run build 进行打包,生成了dist文件

脚手架

Vue脚手架的基本用法

快速生成Vue项目基础架构 官网:https://cli.vuejs.org/zh/

使用步骤

  1. 安装3.x版本的脚手架
    npm install -g @vue/cli

基于3.x版本的脚手架创建vue项目

// 命令行运行
//1. 基于交互式命令行的方式,创建新版vue项目
vue create my-project
//2. 基于图形化界面的方式,创建新版vue项目
vue ui
//3 基于2.x的旧模板,创建旧版vue项目
npm install -g @vue/cli-init
vue init webpack my-project

方法1:交互式命令方式

  1. vue create my-project
    出现选中预设, 包含以前保存的,默认的和手动选择

在这里插入图片描述

  1. 手动选择后,空格选择需要选定的预设

在这里插入图片描述

3.输入n 使用v-router hash模式 (浏览器会出现#的符号),history没有

在这里插入图片描述

  1. 选择eslint模式(标准模式即可)

在这里插入图片描述

  1. 选择文件放置在哪(放单独文件中,以免package.json内容被弄乱)

在这里插入图片描述

进入项目目录,使用npm run serve启动项目

9.4.2脚手架自定义配置

  1. 通过packagejson配置项目
  // 必须是符合规范的json语法
  "vue":{
    "devServer":{
      "port":8888,
      "open":true
    }
  }

注意:不推荐使用这种配置方式。因为package.json主要用来管理包的配置信息;为了方便维护,
推荐将vue脚手架相关的配置,d单独定义到vue.config.js配置文件中

  1. 通过单独的配置文件配置项目
  • 在项目的根目录创建文件vue.config.js
  • 在该文件中进行相关配置,从而覆盖默认配置
// vue.config.js
module.exports = {
    devServer:{
        port:8888
    }
}

9.5 Element-ui 的基本使用

  1. 基于命令行方式手动安装
    安装依赖包 npm i element-ui -S
    main.js中导入Element-UI相关资源
// 导入组件库
import Element from 'element-ui'
// 导入组件相关样式
import 'element-ui/lib/them-chalk/index.css'
// 配置Vue插件
Vue.use(ElementUI)
  1. 基于图形化界面自动安装
  • 运行 vue ui命令,打开图形化界面
  • 通过vue项目管理器,进入项目配置面板
  • 点击插件-添加插件
  • 搜索vue-cli-plugin-elment 并安装
  • 配置插件,实现按需导入,从而减少打包后项目体积
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值