IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue基础(未完) -> 正文阅读

[JavaScript知识库]Vue基础(未完)

1、初识Vuejs

1.1、为什么学习Vuejs?

  • 可能你的公司正要用Vue将原项目重构
  • 可能你的公司新项目决定使用Vue技术栈
  • 可能你正在找工作,会发现十个前端八个对Vue有或多或少的要求
  • 当然,最重要的是Vue非常火,很流行

1.2、简单认识Vuejs

  • Vue(读音/vju:/ ,类似于view)
  • Vue是一个渐进式框架
    • 渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验
    • 或者如果你希望更多的业务逻辑使用Vue实现,那么Vue的核心库及其生态系统;
    • 比如Core + Vue-router + Vuex,也可以满足你各种各样的需求;
  • Vue有很多特点和Web开发中常见的高级功能
    • 解耦视图和数据
    • 可服用的组件
    • 前端路由技术
    • 状态管理
    • 虚拟DOM

1.3、Vuejs的安装

CDN引入

  1. 开发环境(包好了有帮助的命令行警告)
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
  2. 生产环境,优化了尺寸和速度
    <script  src="https://cdn.jsdelivr.net/npm/vue"></script>
    

下载和引入

开发环境:https://vuejs.org/js/vue.js
生产环境:https://vuejs.org/js/vue.min.js

npm安装管理

1.4、Vuejs初体验

之前范式:命令式编程
如今范式:声明式编程

Hello Vuejs

<body>
<div id="app">
    {{message}}
</div>
</body>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",      //用于挂载要管理的元素
        data: {          //定义数据
            message: 'hello, vue'
        }
    });
</script>

在这里插入图片描述

Vue列表展示

<body>
<div id="app">
    <ul>
        <li v-for="item in movies">{{item}}</li>
    </ul>
</div>
</body>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",      //用于挂载要管理的元素
        data: {          //定义数据
            movies: ['星际穿越', '大话西游', '少年派', '盗梦空间']
        }
    });
</script>

在这里插入图片描述

案例:计数器(v-on事件监听)

<body>
<div id="app">
    <h2>当前计数:{{counter}}</h2>
    <!--@可替代v-on:--><!--方法若无参数,()可省略,若存在参数,vue会默认第一个为event事件对象, 以$event形式传入event-->
    <button v-on:click="increament()">+</button>
    <button v-on:click="subtraction($event)">-</button>
</div>
</body>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",      //用于挂载要管理的元素
        data: {          //定义数据
            counter: 0
        },
        methods: {
            increament: function (){
                this.counter++;
            },
            subtraction: function (){
                this.counter--;
            }
        }
    });
</script>

在这里插入图片描述

2、MVVM

2.1、MVVM

View层

  • 视图层
  • 在前端开发中,通常指DOM
  • 主要用来给用户展示信息

Model层

  • 数据层
  • 可能是固定的死数据,更多是来自服务器、网络上的数据

ViewModel

  • 视图模型层
  • View与Model层沟通的桥梁
  • 实现了Data Binding(数据绑定),将Model的改变实时反映到View中
  • 实现了DOM Listener(DOM监听),当监听到DOM发生某种事件时,改变对应的Data

2.2、Vue中的MVVM

在这里插入图片描述

2.3、Vue的生命周期

在这里插入图片描述
在这里插入图片描述

3、插值操作

3.1、Mustache语法:{{}}

<div id="app">
  <!--Mustache语法中不仅可以显示变量,还能写一些表达式-->
  <h2>{{message}}, {{firstName + ' ' + lastName}}</h2>
  <h2>{{counter* 2}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      message: 'Hello',
      firstName: 'kobe',
      lastName: 'bryant',
      counter: 100
    }
  });
</script>

在这里插入图片描述

3.2、v-once

被v-once修饰的变量,一旦赋值无法更改

<div id="app">
  <h2 v-once>{{counter}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      counter: 100
    }
  });
</script>

在这里插入图片描述

3.3、v-html

将字符串形式的html代码添加到dom中

<div id="app">
  <h2 v-html="url"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      url: '<a href="http://www.baidu.com">百度</a>'
    }
  });
</script>

在这里插入图片描述

3.4、v-pre

页面会原封不动的展示标签中的内容

<div id="app">
  <h2 v-pre>{{url}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      url: '<a href="http://www.baidu.com">百度</a>'
    }
  });
</script>

在这里插入图片描述

3.5、v-cloak

当你的js解析html时产生了停顿,就将显示出未渲染的半成品页面,v-cloak属性在渲染之后会自动删除,可以与display:none结合使用解决这个问题

<style>
  [v-cloak]{
    display: none;
  }
</style>

<div id="app" >
  <h2 v-cloak>{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
  setTimeout(function (){
    const app = new Vue({
      el: "#app",      //用于挂载要管理的元素
      data: {          //定义数据
        message: '你好'
      }
    });
  }, 2000)
</script>

在这里插入图片描述
在这里插入图片描述

3.6、v-if / v-else-if / v-else

<div id="app">
  <h1 v-if="isShow == true">true</h1>
  <h1 v-else>false</h1>
</div>

true

false

3.7、v-show

控制元素是否显示
v-show 与 v-if 的区别

v-showfalse时,只是加了一个display : none的样式
v-iffalse时,元素不会被渲染到页面,直接从dom清除
简单来说前者操作样式,而后者操作dom
当切换频率时,使用v-show
频率较v-if更佳

3.8、v-for

<div id="app">
  <!--遍历数组 格式: value |(value, index)-->
  <ul>
    <li v-for="(movie, i) in movies">{{movie}}----{{i}}</li>
  </ul>
  <!--遍历对象 格式:value |(value, key)|(value, key, index)-->
  <ul>
    <li v-for="(value, key) in person">{{value}}----{{key}}</li>
  </ul>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      movies: ['海贼王', '火影忍者', '名侦探柯南'],
      person: {
        id: 8,
        name: '柯南',
        profession: 'detective'
      }
    }
  });
