vue.js学习笔记 from coderwhy

Part1 Meet Vue

1. 安装

方式一:直接CDN引入 你可以选择引入开发环境版本还是生产环境版本

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

方式二:下载和引入(前期学习使用这个,后续学习CLI使用NPM)

https://vuejs.org/js/vue.js

https://vuejs.org/js/vue.min.js

方式三:NPM安装

后续通过webpack和CLI的使用,我们使用该方式。

2. hello world

区分声明式编程和命令式编程

声明式编程的好处,界面和数据可以全部分离

第一个程序

在es6中用let定义变量,用const定义常量

  1. 创建vue实例,传入参数是对象
  2. 创建div元素
  3. vue挂载div,vue帮忙管理div的内容
<body>
    <div id="app">{{message}}</div>
    
    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app", // 用于挂载要管理的元素
            data: {
                message: "你好啊,李银河!",
                name: "coderwhy",
            },
        });
    </script>
</body>

双向绑定展示

image-20211217162708539

在console直接修改message的值,敲回车就可以修改页面数据

image-20211217162734132

vue列表的展示

用到了循环 v-for

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

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app", // 用于挂载要管理的元素
            data: {
                message: "hello",
                movies: ["starwalk", "soul", "dreamspace"],
            },
        });
    </script>
</body>

同样可以在console随意添加数据

image-20211217164756422

3. Vue lifecycle

vue回调函数

生命周期函数也叫做钩子函数 hook 表示回调的意思

小小例子

<body>
    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            created: function fun() { //一般在created里面做网络请求
                console.log("created");
            },
            mounted: function fun() {
                console.log('mounted');
            }
            //这两个函数不是我调的,是vue源码在内部做的回调函数
        });
    </script>
</body>
选项式 APIHook inside setup
beforeCreateNot needed*
createdNot needed*
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered
activatedonActivated
deactivatedonDeactivated

Part2 Basic Vue

在开始之前定义一个模板template

"Print to myvue": {
    "prefix": "myvue",
    "body": [
        "<div id=\"app\">",
        "</div>",
        "<script src='vue.js'></script>",
        "<script>",
        "  const app = new Vue({",
        "    el: '#app', ",
        "    data: {",
        "    }",
        "  })",
        "</script>",
    ],
    "description": "vue模板"
},

1. 插值操作

Mustache语法就是双大括号

可以把data里的值取出来

<body>
    <div id="app">
        <h2>{{message}}</h2>
        <h2>{{message}}, 李银河!</h2>      
        <h2>{{firstName + lastName}}</h2>
        <h2>{{firstName + ' ' + lastName}}</h2>
        <h2>{{firstName}} {{lastName}}</h2>
        <h2>{{counter * 2}}</h2>
    </div>

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                message: "你好啊",
                firstName: "kobe",
                lastName: "bryant",
                counter: 100,
            },
        });
    </script>
</body>

插值操作的其他指令

  • v-once 属性只能改变一次

    <h2 v-once>{{message}}</h2>
    
  • v-html 该指令后面往往会跟上一个string类型

    会将string的html解析出来并且进行渲染

     <div id="app">
      <h2>{{url}}</h2>
      <h2 v-html="url"></h2>
    </div>
    
    <script src="vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: '你好啊',
          url: '<a href="http://www.baidu.com">百度一下</a>'
        }
      })
    </script>
    

    image-20211217193127860

  • v-test 展示文本

    用起来不太灵活

    <h2 v-text="message"></h2>
    
  • v-pre 原封不动的显示出来,而不做任何解析

    <div id="app">
      <h2>{{message}}</h2>
      <h2 v-pre>{{message}}</h2>
    </div>
    
  • v-cloak 我们浏览器可能会直接显然出未编译的Mustache标签

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

2. 绑定属性 v-bind

不光是动态插值,某些属性希望动态绑定

比如a元素的herf属性,img元素的src属性

<div id="app">
    <img v-bind:src="imgURL" alt="" />
    <a v-bind:href="aHref">百度一下</a>

    <!--语法糖的写法-->
    <img :src="imgURL" alt="" />
    <a :href="aHref">百度一下</a>
</div>

<script src="vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            message: "你好啊",
            imgURL:
            "https://img11.360buyimg.com/mobilecms/s350x250_jfs/t1/20559/1/1424/73138/5c125595E3cbaa3c8/74fc2f84e53a9c23.jpg!q90!cc_350x250.webp",
            aHref: "http://www.baidu.com",
        },
    });
</script>

3. 计算属性

把多个数据进行结合或者变化之后再展示

方法一:methods 里面定义的方法也是可以在双大括号里面使用的

