Nicole Zhang

East China Normal University | Software Engineering | 2000.5.30

Meet Vue.js with 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>
选项式 API Hook inside setup
beforeCreate Not needed*
created Not needed*
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered
activated onActivated
deactivated onDeactivated

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 :star:

从现在开始的后续项目中,我们会使用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

image-20211217204850347

xgxt项目运行

npm install

image-20211218135441585

npm run build

image-20211218135741443

npm run serve

Part6 vue-router

前端路由

Part7 vuex

vue状态管理

Part8 axios

ajax