</script>

在这里插入图片描述

4、v-bind(:)

4.1、动态绑定属性

<div id="app">
  <img v-bind:src="imageURL" alt="">
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      imageURL: 'https://img11.360buyimg.com/seckillcms/s280x280_jfs/t1/197347/6/13295/199552/61696bf5E162a9a54/23d76b487b81fe05.jpg.webp'
    }
  });
</script>

在这里插入图片描述

4.2、动态绑定样式

<style>
  .red{
    color: red;
  }
  .green{
    color: green;
  }
</style>

<div id="app">
  <!--class可与:class共存,解析时会被放到一起-->
  <h1 class="title":class="getClasses()">你好啊</h1>
  <button @click = "red">红色</button>
  <button @click = "green">绿色</button>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      isGreen: false,
      isRed: false
    },
    methods: {
      red: function (){
        this.isRed = !this.isRed;
      },
      green: function (){
        this.isGreen = !this.isGreen;
      },
      getClasses: function (){
        return {red: this.isRed, green: this.isGreen};
      }
    }
  });
</script>

在这里插入图片描述

4.3、作业

需求
鼠标移到上边字体变红,移出恢复

<style>
  .red {
    color: red;
  }
</style>

<div id="app">
  <ul>
    <li v-for="(m, index) in movies" @mouseover="i = index" @mouseleave="i = -1" :class="getClasses(index)">{{m}}</li>
  </ul>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      movies: ['海贼王', '火影忍者', '名侦探柯南', '蜡笔小新'],
      i: -1
    },
    methods: {
      getClasses: function (i) {
        if(i == this.i){
          return {red: true};
        }
      }
    }
  });
</script>

4.4、对象语法和数组语法

<ul>
  <!--对象语法-->
  <li :style="{fontSize: '50px', color: 'red'}">{{message}}</li>
  <!--数组语法-->
  <li :style="[{fontSize: '60px'},{color: 'red'}]">{{message}}</li>
</ul>

4.5、计算属性(computed)

computed: {
  fullname: {  //计算方法一般不设置set方法,只读属性
    set: function (newValue) {},
    get: function () {
      return this.firstName + ' ' + this.lastName;
    }
  },
  full: function () {  //简写
    return this.firstName + ' ' + this.lastName;
  }
}

methods与computed区别:

计算属性存在缓存,return值未发生改变时只会调用一次

5、修饰符

5.1、stop

阻止其他跟随事件, 也不会跟随其他事件

<div id="app">
  <div @click = 'divClick' style="background-color: red">
    我是盒子
    <button @click.stop = 'btnClick'>我是按钮</button>
  </div>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    methods: {
      btnClick(){
        console.log('按钮被点了!!!!!!!!')
      },
      divClick(){
        console.log('盒子被点了');
      }
    }
  });
</script>

5.2、prevent

推迟事件的发生

<div id="app">
  <form action="http://www.baidu.com">
    <input type="submit" value="提交" @click.prevent="submitClick">
  </form>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    methods: {
      submitClick(){
        console.log('提交被推迟');
      }
    }
  });
</script>

5.3、enter

监听enter键

<div id="app">
  <for m action="http://www.baidu.com">
    <!--监听键盘抬起的动作-->
    <input type="text" @keyup="enter">

    <!--监听回车-->
    <input type="text" @keyup.enter="enter">
  </form>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    methods: {
      enter(){
        console.log('回车');
      }
    }
  });
</script>

5.4、once

被修饰元素只有第一次会被渲染

5.5、native

用于本地组件生效

5.6、数组中的响应式

并不是所有改变数组的方式都能做到响应式
只有返回新数组才会发生响应,而仅仅是通过下标改变原数组的值是不能做到响应式的

5.7、JavaScript中的高级函数

filter

fileter是数组的一个高阶函数,参数是一个回调函数;也就是说,他会根据数组的长度来决定回调的次数,返回值是bool值;

当为true时,会将当前元素放入一个新数组,全部执行完成会将新数组返回;
当为false,不做任何操作

const nums = [11,1,111,1111];
let newArry = nums.filter(function (n){
  return n < 100;    // 得到所有小于100的元素
});
console.log(newArry);	// 打印:[11, 1]

map

参数也是回调函数,迭代每个元素,执行某种操作后返回

const nums = [11, 1, 111, 1111];
let newArry = nums.map(function (n) {
  return n * 2;    // 将数组中元素*2
});
console.log(newArry);	//打印:[22, 2, 222, 2222]

reduce

对数组中的元素进行汇总

  • reduce函数参数有两个
    • 一为回调函数,其中参数(preValue,n)
      • preValue:上一次回调函数的返回值
      • n:当前下标的元素
    • 二为preValue的初始值
  • 回调次数为数组长度,当循环完毕返回回调函数的最终值
    所有元素相加之和:
const nums = [11, 1, 111, 1111];
let sum = nums.reduce(function (preValue, n) {
  return preValue + n;    // 计算总和
}, 0);
console.log(sum); // 打印:1234

三者结合

常规做法

const nums = [11, 1, 111, 1111];
let sum = nums.filter(function (n) {
  return n < 100;    // 计算总和
}).map(function (n){
  return n * 2;
}).reduce(function (preValue, n) {
  return preValue + n;
}, 0);
console.log(sum);		//打印:24

简洁做法

