Vue.js
开发模式:
-
CDN
-
NPM
- 在用 Vue 构建大型应用时推荐使用 NPM 。NPM 能很好地和诸如 webpack 或 Browserify 模块打包器配合使用。同时 Vue 也提供配套工具来开发单文件组件
学习开发工具:Visual Studio Code
工具下载网址:Visual Studio Code下载地址
- 装好软件后装几个插件:
1、Live Server
为静态和动态页面启动带有实时重新加载功能的开发本地服务器
2、Vetur
用于VS代码的Vue工具
3、Vue.js with TypeScript Snippets for VSCode
使用SFC或基于类的API (vscode)的TypeScript收集Vue.js的代码片段
- 设置一下工具:
- 加上(可以格式化代码):
“editor.formatOnType”: true,
“editor.formatOnSave”: true,
Vue-CDN的使用
- 创建项目(创建一个文件夹:vue-basic-cdn)
- 创建三个资源:index.html、app.js、styles.css
app.js:
//实列化vue对象
new Vue({
el: '#vue-app', //element(容器)返回的数据只能在本容器中使用
data() {
return {
name: "米罗",
age: "18"
};
}
})
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>Vue CDN</title>
</head>
<body>
<div id="vue-app">
<h1>欢迎:{{name}}</h1>
<p>年龄:{{age}}</p>
</div>
</body>
<script src="app.js"></script>
</html>
使用vue中的方法(Methods)和指令(v-bind):
指令还有很多可以看官网的使用方法
- 页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>Vue CDN</title>
</head>
<body>
<div id="vue-app">
<h1>欢迎:{{name}}</h1>
<p>年龄:{{age}}</p>
<h1>methods:{{green()}}</h1>
<h1>methods2:{{green2('2018-5-8')}}</h1>
<a v-bind:href="url">百度</a>
<a :href="url">百度</a>
<p v-html="a"></p>
</div>
</body>
<script src="app.js"></script>
</html>
- js:
//实列化vue对象;this指的就是这个实例
new Vue({
el: '#vue-app', //element(容器)
data() {
return {
name: "米罗",
age: "18",
url: "https:www.baidu.com",
a: "<a href='https:www.taobao.com'>淘宝</a>"
};
},
methods: {
// green: function () {
// return 'Good night' + this.name;
// }
green() {
return `Good night ${this.name}`;
},
green2(time) {
return `Good night ${time} ${this.name}`;//这里是反引号这主键盘去的1后面
}
}
})
vue鼠标事件的使用
-
常见的事件类型
click:鼠标单击某元素时触发,相当于mousedown和mouseup的组合
dblclick:双击事件
mouseover:鼠标放在某元素上触发
mouseout:鼠标移出某元素时触发
mousemove:鼠标移动时触发
mousedown:鼠标按钮被按下时触发
mouseup:鼠标按钮被松开时触发
dblclick:鼠标双击时触发 -
属性修饰符:
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器 -
实例:
页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="styles.css">
<title>Vue CDN</title>
</head>
<body>
<div id="vue-app">
<!-- 加不加()都没问题,它会先找methods中的方法 -->
<button id="but1" v-on:click="num++">单击+1</button>
<button id="but2" @click="num--">单击-1</button>
<button id="but1" v-on:click="numon(1)">单击+1</button>
<button id="but2" @click="numup(1)">单击-1</button>
<button id="but1" v-on:dblclick="numon(10)">双击+10</button>
<button id="but2" @dblclick="numup(10)">双击-10</button>
<p>当前值:{{num}}</p>
<!-- mousemove event(鼠标移动时触发) -->
<div id="mouse" v-on:mousemove="updateXY">
{{x}} , {{y}}
</div>
<!-- 属性修饰符 -->
<a @click.prevent="onmethod" href="https://www.baidu.com">百度</a>
</div>
</body>
<script src="app.js"></script>
</html>
js:
//实列化vue对象;this指的就是这个实例
new Vue({
el: '#vue-app', //element(容器)
data() {
return {
num: 50,
x: 0,
y: 0
};
},
methods: {
numon(a) {
this.num += a;
},
numup(a) {
this.num -= a;
},
updateXY(event) {
// console.log(event);
this.x = event.offsetX;
this.y = event.offsetY;
}
}
})
vue键盘事件的使用
<label>姓名:</label>
<!-- 当按Enter键才会触发 -->
<input type="text" v-on:keydown.enter="logName" />
<label>年龄:</label>
<input type="text" v-on:keyup.alt.enter="logAge" />
双向数据绑定
修饰符:
.lazy - 取代 input 监听 change 事件
.number - 输入字符串转为有效的数字
.trim - 输入首尾空格过滤
用法:
在表单控件或者组件上创建双向绑定。细节请看下面的教程链接。
//js
data() {
return {
name: '',
age: null
};
},
//html
<!-- 双向数据绑定 -->
<label>姓名:</label>
<!-- lazy相当于懒加载就是输入框失去焦点时才改值 -->
<input type="text" v-model.lazy="name" />
<span>{{name}}</span>
<label>年龄:</label>
<input type="text" v-model="age" />
<span>{{age}}</span>
ref 的使用:
可以使用$refs获取ref的父级:
一般用ref获取容器(相当于FindById)
js:
getname() {
this.name = this.$refs.name.value;
},
getage() {
this.age = this.$refs.age.value;
}
html:
<label>姓名:</label>
<input type="text" ref="name" @keyup="getname" />
<span>{{name}}</span>
<label>年龄:</label>
<input type="text" ref="age" @keyup="getage" />
<span>{{age}}</span>
使用watch调式:
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property。
//实列化vue对象;this指的就是这个实例
new Vue({
el: '#vue-app', //element(容器)
data() {
return {
name: '',
age: null
};
},
methods: {
},
watch: {
//val:新值;oldVal:旧值
name(val, oldVal) {
console.log(val, oldVal);
}
}
})
computer计算属性的使用:
使用methods中的方法时,实用其中一个方法,实际上其他方法也会被运行(耗费性能)。这样可以使用计算属性。
js定义:
new Vue({
el: '#vue-app',
data() {
return {
a: 0,
b: 0,
};
},
methods: {
},
//computer中的方法必须有返回值
computed: {
numplus() {
return this.a + this.b;
}
}
})
html使用:
<div id="vue-app">
<!-- computer -->
<button id="but1" v-on:click="a++">单击+1</button>
<button id="but2" @click="b++">单击-1</button>
<p>当前值a:{{a}}</p>
<p>当前值b:{{b}}</p>
<!-- 调用computer时不能加括号 -->
<p>a+b={{numplus}}</p>
</div>
动态CSS(v-bind:class):
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="styles.css">
<title>Vue CDN</title>
</head>
<body>
<div id="vue-app">
<h1>动态绑定样式,两种方式</h1>
<!-- <h2>示例1 属性绑定</h2>
<div @click="mrChangeColor=!mrChangeColor" v-bind:class="{add:mrChangeColor}">
<span>Hello</span>
</div> -->
<h2>示例2 计算属性绑定</h2>
<div @click="michangcolor=!michangcolor" v-bind:class="addclass">
<span>Hello</span>
</div>
</div>
</body>
<script src="app.js"></script>
</html>
js:
new Vue({
el: '#vue-app',
data() {
return {
mrChangeColor: true,
michangcolor: true
};
},
methods: {
},
//computer中的方法必须有返回值
computed: {
addclass() {
return {
add: this.mrChangeColor,
adder: this.michangcolor
};
}
}
});
css:
div span{
background: red;
display: inline=block;
color: white;
margin: 10px 0;
}
.add span{
background: rgb(37, 36, 33);
}
.adder span::after{
content: '效果';
margin-left: 10px;
}
v-if、v-else、v-else-if、v-show:
js:
data() {
return {
error: false,
success: false
};
html:
<div id="vue-app">
<h1>v-if</h1>
<button id="fontclass" @click="error=!error">显示error</button>
<button id="fontclass" @click="success=!success">显示success</button>
<!-- <p v-if="error">error:连接错误404</p>
<p v-else-if="success">success:连接成功:200</p>
<p v-else="success">Other</p> -->
<!-- show -->
<!-- 和v-if的区别在于show会加一个display: none;属性 -->
<p v-show="error">success:连接成功:200</p>
<p v-show="success">Other</p>
</div>
v-for:
html:
<div id="vue-app">
<h1>v-for指令</h1>
<!-- {{names[0]}},
{{names[1]}},
{{names[2]}},
{{names[3]}}, -->
<!-- <ul>
<li v-for="names in names">{{names}}</li>
</ul> -->
<!-- <template>
<li v-for="(names,item) in names">{{item}}.{{names}}</li>
</template> -->
<template>
<li v-for="(names,item) in users">{{names.name}}.{{names.age}}</li>
</template>
<template v-for="(user,item) in users">
<li v-for="(val,key) in user">
<p>{{key}}——{{val}}</p>
</li>
</template>
</div>
js:
new Vue({
el: '#vue-app',
data() {
return {
names: ["小猪佩奇", "西奥潘西", "小鸡莉莉", "小项雍熙"],
users: [
{ name: "小猪佩奇", sex: "男", age: 3 },
{ name: "西奥潘西", sex: "男", age: 2 },
{ name: "小鸡莉莉", sex: "女", age: 1 },
{ name: "小项雍熙", sex: "男", age: 5 },
]
};
},
methods: {
},
});
练习
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="styles.css">
<title>Vue CDN</title>
</head>
<body>
<div id="vue-app">
<div id="image" :class="{burst:start}"></div>
<div id="ku">
<div id="tiao" :style="{width:health+'%'}"></div>
</div>
<div id="con">
<button id="butup" @click="da" v-show="!start">打击</button>
<button id="butnew" @click="nostart">重新开始</button>
</div>
</div>
</body>
<script src="app.js"></script>
</html>
js
new Vue({
el: '#vue-app',
data() {
return {
start: false,
health: 100
};
},
methods: {
da() {
this.health -= 10;
if (this.health <= 0) {
this.start = true;
console.log("da");
}
},
nostart() {
this.health = 100;
if (this.health == 100) {
this.start = false;
}
}
},
});
css
#image{
width: 200px;
height: 200px;
margin: 0 auto;
background: url(image/01.jpg) center no-repeat;
background-size: 100%;
}
#image.burst{
background: url(image/04.jpg) center no-repeat;
background-size: 100%;
}
#ku{
width: 200px;
border: 2px solid black;
margin: 0 auto 20px auto;
}
#tiao{
height: 20px;
background-color: red;
}
#con{
width: 120px;
margin: 0 auto;
}
多个Vue实例(const ):
//多个Vue实例
const method1 = new Vue({
el: '#vue-app',
data() {
},
});
const method2=new Vue({
el: '#vue-app',
data() {
},
});
全局组件(component):
js:
//定义全局变量
let data = {
name: '小罗',
wechat: '2510116656'
};
//创建全局组件(Greeting是自己定义的名称)
Vue.component("Greeting", {
//html模版
template: `
<p>这是一个全局变量,
可以在任何一个Vue实例中使用
姓名:{{name}}
微信:{{wechat}}
<button @click="chanageName">改名</button>
</p>
`,
//属性、方法等
data() {
return data;
},
methods: {
chanageName() {
this.name = "小罗在线";
}
}
})
//多个Vue实例
const app = new Vue({
el: '#vue-app'
});
const app2 = new Vue({
el: '#vue-app2'
});
html:
<div id="vue-app">
<Greeting />
</div>
<div id="vue-app2">
<Greeting></Greeting>
</div>
Vue Fatch和Axios请求
我这使用的接口是:测试接口
实例:
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="styles.css">
<title>Vue CDN</title>
</head>
<body>
<h1>Fetch请求</h1>
<div id="vue-app">
<form @submit.prevent="onSubmit">
<input type="text" v-model="todo.title">
<input type="checkbox" v-model="todo.completed">
<input type="submit" value="提交">
</form>
<ul>
<li v-for="todo in todos">
<h1>{{todo.title}}</h1>
<p v-if="todo.completed">{{todo.completed}}</p>
</li>
</ul>
</div>
<div id="vue-app2">
</div>
</body>
<script src="app.js"></script>
</html>
js:
new Vue({
el: '#vue-app',
data() {
return {
todos: [],
todo: {
title: "",
completed: false
}
};
},
// mounted是个函数会自动执行
mounted() {
//fetch api请求接口
// fetch('http://jsonplaceholder.typicode.com/todos').then(res => {
// //console.log(res.json());
// return res.json();
// })
// .then(todos => {
// this.todos = todos;
// });
//axios get请求(这种常用一点)
axios.get('http://jsonplaceholder.typicode.com/todos').then(
res => {
this.todos = res.data;
}
)
},
methods: {
onSubmit() {
//axios post请求
axios.post("http://jsonplaceholder.typicode.com/todos",
this.todo).then(res => {
//console.log(res);
//将结果写到对象中
this.todos.unshift(res.data);
})
// fetch('http://jsonplaceholder.typicode.com/todos', {
// //请求方式
// method: "POST",
// //转换成json
// body: JSON.stringify(this.todo),
// headers: {
// 'Content-Type': 'application/json'
// }
// }).then(res => {
// return res.json();
// })
// .then(todo => {
// console.log(todo);
// this.todos.unshift(todo);
// });
}
}
});
Vue Cli(脚手架)开发
一般公司不会用CDN,而是使用Vue Cli进行开发。
-
脚手架需要的环境:
- Node.js运行环境(这个环境可以让js独立运行)做前端的可以去学一下Node.js
- npm(node package manage)依赖包(包含很多组件等,国外)
-
脚手架的好处:
- 1.脚手架可以大大的提高开发系效率;
- 2.可以使用最主流的ECMAScript语法;
- 3.通过Webpack实现编译查看效果(非浏览器编译);前端需要去学一下Webpack
- 4.自动更新,可实时查看最新效果等;
-
安装 Node.js运行环境:
- 先下载node.js;下载地址:node.js官网
- 安装一直下一步就OK了
- 测试环境(CMD):node -v\npm -v
-
npm依赖
- 可以去npm官网下载插件:npm官网
-
安装Vue Cli(脚手架)
- 安装Vue Cli可以直接看官网:安装Vue Cli官网
- 在 CMD中输入:npm install -g @vue/cli(-g表示所有)
- 测试:vue --version
成功如下图:
注意脚手架的版本不一定跟vue的版本一样。
-这样配置的npm下载插件是国外的;可以访问cnpm:https://developer.aliyun.com/mirror/NPM?from=tnpm;这是淘宝提供的服务器。配置cnpm在CMD中的输入:npm install -g cnpm --registry=https://registry.npm.taobao.org
使用:cnpm --version查看
-
注意:在其他系统使用这些安装命令时需要加sudo(超级管理员) ,windows不用。
创建vue cil并运行:
1、配置项目存放路径:cd 路径
2、创建项目可以用vue --help查看命令;created project vuecil-demo创建项目名称为vuecil-demo
3、创建完之后在选中创建好的项目:cd vuecil-demo
4、启动脚手架npm run serve(关闭服务ctrl+c(可以多按几次))
打开多个服务,只需重新打开一个cmd然后npm run serve,端口号会不一样
使用Visual Studio Code打开项目:
将项目拖入即可
查看终端如下(点击加号开启多个,按住ctrl点击地址,可以跳转到浏览器):
vue项目目录说明可见:vue项目目录说明
组件传值:
只有父组件传值给子组件。
注意:属性传值:值有两种情况,1.传值 2.传引用(对象、数组)引用的是地址,改变值时,会一起变
子组件想要改变父组件的值时,需要用到事件
子组件:
methods: {
updatetitle() {
//注册事件 参数1:事件名称,参数2:;值
this.$emit("updatetitle", "拉布拉多犬title修改后的值");
}
}
父组件:
vue生命线:
父组件传标签到子组件(slot:占位符):
父组件:
<h1 slot="text">这是一个文本</h1>
子组件:
<slot name="text" />
总结项目
父组件:
<template>
<div id="app">
<!-- 3、调用组件 -->
<Header />
<!-- 属性传值:值有两种情况,1.传值 2.传引用(对象、数组) -->
<Users :users="users">
<h1 slot="text">这是一个文本</h1>
</Users>
<p>{{title}}</p>
<foorder @updatetitle="updatetitle" :title="title" />
</div>
</template>
<script>
//1、局部组件的调用
import Users from "./components/Users";
import Header from "./components/Header";
import Foorder from "./components/Foorder";
export default {
name: "App",
data() {
return {
users: [
{ name: "小猪佩奇", wechat: "2510116656", show: true },
{ name: "小猪佩奇", wechat: "2510116656", show: true },
{ name: "小猪佩奇", wechat: "2510116656", show: true },
{ name: "小猪佩奇2", wechat: "2510116656", show: true },
{ name: "小羊苏西", wechat: "2510116656", show: true },
{ name: "小猪佩奇3", wechat: "2510116656", show: true },
{ name: "小猪佩奇4", wechat: "2510116656", show: true },
{ name: "小猪佩奇5", wechat: "2510116656", show: true },
{ name: "小猪佩奇6", wechat: "2510116656", show: true }
],
title: "拉布拉多犬",
text: "<a>这是一个文本</a>"
};
},
methods: {
updatetitle(updatetitle) {
//console.log(updatetitle);
this.title = updatetitle;
}
},
components: {
//2、注册组件
Users,
//sers:Users,
// "mr-users": Users
Header,
foorder: Foorder
}
};
</script>
//scoped相当于作用域
<style>
h1 {
color: purple;
}
</style>
子组件:
<template>
<div class="foorder">
<footer>
<p>{{copyright}}</p>
<p @click="updatetitle()">{{title}}</p>
</footer>
</div>
</template>
<script>
export default {
props: {
title: {
type: String
}
},
data() {
return {
copyright: "copyright 2020 Vue Demo"
};
},
methods: {
updatetitle() {
//注册事件 参数1:事件名称,参数2:;值
this.$emit("updatetitle", "拉布拉多犬title修改后的值");
}
}
};
</script>
<style scoped>
.foorder {
background: black;
padding: 10px;
}
p {
color: white;
text-align: center;
}
</style>
子组件:
<template>
<div class="users">
<h1>Users.vue</h1>
<slot name="text" />
<ul>
<!-- 在使用脚手架的for时必须给一个key值一定时唯一的值 -->
<li @click="user.show=!use.show" v-for="(use,index) in users" :key="index">
<h2>{{use.name}}</h2>
<h2 v-show="use.show">{{use.wechat}}</h2>
</li>
</ul>
</div>
</template>
<script>
export default {
// props: ["users"],
props: {
users: {
type: Array,
required: true
}
},
data() {
return {};
},
methods: {
test() {
console.log(this.users);
}
}
};
</script>
<style scoped>
h1 {
color: green;
}
</style>
子组件:
<template>
<div class="foorder">
<footer>
<p>{{copyright}}</p>
<p @click="updatetitle()">{{title}}</p>
</footer>
</div>
</template>
<script>
export default {
props: {
title: {
type: String
}
},
data() {
return {
copyright: "copyright 2020 Vue Demo"
};
},
methods: {
updatetitle() {
//注册事件 参数1:事件名称,参数2:;值
this.$emit("updatetitle", "拉布拉多犬title修改后的值");
}
}
};
</script>
<style scoped>
.foorder {
background: black;
padding: 10px;
}
p {
color: white;
text-align: center;
}
</style>
动态组件和缓存(Component和keep-allve):
使用VS Code创建vue项目:
跟cmd是一样的。
可能会出现脚本拦截解决方法可见:拦截解决方法
添加插件:
1、 vue add ·需要添加的插件·
2、npm install ·npm install·(3.0后的版本)
vue的环境变量:
创建一个.env文件,定义变量;使用时需要先在data中拿到它(url: process.env.VUE_APP_URL)。
开发环境变量:创建一个.env.development文件,定义,使用都一样。
Vue 3.0后的新特性(可视化):
可以独立运行.vue文件:
- 输入命令:vue serve holler.vue(holler.vue是文件)这里它会提示让你装一个全局的组件:npm install -g @vue/cli-service-global
图形页面构建项目(GUi)
- 终端中输入vue ui,创建跟终端创建时一样的
vue配置文件(默认路径,静态文件等):
注意文件名必须是(vue.config.js),这样vue才会自动加载这个文件。