文章目录
前端框架
vue官网:https://cn.vuejs.org/guide/introduction.html
Vue基础知识
环境搭建
线上尝试
-
想要快速体验 Vue,你可以直接试试我们的演练场。
-
如果你更喜欢不用任何构建的原始 HTML,可以使用 JSFiddle 入门。
-
如果你已经比较熟悉 Node.js 和构建工具等概念,还可以直接在浏览器中打开 StackBlitz 来尝试完整的构建设置。
CDN使用
<script
src="https://unpkg.com/vue
@3/dist/vue.global.js">
</>
通过CDN使用Vue时,不涉及“构建步骤”。这使得设置更加简单,并且可以用于增强静态的HTML或与后端框架集成。但是,你将无法使用单文件组件(SFC)语法。
Vue CLI
Vue CLI 是官方提供的基于 Webpack 的 Vue 工具链,它现在处于维护模式。我们建议使用 Vite 开始新的项目,除非你依赖特定的 Webpack 的特性。在大多数情况下,Vite 将提供更优秀的开发体验。
Vite
Vite 是一个轻量级的、速度极快的构建工具,对 Vue SFC 提供第一优先级支持。作者是尤雨溪,同时也是 Vue 的作者!要使用 Vite 来创建一个 Vue 项目,非常简单:
npm init vue@latest
这个命令会安装和执行 create-vue,它是 Vue 提供的官方脚手架工具。跟随命令行的提示继续操作即可。
开发准备
安装Vue工具Vue CLI
Vue CLI Vue.js开发的标准工具,Vue CLI是一个基于Vue.js进行快速开发的完整系统。
npm install -g @vue/cli
安装之后,就可以在命令行中访问vue命令。验证是否安装成功。
vue --version
创建一个项目
运行以下命令
vue create vue-demo(必须全小写)
1.选择Manually select features
2.空格选中,再次空格取消选择
3.去除“Linter / Formatter”
4.选择该选择的安装
运行项目
1.进入项目根目录 cd vue-demo
2.npm run serve
安装Vue高亮插件
Volar:vue3
Vetur: vue2
- 推荐使用的 IDE 是 VSCode,配合 Vue 语言特性 (Volar) 插件。该插件提供了语法高亮、TypeScript 支持,以
及模板内表达式与组件 props 的智能提示。 - Volar 取代了我们之前为 Vue 2 提供的官方 VSCode 扩展 Vetur。如果你之前已经安装了 Vetur,请确保在
Vue 3 的项目中禁用它
模板语法
文本
数据绑定最常见的形式就是使用“Mustache”(双大括号)语法的文本插值。
<span>Message:{{msg}}</span>
一般配合js中的data()设置数据
export default {
name: 'HelloWorld',
data(){
return{
msg:"消息提示"
}
}
}
原始HTML
双大括号会将数据解释为普通文本,而非html代码。为了输出真正的html,你需要使用v-html指令。
<p>Using mutaches:{{rawhtml}}</p>
<p>Using v-html directive:<span v-html="rawhtml"></span></p>
data(){
return{
rawhtml:"<a href='https://www.baidu.com' target=_blank>baidu</a>"
}
}
属性Attribute
Mustache语法不能在html属性中使用,然而,可以使用v-bind指令
<div v-bind:id="DynamicsId"></div>
data(){
return{
DynamicsId:1001
}
}
v-bind: 可以简写为:
使用javascript表达式
在我们的模板中,我们一直都只绑定简单的property键值,vue.js都提供了完全的js表达式支持。
{{ number + }}
{{ ok ? 'yes' : 'no'}}
{{ message.split('').reverse().join('') }}
这些表达式会在当前活动实例的数据作用域下作为js被解析。但是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<!-- 这是语句,不是表达式 -->
{{var a = 1}}
<!-- 流程控制也不会生效,请使用三元表达式 -->
{{if (ok) {return message} }}
条件渲染
v-if
v-if 指令用于条件性渲染一块内容。这块内容只会在指令的表达式返回true值时被渲染。
<p v-if ="flag">Vue</p>
data(){
return{
flag:true
}
}
v-else
使用v-else指令来表示v-if的“else”块
<p v-if ="flag">你是猴子</p>
<p v-else ="flag">你不是猴子</p>
data(){
return{
flag:true
}
}
v-show
用于条件性展示元素的选项是v-show
指令
<h1 v-show="flag">hello</h1>
- v-if he v-show 的区别
- v-if是真正的条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。
- v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做一一直到条件第一次变为真时,才会开始渲染条件快。
- 相比之下,v-show不管初始条件是什么,元素总是会被渲染。并且只是简单的基于css进行切换。display:none
- 一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁的切换,则使用v-show较好;如果在运行时条件很少改变,则使用v-if较好。
列表渲染
用v-for 把一个数组映射为一组元素
用v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items形式的特殊语法。
<ul>
<li v-for="item in items">{{ item.msg }}</li>
</ul>
data(){
return{
items:[{msg:"foo"},{msg:"bar"}]
}
}
维护状态
当Vue正在更新使用v-for渲染的元素列表时,它默认使用”就地更新“的策略。如果数据项的顺序被改变,vue将不会移动dom元素来匹配数据项的顺序,而是就地更新每个元素,并且确保他们在每个索引位置正确渲染。
为了给vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现用的元素,将为每一项提供一个唯一的key attribute:
<div v-for="(item,index) in items" :key="item.id|index">
<!-- content -->
</div>
事件处理
监听事件
我们可以使用v-on指令(通常缩写为@符号)来监听DOM事件,并在触发事件时执行一些js。用法为v-on:click="methodName"或使用快捷方式@click=“methodName”
<button @click="counter +=1"> add {{ counter }}</button>
data(){
return{
counter:0
}
}
事件处理方法
直接把js代码写在v-on指令中时不可行的。因此v-on还可以接收一个需要调用的方法名称。
<button @click="clickhandle"> {{greet}}</button>
methods:{
clickhandle(event){
// event 是原生dom event
console.log(event)
// 在事件中,读取data中的属性,是需要通过this.属性
// this.greet = "触发点击"
event.target.innerHtml = "点击之后"
}
}
内联处理器中的方法
也叫“事件传递参数”
<button @click="say('hi')"> say hi </button>
<button @click="say('what')"> say what </button>
methods:{
say(message){
alert(message)
}
}
表单输入绑定
双向数据绑定
用v-model指令在表单<input>、<textarea>及<select>
元素上创建双向数据绑定。他会根据控件类型来自动选取正确的方法来更新元素。它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。
<input v-model= "message" placeholder="edit me "/>
<p> message is :{{ message }}</p>
data(){
return{
message:""
}
}
修饰符
- .lazy
在默认情况下,v-model在每次input事件触发后将输入框与数据进行同步。可以添加lazy修饰符,从而转为在change事件之后进行同步。
<input v-model.lazy = "message"/>
<p> msg:{{message}} </p>
data(){
return{
message:""
}
}
- .trim
如果要自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符。
<input v-model.trim = "message"/>
data(){
return{
message:""
}
}
组件基础
单文件组件
vue单文件组件(又名*.vue文件,缩写为sfc)是一种特殊的文件格式,它允许将vue组件的模板、逻辑与样式封装在单个文件中。
<template>
<h3>我是单文件组件</h3>
</template>
<script>
export default {
name:"MyComponent",
}
</script>
<!-- scoped:如果在style中添加此属性,就代表着,当前样式只在当前组件中生效。 -->
<style scoped>
h3{
color:red
}
</style>
加载组件
1.引入组件 import MyComponent from "./components/MyComponent.vue"
2.挂载组件 components:{MyComponent}
3.显示组件<my-MyComponent->
组件的组织
以一棵嵌套的组件树的形式来组织
Props组件交互
组件与组件之间是需要存在交互的饿,否则完全没关系,组件的意义就很小了。
Prop是可以在组件上注册的一些自定义attribute
<MyComponent :title="title"/>
export default {
name: 'App',
data(){
return{
title:"标题"
}
},
<template>
<h2>prop 传递数据</h2>
<p>{{ title }}</p>
</template>
<script>
export default {
name: 'Mycomponent',
props:{
title:{
type:String,
default:""
}
}
}
</script>
props类型
props传递参数其实是没有类型限制的
props:{
title:{
type:String,
default:""
},
likes:{
type:Number,
default:0
},
ispublished:{
type:Boolean,
default:false
},
commentIds:{
type:Array,
// 数组和对象必须使用函数进行返回
default:function(){
return []
}
},
// author:Object,
// calllback:Function
}
}
数据类型为数组或者对象的时候,默认值是需要返回工厂模式。
自定义事件组件交互
自定义事件可以在组件中反向传递数据,props可以将数据从父组件传递到子组件,那么反向如果操作呢,就是利用自定义事件实现$emit
<template>
<button @click="sendClickHandle">点击传递</button>
</template>
<script>
export default {
name: 'Mycomponent',
data(){
return {
message:"我来自子组件"
}
},
methods:{
sendClickHandle(){
// 参数1:字符串:理论上是随便的,但是需要具有意义
// 参数2:传递的数据
this.$emit("onEvent",this.message)
}
}
}
</script>
<MyComponent @onEvent="getDataHandel"/>
methods:{
getDataHandel(data){
console.log(data);
}
}
组件的生命周期
每个组件在被创建时都要经过一系列的初始化过程–例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
<template>
<h3>生命周期函数</h3>
<p>{{ message }}</p>
<button @click="message='数据'">点击</button>
</template>
<script>
export default {
name: 'Mycomponent',
data(){
return {
message:"我是组件"
}
},
beforeCreate(){
console.log("beforeCreate:组件创建前")
},
created(){
console.log("beforeCreate:组件创建完成")
},
beforeMount(){
console.log("beforeCreate:组件渲染之前")
},
mounted(){
console.log("beforeCreate:组件渲染完成")
// 网络请求放到这里
},
beforeUpdate(){
console.log("beforeCreate:组件更新之前")
},
updated(){
console.log("beforeCreate:组件更新完成")
},
beforeUnmount(){
console.log("beforeCreate:组件卸载之前")
// 卸载之前,把消耗性能的处理都干掉
// 定时器
},
unmounted(){
console.log("beforeCreate:组件卸载完成")
},
}
Vue引入第三方
github合作第三方(注意vue3和vue2区别):https://github.com/vuejs/awesome-vue
swiper
swiper开源、免费、强大的触摸滑动插件
swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。
swiper能实现触屏焦点图、触屏tab切换、触屏轮播图切换等常用效果。
结合vue官方文档:https://swiperjs.com/vue
安装指定版本并直接放到package.json:npm install --save swiper@8.1.6
Axios网络请求
axios是一个基于promise的网络请求库
安装
axios的应用是需要单独安装的npm install --save axios
引入
组件中引入:import axios from “axios”
全局引用:在main.js文件中引入
import axios from 'axios'
const app = createApp(App)
app.config.globalProperties.$axios = axios
app.mount('#app')
get请求
// get请求方式
axios({
method:"get",
url:"http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php"
}).then(res =>{
console.log(res.data)
})
// 全局快速
this.$axios.get("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php")
.then(res =>{
console.log(res.data)
})
post请求
post请求参数是需要额外处理的
安装依赖:npm install --save querystring
转换参数格式:qs.stringify({})
import qs from "querystring"
axios({
method:"post",
url:"http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php",
data:qs.stringify({
user_id:"iwen@qq.com",
password:"iwen123",
verification_code:"crfvw"
})
}).then(res =>{
console.log(res.data)
})
// 全局快速
this.$axios.post("http://iwenwiki.com/api/blueberrypai/login.php",qs.stringify({
user_id:"iwen@qq.com",
password:"iwen123",
verification_code:"crfvw"
}))
.then(res =>{
console.log(res.data)
})
Axios网络请求封装
在src目录中创建文件夹utils,并创建文件request.js,用来存储网络请求对象axios
import axios from "axios"
import { Promise } from "core-js"
import qs from "querystring"
// 参考文档
// https://www.axios-http.cn/docs/req_config
// https://www.kancloud.cn/yunye/axios/234845/234845
const errorHandle = (status,info) =>{
switch(status){
case 400:
console.log("语义有误");
break;
case 401:
console.log("服务器认证失败");
break;
case 403:
console.log("服务器拒绝访问");
break;
case 404:
console.log("地址错误");
break;
case 500:
console.log("服务器遇到意外");
break;
case 502:
console.log("服务器无响应");
break;
default:
console.log("info");
break;
}
}
const instance = axios.create({
// 网络请求的公共配置
timeout:5000
})
// 拦截器最常用
// 发送数据之前
instance.interceptors.request.use(
config =>{
if(config.method === "post"){
config.data = qs.stringify(config.data)
}
return config;
},
error =>{
return Promise.reject(error)
}
)
//获取数据之前
instance.interceptors.response.use(
response =>{
return response.status ===200 ? Promise.resolve(response):Promise.reject(response)
},
error =>{
const {response } = error;
// 错误的处理才是最需要关注的
errorHandle(response.status,response.info)
}
)
export default instance;
网络请求跨域解决方案
js采取的是同源策略:
同源策略是浏览器的一项安全策略,浏览器只允许js代码请求和当前所在服务器域名,端口,协议相同的数据接口上的数据,这就是同源策略。
跨域错误提示信息
目前主流的跨域解决方案有两种
1.后台解决:cors
2.前台解决:proxy
在vue.config.js添加一下配置,最后重启服务器。
devServer:{
proxy:{
'/api':{
target:"域名",
changOrigin:true
}
}
}
Vue引入路由配置
注意:如果在@vue/cli安装中勾选了路由,就会自动创建路由配置
在vue中,通过vue-router路由管理页面之间的关系。
vue router是vue.js的官方路由。它与vue.js核心深度集成,让vue.js构建单页应用轻而易举。
Vue中引入路由
1.安装路由 npm install --save vue-router
2.配置独立的路由文件
import { createRouter,createWebHashHistory } from "vue-router";
import HomeView from "../views/HomeView.vue"
// 配置信息中需要页面的相关配置
const routes = [
{
path:"/",
name:"home",
component : HomeView
},
{
path:"/about",
name:"about",
// 异步加载方式
component : () => import('../views/AboutView.vue')
},
]
const router = createRouter({
createWebHashHistory
http://localhost:8080/#/about
原理:a标签锚点连接
createWebHistory
http://localhost:8080/about
此种方式,需要后台配合做重定向,否则会出现404问题
原理:H5 pushState()
history:createWebHashHistory(),
routes
})
export default router
3.引入路由到项目
// main.js
import router from "./router"
app.use(VueRouter)
4.指定路由显示入口
5.指定路由跳转
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
路由传递参数
1.在路由配置中指定参数的key
{
path:"/list/:name(/:class)",
name:"list",
component:() => import("../views/ListView.vue")
}
2.在跳转过程中携带参数
<li><router-link to= "/list/内蒙">内蒙旅游</router-link></li>
<li><router-link to= "/list/北京">北京旅游</router-link></li>
<li><router-link to= "/list/四川">四川旅游</router-link></li>
3.在详情页面读取路由携带的参数
<p>{{ $route.params.name}}城市旅游</p>
嵌套路由配置
1.创建子路由要加载的显示页面
2.在路由配置文件中添加子路由配置
{
path:"/news",
name:"news",
redirect:"/news/baidu",
component:() => import("../views/NewsView.vue"),
// 二级导航的路径不要加/
children:[
{
path:"baidu",
component:() => import("../views/NewsList/Baidu.vue"),
},
{
path:"wangyi",
component:() => import("../views/NewsList/Wangyi.vue"),
}
]
}
3.指定子路由显示位置
4.添加子路由跳转链接
<router-link to="/news/baidu">Home</router-link>
<router-link to="/news/wangyi">About</router-link>
5.重定向配置redirect:“/news/baidu”
Vue状态管理(Vuex)
Vuex是一个专为Vue.js应用程序开发的状态管理模式+库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
简单来说,状态管理可以理解成为了更方便的管理组件之间的数据交互,提供了一个集中式的管理方案,任何组件都可以按照指定的方式进行读取和改变数据。
引入Vuex的步骤
安装vue-cli时可以直接集成
1.按照Vuex npm install --save vuex
2.配置Vuex文件
//store/index.js
import {createStore} from 'vuex'
//Vuex的核心作用就是帮我们管理组件之间的状态
export default createStore({
// 所有的状态都放在这里(数据)
state:{
counter:0
}
})
3.在主文件中引入Vuex
// main.js
import store from './store'
app.use(store)
4.在组件中读取状态
<p>counter:{{ $store.state.counter}}</p>
// 或者vuex提供的快捷读取方式
import {mapstate} from 'vuex'
computed:{
...mapstate(["counter"])
}
Vue状态管理核心(Vuex)
最常用的核心概念包含:State、Getter、Mutation、Action
Getter
对Vuex中的数据进行过滤
//store/index.js
import {createStore} from 'vuex'
export default createStore({
state:{
counter:0
},
getters:{
getCount(state){
return state.counter > 0 ?state.counter:"counter小于0,不符合要求"
}
}
})
import { mapGetters } from 'vuex';
computed:{
...mapGetters(["getCount"])
},
Mutation
更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数
//store/index.js
import {createStore} from 'vuex'
//Vuex的核心作用就是帮我们管理组件之间的状态
export default createStore({
// 所有的状态都放在这里(数据)
state:{
counter:0
},
getters:{
getCount(state){
return state.counter > 0 ?state.counter:"数据异常"
}
},
mutations:{
addCounter(state,num){
state.counter +=num
}
}
})
// 应用
<button @click="addClickHandle">add</button>
import { mapGetters,mapMutations } from 'vuex';
methods:{
...mapMutations(["addCounter"]),
addClickHandle(){
// // 固定调用方法
// this.$store.commit("addCounter",15)
this.addCounter(20)
}
}
Action
Action类似于mutation,不同在于:
- Action提交的是mutation,而不是直接变更状态
- Action可以包含任意异步操作
import axios from 'axios'
import {createStore} from 'vuex'
//Vuex的核心作用就是帮我们管理组件之间的状态
export default createStore({
// 所有的状态都放在这里(数据)
state:{
counter:0
},
getters:{
getCount(state){
return state.counter > 0 ?state.counter:"数据异常"
}
},
mutations:{
addCounter(state,num){
state.counter +=num
}
},
// 为异步操作所准备的
actions:{
asyncAddCounter({commit}){
axios.get("http://iwenwiki.com/api/generator/list.php")
.then(res =>{
// 调用mutations
commit("addCounter",res.data[0])
})
}
}
})
// 应用
<button @click="addAsyncClickHandle">async——add</button>
import {mapActions } from 'vuex';
methods:{
...mapMutations(["addCounter"]),
...mapActions(["asyncAddCounter"]),
addAsyncClickHandle(){
// this.$store.dispatch("asyncAddCounter")
this.asyncAddCounter();
}
}
Vue3新特性
六大亮点
- performance:性能比vue2.0强
- tree shaking support:可以将无用模块“剪辑”,仅打包需要的。
composition api:组合api
- fragment,teleport,suspense:“碎片”,teleport即protal传送门,“悬念”
- better TypeScript support:更优秀的ts支持
- custom renderer api:暴露了自定义渲染api
ref 或者reactive
在2.x中通过组件data的方法来定义一些当前组件的数据。
data(){
return {
name:'soner',
list:[]
}
}
在3.x中通过ref或者reactive创建响应式对象
import {ref,reactive} from "vue"
export default{
name:"helloworld",
setup(){
const name = ref("soerr")
const state = reactive({
list:[]
})
return {
name,
state
}
}
}
methods中定义的方法写在setup()
在2.X中methods来定义一些当前组件内部方法
methods:{
http(){}
}
在3.X中直接在setup方法中定义并return
setup(){
const http =>()=>{
// do something
}
return {
http
}
}
setup()中使用prop和context
在2.x中,组件的方法可以通过this获取到当前组件的实例,并执行data变量的修改,方法的调用,组件的通信等等,但是在3.X中,setup()在beforeCreate和created时机就已调用,无法使用2.x一样的this,但是可以通过接收setup(props,ctx)的方法,获取到当前组件的实例和props。
export default{
props:{
name:String,
},
setup(props,ctx){
console.log(props.name)
ctx.emit('event')
}
}
在setup中使用生命周期函数
可以通过生命周期钩子前面加上“on”来访问组件的生命周期钩子。
下表包含如何在setup()内部调用生命周期钩子
export default {
setup(){
// 相比于之前的生命周期函数,这里可以使用多次
onMounted(() => {
// do something
})
}
}
provide / inject
- provide()和inject()可以实现嵌套组件之间的数据传递。
- 这两个函数只能在setup()函数中使用
- 父级组件中使用provide()函数向下传递数据
- 子级组件中使用inject()获取上层传递过来的数据。
- 不限层级
// 父组件
import {provide } from "vue"
setup(){
provide("customVal","我是父组件向子组件传递的值")
}
import {inject} from "vue"
setup(){
const customVal = inject("customVal");
return {
customVal
}
}
Fragment
Fragment 翻译为“碎片”
- 不再限于模板中的单个根节点
<template>
<img alt="vue logo" src= "./assets/logo.png">
<helloworld msg="welcome to your vue.js app"/>
<div></div>
</template>
vue3加载element-plus
https://element-plus.org/zh-CN/guide/quickstart.html#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5
vue基础知识
什么是Vue
概念:Vue (读音 /vjuː/,类似于 view) 是一套 **构建用户界面 ** 的 渐进式 框架
Vue2官网:https://v2.cn.vuejs.org/
1.什么是构建用户界面
基于数据渲染出用户可以看到的界面
2.什么是渐进式
所谓渐进式就是循序渐进,不一定非得把Vue中的所有API都学完才能开发Vue,可以学一点开发一点
Vue的两种开发方式:
-
Vue核心包开发
场景:局部模块改造
-
Vue核心包&Vue插件&工程化
场景:整站开发
3.什么是框架
所谓框架:就是一套完整的解决方案
举个栗子
如果把一个完整的项目比喻为一个装修好的房子,那么框架就是一个毛坯房。
我们只需要在“毛坯房”的基础上,增加功能代码即可。
提到框架,不得不提一下库。
- 库,类似工具箱,是一堆方法的集合,比如 axios、lodash、echarts等
- 框架,是一套完整的解决方案,实现了大部分功能,我们只需要按照一定的规则去编码即可。
下图是 库 和 框架的对比。
框架的特点:有一套必须让开发者遵守的规则或者约束
咱们学框架就是学习的这些规则 官网
创建Vue实例
我们已经知道了Vue框架可以 基于数据帮助我们渲染出用户界面,那应该怎么做呢?
比如就上面这个数据,基于提供好的msg 怎么渲染后右侧可展示的数据呢?
核心步骤(4步):
- 准备容器
- 引包(官网) — 开发版本/生产版本
- 创建Vue实例 new Vue()
- 指定配置项,渲染数据
- el:指定挂载点
- data提供数据
总结:创建Vue实例需要执行哪4步
插值表达式 {{}}
插值表达式是一种Vue的模板语法
我们可以用插值表达式渲染出Vue提供的数据
1.作用:利用表达式进行插值,渲染到页面中
表达式:是可以被求值的代码,JS引擎会讲其计算出一个结果
以下的情况都是表达式:
money + 100
money - 100
money * 10
money / 10
price >= 100 ? '真贵':'还行'
obj.name
arr[0]
fn()
obj.fn()
2.语法
插值表达式语法:{{ 表达式 }}
<h3>{{title}}<h3>
<p>{{nickName.toUpperCase()}}</p>
<p>{{age >= 18 ? '成年':'未成年'}}</p>
<p>{{obj.name}}</p>
<p>{{fn()}}</p>
3.错误用法
1.在插值表达式中使用的数据 必须在data中进行了提供
<p>{{hobby}}</p> //如果在data中不存在 则会报错
2.支持的是表达式,而非语句,比如:if for ...
<p>{{if}}</p>
3.不能在标签属性中使用 {{ }} 插值 (插值表达式只能标签中间使用)
<p title="{{username}}">我是P标签</p>
响应式特性
1.什么是响应式?
简单理解就是数据变,视图对应变。
2.如何访问 和 修改 data中的数据(响应式演示)
data中的数据, 最终会被添加到实例上
① 访问数据: “实例.属性名”
② 修改数据: “实例.属性名”= “值”
Vue开发者工具安装
- 通过谷歌应用商店安装(国外网站)
- 极简插件下载(推荐) https://chrome.zzzmh.cn/index
安装步骤:
安装之后可以F12后看到多一个Vue的调试面板
Vue中的常用指令
概念:指令(Directives)是 Vue 提供的带有 v- 前缀 的 特殊 标签属性。
为啥要学:提高程序员操作 DOM 的效率。
vue 中的指令按照不同的用途可以分为如下 6 大类:
- 内容渲染指令(v-html、v-text)
- 条件渲染指令(v-show、v-if、v-else、v-else-if)
- 事件绑定指令(v-on)
- 属性绑定指令 (v-bind)
- 双向绑定指令(v-model)
- 列表渲染指令(v-for)
指令是 vue 开发中最基础、最常用、最简单的知识点。
内容渲染指令
内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下2 个:
-
v-text(类似innerText)
-
- 使用语法:
<p v-text="uname">hello</p>
,意思是将 uame 值渲染到 p 标签中 - 类似 innerText,使用该语法,会覆盖 p 标签原有内容
- 使用语法:
-
v-html(类似 innerHTML)
-
- 使用语法:
<p v-html="intro">hello</p>
,意思是将 intro 值渲染到 p 标签中 - 类似 innerHTML,使用该语法,会覆盖 p 标签原有内容
- 类似 innerHTML,使用该语法,能够将HTML标签的样式呈现出来。
- 使用语法:
代码演示:
<div id="app">
<h2>个人信息</h2>
// 既然指令是vue提供的特殊的html属性,所以咱们写的时候就当成属性来用即可
<p v-text="uname">姓名:</p>
<p v-html="intro">简介:</p>
</div>
<script>
const app = new Vue({
el:'#app',
data:{
uname:'张三',
intro:'<h2>这是一个<strong>非常优秀</strong>的boy<h2>'
}
})
</script>
条件渲染指令
条件判断指令,用来辅助开发者按需控制 DOM 的显示与隐藏。条件渲染指令有如下两个,分别是:
-
v-show
- 作用: 控制元素显示隐藏
- 语法: v-show = “表达式” 表达式值为 true 显示, false 隐藏
- 原理: 切换 display:none 控制显示隐藏
- 场景:频繁切换显示隐藏的场景
-
v-if
- 作用: 控制元素显示隐藏(条件渲染)
- 语法: v-if= “表达式” 表达式值 true显示, false 隐藏
- 原理: 基于条件判断,是否创建 或 移除元素节点
- 场景: 要么显示,要么隐藏,不频繁切换的场景
示例代码:
<div id="app">
<div class="box">我是v-show控制的盒子</div>
<div class="box">我是v-if控制的盒子</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
flag: false
}
})
</script>
-
v-else 和 v-else-if
- 作用:辅助v-if进行判断渲染
- 语法:v-else v-else-if=“表达式”
- 需要紧接着v-if使用
示例代码:
<div id="app">
<p>性别:♂ 男</p>
<p>性别:♀ 女</p>
<hr>
<p>成绩评定A:奖励电脑一台</p>
<p>成绩评定B:奖励周末郊游</p>
<p>成绩评定C:奖励零食礼包</p>
<p>成绩评定D:惩罚一周不能玩手机</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
gender: 2,
score: 95
}
})
</script>
事件绑定指令
使用Vue时,如需为DOM注册事件,及其的简单,语法如下:
- <button v-on:事件名=“内联语句”>按钮
- <button v-on:事件名=“处理函数”>按钮
- <button v-on:事件名=“处理函数(实参)”>按钮
v-on:
简写为 @
-
内联语句
<div id="app"> <button @click="count--">-</button> <span>{{ count }}</span> <button v-on:click="count++">+</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { count: 100 } }) </script>
-
事件处理函数
注意:
- 事件处理函数应该写到一个跟data同级的配置项(methods)中
- methods中的函数内部的this都指向Vue实例
<div id="app">
<button>切换显示隐藏</button>
<h1 v-show="isShow">黑马程序员</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isShow: true
}
})
</script>
3.给事件处理函数传参
-
如果不传递任何参数,则方法无需加小括号;methods方法中可以直接使用 e 当做事件对象
-
如果传递了参数,则实参
$event
表示事件对象,固定用法。
<style>
.box {
border: 3px solid #000000;
border-radius: 10px;
padding: 20px;
margin: 20px;
width: 200px;
}
h3 {
margin: 10px 0 20px 0;
}
p {
margin: 20px;
}
</style>
<div id="app">
<div class="box">
<h3>小黑自动售货机</h3>
<button>可乐5元</button>
<button>咖啡10元</button>
<button>牛奶8元</button>
</div>
<p>银行卡余额:{{ money }}元</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
money: 100
}
})
</script>
属性绑定指令
- **作用:**动态设置html的标签属性 比如:src、url、title
- 语法:**v-bind:**属性名=“表达式”
- **v-bind:**可以简写成 => :
比如,有一个图片,它的 src
属性值,是一个图片地址。这个地址在数据 data 中存储。
则可以这样设置属性值:
<img v-bind:src="url" />
<img :src="url" />
(v-bind可以省略)
<div id="app">
<img v-bind:src="imgUrl" v-bind:title="msg" alt="">
<img :src="imgUrl" :title="msg" alt="">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
imgUrl: './imgs/10-02.png',
msg: 'hello 波仔'
}
})
</script>
列表渲染指令
Vue 提供了 v-for 列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。
v-for 指令需要使用 (item, index) in arr
形式的特殊语法,其中:
- item 是数组中的每一项
- index 是每一项的索引,不需要可以省略
- arr 是被遍历的数组
此语法也可以遍历对象和数字
//遍历对象
<div v-for="(value, key, index) in object">{{value}}</div>
value:对象中的值
key:对象中的键
index:遍历索引从0开始
//遍历数字
<p v-for="item in 10">{{item}}</p>
item从1 开始
v-for中的key
语法: key=“唯一值”
作用:给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用。
**为什么加key:**Vue 的默认行为会尝试原地修改元素(就地复用)
实例代码:
<ul>
<li v-for="(item, index) in booksList" :key="item.id">
<span>{{ item.name }}</span>
<span>{{ item.author }}</span>
<button @click="del(item.id)">删除</button>
</li>
</ul>
注意:
- key 的值只能是字符串 或 数字类型
- key 的值必须具有唯一性
- 推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key(会变化,不对应)
双向绑定指令
所谓双向绑定就是:
- 数据改变后,呈现的页面结果会更新
- 页面结果更新后,数据也会随之而变
作用: 给表单元素(input、radio、select)使用,双向绑定数据,可以快速 获取 或 设置 表单元素内容
**语法:**v-model=“变量”
**需求:**使用双向绑定实现以下需求
- 点击登录按钮获取表单中的内容
- 点击重置按钮清空表单中的内容
<div id="app">
账户:<input type="text"> <br><br>
密码:<input type="password"> <br><br>
<button>登录</button>
<button>重置</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
username: '',
password: ''
},
})
</script>
Vue2全家桶实战项目
概念
一个完整的项目,除了有组件有数据等跨域完成页面的渲染外,还需要一些其他功能。例如:路由、状态机、网络请求、UI框架等。在Vue官方配套的插件中,提供了Vue Router(路由) 和 Vuex(状态机)。所以,有些人会将Vue+Vue Router + Vuex称为“Vue全家桶”。
搭建Vue全家桶
1.创建项目
cmd到指定的路径,执行以下命令创建Vue项目:
vue create hx_web
说明:项目名,可更改,注意不要用中文和大写字母
2.选择创建模式
选择项目的安装方式(Manually)
Vue CLI v5.0.8
? Please pick a preset: (Use arrow keys)
Default ([Vue 3] babel, eslint) # 默认方式(vue3)
Default ([Vue 2] babel, eslint) # 默认方式(vue2)
> Manually select features # 自定义安装
3.选择插件
选择项目中需要安装的插件,通过“空格”来切换是否选中。
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
(*) Router
(*) Vuex
(*) CSS Pre-processors
>( ) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
说明:这一次我们总共选择4个插件:
- Babel:用于将高版本的js语法转换为浏览器能够支持的低版本语法。
- Router:路由插件;
- Vuex:状态机插件
- Css Pre-processors:CSS预处理器
4.选择Vue的版本
目前我们选择Vue2的版本:
? Choose a version of Vue.js that you want to
start the project with
3.x
> 2.x
5.选择路由模式
? Use history mode for router? (Requires proper
server setup for index fallback in production)
(Y/n) y
说明:后续可以在代码中更改
6.选择css预处理器
? Pick a CSS pre-processor (PostCSS, Autoprefixer
and CSS Modules are supported by default): (Use
arrow keys)
> Sass/SCSS (with dart-sass)
Less
Stylus
7.选择插件配置代码的位置
我们选择的插件,会自动生成相关配置代码,需要选择这些配置的保存位置
? Where do you prefer placing config for Babel,
ESLint, etc.? (Use arrow keys)
> In dedicated config files # 保存在独立的文件中
In package.json # 保存在package.json中
8.是否保存以上配置
选择是否保存供下一次使用(当前的配置已生效)
? Save this as a preset for future projects?
(y/N) y
save preset as :vue2_all
9.项目创建成功
🎉 Successfully created project hx_web.
👉 Get started with the following commands:
$ cd hx_web
$ npm run serve
下载第三方插件
1.网络请求
npm i axios
2.UI框架
适配vue2:https://element.eleme.cn/#/zh-CN
vue add element
WARN There are uncommitted changes in the current repository, it's recommended to commit or stash them first.
? Still proceed? Yes
📦 Installing vue-cli-plugin-element...
added 1 package in 2s
✔ Successfully installed plugin: vue-cli-plugin-element
? How do you want to import Element? Fully import
? Do you wish to overwrite Element's SCSS variables? Yes
? Choose the locale you want to load zh-CN
说明:如果报错,卸载sass相关插件后再安装
npm uninstall node-sass sass sass-loader
npm install node-sass sass sass-loader
路由与SPA
SPA的概念
SPA是single Page Application的缩写,表示“单页应用”。单页应用,指的是整个项目中,只有一个.html页面。例如Vue项目中的public/index.html。
路由的概念
因为spa中只有一个页面,那么在组件中进行切换时,需要一个工具来进行辅助,帮助我们管理组件与浏览器路径之间的关系。所以,Vue Router路由插件,就为我们提供了这样的功能:
- 可以通过路由来管理路径和组件之间的对应关系
- 当路径发生改变时,路由会切换页面中对应的组件
路由的配置
src/router/index.js文件,是路由的配置文件。
- 基础配置
import HomeView from '../views/HomeView.vue'
import RegisterVuew from '../views/RegisterVuew.vue'
import LoginVuew from '../views/LoginVuew.vue'
// 用于配置项目中所有需要的页面(组件和路径)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/register',
name: 'register',
component: RegisterVuew
},
{
path: '/login',
name: 'register',
component: LoginVuew
},
说明:每个路由对象,都对应着项目中的一个页面。其中每个路由对象都有两个必选的属性。
-
path:路由路径,实际上就是浏览器中每一个页面的路径。(建议首字母不要大写)
-
component:路由组件,指的是浏览器中需要渲染的组件。
-
name(可选):路由名称
-
路由出口
通过路由配置,当浏览器的路径发生改变时,浏览器会加载对应的组件。但是,路由配置并没有告诉浏览器组件要渲染在什么地方。因此,我们需要通过路由出口,告诉浏览器组件渲染在什么位置。
<template>
<router-view></router-view>
</template>
有了路由的基本配置和路由出口后,就可以在浏览器中手动切换路径,来实现页面组件的切换。
嵌套路由
- 基础配置
import CompanyNews from '../views/news/CompanyNewsView.vue'
import MediaNews from '../views/news/MediaNewsView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView,
children: [
{
// 子路由的path不能以 / 开头
path: "companynews",
name: "companynews",
component: CompanyNews
},
{
path: "medianews",
name: "medianews",
component: MediaNews
},
]
},
]
以上两个路由配置成功后,可以在浏览器中通过/home/companynews 和/home/medianews来访问对应的子路由
- 路由出口
嵌套子路由对应的组件,也需要在父组件中设置一个路由出口
<router-view></router-view>
- 默认子路由
通常我们在配置嵌套路由时,都会再单独设置一个path路由路劲,这样我们访问子路由时,就可以通过 /父级路由/子级路由 来渲染对应的组件。
但是,如果我们希望当用户访问 /父级路由 路径时,依然可以在子组件的位置中渲染一个默认的组件,这种情况下,就可以配置一个默认子路由。
const routes = [
{
path: '/',
component: HomeView,
children: [
{
path:"", // path为空字符串
name: "home" //父级路由的name属性,设置在默认子路由身上
component: ChartsView,
}
{
path: "companynews",
name: "companynews",
component: CompanyNews
},
...其他子路由
访问 / 路劲时 ,在页面中会先渲染homeView父组件,然后在父组件内部渲染子组件Charts。
路由的跳转
Vue Router中提供了两种方式来实现路由的跳转:
1.组件跳转(标签)
2.API跳转(方法跳转)
组件的跳转
Vue Router中提供了一个 组件来实现路由的跳转.(二级路也需要完整路由)
<router-link to="/register">注册</router-link>
API跳转
<el-button @click="register">登录</el-button>
export default {
methods:{
register(){
// 注册成功后跳转到登录页面
this.$router.push('/login')
}
}
}
push()跳转完成后,用户可以通过浏览器的回退按钮,返回上一页。
如果我们希望用户跳转之后,不能再返回上一页,可以通过replace实现跳转。(删除上一个页面的访问记录)
export default{
methods:{
logout(){
this.$router.replace('/login')
}
}
}