const nums = [11, 1, 111, 1111];
let sum = nums.filter(n => n < 100)
              .map(n => n * 2)
              .reduce((pre, n) => pre + n);
console.log(sum);		// 打印:24

6、v-model

  • 表单绑定
  • 表单控件在实际开发中很常见,特别是对于用户信息的提交,需要大量表单
  • Vue中使用v-model来实现表单元素和数据的双向绑定

6.1、input和data的双向绑定

<div id="app">
  <input type="text" v-model="message"/>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      message: '哈哈哈'
    }
  });
</script>

在这里插入图片描述
v-model其实是个语法糖,他的背后本质包含两个操作:

  1. v-bind绑定属性value
  2. v-on执行给当前元素绑定input事件

6.2、radio和data的双向绑定

<div id="app">
  <input type="radio" value="" name="sex" v-model="sex"/><input type="radio" value="" name="sex" v-model="sex"/><h1>您选择的性别是:{{sex}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      sex: '男'
    }
  });
</script>

在这里插入图片描述

6.3、checkbox和data的双向绑定

单个单选框

<div id="app">
  <input type="checkbox" v-model="isAgree"/> 同意协议
  <button :disabled="!isAgree">下一步</button>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      isAgree: false
    }
  });
</script>

在这里插入图片描述
关于多选框true和false的问题
多个多选框

<div id="app">
  <!--多选框-->
  <input type="checkbox" value="" v-model="hobbies"/><input type="checkbox" value="" v-model="hobbies"/><input type="checkbox" value="rap" v-model="hobbies"/> rap
  <input type="checkbox" value="篮球" v-model="hobbies"/> 篮球
  <h1>您的爱好是:{{hobbies}}</h1>

</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      hobbies: []
    }
  });
</script>

在这里插入图片描述

6.4、select和data的双向绑定

选择单个

<div id="app">
  <select v-model="option">
    <option type="checkbox" value=""></option>
    <option type="checkbox" value=""></option>
    <option type="checkbox" value="rap"> rap</option>
    <option type="checkbox" value="篮球"> 篮球</option>

  </select>
  <h1>您的爱好是:{{option}}</h1>

</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      option: 'rap'
    }
  });
</script>

在这里插入图片描述
选择多个

<div id="app">
  <select v-model="option" multiple>
    <option type="checkbox" value=""></option>
    <option type="checkbox" value=""></option>
    <option type="checkbox" value="rap"> rap</option>
    <option type="checkbox" value="篮球"> 篮球</option>

  </select>
  <h1>您的爱好是:{{option}}</h1>

</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      option: []
    }
  });
</script>

在这里插入图片描述

6.5、修饰符

lazy

有时我们更改输入框的数据不想让它实时更新,这时我们就可以使用lazy修饰符,它只有在元素回车失去焦点才会更新
v-model.lazy

number

<div id="app">
  <input v-model.number="message" type="text">
  {{message}}
  {{typeof(message)}}
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      message: 0
    }
  });
</script>
  • 若输入为number类型,会自动转换
    在这里插入图片描述

  • 若开始为字符串,无论后面是什么类型,都为字符串
    在这里插入图片描述

  • 若开始为number,后面为字符串,会自动忽略后面的所有类型
    在这里插入图片描述

trim

去除首尾空格
在这里插入图片描述

7、组件化

  • 人面对复杂问题的处理方式:
    • 任何一个人处理信息的逻辑能力都是有限的
    • 所以,当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆的内容。
    • 但是,我们人有一种天生的能力,就是将问题进行拆解。
    • 如果将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在整体当中,你会发现大的问题也会迎刃而解。
  • 组件化也是类似的思想:
    • 如果我们将一个页面中所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展。
    • 但如果,我们将一个页面拆分成一个个小的功能块
    • 每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易了。

7.1、组件的使用(全局与局部)

  1. 创建
    调用Vue.extend()方法创建组件构造器
  2. 注册
    调用Vue.component()方法注册组件
  3. 使用
    在Vue作用范围内使用组件
<div id="app">
  <smile></smile>
</div>
<script src="../js/vue.js"></script>
<script>
  //创建组件构造器对象
  const myComp = Vue.extend({
    template: "<div>\n" +
      "          <h1>哈</h1>\n" +
      "          <h2>呵呵</h2>\n" +
      "          <h3>嘿嘿嘿</h3>\n" +
      "        </div>"
  });
  //注册组件(全局)
  //smile为组件的标签名
  Vue.component('smile', myComp);

  const app = new Vue({
    el: "#app",
    components: {
		// 局部
		cpn: smile	//cpn为组件的标签名
	}
  });
</script>

在这里插入图片描述
Vue.extend()

  • 调用Vue.extend()创建的是一个组件构造器。
  • 通常在创建组件构造器时,传入template代表我们自定义组件的模板。
  • 该模板就是在使用到组件的地方,要显示的HTML代码。
  • 事实上,这种写法在Vue2g的文档中几乎已经看不到了,它会直接使用下面我们会讲到的语法糖,但是在很多资料还是会提到这种方式,而且这种方式是学习后面方式的基础。

Vue.component

  • 调用Vue.component0是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。
  • 所以需要传递两个参数:
    1. 注册组件的标签名
    2. 组件构造器

7.2、组件的使用(语法糖)

==Vue提供了一个语法糖,省去了手动调用extend的步骤,直接在注册时传入对象,component方法会在底层帮你调用。

<div id="app">
  <uncst></uncst>
  <cst></cst>
