vue框架快速上手
1.导入vue的脚本文件
2.声明要被vue所控制的DOM区域
3.创建vue的实例对象
1.基本用法
<!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>
//1.导入vue的脚本文件
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
//2.声明要被vue所控制的DOM区域
<div id="app">
{{message}}
</div>
//3.创建vue的实例对象
<script>
Vue.createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
</body>
</html>
2.内容渲染
<!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>姓名:{{username}}</p>
<p>{{desc}}</p>
<p v-html="desc"></p>
</div>
<script>
const vm={
data:function(){
return{
username:'zhangshan',
desc:'<a href="http://www.baidu.com">百度</a>'
}
}
}
const app=Vue.createApp(vm)
app.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">
<a :href="link">百度</a>
<input type="text" :placeholder="inputValue">
<img :src="imgSrc" :style = "{width:w}" alt="">
</div>
<script>
const vm = {
data: function(){
return{
link:"http://www.baidu.com",
inputValue:'请输入内容',
imgSrc:'./images/demo.png',
w:'500px'
}
}
}
const app = Vue.createApp(vm)
app.mount('#app')
</script>
</body>
</html>
运行结果:
4.使用JavaScript表达式
<!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>{{number + 1}}</p>
<p>{{ok ? 'True' : 'False'}}</p>
<p>{{message.split('').reverse().join('')}}</p>
<p :id="'list-' + id">xxx</p>
<p>{{user.name}}</p>
</div>
<script>
const vm = {
data: function(){
return {
number: 9,
ok: false,
message: 'ABC',
id: 3,
user:{
name:'zs'
}
}
}
}
const app = Vue.createApp(vm)
app.mount('#app')
</script>
</body>
</html>
运行结果:
5.事件绑定指令
<!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">
<h3>count 的值为:{{count}}</h3>
//原生onclick封装成 v-on:click,v-on:和@等价
<button v-on:click="addCount">+1</button>
<button @click="count+=1">+1</button>
</div>
<script>
const vm ={
data :function(){
return{
count: 0,
}
},
methods:{
//点击按钮,让count自增+1
addCount(){
this.count += 1
},
},
}
const app = Vue.createApp(vm)
app.mount("#app")
</script>
</body>
</html>
运行结果:
6.条件渲染指令
<!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">
<button @click="flag = !flag">Toggle Flag</button>
//如果flag值为false,v-if和v-show都不显示,但是区别在于v-if标签不会被创建,v-show标签会被创建
<p v-if="flag">请求成功----被v-if控制</p>
<p v-show="flag">请求成功----被v-show控制</p>
</div>
<script>
const vm = {
data :function(){
return{
flag:false,
}
}
}
const app = Vue.createApp(vm)
app.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">
<ul>
<li v-for="(user, i) in userList">索引是:{{i}},姓名是:{{user.name}}</li>
</ul>
</div>
<script>
const vm = {
data :function(){
return {
userList:[
{id:1,name:'zhangsan'},
{id:2,name:'lisi'},
{id:3,name:'wangwu'}
],
}
},
}
const app = Vue.createApp(vm)
app.mount("#app")
</script>
</body>
</html>
运行结果:
8.v-for中的key
<!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">
<!-- 添加用户区域 -->
<div>
<!-- v-model比起:value可以双向绑定,输入的值可以影响name -->
<input type="text" v-model="name">
<button @click="addNewUser">添加</button>
</div>
<!-- 用户列表区域 -->
<ul>
<li v-for="(user, index) in userlist" :key="user.id">
<input type="checkbox"/>
姓名:{{user.name}}
</li>
</ul>
</div>
<script>
const vm = {
data :function(){
return{
//用户列表
userlist:[
{id:1,name:'zs'},
{id:2,name:'ls'}
],
//输入用户名
name:'',
//下一个可用的id值
nextId:3
}
},
methods:{
//点击了添加按钮
addNewUser(){
//unshift是在列表起初位置加进去
this.userlist.unshift({id: this.nextId,name:this.name})
this.name=''
this.nextId++
}
}
}
const app = Vue.createApp(vm)
app.mount("#app")
</script>
</body>
</html>
运行结果:
NPM简介
- NPM(Node Package Manager)是一个NodeJS包管理和分发工具。
- NPM以其优秀的依赖管理机制和庞大的用户群体,目前已经发展成为整个JS领域的依赖管理工具。
- NPM最常见的用法就是用于安装和更新依赖。要使用NPM,首先要安装Node工具。
Vue CLl使用
- Vue CLl是Vue官方提供的构建工具,通常称为脚手架
- 用于快速搭建一个带有热重载(在代码修改后不必刷新页面即可呈现修改后的效果)及构建生产版本等功能的单页面应用。
- Vue CLl基于 webpack 构建,也可以通过项目内的配置文件进行配置,安装:npm install -g @vue/cli
创建vue
创建条件:npm install -g @vue/cli(已经安装过,不用再次输入)
出现bug
1.输入 vue create test1,出现下面,选择Manually select features
Vue CLI v5.0.8
? Please pick a preset: (Use arrow keys)
> Default ([Vue 3] babel, eslint)
Default ([Vue 2] babel, eslint)
Manually select features
2.出现下面,对 (* ) Linter / Formatter按下空格取消,回车
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and
<enter> to proceed)
>(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
( ) Router
( ) Vuex
( ) CSS Pre-processors
( ) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
3.出现下面,选择3.x
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel
? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
> 3.x
2.x
4.出现下面,选择> In package.json
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel
? Choose a version of Vue.js that you want to start the project with 3.x
? Where do you prefer placing config for Babel, ESLint, etc.?
In dedicated config files
> In package.json
5.出现下面,输入大写N
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel
? Choose a version of Vue.js that you want to start the project with 3.x
? Where do you prefer placing config for Babel, ESLint, etc.? In package.json
? Save this as a preset for future projects? (y/N) N
6.创建成功
Vue CLI v5.0.8
✨ Creating project in D:\Vscode_workspace\test1.
⚙️ Installing CLI plugins. This might take a while...
added 857 packages in 34s
98 packages are looking for funding
run `npm fund` for details
🚀 Invoking generators...
📦 Installing additional dependencies...
added 6 packages in 3s
98 packages are looking for funding
run `npm fund` for details
⚓ Running completion hooks...
📄 Generating README.md...
🎉 Successfully created project test1.
👉 Get started with the following commands:
$ cd test1
$ npm run serve
vue组件开发
组件的构成
- Vue 中规定组件的后缀名是.vue
- 每个 .vue 组件都由 3部分构成,分别是
1.template,组件的模板结构,可以包含HTML标签及其他的组件
2.script,组件的JavaScript 代码
3.style,组件的样式
新建组件
1.在components目录下新建一个Hello.vue
2.在App.vue的里添加 import Hello from ‘./components/Hello.vue’
3.在components:{}中添加注册 Hello
4.在添加标签
组件间的传值
- 组件可以由内部的Data提供数据,也可以由父组件通过prop的方式传值
- 兄弟组件之间可以通过Vuex等统一数据源提供数据共享。
数据title
<template>
<div>
<h1>{{ title }}</h1>
</div>
</template>
<script>
export default{
name:"Movie",
data:function(){
return{
title:"静冈1"
}
}
}
</script>
本机npm install element-ui 仅支持vue2版本,如果从网上下载了文件,先删除node_modules文件,然后在终端输入npm install就会自动生成node_modules文件
使用element-ui
1.先创建vue2的项目
2.输入npm install element-ui
3.在main.js中添加
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI); //全局注册
使用font-awesome
1.输入npm install font-awesome
2.在main.js中添加import 'font-awesome/css/font-awesome.min.css'
3.<i class="fa fa-address-book fa-1g">asf</i>
所有样式前都要加上fa
4.使用 fa-lg (33%递增)、fa-2x、 fa-3x、fa-4x,或者 fa-5x 类 来放大图标。
Axios简介
- 在实际项目开发中,前端页面所需要的数据往往需要从服务器端获取,这必然涉及与服务器的通信。
- Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。
- Axios 在浏览器端使用XMLHttpRequests发送网络请求,并能自动完成JSON数据的转换。
- 安装:npm install axios
- 地址:https://www.axios-http.cn/
发送网络请求
- vue的生命周期:创建,加载,渲染,销毁
- methods:{}里面是放自定义函数
- created:function(){}这种跟生命周期相关的函数放在跟data:function(){}同级
created:function(){
console.log("组件被创建")
},
mounted:function(){
console.log("组件被挂载") //挂载就是渲染
},
使用axios
1.在终端输入npm install axios
2.在Hello.vue中添加import axios from 'axios'
(哪里使用就在哪里加)
3.前端端口8080,后端端口改成server.port=8088
4.在App.vue添加下面代码,记得加上后端端口localhost:8088
created:function(){
console.log("app组件被创建")
axios.get("http://localhost:8088/user/findAll").then(function(response){
console.log(response)
})
},
5.报错,该报错是跨域问题
6.解决:在控制器加上@CrossOrigin
7.在Hello.vue添加
<template>
<el-table :data="tableData" style="width: 100%" :row-class-name="tableRowClassName">
<el-table-column prop="id" label="序号" width="180"></el-table-column>
<el-table-column prop="username" label="姓名" width="180"></el-table-column>
<el-table-column prop="password" label="密码" width="180"></el-table-column>
<el-table-column prop="birthday" label="生日" width="180"></el-table-column>
</el-table>
</template>
<script>
import axios from 'axios'
export default{
name:"Hello",
methods: {
tableRowClassName({row, rowIndex}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
}
},
created:function(){
console.log("hello创建")
axios.get("http://localhost:8088/user/findAll").then((response)=>{
this.tableData = response.data
})
},
data() {
return {
tableData: []
}
},
}
</script>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
8.运行成功
axios全局配置
- 就不用每个组件都要导入axios
1.在main.js中加入
import axios from 'axios'
axios.defaults.baseURL = "http://localhost:8088"
Vue.prototype.$http = axios
2.Hello.vue中created:function(){}内容修改成
created:function(){
this.$http.get("/user/findAll").then((response)=>{
this.tableData = response.data
})
},
3.运行成功
为什么会出现跨域问题
- 为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下,不能
读写对方资源,称为同源策略,同源策略是浏览器安全的基石 - 同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能
- 所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
- 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域,此时无法读取非同源网页的 Cookie,无法向非同源地址发送 AJAX 请求
跨域问题解决
- CORS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域请求。
- CORS可以在不破坏即有规则的情况下,通过后端服务器实现CORS接口,从而实现跨域通信。
- CORS将请求分为两类:简单请求和非简单请求,分别对跨域通信提供了支持。
简单请求
满足以下条件的请求即为简单请求:
- 请求方法:GET、POST、HEAD
- 除了以下的请求头字段之外,没有自定义的请求头:
Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type - Content-Type的值只有以下三种:
text/plain、multipart/form-data、application/x-www-form-urlencoded
简单请求的服务器处理
- 对于简单请求,CORS的策略是请求时在请求头中增加一个Origin字段
Host:localhost:8080
Origin:http://localhost:8081
Referer:http://localhost:8081/index.html
- 服务器收到请求后,根据该字段判断是否允许该请求访问,如果允许,则在
HTTP头信息中添加Access-Control-Allow-Origin字段。
Access-Control-Allow-0rigin:http://localhost:8081
Content-Length:20
Content-Type:text/plain;charset=UTF-8
Date:Thu,12 Jul 2018 12:51:14 GMT
非简单请求
- 对于非简单请求的跨源请求,浏览器会在真实请求发出前增加一次OPTION请求,称为预检请求(preflight request)
- 预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到HTTP头信息字段中,询问服务器是否允许这样的操作。
- 例如一个GET请求:
OPTIONS /test HTTP/1.1
Origin:http://www.test.com
Access-Control-Request-Method:GET
Access-Control-Request-Headers:X-Custom-Header
Host:www.test.com
-
Access-Control-Request-Method表示请求使用的HTTP方法,Access- Control-Request-Headers包含请求的自定义头字段
-
服务器收到请求时,需要分别对Origin、Access-Control-Request-Method、Access-Control-Request-Headers进行验证,验证通过后,会在返回HTTP头
-
信息中添加:
Access-Control-Allow-0rigin:http://www.test.com
Access-Control-A1low-Methods:GET,POST,PUT,DELETE
Access-Control-Allow-Headers:X-Custom-Header
Access-Control-Allow-Credentials:true
Access-Control-Max-Age:1728000
- Access-Control-Allow-Methods、Access-Control-Allow-Headers:真实请求允许的方法、允许使用的字段
- Access-Control-Allow-Credentials: 是否允许用户发送、处理cookie
- Access-Control-Max-Age: 预检请求的有效期,单位为秒,有效期内不会重复发送预检请求。
- 当预检请求通过后,浏览器才会发送真实请求到服务器。这样就实现了跨域资源的请求访问。
VueRouter安装与使用
- Vue路由vue-router是官方的路由插件,能够轻松的管理 SPA 项目中组件的切换。
- Vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来
- vue-router 目前有 3.x的版本和 4.x的版本,vue-router 3.x只能结合 vue2进行使用,vue-router 4.x 只能结合 vue3 进行使用
- 安装:npm install vue-router@4
vue2只能按照npm install vue-router@3
使用VueRouter
1.创建Discover.vue、Friend.vue、My.vue
2.在App.vue添加
<template>
<div>
<h1>App组件</h1>
<router-link to="/discover">发现音乐</router-link>
<router-link to="/Friends">发现音乐</router-link>
<router-link to="/My">发现音乐</router-link>
<router-view></router-view>
</div>
</template>
3.新建router文件夹,vrouter文件夹下新建index.js文件,并在index.js中添加
import VueRouter from "vue-router";
import Vue from "vue";
//把组件导进来
import Discover from '../components/Discover.vue'
import Friends from '../components/Friends.vue'
import My from '../components/My.vue'
Vue.use(VueRouter)
const router = new VueRouter({
//指定hash属性与组件的对应关系
routes:[
{path:'/',redirect:"/discover"},//首页定向到discover页面
{path:'/discover',component:Discover},
{path:'/friends',component:Friends},
{path:'/my',component:My},
]
})
export default router//对象导出
4.在main.js中添加
import Vue from 'vue'
import App from './App.vue'
import router from './router' //
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router //
}).$mount('#app')
嵌套组件
- 新建Playlist.vue、Toplist.vue
- 在Discover中嵌套子组件
<template>
<div>
<h1>发现音乐</h1>
//discover前一定要加/
<router-link to="/discover/toplist">推荐</router-link>
<router-link to="/discover/playlist">歌单</router-link>
<hr>
<router-view></router-view>
</div>
</template>
- 在index.js导入需要的组件
//法一:添加
import Toplist from '../components/Toplist.vue'
import Playlist from '../components/Playlist.vue'
{path:'/discover/playlist',component:Playlist},
{path:'/discover/toplist',component:Toplist},
//法二:通过children属性,嵌套声明子路由
import Toplist from '../components/Toplist.vue'
import Playlist from '../components/Playlist.vue'
{
path:'/discover',
component:Discover,
//通过children属性,嵌套声明子路由
children:[
{path:"toplist",component:Toplist},
{path:"playlist",component:Playlist},
]
},
动态路由
1.在My.vue添加嵌套组件
<template>
<div>
<h1>我的音乐</h1>
<router-link to="/my/1">商品1</router-link>
<router-link to="/my/2">商品2</router-link>
<router-link to="/my/3">商品3</router-link>
<router-view></router-view>
</div>
</template>
2.动态路由添加
//法一:
(1)新建Product.vue,添加
<template>
<h3>商品{{ $route.params.id }}</h3>
</template>
(2)在index.js添加
import Product from '../components/Product.vue'
{
path:'/my',
component:My,
children:[
{path:":id",component:Product},
]
},
//法二:
(1)新建Product.vue,添加
<template>
<h3>商品{{ id }}</h3>
</template>
<script>
export default {
props:["id"]
}
</script>
(2)在index.js添加
import Product from '../components/Product.vue'
{
path:'/my',
component:My,
children:[
{path:":id",component:Product,props:true},
]
},
编程式导航
<template>
<button @click="gotoProduct(2)">跳转到商品2</button>
</template>
<script>
export default{
methods :{
gotoProduct:function(id){
this.$router.push('/movie/s{id}')
}
}
}
</script>