Vue
1、Vue介绍
Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。
2、使用Vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 1、引入Vue-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<!--2、新建app-->
<div id="app">
<!-- 6、双大括号展示数据-->
<button @:click="count++">Count is:{{count}}</button>
</div>
<script>
// 3、导入createApp
const {createApp} = Vue //ES6对象的解构赋值
createApp({
data() { //ES6对象的解构赋值(函数)
return {
count: 0 //3、创建数据
}
}
}).mount('#app') //5、挂载到#app上
/* Vue.createApp({
data: function () {
return {
count: 0
}
}
}).mount('#app')*/
</script>
</body>
</html>
3、文本插值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<p>{{msg}}</p>
<!-- 最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号): -->
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
msg: "Hello,World",
};
},
}).mount("#app");
</script>
</body>
</html>
js中的数据展示在界面上,相当于原生js中的innerText方法
4、原始HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<p>我会{{msg}}</p>
<p>我会 <span v-html="msg"></span>了</p>
</div>
<script>
const {createApp}=Vue
createApp({
data() {
return{
msg:'<strong>Vue</strong>'
}
}
}).mount('#app')
</script>
</body>
</html>
本指令相当于原生js中的innerHTML
5、Attribute 绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<img v-bind:src="imgUrl" alt="">
<img :src="imgUrl" alt="">
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
imgUrl:'1.png'
};
},
}).mount("#app");
</script>
</body>
</html>
v-bind来修改标签的属性,简写用:即可
5.1 布尔型 Attribute
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<audio src="":controls="ctl"></audio>
</div>
<script>
const {createApp}=Vue
createApp({
data() {
return{
ctl:false //true
}
}
}).mount('#app')
</script>
</body>
</html>
5.2 同时绑定多个Attribute
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<div v-bind="obj">1231</div>
<div :="obj">简写成:也可以</div>
</div>
<script>
const {createApp}=Vue
createApp({
data() {
return{
obj:{
id:'textId',
className:'textClass', //注意:class名在js中要写成className,在这里用class或className都可以
title:'我是title'
}
}
}
}).mount('#app')
</script>
</body>
</html>
6、使用JavaScript表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<p>number:{{num+1}}</p>
<p>小明本次考试{{scoreNum<60?"不及格":"及格"}}</p>
<!-- 这里必须是表达式-->
<p :id="`list-${id}`">{{message.split('').reverse().join('')}}</p>
</div>
<script>
const {createApp}=Vue
createApp({
data() {
return{
num:0,
scoreNum:60,
message:'Hello,world!',
id:1
}
}
}).mount('#app')
</script>
</body>
</html>
注意:每个绑定仅支持单一表达式,也就是一段能够被求值的JavaScript代码(语句不可以)
5.4 调用函数
可以在绑定的表达式里调用函数,但是非常不建议如此去做,可以使用Math或Date等全局暴露的函数。
<p>生成一个随机数{{Math.random()}}}</p>
6、computed计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<p>{{reverseStr}}</p >
<ul>
<li>{{text.split('').reverse().join('')}}</li>
<li>{{text.split('').reverse().join('')}}</li>
<!-- 上面两行,同样的功能要计算两次,消耗性能,并且导致html代码臃肿,下面用计算属性更优-->
<li>{{reverseStr}}</li>
<li>{{reverseStr}}</li>
<li>{{reverseStr}}</li>
<li>{{reverseStr}}</li>
</ul>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
text: "Hello,world",
};
},
computed: {
reverseStr() { //这里一定要指定this.text,this指的是当前实例,可以理解为data里的数据
return this.text.split("").reverse().join("");
},
},
}).mount("#app");
</script>
</body>
</html>
7、事件处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<p>{{count}}</p>
<button v-on:click="increment()">+</button>
<button @:click="increment()">+</button>
<button v-on:click="decrement()">-</button>
<button @:click="decrement()">-</button>
<button @click="increment(6)">+6</button>
<button @click="decrement(6)">-6</button>
</div>
<script>
const {createApp} = Vue;
createApp({
data() {
return {
count: 0,
};
},
computed: {
//计算属性
},
methods: {
//计算方法
increment(a=1) {
this.count+=a
},
decrement(a=1) {
this.count-=a;
},
},
}).mount("#app");
</script>
</body>
</html>
计算属性VS计算方法
注意:计算属性和方法,在结果上确实是相同的,然而不同之处在于
计算属性会基于其响应式依赖而被缓存。一个计算属性仅会在响应式依赖更新时才会被重新计算。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<input type="number" v-model="count">
<p>输入的数字乘以2:{{chengYi2}}</p >
<p>{{methodChengYi2()}}</p >
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
count: 0,
};
},
computed: {
chengYi2(){//当数据来源被改变,则计算属性重新计算
return this.count*2
}
},
methods: {
methodChengYi2(){//何时调用,何时计算
return this.count*2
}
},
}).mount("#app");
</script>
</body>
</html>
8、条件渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<ul>
<li v-if="type==='A'">AAAA</li>
<li v-else-if="type==='B'">BBBB</li>
<li v-else>CCCC</li>
</ul>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
type: "A",
};
},
}).mount("#app");
</script>
</body>
</html>
9、列表渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<table>
<thead>
<tr>
<th>id</th>
<th>书名</th>
<th>价格</th>
</tr>
</thead>
<tbody>
<tr v-for="book of books" :key="book.id">
<!-- key一般是数据库里的数据上的唯一且不重复的主键——即id -->
<td>{{book.id}}</td>
<td>{{book.name}}</td>
<td>{{book.price}}</td>
</tr>
</tbody>
</table>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
books: [
{ id: 0, name: "三体", price: 68 },
{ id: 1, name: "平凡的世界", price: 89 },
{ id: 2, name: "三国演戏", price: 48 },
],
};
},
}).mount("#app");
</script>
</body>
</html>
10、表单输入绑定
多行文本,即换行符,可以被v-model实时修改数据
此CSS属性可以展示字符串中的换行符
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<p style="white-space: pre-line;">{{message}}</p>
<textarea name="" id="" v-model="message"></textarea>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
message:''
};
},
}).mount("#app");
</script>
</body>
</html>
复选框
数据的单向绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<label for="ipt">
<input type="checkbox" id="ipt" :checked="checked">数据单向绑定,data驱动UI,UI不可修改data
<p>{{checked}}</p>
</label>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
checked:false
};
},
}).mount("#app");
</script>
</body>
</html>
数据的双向绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<label for="ipt">
<input type="checkbox" id="ipt" v-model="checked">
<p>{{checked}}</p>
</label>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
checked:true
};
},
}).mount("#app");
</script>
</body>
</html>
将多个复选框绑定到同一个数组或集合
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<h2>选中的人是:{{checkedNames}}</h2>
<input type="checkbox" v-model="checkedNames" value="Jack">Jack
<input type="checkbox" v-model="checkedNames" value="John">John
<input type="checkbox" v-model="checkedNames" value="Mike">Mike
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
checkedNames:[]
};
},
}).mount("#app");
</script>
</body>
</html>
单选按钮
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<h2>选中的人是:{{picked}}</h2>
<input type="radio" v-model="picked" value="1">男
<input type="radio" v-model="picked" value="0">女
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
picked:1
};
},
}).mount("#app");
</script>
</body>
</html>
选择器
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
selected: "",
};
},
}).mount("#app");
</script>
</body>
</html>
注意: 如果 v-model 表达式的初始值不匹配任何一个选择项, 元素会渲染成一个“未选择”的状态。在 iOS 上,这将导致用户无法选择第一项,因为 iOS 在这种情况下不会触发一个 change 事件。因此,我们建议提供一个空值的禁用选项,如上面的例子所示。
多选
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<div>Selected: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
selected: []
};
},
}).mount("#app");
</script>
</body>
</html>
修饰符
.lazy
默认情况下,v-model 会在每次 input 事件后更新数据 (IME 拼字阶段的状态例外)。你可以添加 lazy 修饰符来改为在每次 change 事件后更新数据
.number
- 如果你想让用户输入自动转换为数字,你可以在 v-model 后添加 .number 修饰符来管理输入
- 如果该值无法被 parseFloat() 处理,那么将返回原始值。
- number 修饰符会在输入框有 type="number" 时自动启用。
.trim
如果你想要默认自动去除用户输入内容中两端的空格,你可以在 v-model 后添加 .trim 修饰符
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
<input type="text" v-model.lazy="message">
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
message:''
};
},
}).mount("#app");
</script>
</body>
</html>
11、声明周期
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
<style>
</style>
</head>
<body>
<div id="app">
{{message}}
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
message:111
};
},
setup(){
console.log('setup');
},
beforeCreate(){
// this.test() 失败
console.log('beforeCreate');
},
created(){
this.test() //成功
console.log('created');
},
beforeMount(){
console.log('beforeMount');
},
mounted(){
this.test()
console.log('mounted');
},
beforeUpdate(){
this.test()
console.log('beforeUpdate');
},
updated(){
console.log('updated');
},
beforeUnmount(){
console.log('beforeUnmount');
},
unmounted(){
console.log('unmounted');
},
methods:{
test(){
console.log('test');
}
}
}).mount("#app");
</script>
</body>
</html>
12、 watch 侦听器
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
<style></style>
</head>
<body>
<div id="app">
<p>{{message}}</p>
<input type="text" v-model="message" />
<!-- name没有被监听(watch),所以name不会有alert -->
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
message: "111",
name: "小明",
};
},
watch: {
message() {
if (this.message.length > 10) alert("long");
},
},
}).mount("#app");
</script>
</body>
</html>
13、vue中的DOM操作
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3"></script>
<style>
#test{
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<div id="test" ref="test"></div>
<button @click="big">变大div</button>
<input type="text" ref="ipt">
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
};
},
methods:{
big(){
console.log(this.$refs);//对象
this.$refs.test.style.width='200px'
}
},
mounted(){//在mounted之后才会真正的有 $refs
console.log(this.$refs);
this.$refs.ipt.focus()
}
}).mount("#app");
</script>
</body>
</html>
14、Vue脚手架
14.1 vue-cli
14.1.1 安装
首先确保已安装的node和npm
node -v
npm -v
其次确保npm镜像地址是淘宝镜像(有梯子除外)
npm config get registry
如果结果是:https://registry.npmmirror.com/,则说明是淘宝镜像,否则改成淘宝镜像命令如下:
npm config set registry https://registry.npmmirror.com/
再次安装vue-cli,命令如下:
npm i -g @vue/cli
查看vue-cli安装版本
vue -V
14.1.2 基于vue-cli创建vue3.0项目
vue create hello-world #项目名称必须是小写英文字母
Manally select features #手动选择分支
Bable #仅选择bable
choose a version for Vue? #3.x
where do you ? #In dedicated config files 保存到另外文件夹中,既不保存到package.json中(package.json 内容够多了)
Save this as preset #No 不保存为未来分支
Loading。。。。。。
cd hello-world
npm run serve
#复制网址打开浏览器即可
14.1.3 基于vue-cli vueUI创建项目
非常不建议使用,丢人现眼
14.2基于Vite创建项目
基于vite,不需要安装,只要有node和npm环境即可,但是node版本要在15.0以上
$ npm init vue
项目目录
vue-project
--.vscode #配置vscode,没用
--node_modules
--public
--src #关键,程序员写的代码都在这里
----assets #项目所需的静态文件,图片,css等
----components #组建文件夹
----App.vue #根组件
----main.js
--.gitignore #git上传时,不要的文件配置
--index.html #页面,仅包含一个#app
--package.json
--package-lock.json
--README.md
--vite #vite配置文件
15、组件
![]()
15.1 新建组件
在vite创建的项目中创建组件:
在components文件夹下,右键新建.vue文件,就是一个组件
<template>
<p>这里面写标签,外层的template仅能做辅助编译将来生成的HTML界面中,不存在template标签</p>
<div>
在过去,vue2中,这里的根标签必须仅能有一个(即template的亲儿子只能有一个,)vue3不做限制
</div>
</template>
<script>
这里面写JS
export default {//对外暴露,ES6模块化语法,等同于node中commonJS中的module.exports
name: 'Header-1',
data () {
return {
message:''
}
},
},
</script>
<style scoped>
这里是css
这里的scoped
</style>
15.2 引入组件
在父组件中引入组件
<template>
</template>
<script>
import HellowWorld from './components/HelloWorld.vue'
//编辑器可能会吧.vue省略掉,vite中一定要加上,如果在vue-cli 中,可以不加.vue后缀
export default {
name: 'Header-1',
}
</script>
<style scoped>
</style>
注册组件
注册组件分两种,分别为注册局部组件和全局组件
注册局部组件(常用)
<template>
</template>
<script>
import HellowWorld from './components/HelloWorld.vue'
//编辑器可能会吧.vue省略掉,vite中一定要加上,如果在vue-cli 中,可以不加.vue后缀
export default {
name: 'Header-1',
components:{
HelloWorld
}
}
</script>
<style scoped>
</style>
注册全局组件
main.js
import { createApp } from 'vue'
import App from './App.vue'
import './assets/main.css'
import Header1 from './components/Header-1.vue'
createApp(App).component('Header1',Header1)//全局注册
.mount('#app')
使用组件
父组件
<template>
<HelloWorld></HelloWorld>
<HelloWorld/>
<helloWorld></helloWorld>
<helloWorld/>
</template>
注意 当组件中没有内容时,才可以改写成单标签形式

浙公网安备 33010602011771号