</div>
<script src="../js/vue.js"></script>
<script>
  //全局
  Vue.component('cst', {
    template: `<div>
    				<h1>哈</h1>
    				<h2>全局</h2>
    				<h3>嘿嘿嘿</h3>
    			</div>`
  });

  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    components: {
      'uncst': {
        template: `<div>
    				<h1>哈</h1>
    				<h2>全局</h2>
    				<h3>嘿嘿嘿</h3>
    			</div>`
      }
    }
  });
</script>

7.3、父子组件

const myCompSon = Vue.extend({
  template: `<div>
    				<h1>哈</h1>
    				<h2>全局</h2>
    				<h3>嘿嘿嘿</h3>
    		 </div>`
});

const myCompFather = Vue.extend({
  template: `<div>
    				<h1>哈</h1>
    				<h2>全局</h2>
    				<h3>嘿嘿嘿</h3>
    			</div>`,
  components: {
    cpn2: myCompSon
  }
});

7.4、模板html分离

第一种:template标签

<template id="cpn1">
  <h1>第一种模板</h1>
</template>
<script>
  Vue.component('cpn1', {
    template: '#cpn1'
  })
</script>

第二种:script标签

<script type="text/x-template" id="cpn2">
  <div>
    <h1>第二种模板</h1>
  </div>
</script>
<script>
  Vue.component('cpn2', {
    template: '#cpn2'
  })
</script>

7.5、组件中的数据

  • 组件不能直接访问实例中的数据
  • 可以在组件中添加自己的data属性
  • 必须定义为一个函数,且返回一个对象
  • 对象中保存着数据
Vue.component('cpn', {
  data: function () {
    return {
      title: '我是标题'
    }
  },
  template: `
    <div>
      <h1>{{title}}</h1>
    </div>
  `
});
  • 为什么Vue要将data设计成一个函数并return呢?

因为当页面中使用了多个相同组件时,如果不是函数,data数据就会共享,产生不必要的bug,而使用函数,每次调用都能返回一个新的对象,能够很好的隔离各个组件,因此被设计成函数。

7.6、父子间的通信

父传子:props属性
子传父:emit事件
在这里插入图片描述

父传子

  • 方式一:字符串数组,数组中的字符串就是传递时的名称
  • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等

注:若想在props中使用驼峰命名法,子标签的v-bind绑定的属性必须用’-‘分割
比如:

props:cMessage
v:bind:c-message = ‘message’
v-bind作用是使父组件变量名生效,当然你也可以选择不用,直接将值放进去,虽效率不高,然易于理解

<div id="app">
  <!--父传子-->
  <cpn :cmovies="movies" :cmessage="messages"></cpn>
</div>
<script src="../js/vue.js"></script>
<!--创建模板-->
<script type="text/x-template" id="cpn_tpe">
  <div>
    <h1>{{cmessage}}</h1>
    <h1>{{cmovies}}</h1>
  </div>
</script>
<script>
  // 创建组件
  const cpn = {
    template: '#cpn_tpe',  //引用模板
    // props: ['cmovies', 'cmessage'],   //父 传 子 (数组法)
    props: {                             //父 传 子 (对象法)
      // cmovies: Array,                 //类型限制
      // cmessage: String
      cmovies: {                         //类型限制和默认值
        type: Array,
        //2.5.3以上会报错,当值为对象或数组,必须传入函数
        // default: [],
        default(){
          return []
        },
        required: true                    //required值为true,使用组件必须传值,否则报错
      },
      cmessage: {
        type: String,
        default: '默认值'
      }
    }
  }

  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      messages: '雷猴啊',
      movies: ['海王', '海贼王', '海尔兄弟', '海绵宝宝']
    },
    components: {
      cpn //注册组件,es6的增强写法
    }
  });
</script>

子传父

<div id="app">
  <!--3. 检测到item_click被调用,调用父类方法cpn_click-->
  <son @item_click="cpn_click"></son> <!--v-on监听事件若无参数,浏览器默认传递event; 但这里是我们自定义的事件,默认传递我们传递的参数item-->
</div>
<script src="../js/vue.js"></script>
<script type="text/x-template" id="sontemplate">
 <div>
  <button type="button" v-for="(item) in catagories" @click="btn_click(item)"> <!--1. 检测到点击,调用btn_click-->
    {{item.name}}
  </button>
 </div>
</script>

<script>
  const son = {
    template: '#sontemplate',
    data(){
      return {
        catagories: [
          {id: 'a', name: '热门推荐'},
          {id: 'b', name: '手机数码'},
          {id: 'c', name: '家用家电'},
          {id: 'd', name: '电脑办公'}
        ]
      }
    },
    methods:{
      btn_click(item){
      	// 自定义事件item_click
        this.$emit('item_click', item);   // 2. 调用item_click
      }
    }
  }

  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    components: {
      son
    },
    methods: {
      cpn_click(item){
        console.log(item.name);
      }
    }
  });
</script>

父子互传案例

<div id="app">
  <cpn :cpn_num1="num1" :cpn_num2="num2" @change_num1="changeNum1" @change_num2="changeNum2"></cpn>
</div>


<template id="cpn">
  <div>
    <h1> props1: {{cpn_num1}}</h1>
    <h1> data1: {{dnum1}}</h1>
    <input :value="dnum1" @input="inputNum1"/>
    <h1> props2: {{cpn_num2}}</h1>
    <h1> data2: {{dnum2}}</h1>
    <input :value="dnum2" @input="inputNum2"/>
  </div>
</template>

