0.vue项目创建
01.vscode创建vue项目以及常见问题汇总
02.项目结构解读
03.启动项目直接访问自定义功能页面非APP.vue
1.事件修饰符
1.1事件修饰符stop
1.2事件修饰符capture
1.3事件修饰符self
1.4事件修饰符once
1.5事件修饰符prevent
2.过滤器(全局/私有)
3.自定义组件
3.1 自定义组件方式一
3.2 自定义组件方式二
3.3自定义组件方式三
3.4自定义组件方式四
3.5自定义私有组件
3.6自定义组件定义data数据
3.7父组件向子组件传参
3.8子组件向父组件传参
3.9 ref引用
4.路由
4.1 路由创建
4.2 路由路径传参:query和params
4.3 嵌套路由
4.4命名视图
5.watch监听器
6.computed计算属性
7.vscode常用操作
7.1 创建vue文件并自动补全
8.常用指令
8.1 v-for
9.axios
0.vscode创建vue项目以及启动
01.vscode创建vue项目以及常见问题汇总
打开vscode,工具栏点击终端选择新建终端.进入到项目存储目录,执行以下命名创建项目:
npm init vue@latest
按照项目进行对应选择,创建项目名称需要注意,不要大写,默认项目名是vue_project.这里创建项目名为.
进入到创建项目vue_demo下安装项目依赖:
cnpm install
显示下面说明安装成功:
启动项目:
在项目目录下执行(项目构建完成提示可用指令):
npm install
npm run dev
注意Ctrl+点击连接,直接点击是打不开的.打开之后页面(默认打开的是app.vue页面):
可能遇到问题:
1.权限问题
处理方案:
涉及命令:
get-ExecutionPolicy
set-ExecutionPolicy RemoteSigned
2.Cannot find module ‘bug-versions/package.json’
处理方案:
npm install --save-dev
执行后重新执行cnpm install
3.证书过期
处理方案:
1、取消ssl验证:
npm config set strict-ssl false
这个方法一般就可以解决了。
2、更换npm镜像源:
npm config set registry http://registry.cnpmjs.org
npm config set registry http://registry.npm.taobao.org
项目结构解读
入口文件是main.js,配置路由,实例化vue
router下的index.js是路由配置规则,配置指定路径对应的vue页面.
入口页面是APP.vue,根据路由跳转对应页面.
main.js:
import './assets/main.css'
// 引入createApp方法
import { createApp } from 'vue'
// 引入根组件,可以看做入口组件
import App from './App.vue'
// 引入路由
import router from './router'
// createApp方法创建vue组件,相当于new Vue,#app为id为app的div根标签
const app = createApp(App)
// new Vue({
// el:"#app",
// data() {
// return {
// message: 'hello',
// };
// },
// })
// vue实例添加路由配置
app.use(router)
// 全局挂载vue实例到页面
app.mount('#app')
router下的index.js:
// 路由配置方法
import { createRouter, createWebHistory } from 'vue-router'
// 引入组件
import HomeView from '../views/HomeView.vue'
import MyPage from '../views/MyPage.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
// 配置路由组件
routes: [
{
path: '/',
name: 'myPage',
component: MyPage
},
{
path: '/home',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue')
}
]
})
export default router
APP.vue:
<script setup>
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<header>
<!-- <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" /> -->
<div class="wrapper">
<HelloWorld msg="You did it!" />
<nav>
<RouterLink to="/home">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
<RouterLink to="/">myPage</RouterLink>
</nav>
</div>
</header>
<RouterView />
</template>
03.启动项目直接访问自定义功能页面非App.vue
创建完项目之后,启动项目默认打开的就是App.vue,因为是基于App.vue创建的vue实例.都是在main.js中进行的设置:
// 引入createApp方法
import { createApp } from 'vue'
// 引入根组件,可以看做入口组件
import App from './App.vue'
// createApp方法创建vue组件,相当于new Vue,#app为id为app的div根标签
const app = createApp(App)
// new Vue({
// el:"#app",
// data() {
// return {
// message: 'hello',
// };
// },
// })
// 全局挂载vue实例到页面
app.mount('#app')
所以在项目启动后修改默认启动页可以修改创建vue实例时引入的页面.只需要将引入的App.vue替换为自定义页面即可.
// 引入根组件,可以看做入口组件
// import App from './App.vue'
// 此页面为自定义功能页面
import App from './views/weather.vue'
另外一种方式就是通过路由方式设置,具体设置可以参考4.路由.项目启动打开页面还是App.vue,跳转其他页面通过自定义页面实现.
1.事件修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./lib/vue.js"></script>
<style>
.out{
background: aqua;
height: 200px;
width: 200px;
}
.in{
background: red;
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<div id="app">
<div class="out" @click="clickOut">
<div class="in" @click="clickIn">
<button @click="clickButton">点我输出内容</button>
</div>
</div>
</div>
<script>
var app=new Vue(
{
el:"#app",
data:{
"msg":"vue学习"
},
methods:{
clickOut(){
console.log("out执行")
},
clickIn(){
console.log("in执行")
},
clickButton(){
console.log("按钮执行")
}
}
}
)
</script>
</body>
</html>
点击按钮发现按钮外边的两个div中的方法都会执行,这种属于冒泡;
1.1事件修饰符stop
stop阻止冒泡事件修饰符
<!--stop:阻止冒泡,使用方式:按钮中click事件后面添加stop-->
<div class="out" @click="clickOut">
<div class="in" @click="clickIn">
<button @click.stop="clickButton">点我输出内容</button>
</div>
点击按钮效果如下:
1.2事件修饰符capture
capture捕捉修饰符
<!--capture在out元素时:捕捉所在元素,执行对应方法,点击按钮标签依次执行clickOut、clickButton、clickIn-->
<div class="out" @click="clickOut">
<!--capture在in元素时:捕捉所在元素,执行对应方法,点击按钮标签依次执行clickIn、clickButton、clickOut-->
<div class="in" @click.capture="clickIn">
<!--capture在button元素时:捕捉所在元素,执行对应方法,点击按钮标签依次执行clickButton、clickIn、clickOut-->
<button @click="clickButton">点我输出内容</button>
</div>
可以理解为capture修饰符所在元素方法先执行,然后元素方法开始从最里面冒泡执行.
1.3事件修饰符self
self自身事件触发时执行
<div class="out" @click="clickOut">
<div class="in" @click="clickIn">
<button @click.self="clickButton">点我输出内容</button>
</div>
作用于button,button事件触发,依次执行方法:clickButton、clickIn、clickOut
<div class="out" @click="clickOut">
<div class="in" @click.self="clickIn">
<button @click="clickButton">点我输出内容</button>
</div>
self作用于里面class为in的div,点击按钮,依次执行方法:clickButton、clickOut.clickIn方法没有冒泡执行是因为有self事件修饰符.
self作用于里面class为in的div,点击里面class为in的div,依次执行方法:clickIn、clickOut.此时还会冒泡执行clickOut
self作用于里面class为in的div,点击外面class为out的div,只执行方法clickOut.
<div class="out" @click.self="clickOut">
<div class="in" @click="clickIn">
<button @click="clickButton">点我输出内容</button>
</div>
self作用于外面class为out的div,点击按钮,依次执行方法:clickButton、clickIn.clickOut方法没有冒泡执行是因为有self事件修饰符.
self作用于外面class为out的div,点击里面class为out的div,只执行方法clickIn.clickOut方法没有冒泡执行是因为有self事件修饰符.
self作用于外面class为out的div,点击外面class为out的div,只执行方法clickOut.
1.4事件修饰符once
once只允许操作一次:
<div class="out" @click.self="clickOut">
<div class="in" @click="clickIn">
<button @click.once="clickButton">点我输出内容</button>
</div>
点击按钮只会执行一次,重复点击不会执行方法
1.5事件修饰符prevent
prevent组织默认行为
比如a标签默认会跳转地址,添加prevent修饰符之后会禁用掉跳转功能.修改如下:
<a href.prevent="https://www.baidu.com">点我跳转百度</a>
2.过滤器
使用过滤器可以将后端返回的数据处理之后重新渲染到前端页面
使用方法:
差值表达式中调用:变量A 丨过滤器函数1名(过滤器传递参数) 丨过滤器函数2名(过滤器传递参数)
过滤器用 Vue.filter方式创建
注意:支持创建多个过滤器,function函数中第一个参数固定为差值表达式中变量名,过滤器创建位置要在new Vue上面.
案例说明:将所示文字部分内容进行替换并后面追加描述.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤器</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<!--过滤器调用方法:差值表达式中使用:变量A 丨过滤器函数名(过滤器传递参数)-->
<!--过滤器调用方法:差值表达式中使用:变量A 丨过滤器函数1名(过滤器传递参数) 丨过滤器函数2名(过滤器传递参数)-->
{{msg | filter1("坏") | filter2}}
</div>
<script>
// 定义过滤器
Vue.filter('filter1',function (msg,arg) {
return msg.replace(/好/g,arg)
})
Vue.filter('filter2',function (msg) {
return msg.concat("真的吗?")
})
var app=new Vue(
{
el:"#app",
data:{
"msg":"我是好人,确实是好人!"
},
methods:{
}
}
)
</script>
</body>
页面显示:
私有过滤器是针对于同一页面有多个vue对象时,只允许指定vue对象进行使用.
在上面案例的基础上添加一个vue对象app2,并将filter2过滤器只允许app2对象使用.app2的vue对象中添加filters属性并定义私有过滤器.代码如下:
<body>
<div id="app">
<!--过滤器调用方法:差值表达式中使用:变量A 丨过滤器函数名(过滤器传递参数)-->
<!--过滤器调用方法:差值表达式中使用:变量A 丨过滤器函数1名(过滤器传递参数) 丨过滤器函数2名(过滤器传递参数)-->
{{msg | filter1("坏") | filter2}}
</div>
<div id="app2">
<!--过滤器调用方法:差值表达式中使用:变量A 丨过滤器函数名(过滤器传递参数)-->
<!--过滤器调用方法:差值表达式中使用:变量A 丨过滤器函数1名(过滤器传递参数) 丨过滤器函数2名(过滤器传递参数)-->
{{msg | filter1("坏") | filter2}}
</div>
<script>
// 定义过滤器
Vue.filter('filter1',function (msg,arg) {
return msg.replace(/好/g,arg)
})
Vue.filter('filter2',function (msg) {
return msg.concat("我是全局过滤器")
})
var app=new Vue(
{
el:"#app",
data:{
"msg":"我是好人,确实是好人!"
},
methods:{
},
// 定义私有过滤器
filters:{
filter2:function (msg) {
return msg.concat("我是私有过滤器")
}
}
}
)
var app2=new Vue(
{
el:"#app2",
data:{
"msg":"我是好人2,确实是好人2!"
},
methods:{
}
}
)
</script>
</body>
对于全局过滤器和私有过滤器存在重名的情况下,默认就近使用私有顾虑器.上述代码效果:
3.自定义组件
3.1 自定义组件方式一
Vue.component("组件名",Vue.extend({
// 此处定义组件页面展示内容
template:"组件内容"
}))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义组件</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<!--驼峰式组件名,标签使用-分隔-->
<!--<my-componet1></my-componet1>-->
<!--非驼峰式组件名,标签直接使用-->
<mycomponet1></mycomponet1>
</div>
<script>
// 组件创建方式一
var com1 = Vue.extend({
// 此处定义组件页面展示内容
template:"<h2>我是组件</h2>"
})
// 参数前者为自定义组件名,如果是驼峰形式,标签应用-进行分隔,如果不是驼峰,标签可以直接用;后面参数为组件的模板对象
// Vue.component("myComponet1",com1)
// Vue.component("mycomponet1",com1)
// 简化写法,不定义变量com1
Vue.component("mycomponet1",Vue.extend({
// 此处定义组件页面展示内容
template:"<h2>我是组件1</h2>"
}))
var app=new Vue(
{
el:"#app",
}
)
</script>
</body>
</html>
3.2 自定义组件方式二
Vue.component("组件名",{
template:"组件页面内容"
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义组件</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<mycomponet2></mycomponet2>
</div>
<script>
// 组件创建方式二
Vue.component("mycomponet2",{
template:"<h3>我是组件2</h3>"
})
var app=new Vue(
{
el:"#app",
}
)
</script>
</body>
</html>
3.3自定义组件方式三
Vue.component("组件名",{
template:"#tem" // 组件模板对象引用,单独定义在template标签中
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义组件</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
<template id="tem">
<h1>我是组件3</h1>
</template>
</div>
<script>
// 组件创建方式三
Vue.component("mycomponet3",{
template:"#tem"
})
// 简化写法
//var mycomponet3={
// template:"#tem"
//}
var app=new Vue(
{
el:"#app",
}
)
</script>
</body>
</html>
3.4自定义组件方式四
使用vue自带的标签展示自定义的组件,创建方式还是上面提到的三种,component标签中is属性用于绑定自定义组件名
<body>
<div id="app1">
<component is="mycomponet4"></component>
</div>
<script>
var app=new Vue(
{
el:"#app1",
components:{
mycomponet4:{
template:"<h2>我是自定义组件4</h2>",
}
}
}
)
</script>
3.5自定义私有组件
和过滤器相同,Vue.componet定义的组件是全局共用的,如果一个页面两个vue对象 如何保证自定义组件只在一个中生效?下面是定义私有组件的方式(和自定义过滤器相似)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义组件</title>
<script src="./lib/vue.js"></script>
<style>
#app1{
background: aqua;
height: 200px;
width: 200px;
}
#app2{
background: red;
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<template id="tem4">
<h1>我是组件4</h1>
</template>
<div id="app1">
<mycomponet4></mycomponet4>
</div>
<div id="app2">
<mycomponet4></mycomponet4>
</div>
<script>
var app1=new Vue(
{
el:"#app1",
components:{
}
}
)
var app2=new Vue(
{
el:"#app2",
data:{},
methods:{},
filters:{},
directives:{},
components:{
// 自定义私有组件
mycomponet4:{
template:"#tem4"
}
}
}
)
</script>
</body>
</html>
3.6自定义组件定义data数据
组件中定义data数据,需要区别vue对象中data:需要定义函数并且函数中需要返回一个对象;
调用方式也是使用差值表达式
<div id="app1">
<mycomponet></mycomponet>
</div>
<script>
var app=new Vue(
{
el:"#app1",
components:{
mycomponet:{
template:"<h2>{{msg1}}我是自定义组件{{msg2}}</h2>",
data: function () {
return {
msg1:"我是组件数据前缀====",
msg2:"====我是组件数据后缀"
}
}
}
}
}
)
</script>
效果如下:
3.7父组件向子组件传参
<div id="app">
<div>{{parentMsg}}</div>
<!--子组件自定义parentdata属性传递父组件数据parentMsg,注意子组件属性不建议使用驼峰-->
<mycomponet v-bind:parentdata="parentMsg"></mycomponet>
</div>
<script>
var app=new Vue(
{
el:"#app",
data:{
parentMsg:"我是父组件信息"
},
components:{
mycomponet:{
// 子组件使用父组件数据,需要先声明子组件自定义属性parentdata并直接在模板对象中使用该属性parentdata即可显示父组件数据parentMsg
props:["parentdata"],
template:"<h2>我是子组件,父组件中传递的数据:{{parentdata}}</h2>"
}
}
}
)
</script>
3.8子组件向父组件传参
自定义事件传参
<div id="app">
<!--子组件通过自定义事件的方式调用父组件方法传递参数,注意自定义事件不能是驼峰-->
<mycomponet v-on:componentmethod="parentMethod"></mycomponet>
<!--<mycomponet @componentmethod="parentMethod"></mycomponet>-->
</div>
<template id="tem">
<div>
<button @click="sonMethod">我是子组件按钮</button>
</div>
</template>
<script>
var app=new Vue(
{
el:"#app",
data:{},
methods:{
parentMethod(param1,param2){
console.log("父组件parentMethod方法执行了,参数param1:"+param1+",参数param2:"+param2)
}
},
components:{
mycomponet:{
template:"#tem",
methods:{
sonMethod(){
console.log("子组件方法执行了")
// 通过事件提交的方式调用父组件中的方法,传递参数给父组件.
// 注意第一个参数为自定义事件,类型为字符串,后面参数为该事件componentmethod对应的父组件中方法parentMethod锁需要的参数
this.$emit("componentmethod","123","456")
}
}
}
}
}
)
</script>
</body>
</html>
3.9 ref引用
注意:this.$refs不能用于子组件中
点击父组件按钮显示内容如下:
<div id="app">
<h2 ref="parenth2">我是父组件标题</h2>
<button @click="parentMethod">我是父组件按钮</button>
<mycomponet ref="mycomponet"></mycomponet>
</div>
<template id="tem">
<div>
<h1>我是子组件标题</h1>
</div>
</template>
<script>
var app=new Vue(
{
el:"#app",
data:{},
methods:{
parentMethod(){
console.log("我是父组件方法")
// 获取父组件的dom属性值,this.$refs.ref引用值parenth2
console.log("父组件引用parenth2文本内容:"+this.$refs.parenth2.innerText)
// 调用子组件的属性sonMsg,this.$refs.ref引用值mycomponet.属性值sonMsg
console.log("子组件mycomponet中sonMsg属性:"+this.$refs.mycomponet.sonMsg)
// 调用子组件的方法sonMethod,this.$refs.ref引用值mycomponet.方法sonMethod()
console.log("子组件mycomponet中sonMethod方法:"+this.$refs.mycomponet.sonMethod())
}
},
components:{
mycomponet:{
template:"#tem",
data:function () {
return {sonMsg:"我是子组件数据"}
},
methods:{
sonMethod(){
console.log("子组件方法执行")
return "1"
}
}
}
}
}
)
</script>
4.路由
4.1 路由创建
路由是用于单页面间不同组件之间的切换,以下为例,点击不同按钮切换到不同的组件,注意变化的之后#后面的组件路径.#为hash路由方式.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<script src="./lib/vue.js"></script>
<script src="./lib/vue-router.js"></script>
<body>
<div id="app">
<!-- 3.router-view路由占位符,用于展示不同路径下对应的组件 -->
<router-view></router-view>
<!-- <a href="#/login">登录</a>
<a href="#/register">注册</a> -->
<!-- router-link默认为a标签,提供跳转功能 -->
<router-link to="login">登录</router-link>
<router-link to="register">注册</router-link>
</div>
<script>
// 创建登录组件
// var login = Vue.component("login",{
// template:"<h2>登录组件</h2>"
// })
// 组件创建的简化写法
var login = {
template:"<h2>登录组件</h2>"
}
// 创建注册组件
var register = Vue.component("register",{
template:"<h2>注册组件</h2>"
})
// 1.创建路由对象
var routerObj = new VueRouter({
// 指定路径的匹配规则,path表示跳转路径,component为组件对象,注意这里不能写字符串
routes:[
// 设置默认重定向跳转到login
{path:"/",redirect:"/login"},
{path:"/login",component:login},
{path:"/register",component:register}
]
})
var app =new Vue({
el:"#app",
// 2.注册全局路由
router:routerObj
})
</script>
</body>
</html>
4.2 路由路径传参:query和params
参数传递时从跳转的路径上进行拼接,拼接方式有两种?和/,具体看下面案例:
<body>
<div id="app">
<!-- 3.router-view路由占位符,用于展示不同路径下对应的组件 -->
<router-view></router-view>
<!-- <a href="#/login">登录</a>
<a href="#/register">注册</a> -->
<!-- router-link默认为a标签,提供跳转功能 -->
<router-link to="login?username=zs&age=18">登录</router-link>
<router-link to="register/lisi/20">注册</router-link>
</div>
<script>
// 创建登录组件
// var login = Vue.component("login",{
// template:"<h2>登录组件</h2>"
// })
// 组件创建的简化写法
var login = {
template:"<h2>登录组件,获取参数:{{$router.currentRoute.query.username}},{{$router.currentRoute.query.age}}</h2>",
// 创建生命周期
created(){
console.log(this.$router)
console.log("登录请求参数:",this.$router.currentRoute.query.username,this.$router.currentRoute.query.age,)
}
}
// 创建注册组件
var register = Vue.component("register",{
template:"<h2>注册组件,获取参数:{{$router.currentRoute.params.username}},{{$router.currentRoute.params.age}}</h2>",
created(){
console.log(this.$router)
console.log("注册请求参数:",this.$router.currentRoute.params.username,this.$router.currentRoute.params.age)
}
})
// 1.创建路由对象
var routerObj = new VueRouter({
// 指定路径的匹配规则,path表示跳转路径,component为组件对象,注意这里不能写字符串
routes:[
// 设置默认重定向跳转到login
{path:"/",redirect:"/login"},
// ?拼接传参路由匹配规则不需要添加形参
{path:"/login",component:login},
// /拼接传参路由匹配规则需要添加形参
{path:"/register/:username/:age",component:register}
]
})
var app =new Vue({
el:"#app",
// 2.注册全局路由
router:routerObj
})
</script>
</body>
</html>
4.3 嵌套路由
通过案例的方式介绍嵌套路由,上面实现过登录注册组件路由跳转,现在需求变更,个人中心模块下有登录注册模块,切换登录注册操作都是在个人中心下进行.效果如下:
实现代码:
<script src="./lib/vue.js"></script>
<script src="./lib/vue-router.js"></script>
<div id="app">
<!--用于匹配显示路由规则对应的组件,去掉则不显示对应组件-->
<router-view></router-view>
</div>
<template id="tem">
<div>
<h2>个人中心组件</h2>
<a href="#/personCenter/login">登录</a>
<a href="#/personCenter/register">注册</a>
<!--router-link可以代替a标签-->
<!--<router-link to="/personCenter/login">登录</router-link>-->
<!--<router-link to="/personCenter/register">注册</router-link>-->
<!--用于匹配显示路由规则对应的组件,去掉则不显示对应组件-->
<router-view></router-view>
</div>
</template>
<script>
// 创建个人中心组建
var personCenter = Vue.component("personCenter",{
template:"#tem"
})
// 组件创建的简化写法
var login = {
template:"<h2>登录组件</h2>",
}
// 创建注册组件
var register = {
template:"<h2>注册组件</h2>",
}
// 1.创建路由对象
var routerObj = new VueRouter({
// 指定路径的匹配规则,path表示跳转路径,component为组件对象,注意这里不能写字符串
routes:[
{
path:"/personCenter",
component:personCenter,
children:[
{path:"login",component:login},
{path:"register",component:register}
]
}
]
})
var app =new Vue({
el:"#app",
// 2.注册全局路由
router:routerObj
})
</script>
</body>
</html>
配置router-view标签才能保证对应路径下的组件显示.
嵌套路由中的子路由通过children属性配置.
4.4命名视图
实现效果:同一路径下显示多个组件
实现代码:
<script src="./lib/vue.js"></script>
<script src="./lib/vue-router.js"></script>
<body>
<div id="app">
<router-view></router-view>
<div>
<router-view name="left"></router-view>
<router-view name="right"></router-view>
</div>
</div>
<script>
// 创建头部组件
var head = Vue.component("head",{
template:"<h2>头部组件</h2>"
})
// 最侧组件
var left = {
template:"<h2>左侧组件</h2>"
}
// 创建右侧组件
var right = {
template:"<h2>右侧组件</h2>"
}
// 1.创建路由对象
var routerObj = new VueRouter({
// 指定路径的匹配规则,path表示跳转路径,component为组件对象,注意这里不能写字符串
routes:[
{
path:"/",
// 对于同一路径显示多个组件的处理方式
components:{
default:head, // 默认显示组件
left:left, // 设置name为left显示left组件
right:right // 设置name为right显示right组件
}
}
]
})
var app =new Vue({
el:"#app",
// 2.注册全局路由
router:routerObj
})
</script>
</body>
</html>
5.watch监听data数据与路由路径
监听器作用数监听data属性值变化,示例:
<body>
<div id="app">
<div>
请出入内容:<input type="text" name="inputContent" v-model="content">
</div>
<div>
num值:{{num}}<button @click="addNum()">点击加一</button>
</div>
</div>
<script>
var app =new Vue({
el:"#app",
data:{
content:"初始内容",
num:1
},
methods:{
addNum(){
this.num++
}
},
watch:{
// 监听器作用:监听data中定义的属性,监听函数参数为改变后的新值、改变前的旧值
content:function (newVal,OldVal) {
console.log("content旧值:",OldVal)
console.log("content新值:",newVal)
},
num:function (newVal,OldVal) {
console.log("num旧值:",OldVal)
console.log("num新值:",newVal)
}
}
})
</script>
</body>
</html>
实现效果:
点击切换不同组件会监听路由变化:
<body>
<div id="app">
<!--用于匹配显示路由规则对应的组件,去掉则不显示对应组件-->
<a href="#/login">登录</a>
<a href="#/register">注册</a>
<router-view></router-view>
</div>
<script>
// 组件创建的简化写法
var login = {
template:"<h2>登录组件</h2>",
}
// 创建注册组件
var register = {
template:"<h2>注册组件</h2>",
}
// 1.创建路由对象
var routerObj = new VueRouter({
// 指定路径的匹配规则,path表示跳转路径,component为组件对象,注意这里不能写字符串
routes:[
{path:"/login",component:login},
{path:"/register",component:register}
]
})
var app =new Vue({
el:"#app",
// 2.注册全局路由
router:routerObj,
watch:{
"$route.path":function(newVal,oldVal){
console.log("$route.path旧值:",oldVal)
console.log("$route.path新值:",newVal)
}
}
})
</script>
</body>
</html>
6.computed计算属性
实现效果:第三个输入框中显示内容由前两个输入框的值动态变化
代码:
<body>
<div id="app">
<input v-model="name1">+
<input v-model="name2">=
<input v-model="name3">
</div>
<script>
var app =new Vue({
el:"#app",
data:{
name1:"",
name2:""
},
computed:{
// 计算属性,可以理解为根据data中属性动态改变的属性值
name3:function () {
console.log(this.name1+"=="+this.name2)
return this.name1+"=="+this.name2
}
}
})
</script>
</body>
</html>
7.vscode常用操作
7.1 创建vue文件并自动补全
在指定目录下右键选择新建文件,后缀名已vue结尾,输入vue回车即可自动补全、
8.常用指令
8.1 v-for
v-for=(数组元素,索引) in 数组 :key=默认索引(也可以根据指定)
此处索引默认为数组元素下标,数组元素和索引均使用差值表达式获取值即可
<div v-if="divArr.leng != 0" v-for="(item,index) in divArr">
<div>{{item}}</div>
</div>
data() {
return {
divArr:[]
};
}
9.axios
以vue3项目为例说明如何配置axios
安装axios
cnpm install axios
main.js中配置axios
// 引入axios
import axios from "axios"
// 注册全局变量方式全局注册axios
app.config.globalProperties.$axios=axios
// 配置服务端服务地址
axios.defaults.baseURL = "http://123.123.225.85:8082"
页面引用
this.$axios.get("/user/findManageRoleList")
.then(
(res)=>{
console.log("res:",res)
},
(err)=>{
console.log("res:",err)
}
)
跨域配置vite.config.js
export default defineConfig({
plugins: [
vue(),
],
resolve: {
// 设置代理服务器向服务器的请求地址,即向服务器发起请求
devServer: {
open: true, //是否自动弹出浏览器页面
host: "localhost",
port: '5173', // vue本地项目访问端口
// https: false,
hotOnly: false,
proxy: {
'/': {
target: 'http://123.123.225.85:8082', //服务器的地址
changeOrigin: true
}
},
}
})
get请求:
methods: {
this.$axios(
{
// 注意左边的key可以加引号也可以不加,不影响使用
method:"get",
"url":"/user/findManageRoleList",
"params":{
// 此处key需要添加引号
"name":"wangwu"
},
// 对于get请求,可以直接使用路径拼接方式
// "url":"/user/findManageRoleList?name=wangwu",
"headers":{
"token":"sjjxia"
}
}
).then(
// 响应处理
(res)=>{
console.log("res:",res)
}
)
}
post两种请求方式:
// 表单提交
this.$axios(
{
// 注意左边的key可以加引号也可以不加,不影响使用
method:"post",
"url":"/user/addUser?name=zh&age=18",
"headers":{
"token":"sjjxia"
}
}
).then(
// 响应处理
(res)=>{
console.log("res:",res)
}
)
// 分割线+++++++++++++++++++++++++++++++++++++++++++++
// 请求体
this.$axios(
{
// 注意左边的key可以加引号也可以不加,不影响使用
method:"post",
"url":"/user/addUser",
"headers":{
"token":"sjjxia"
},
data:{
// 此处key需要添加引号
"name":"lisi",
"age":18
}
}
).then(
// 响应处理
(res)=>{
console.log("res:",res)
}
)