方法二:使用计算属性 computed

尽可能按照属性的方法给函数取名字,使用的时候不需要加小括号

这样写其实也是一个语法糖 里面有setter和getter 这个是getter

<div id="app">
    <h2>{{getFullName()}}</h2>
    <!-- !!计算属性不用加括号 -->
    <h2>{{fullName}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            firstName: 'Lebron',
            lastName: 'James'
        },
        computed: {   // computed: 计算属性()
            fullName: function () {
                return this.firstName + ' ' + this.lastName
            }
        },
        methods: {
            getFullName() {
                return this.firstName + ' ' + this.lastName
            }
        }
    })
</script>

4. 事件监听 v-on

5. 条件和循环 v-show

6. 表单绑定 v-model

实现表单元素和数据的双向绑定

比如,当我们在输入框输入内容时,因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message实时发生改变

 <div id="app">
  <input type="text" v-model="message">
  {{message}}
</div>
 
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })
</script>

7. ES6语法补充

let/var

我们可以将let看成更完美的var

var没有块级作用域,在代码块里定义的东西,在变量外也可以访问

块级作用域引起的问题

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>

<script>
    var btns = document.getElementsByTagName('button');
    for (var i = 0; i < btns.length; i++) {
        btns[i].addEventListener('click', function () {
            console.log('第' + i + '个按钮被点击');
            // 点击了第1个,打印却是第5个,点击其他按钮也是打印第5个
            // 打印的i是在一个函数里面,在点击之前,这个i已经被改掉了,进行了5次循环
        })
    }
</script>

在es5中,我们解决的方法是建立一个函数作用域,形成闭包。在js里面只有函数有作用域,而if和for都没有块级作用域

var btns = document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
    (function (num) { // 0
        btns[i].addEventListener('click', function () {
            console.log('第' + num + '个按钮被点击');
        })
    })(i)
}

在es6中加入了let,if和for都有块级作用域

// es6写法
const btns = document.getElementsByTagName('button')
for (let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function () {
        console.log('第' + i + '个按钮被点击');
    })
}

const

使用const修饰的标识符为常量,不可以再次赋值

在ES6开发时优先使用const,只有需要改变某一个标识符时才使用let

  1. 不能修改

     const a=20;
     a=30;// 错误:不可以修改
    
  2. 必须赋值

    const name; // 错误:const修饰的标识符必须赋值
    
  3. 指针不能改,内部属性可以改

    const obj = {
        name: 'why',
        age: 18,
        height: 1.88
    }
    // obj = {}
    console.log(obj);
    
    obj.name = 'kobe';
    obj.age = 40;
    obj.height = 1.87;
    
    console.log(obj);
    

javascript高阶函数

fliiter

map

换行字符串

用波浪号的按键敲出的引号

const str = `abc`

template: `
  <div>
    <h2></h2>
  <div<`

可以换行的字符串

Part3 Vue组件化开发

提供了一种抽象,开发出一个个独立的可复用的小组件来构造应用,任何应用都会被抽象一颗组件树

image-20211219170358736

1. 组件基础

创建组件构造器对象 → 注册组件 → 使用组件

1. const cpnC = Vue.extend()
2. Vue.component("my-cpn", cpnC);
3. <my-cpn></my-cpn>

举例

  <body>
    <div id="app">
      <!-- 第一种展示 -->
      <my-cpn></my-cpn>
      <my-cpn></my-cpn>
      <my-cpn></my-cpn>
      <!-- 第二种展示 -->
      <div>
        <my-cpn></my-cpn>
      </div>
    </div>

    <!-- 第三种展示 -->
    <my-cpn></my-cpn>

    <script src="vue.js"></script>

    <script>
      // 1. 创建组件构造器对象
      const cpnC = Vue.extend({
        template: `
          <div>
            <h2>我是标题</h2>
            <h2>我是内容,哈哈哈哈</h2>
          </div>
          `,
      });

      // 2.注册组件
      Vue.component("my-cpn", cpnC);

      const app = new Vue({
        el: "#app",
        data: {},
      });
    </script>
  </body>

注册全局组件的语法糖:省略extend

Vue.component("cpn1", {
    template: `
		<div>
		  <h2>我是标题1</h2>
		  <h2>我是内容</h2>
		</div>
		`,
});

注册局部组件的语法糖

写在vue对象参数里面

const app = new Vue({
        el: "#app",
        data: {
          message: "你好",
        },
        components: {
          cpn2: {
            template: `
        		<div>
       		   	  <h2>我是标题2</h2>
     		      <h2>我是内容</h2>
      			</div>
      			`,
          },
        },
      });