<script>
  const cpn = {
    template: '#cpn',
    data(){
      return {
        dnum1: this.cpn_num1,
        dnum2: this.cpn_num2
      }
    },
    props: {
      cpn_num1: Number,
      cpn_num2: Number
    },
    methods: {
      inputNum1(event){
        this.dnum1 = event.target.value;
        this.$emit('change_num1', this.dnum1);
        this.dnum2 = this.dnum1 * 100;
        this.$emit('change_num2', this.dnum2);
      },
      inputNum2(event){
        this.dnum2 = event.target.value;
        this.$emit('change_num2', this.dnum2);
        this.dnum1 = this.dnum2 * 1/100
        this.$emit('change_num1', this.dnum1);
      }
    }
  }
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
      num1: 1,
      num2: 0
    },
    components: {
      cpn
    },
    methods: {
      changeNum1(value){
        this.num1 = value*1;
      },
      changeNum2(value){
        this.num2 = parseInt(value);
      }

    }
  });
</script>

在这里插入图片描述

父子访问

  • 父组件访问子组件的成员,有两种方式

    1. 通过this.$children属性取到由子组件Component的构成的数组集合;
    2. ref在子组件标签起名字:<cpn ref='xxx'></cpn>,通过this.$ref.xxx取到单个Component;(常用)
    3. 注意:访问不是传递!!!
  • 子组件访问父组件的成员:
    通过this.$parent属性得到父组件Component,若父组件为Vue实例,则返回Vue

  • 子组件访问root组件
    通过this.$parent属性得到根组件,一般为Vue实例

8、插槽Slot

8.1、什么是插槽?

  • 组件里的插槽,类似于Java抽象类中的抽象方法;
  • 因为具有不确定性,因此能够很好的复用;
  • 导航栏为一种使用场景

8.1、为什么使用Slot?

Slot翻译为插槽:

  • 在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽。
  • 插槽的目的是让我们原来的设备具备更多的扩展性。
  • 比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等等。组件的插槽:
  • 组件的插槽也是为了让我们封装的组件更加具有扩展性。
    让使用者可以决定组件内部的一些内容到底展示什么。

8.3、案例:单插槽

<div id="app">
  <cpn></cpn>
  <cpn>
    <font>slot</font>
  </cpn>
  <cpn></cpn>
</div>

<template id="cpn">
   <slot>
    <button>hello,</button><!--若为空,则默认-->
  </slot>
</template>
<script src="../js/vue.js"></script>
<script>

  const cpn = {
    template: '#cpn'
  }
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    components: {
      cpn
    }
  });
</script>

在这里插入图片描述

8.4、案例:具名(多)插槽

<div id="app">
  <cpn>
    <!--替换name为middle的slot-->
    <!--给middle加入多个元素-->
    <h1 slot="middle">嘿嘿嘿</h1>
    <h2 slot="middle">吼吼吼</h2>
  </cpn>
  <cpn>
    <!--若不指定名字,会把没有名字的全部替换-->
    <h1>哈哈哈</h1>
  </cpn>
</div>

<template id="cpn">
  <div>
    <slot name="left"></slot>
    <slot name="middle"></slot>
    <slot name="right"></slot>
    <slot>右右</slot>
    <slot>右右右</slot>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn'
  }
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    components: {
      cpn
    }
  });
</script>

在这里插入图片描述

8.5、作用域插槽

  • 父组件替换插槽的标签,但数据是由子组件提供
  • 比如有些子组件内容要水平展示,或者竖直展示,它的结构是变化的,因此就有了作用域插槽
<div id="app">
  <cpn></cpn>
  <cpn>
    <template slot-scope="aaa">
<!--      <span v-for="item in slot.data">{{item}}  </span>-->
      <span>{{aaa.xxx.join(' - ')}}</span>
    </template>
  </cpn>
</div>

<template id="cpn">
  <div>
    <slot :xxx="pLanguage">
      <li v-for="item in pLanguage">{{item}}</li>
    </slot>
  </div>
</template>
<script>
  const cpn = {
    template: '#cpn',
    data() {
      return {
        pLanguage: ['Java', 'Python', 'JavaScript', 'MySQL', 'C#']
      }
    }
  }
  const app = new Vue({
    el: "#app",      //用于挂载要管理的元素
    data: {          //定义数据
    },
    components: {
      cpn
    }
  });
</script>

作用域插槽

9、模块化

9.1、为什么要有模块化?

命名冲突

比如小明写了a.js,定义变量a,为1;
小红写了b.js文件,也定义了a,为2;
如果将a与b同时引入,大概率出现严重问题!

如果将代码改成这样

;(function(){
	/*代码写在这*/
})()

闭包可以解决这种冲突,但会产生新的问题,js代码无法被引用,复用性太差。
可以将可能被访问的数据返回到一个变量用来保存

var moduleA = (function(){
	var result = {}
	/*代码写在这*/
	return result
})()

9.2、ES6的模块化

aaa.js

let a = 1
function sum(num1, num2) {
  return num1 + num2 
}
//导出方式一:
export {
  a, sum
}
//导出方式二:
export var a = 1000
export function sum(num1, num2) {
  return num1 + num2 
}
// 导出方式三:只能有一个default,导入时可以起任意名
export default var address = 1
export default function(){
	console.log("匿名函数");
}

bbb.js

// 导入即可使用
import {a, sum, addr} from './aaa.js'
console.log('a = ' + a)
console.log(sum(1, 2))
// 若导入变量过多或者命名冲突,还可以这样
import * as aaa from './aaa.js'
console.log(aaa.变量名);

ccc.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ES6模块化</title>
  <!--type为module,去除了命名冲突-->
  <script src="../js/bbb.js" type="module"/>
</head>
</html>

10、webpack

10.1、认识webpack

  • 从本质来讲,webpack是一个现代的JS应用的静态模块打包工具。
  • 有些文件,如.sass,ES6语法,要转成ES5大部分浏览器才能支持。所以要通过一些工具做一些打包转化之类的工作。
  • webpack不仅用来打包,还能进行模块化,帮我们处理模块之间的依赖关系
  • 打包就是将各种资源合并成一或多个包(Bundle)

10.2、webpack的起步

  • webpack依赖node环境
  • node必须包含各种依赖的包才能正常执行代码,
  • 所以安装node时会自动安装帮助我们管理各种包的工具npm(node package manager)

10.3、webpack的配置

  1. 安装支持环境nodejs,会自动安装npm
  2. 全局安装webpack
    npm install webpack@3.6.0 -g
    
  3. 局部安装webpack(后需用到)
    cd 对应目录
    npm install webpack@3.6.0 --save-dev	
    

10.4、案例

  1. 编写mainUtils.js
    // CommonJS语法
    function sum(num1, num2){
      return num1 + num2
    }
    
    function mul(num1, num2) {
      return num1 * num2
    }
    
    module.exports = {
      sum, mul
    }
    // ES6语法
    export const id = 1
    export const name = 'Candy'
    export const age = 18
    
  2. 编写info.js
    // ES6语法
    export const id = 1
    export const name = 'Candy'
    export const age = 18
    
  3. 编写main.js
    // CommonJS语法
    const {sum, mul} = require('./mainUtil.js')
    
    console.log(sum(1, 2));;
    console.log(mul(1, 4));;
    
    // ES6语法
    import {id, name, age} from './mainUtil'
    
    console.log(id);
    console.log(name);
    console.log(age);
    
  4. 终端打包
    PS E:\VueProjects\Day-01> webpack ./js/main.js ./dist/bundle.js
    Hash: 0237d7838c5fb13a1c57
    Version: webpack 3.6.0
    Time: 59ms
        Asset     Size  Chunks             Chunk Names
    bundle.js  2.76 kB       0  [emitted]  main
       [0] ./js/main.js 69 bytes {0} [built]
       [1] ./js/mainUtil.js 142 bytes {0} [built]
    PS E:\VueProjects\Day-01>
    
    会将main.js及所有依赖js打包成一个bundle.js文件
  5. 编写main.html引入bundle.js文件
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <script src="../dist/bundle.js"></script>
    </head>
    </html>
    
    结果展示:
    在这里插入图片描述

10.5、配置文件设置出入口

  1. 终端输入npm init
    package name起个名字,之后可以一路回车
    生成package.json文件
    在这里插入图片描述
    如果使用了node依赖的包,需要这个文件
  2. 项目根目录编写webpack.config.js
    const path = require('path')
    module.exports = {
    	  entry: './src/main.js',
    	  output: {
    	    path: path.resolve(_dirname, 'dist'),
    		//path是一个绝对路径
    		//__dirname是node上下文的东西,是一个全局变量,保存了当前文件所在目录
    	    //resolve函数可以拼接参数 
    	    filename: 'bundle.js'
    	  }
    	}
    
  3. 打包:
    终端输入webpack
    报错
    ERROR in Entry module not found: Error: Can't resolve 'src/main.js' in 'E:\VueProjects\Day-01
    检查entry路径
    果然是路径错了
    继续打包,成功!
    在这里插入图片描述 在这里插入图片描述