组件模板分离的写法

1.script标签

2.template标签

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

<!-- 1.script标签,类型必须是text/x-template -->
<script type="text/x-template" id="cpn">
    <div>
		<h2>我是标题1</h2>
		<h2>我是内容</h2>
    </div>
</script>

<!-- 2.template标签 -->
<template id="cpn">
    <div>
        <h2>我是标题1</h2>
        <h2>我是内容</h2>
    </div>
</template>

<script src="vue.js"></script>

<script>
    //注册一个全局组件
    Vue.component("cpn", {
        template: "#cpn",
    });

    const app = new Vue({
        el: "#app",
        data: {
        },
    });
</script>

2. 组件高级

3. 组件声明周期

4. ES6模块化实现

export/import关键字

在script里面加上 type = ”module“表示按照模块化开发

<script src="./aaa.js" type="module"></script>
<script src="./bbb.js" type="module"></script>

每一个模块都是一个自己的空间,不能用其他模块的东西,如果想访问别的模块的东西,就export/import

导出

// aaa.js 文件

//第一种方法,先把三个变量定义好再一起导出
let name = "小明";
let age = 18;
function sum(num1, num2) {
  return num1 + num2;
}

export { name, flag, sum };

//第二种方法,定义的时候就导出
export let name = "小明";
export let age = 18;
export function sum(num1, num2) {
  return num1 + num2;
}
export class person {
    run() {
        console.log("running");
    }
}

//

导入

// mmm.js文件想使用aaa.js文件中的flag和sum

// import
import { flag, sum } from "./aaa.js";

if (flag) {
  console.log("小明是天才");
}

//统一导入
import * as aaa from './aaa.js'
console.log(aaa.name);

Part4 Webpack

前端模块化,并帮我们处理模块间的依赖关系

webpack模块化打包,为了可以正常运行,必须依赖node环境

1. 安装

先检查自己的node环境

image-20211219193804903

全局安装webpack

npm install webpack@3.6.0 -g

image-20211219213152611

局部安装webpack

npm install webpack@3.6.0 --save-dev

一般项目有两个文件夹,src和dist,src是开发的源代码,dist是发布给服务器的打包代码

2. 简单使用

把src文件夹里的两个js文件用webpack打包,在dist文件里生成bundle.js文件

webpack ./src/main.js ./dist/bundle.js

image-20211219213451514

只需在index.js里引用bundle.js就可以了

<script src="./dist/bundle.js"></script>

3. 配置vue ⭐️

从现在开始的后续项目中,我们会使用vuejs进行开发,而且以特殊的文件来组织vue的组件

我们首先需要对其有依赖,先进行安装

npm install vue --save
import Vue from "vue";

new Vue({
  el: "#app",
  data: {
    message: 'hello webpack'
  }
})

SPA:单页面复应用 simple page web application

一般项目里只有一个html代码,多个页面是通过路由跳转的

Part5 Vue CLI

开发大型项目需要考虑项目结构,必然要使用vue cli,自动生成目录结构和各种配置

command line interface 命令行界面,俗称脚手架

vue-cli可以快速搭建vue开发环境以及webpack相应配置

使用前提:1.node和npm 2. webpack

安装 vue脚手架

npm install -g @vue/cli

image-20211217195256240

vue-cli 3 特点

vue-cli 3 基于webpack 4,设计原则是零配置

提供了vue ui命令,提供了可视化配置

新增了public文件夹

vue-cli 3 创建项目

在vscode进入文件夹,用集成终端terminal打开文件夹

> vue create projectname

选择手动 manual

image-20211217201953952

选择项目需要的东西

image-20211217202900387

放在独立的配置文件还是 package.json

image-20211217203012473

再选择一些其他配置之后,回车开始创建项目,创建成功

image-20211217203439714

vue-cli 3 项目结构

image-20211217204020408

node_modules:保存的node包

public:相当于 vue-cli 2 的static

src:源代码

.browserSlistrc:浏览器相关配置

.gitignore:忽略文件,不提交到服务器的文件,很少改

babel.config.js:配置babel的东西

package.json:项目配置

package.lock.json:中间文件,安装的真实版本

postcss.config.js:css转化文件

vue-cli 3 项目运行

打包用build

vue-cli service build

跑项目用serve

npm run serve

image-20211217204815471

访问localhost:8080

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iRpz707P-1639986580280)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20211217204850347.png)]

xgxt项目运行

npm install

image-20211218135441585

npm run build

image-20211218135741443

npm run serve

Part6 vue-router

前端路由

Part7 vuex

vue状态管理

Part8 axios

ajax