10.6、打包需要注意的问题:

  1. 有时候使用了比如`4.0版本的语法
  2. 全局的打包工具是3.6的,就会出问题
  3. 这时候需要配置本地webpack
  4. 在项目目录下输入npm install webpack@4.0.0 --save-dev来下载本地webpack
  5. 生成本地文件
    在这里插入图片描述在这里插入图片描述
  6. 终端使用webpack都会使用全局的webpack,不可选
  7. package.jsonscript关键字中设置build,值为webpack,终端执行npm run build,会优先使用本地webpack在这里插入图片描述

10.7、loader

  • Webpack 本身只能处理 JS 模块,若要处理其他类型的文件,就需要扩展 loader

.css 的处理

  • 如果需要使用 css 文件,就需要使用到 css-loaderstyle-loader
  • css-loader 解析CSS文件,使用import加载并返回CSS代码
  • style-loader 将模块的导出作为样式添加到DOM
    使用步骤:
  1. 安装
    通过npm安装需要使用的loader,全局安装需要参数 -g

    npm install css-loader@2.0.2 style-loader@0.23.1 --save-dev
    

    执行以上命令会在当前目录生成 node_modules 目录,它是 css-loader 和 style-loader 的安装目录。
    在这里插入图片描述

  2. 配置
    在webpack.config.js中的modules关键字下进行配置大部分loader

    module: {
        loaders: [{ 
            	test: /\.css$/, 
            	loader: "style-loader!css-loader"    
        }]
    }
    

    编写style.css文件,在入口文件引用

    require("./css/style.css");
    
  3. 打包运行
    在这里插入图片描述
    成功!

.less 的处理

  1. 编写my.less
    @fontSize: 50px;
    @fontColor: black;
    body{
      font-size: @fontSize;
      color: @fontColor;
    }
    
  2. 在入口文件中引用
    require("./css/my.less");
    
  3. 本地安装less的loader
    npm install less-loader@4.1.0 less@3.9.0 --save-dev
    # less-loader只负责加载less文件
    # less是用来解析less文件的工具,不是一个loader
    
    安装成功在这里插入图片描述
  4. 在webpack.config.js中使用loader
    {
      test: /\.less$/,
      use: [
        // loader是按照从后往前的顺序加载的,顺序不能错
        {
          loader: "style-loader"
        },
        {
          loader: "css-loader"
        },
        {
          loader: "less-loader"
        }
      ]
    }
    
  5. 打包运行
    npm run build
    
    在这里插入图片描述

静态文件 的处理

  1. 安装依赖loader
    npm install url-loader@1.1.2 --save-dev	
    
  2. 在webpack.config.js中使用loader
    {
      test: /\.png|gif|jpg|jpeg$/,
      use: [
        {
          loader: "url-loader"
          options: {
            limit: 8192
          }
        }
      ]
    }
    
  3. file-loader
    当加载的图片,小于limit时,会将图片编译成base64字符串形式.
    npm install file-loader@3.0.1 --save-dev		
    

使用file-loader需要注意的第一个问题

  • ta会将超出大小限制的资源打包到输出目录下,并用hashcode重新命名防止重复
  • 所以我们直接访问肯定会报错的
  • 在webpack.config.js的output配置publicPath属性为dist/
  • 这样ta访问url时都会自动拼接上dist/
    publicPath: "dist/"
    
  • 使用
    打包,运行,成功!
    使用file-loader需要注意的第二个问题
  • file-loader打包后会生成32位hash值替换原文件名,但开发中会起一个有规律的名字,最好是 name + hash.ext,其中hash不需要这么长的话可以截取,而且生成文件位置可以自定。
  • 在webpack.config.js中url-loader的option中添加配置
    name: img/[name].[hash:8].[ext]
    
    在这里插入图片描述
    成功!

ES6 的处理

  • 如果你仔细阅读webpack打包的js文件
  • 发现写的ES6语法并没有转成ES5
  • 那么就意味着可能一些对ES6还不支持的浏览器不能很好的运行我们的代码。
  • 此时我们需要手动进行处理
  1. 安装babel-loader
    npm install babel-loader@7 babel-core babel-preset-es2015 --save-dev
    # babel-preset-es2015用来转换es语法
    
  2. 配置
    webpack.config.js -> module.exports -> module -> rule
    {
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/, //排除
      use: [
        {
          loader: "babel-loader",
          options: {
            presets: ['es2015']
          }
        }
      ]
    }
    
  3. 打包
    npm run build	
    
    在这里插入图片描述
    成功!

10.8、Webpack的Vue

  1. npm安装vue
    # 因为项目上线也需要依赖vue,因此不需要-dev
    npm install vue@2.5.21 --save
    
  2. 配置
    出口文件中配置
    // 导入node_modules包下的export defualt Vue
    import Vue from 'vue'
    
    const app = new Vue({
      el: '#app',
      data: {
        message: '信息'
      }
    })
    
    html页面body中配置
      <div id="app">
        {{message}}
      </div>
    
  3. 运行报错
    npm run build
    
    在这里插入图片描述
    • 原因是vue发布后会生成runtime-only和runtime-compiler两个版本
    • 前者不能包含template,因此找不到‘#app’
    • 而后者因为有compiler可以用于编译template,因此选择ta
      webpack.config.js -> module.exports中配置
      resolve: {
          // 别名
          alias: {
            // 当vue被导入,ta就不会按照默认路径
            // 会先来这里找一下是否配置了映射路径
            // 这个路径里包含了compiler
            'vue$': 'vue/dist/vue.esm.js'
          }
      }
      

vue实例中的template

  • 如果vue实例中有template属性,会将该属性值进行编译,将编译后的虚拟dom直接替换掉vue实例绑定的元素(即el绑定的那个元素);
  • template属性中的dom结构只能有一个根元素
  • 如果有多个根元素需要使用v-if、v-else、v-else-if设置成只显示其中一个根元素;
  1. vue -> app.js
    // 将模板抽离到一个组件
    // 模板用到的data和method一并抽离
    export default {
      template: `
        <div>
          <h1>{{name}}</h1>
        </div>
      `,
      data(){
        return {
          name: 'Candy'
        }
      },
      methods: {
        btnClick(){
          console.log("我是组件!");
        }
      }
    }
    
  2. 在出口文件中配置
    import Vue from 'vue'
    import app from './vue/app'
    
    new Vue({
      el: '#app',
      // 子组件以前是放在父组件的模板中
      // 现在这种写法会直接将父组件模板替换
      template: '<app/>',
      components: {
        app
      }
    })
    
  3. 运行
    在这里插入图片描述
  4. 升级写法 -> 模板分离
    1. 创建Vue组件
      在这里插入图片描述
    2. 将之前模板移入
      在这里插入图片描述
    3. script移入
      在这里插入图片描述
    4. 样式移入
      在这里插入图片描述
    5. 出口函数中更改配置
      // import app from './vue/app'
      import app from './vue/app'
      
    6. 安装loader
      npm install vue-loader vue-template-compiler --save-dev
       # vue-loader加载vue组件
       # vue-template-compiler编译模板
      
    7. 引入子组件
      vue -> Cpn.vue
      <template>
        <div>
          <h1>我是子组件</h1>
        </div>
      </template>
      
      <script>
      export default {
        name: "Cpn"
      }
      </script>
      
      <style scoped>
      
      </style>
      
      在vue -> App.vue导入,components中注册
      import Cpn from './Cpn.vue'
      
      如果不像每次都写后缀,可以在配置文件的resolve关键字中加入以下代码:
      extensions: ['.js', '.css', '.vue']
      

10.9、plugin的使用

  1. plugin是插件的意思,通常用于对现有的架构进行扩展
  2. loader主要用于转换类型,相当于转换器;
    plugin是对webpack本身的扩展,是一个扩展程序

版权声明

  1. 配置文件中引入webpack
    const webpack = require('webpack')
    
  2. module.exports中添加plugins关键字
      plugins: [
        new webpack.BannerPlugin('最终版权归Monster所有')
      ]
    
  3. 成功
    在这里插入图片描述

打包html

  1. 安装插件
npm install html-webpack-plugin@3.2.0 --save-dev
  1. 配置引入
const HtmlWebpackPlugin = require('html-webpack-plugin')
...
// plugins加入
new HtmlWebpackPlugin()
  1. 打包运行
    在这里插入图片描述
    • 在dist下生成index.html,帮我们引入了bundle.js
      在这里插入图片描述
    • 之前配置的拼接路径dist/不再需要
      在这里插入图片描述
    • 但细细一看,我们id为app的div不见了,这是因为此页面是自动生成的,我们可以在插件配置中添加原页面为模板
      在这里插入图片描述 在这里插入图片描述
      重新打包 在这里插入图片描述

压缩

  1. 安装
    npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
    
  2. 引入
    const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
    ...
    // plugins加入
    new UglifyjsWebpackPlugin ()
    
  3. 丑化
    在这里插入图片描述

10.10、搭建本地服务器

  • webpack提供了一个可选的本地开发服务器
  • 基于node.js搭建
  • 内部使用express框架
  • 可以实现让浏览器自动刷新显示修改后的结果。
  • 每次修改时会将结果放到内存,等我们手动发布后才会放到磁盘

不过他是一个单独的模块,需要先进行安装

npm install webpack-dev-server@2.9.3 --save-dev
  • devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:
    • contentBase :为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写/dist
    • port :端口号
    • inline :页面实时监听
    • historyApiFallback :在SPA页面中,依赖HTML5的history模式
    devServer: {
      contentBase: './dist',
      inline: true
    }
    

启动服务器的方式:

  1. 相对路径
    # 终端启动
    .\node_modules\.bin\webpack_dev_server
    
  2. 脚本启动
    在package.json中的scripts关键字中配置
    "dev": "webpack-dev-server --open"
    // open参数,启动时自动打开网页 
    
    # 终端启动
    npm install dev
    

10.11、配置分离

有些开发时的配置等项目上线后就没用了
我们可以将他们抽离出来

  1. 项目根目录创建build文件夹
  2. 在build下创建base.config.js,里面放一些开发上线通用的配置
  3. 创建prod.config.js,放生产时的配置
  4. 创建dev.config.js,放开发时的配置
  5. 为了最终能合并配置文件,需要安装webpack-merge
    npm isntall webpack-merge --save-dev
    
  6. 在prod.config.js和dev.config.js中引入
    const baseConfig = require('./base.config')
    const WebpackMerge = require('webpack-merge')
    
    module.exports = WebpackMerge(baseConfig, {
    	//自己的配置
    })
    
  7. 项目启动时会默认启动webpack.config.js,所以我们需要对我们的配置文件进行单独配置
    • package.json -> scripts
    • 找到之前配置的build和dev属性,更改为:
      "build": "webpack --config ./build/prod.config.js",
      "dev": "webpack-dev-server --open --config ./build/dev.config.js"
      
  8. 更改打包位置
    通过观察可以发现打包位置在build下,是因为我们之前设置的是配置文件当前目录下打包,我们可以更改一下,找到base.config.js,更改output -> path的第二个参数为../dist

项目地址: https://gitee.com/candy-xiaojing/vue-study.git

11、Vue CLI

11.1、简介

  • 如果你只是简单写几个Vue的Demo程序,那么你不需要Vue CL.
  • 如果你在开发大型项目,那么你需要,并且必然需要使用Vue CLI
  • 使用Vuejs开发大型应用时,我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。
  • 如果每个项目都要手动完成这些工作,那无疑效率比较低效,所以通常我们会使用一些脚手架工具来帮助完成这些事情。

CLI是什么意思?
CLI是Command-Line Interface,翻译为命令行界面,但是俗称脚手架.
Vue CLI是一个官方发布vuejs项目脚手架
使用vue-cli可以快速搭建Vue开发环境以及对应的webpack配置.

11.2、安装

安装NodeJs

  • 可以直接在官方网站中下载安装.
  • 网址: http://nodejs.cn/download/

检测安装的版本

  • 默认情况下自动安装Node和NPM
  • Node环境要求8.9以上或者更高版本
    在这里插入图片描述

更换淘宝镜像

npm install -g cnpm --registry=https://registry.npm.taobao.org

安装脚手架

cnpm install -g @vue/cli

这里安装的是CLI3,Vue CLI2和3使用了相同的vue命令,因此被覆盖了,如果还想使用旧版,可以安装一个桥接工具

cnpm install @vue/cli-init -g

11.3、Vue CLI2初始化项目

初始化参数解读

vue init webpack my_project

初始化参数:

  1. Project name: 项目名称初始化命令中的名称是最终生成文件夹的名称,这里才是真正的项目名,一般情况下保持一致,直接回车
  2. Project description:描述信息,自定义,回车
  3. Author:作者信息,自定义,回车
  4. Runtime Compiler / Runtime Only:初学者可以选择前者,回车
  5. vue-router:是否安装路由,自定义Yes / No,回车
  6. Use ESLint to lint your code?(Y/n):是否对你的代码开启严格模式,自定义,回车
    6.1. Pick an ESLint preset(Standard / Airbnb / none):选择规范模板,回车
  7. Set up unit tests?(Y/n)是否需要单元测试,自定义,回车
  8. Setup e2e tests with NightWatch:end to end 安装NightWatch,是一个利用selenium或webdriver或phantomjs等进行自动化测试的框架,自定义
  9. NPM / Yarn:使用什么工具管理我们的项目,自定义,回车

环境解读

node由C++开发,内嵌了V8引擎,可以直接通过命令运行js代码

node  xxx.js

11.4、Vue CLI3初始化项目

vue create 项目名
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 09:48:55  更:2021-11-27 09:50:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:59:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码