博主主页:追求~
本文承接上一篇:
学好vue靠他就行了—vue基础知识与原理(一)
学好vue靠他就行了—vue基础知识与原理(二)
希望各位博主多多关注
使用前置:
第一步(没有安装过的执行):全局安装 @vue/cli
npm install -g @vue/cli
第二步:切换到要创建项目的目录,然后使用命令创建项目
vue create xxxxx
第三步:启动项目
npm run serve
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件
components:
就直接把单文件组件的 School.vue 和 Student.vue 两个文件直接拿来用,不需要修改。
App.vue:
引入这两个组件,注册一下这两个组件,再使用。
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<Student>Student>
<School>School>
div>
template>
<script>
import School from './components/School.vue'
import Student from './components/Student.vue'
export default {
name: 'App',
components: {
School,
Student
}
}
script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
style>
main.js:
入口文件
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
接下来就要详细讲解 main.js 中的 render 函数
回到 render 函数
之前的写法是这样:
import App from './App.vue'
new Vue({
el:'#root',
template:` `,
components:{App},
})
如果这样子写,运行的话会引发如下的报错
报错的意思是,是在使用运行版本的 vue ,没有模板解析器。
从上面的小知识可以知道,我们引入的 vue 不是完整版的,是残缺的(为了减小vue的大小)。所以残缺的vue.js 只有通过 render 函数才能把项目给跑起来。
来解析一下render
// render最原始写的方式
// render是个函数,还能接收到参数a
// 这个 createElement 很关键,是个回调函数
new Vue({
render(createElement) {
console.log(typeof createElement);
// 这个 createElement 回调函数能创建元素
// 因为残缺的vue 不能解析 template,所以render就来帮忙解决这个问题
// createElement 能创建具体的元素
return createElement('h1', 'hello')
}
}).$mount('#app')
因为 render 函数内并没有用到 this,所以可以简写成箭头函数。
new Vue({
// render: h => h(App),
render: (createElement) => {
return createElement(App)
}
}).$mount('#app')
再简写:
new Vue({
// render: h => h(App),
render: createElement => createElement(App)
}).$mount('#app')
最后把 createElement
换成 h 就可以了。
对象内写方法最原始的:
let obj = {
name: 'aaa',
work: function (salary) {
return '工资' + salary;
}
}
ES6 简化版:
let obj = {
name: 'aaa',
work(salary) {
return '工资' + salary;
}
}
箭头函数简化版:
let obj = {
name: 'aaa',
work: (salary) => {
return '工资' + salary;
}
}
箭头函数再简化(最终版):
// 只有一个参数就可以把圆括号去了,函数体内部只有一个 return 就可以把大括号去掉,return去掉
let obj = {
name: 'aaa',
work: salary => '工资' + salary;
}
这样就可以理解 render 函数的简写方式了。
来个不同版本 vue 的区别
DOCTYPE html>
<html lang="">
<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">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">
<title>硅谷系统title>
head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.strong>
noscript>
<div id="app">div>
body>
html>
.....
或
this.$refs.xxx
具体案例
<template>
<div>
<h1 v-text="msg" ref="title">h1>
<button ref="btn" @click="showDOM">点我输出上方的DOM元素button>
<School ref="sch"/>
div>
template>
<script>
//引入School组件
import School from './components/School'
export default {
name:'App',
components:{School},
data() {
return {
msg:'欢迎学习Vue!'
}
},
methods: {
showDOM(){
console.log(this.$refs.title) //真实DOM元素
console.log(this.$refs.btn) //真实DOM元素
console.log(this.$refs.sch) //School组件的实例对象(vc)
}
},
}
script>
功能:让组件接收外部传过来的数据
传递数据:
接收数据:
第一种方式(只接收):props:['name']
第二种方式(限制类型):props:{name:String}
第三种方式(限制类型、限制必要性、指定默认值):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
示例代码:
父组件给子组件传数据
App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<Student>Student>
<School name="haha" :age="this.age">School>
div>
template>
<script>
import School from './components/School.vue'
import Student from './components/Student.vue'
export default {
name: 'App',
data () {
return {
age: 360
}
},
components: {
School,
Student
}
}
script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
style>
School.vue
<template>
<div class="demo">
<h2>学校名称:{{ name }}h2>
<h2>学校年龄:{{ age }}h2>
<h2>学校地址:{{ address }}h2>
<button @click="showName">点我提示学校名button>
div>
template>
<script>
export default {
name: "School",
// 最简单的写法:props: ['name', 'age']
props: {
name: {
type: String,
required: true // 必须要传的
},
age: {
type: Number,
required: true
}
},
data() {
return {
address: "北京昌平",
};
},
methods: {
showName() {
alert(this.name);
},
},
};
script>
<style>
.demo {
background-color: orange;
}
style>
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
例子:
// 定义一个混入对象
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
mixins: [myMixin]
})
选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。
比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
var mixin = {
created: function () {
console.log('混入对象的钩子被调用')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('组件钩子被调用')
}
})
// => "混入对象的钩子被调用"
// => "组件钩子被调用"
值为对象的选项,例如 methods
、components
和 directives
,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
var mixin = {
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
bar: function () {
console.log('bar')
},
conflicting: function () {
console.log('from self')
}
}
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
全局混入不建议使用
插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制。
通过全局方法 Vue.use()
使用插件。它需要在你调用 new Vue()
启动应用之前完成:
// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)
new Vue({
// ...组件选项
})
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:
对象.install = function (Vue, options) {
// 1. 添加全局过滤器
Vue.filter(....)
// 2. 添加全局指令
Vue.directive(....)
// 3. 配置全局混入(合)
Vue.mixin(....)
// 4. 添加实例方法
Vue.prototype.$myMethod = function () {...}
Vue.prototype.$myProperty = xxxx
}
具体案例:
plugin.js
export default {
install(Vue, x, y, z) {
console.log(x, y, z)
//全局过滤器
Vue.filter('mySlice', function (value) {
return value.slice(0, 4)
})
//定义全局指令
Vue.directive('fbind', {
//指令与元素成功绑定时(一上来)
bind(element, binding) {
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element, binding) {
element.focus()
},
//指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value
}
})
//定义混入
Vue.mixin({
data() {
return {
x: 100,
y: 200
}
},
})
//给Vue原型上添加一个方法(vm和vc就都能用了)
Vue.prototype.hello = () => { alert('你好啊aaaa') }
}
}
main.js
// 引入插件
import plugin from './plugin'
// 使用插件
Vue.use(plugin)
然后就可以在别的组件使用插件里的功能了。
具体案例:
组件化编码流程:
(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
(2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
1).一个组件在用:放在组件自身即可。
2). 一些组件在用:放在他们共同的父组件上(状态提升)。
(3).实现交互:从绑定事件开始。
props适用于:
(1).父组件 ==> 子组件 通信
(2).子组件 ==> 父组件 通信(要求父先给子一个函数)
使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
Cookie是最早被提出来的本地存储方式,在此之前,服务端是无法判断网络中的两个请求是否是同一用户发起的,为解决这个问题,Cookie就出现了。Cookie 是存储在用户浏览器中的一段不超过 4 KB 的字符串。它由一个名称(Name)、一个值(Value)和其它几个用 于控制 Cookie 有效期、安全性、使用范围的可选属性组成。不同域名下的 Cookie 各自独立,每当客户端发起请求时,会自动把当前域名下所有未过期的 Cookie 一同发送到服务器。
Cookie的特性:
Cookie 在身份认证中的作用
客户端第一次请求服务器的时候,服务器通过响应头的形式,向客户端发送一个身份认证的 Cookie,客户端会自动 将 Cookie 保存在浏览器中。
随后,当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的 Cookie,通过请求头的形式发送给 服务器,服务器即可验明客户端的身份。
Cookie 不具有安全性
由于 Cookie 是存储在浏览器中的,而且浏览器也提供了读写 Cookie 的 API,因此 Cookie 很容易被伪造,不具有安全 性。因此不建议服务器将重要的隐私数据,通过 Cookie 的形式发送给浏览器。
注意:千万不要使用 Cookie 存储重要且隐私的数据!比如用户的身份信息、密码等。
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了session是一种特殊的cookie。cookie是保存在客户端的,而session是保存在服务端。
为什么要用session
由于cookie 是存在用户端,而且它本身存储的尺寸大小也有限,最关键是用户可以是可见的,并可以随意的修改,很不安全。那如何又要安全,又可以方便的全局读取信息呢?于是,这个时候,一种新的存储会话机制:session 诞生了
session原理
当客户端第一次请求服务器的时候,服务器生成一份session保存在服务端,将该数据(session)的id以cookie的形式传递给客户端;以后的每次请求,浏览器都会自动的携带cookie来访问服务器(session数据id)。
图示:
session我觉得可以简单理解为一个表,根据cookie传来的值查询表中的内容
session 标准工作流程
我在 node.js 中详细演示了一遍 session 的使用,具体看了另一篇博客:https://blog.csdn.net/hangao233/article/details/123089029
LocalStorage是HTML5新引入的特性,由于有的时候我们存储的信息较大,Cookie就不能满足我们的需求,这时候LocalStorage就派上用场了。
LocalStorage的优点:
LocalStorage的缺点:
LocalStorage的常用API:
// 保存数据到 localStorage
localStorage.setItem('key', 'value');
// 从 localStorage 获取数据
let data = localStorage.getItem('key');
// 从 localStorage 删除保存的数据
localStorage.removeItem('key');
// 从 localStorage 删除所有保存的数据
localStorage.clear();
// 获取某个索引的Key
localStorage.key(index)
LocalStorage的使用场景:
SessionStorage和LocalStorage都是在HTML5才提出来的存储方案,SessionStorage 主要用于临时保存同一窗口(或标签页)的数据,刷新页面时不会删除,关闭窗口或标签页之后将会删除这些数据。
SessionStorage与LocalStorage对比:
SessionStorage的常用API:
// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');
// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');
// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');
// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();
// 获取某个索引的Key
sessionStorage.key(index)
SessionStorage的使用场景
由于SessionStorage具有时效性,所以可以用来存储一些网站的游客登录的信息,还有临时的浏览记录的信息。当关闭网站之后,这些信息也就随之消除了。
具体案例:
localStorage
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>localStoragetitle>
head>
<body>
<h2>localStorageh2>
<button onclick="saveData()">点我保存一个数据button>
<button onclick="readData()">点我读取一个数据button>
<button onclick="deleteData()">点我删除一个数据button>
<button onclick="deleteAllData()">点我清空一个数据button>
<script type="text/javascript" >
let p = {name:'张三',age:18}
function saveData(){
localStorage.setItem('msg','hello!!!')
localStorage.setItem('msg2',666)
// 转成 JSON 对象存进去
localStorage.setItem('person',JSON.stringify(p))
}
function readData(){
console.log(localStorage.getItem('msg'))
console.log(localStorage.getItem('msg2'))
const result = localStorage.getItem('person')
console.log(JSON.parse(result))
// console.log(localStorage.getItem('msg3'))
}
function deleteData(){
localStorage.removeItem('msg2')
}
function deleteAllData(){
localStorage.clear()
}
script>
body>
html>
sessionStorage
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>sessionStoragetitle>
head>
<body>
<h2>sessionStorageh2>
<button onclick="saveData()">点我保存一个数据button>
<button onclick="readData()">点我读取一个数据button>
<button onclick="deleteData()">点我删除一个数据button>
<button onclick="deleteAllData()">点我清空一个数据button>
<script type="text/javascript" >
let p = {name:'张三',age:18}
function saveData(){
sessionStorage.setItem('msg','hello!!!')
sessionStorage.setItem('msg2',666)
// 转换成JSON 字符串存进去
sessionStorage.setItem('person',JSON.stringify(p))
}
function readData(){
console.log(sessionStorage.getItem('msg'))
console.log(sessionStorage.getItem('msg2'))
const result = sessionStorage.getItem('person')
console.log(JSON.parse(result))
// console.log(sessionStorage.getItem('msg3'))
}
function deleteData(){
sessionStorage.removeItem('msg2')
}
function deleteAllData(){
sessionStorage.clear()
}
script>
body>
html>
组件自定义事件是一种组件间通信的方式,适用于:子组件 ===> 父组件
使用场景
A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
绑定自定义事件:
第一种方式,在父组件中:
或
具体代码
App.vue
<template>
<div class="app">
<Student @atguigu="getStudentName"/>
div>
template>
<script>
import Student from './components/Student'
export default {
name:'App',
components:{Student},
data() {
return {
msg:'你好啊!',
studentName:''
}
},
methods: {
getStudentName(name,...params){
console.log('App收到了学生名:',name,params)
this.studentName = name
}
}
}
script>
<style scoped>
.app{
background-color: gray;
padding: 5px;
}
style>
Student.vue
<template>
<div class="student">
<button @click="sendStudentlName">把学生名给Appbutton>
div>
template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
}
},
methods: {
sendStudentlName(){
//触发Student组件实例身上的atguigu事件
this.$emit('atguigu',this.name,666,888,900)
}
},
}
script>
<style lang="less" scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
style>
第二种方式,在父组件中:
使用 this.$refs.xxx.$on()
这样写起来更灵活,比如可以加定时器啥的。
具体代码
App.vue
<template>
<div class="app">
<Student ref="student"/>
div>
template>
<script>
import Student from './components/Student'
export default {
name:'App',
components:{Student},
data() {
return {
studentName:''
}
},
methods: {
getStudentName(name,...params){
console.log('App收到了学生名:',name,params)
this.studentName = name
},
},
mounted() {
this.$refs.student.$on('atguigu',this.getStudentName) //绑定自定义事件
// this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性)
},
}
script>
<style scoped>
.app{
background-color: gray;
padding: 5px;
}
style>
Student.vue
<template>
<div class="student">
<button @click="sendStudentlName">把学生名给Appbutton>
div>
template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
}
},
methods: {
sendStudentlName(){
//触发Student组件实例身上的atguigu事件
this.$emit('atguigu',this.name,666,888,900)
}
},
}
script>
<style lang="less" scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
style>
若想让自定义事件只能触发一次,可以使用
once
修饰符,或$once
方法。触发自定义事件:
this.$emit('atguigu',数据)
使用 this.$emit() 就可以子组件向父组件传数据
解绑自定义事件this.$off('atguigu')
代码
this.$off('atguigu') //解绑一个自定义事件
// this.$off(['atguigu','demo']) //解绑多个自定义事件
// this.$off() //解绑所有的自定义事件
组件上也可以绑定原生DOM事件,需要使用native
修饰符。
代码
注意:通过
this.$refs.xxx.$on('atguigu',回调)
绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!
一种组件间通信的方式,适用于任意组件间通信。
安装全局事件总线:
new Vue({
......
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
},
......
})
使用事件总线:
接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
methods(){
demo(data){......}
}
......
mounted() {
this.$bus.$on('xxxx',this.demo)
}
提供数据:this.$bus.$emit('xxxx',数据)
最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。
示例代码
School.vue
<template>
<div class="school">
<h2>学校名称:{{name}}h2>
<h2>学校地址:{{address}}h2>
div>
template>
<script>
export default {
name:'School',
data() {
return {
name:'尚硅谷',
address:'北京',
}
},
methods: {
demo(data) {
console.log('我是School组件,收到了数据',data)
}
}
mounted() {
// console.log('School',this)
this.$bus.$on('hello',this.demo)
},
beforeDestroy() {
this.$bus.$off('hello')
},
}
script>
<style scoped>
.school{
background-color: skyblue;
padding: 5px;
}
style>
Student.vue
<template>
<div class="student">
<h2>学生姓名:{{name}}h2>
<h2>学生性别:{{sex}}h2>
<button @click="sendStudentName">把学生名给School组件button>
div>
template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
}
},
mounted() {
// console.log('Student',this.x)
},
methods: {
sendStudentName(){
this.$bus.$emit('hello',this.name)
}
},
}
script>
<style lang="less" scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
style>
一种组件间通信的方式,适用于任意组件间通信。
使用步骤:
安装pubsub:npm i pubsub-js
引入: import pubsub from 'pubsub-js'
接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods:{
demo(data){......}
}
......
mounted() {
this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
}
提供数据:pubsub.publish('xxx',数据)
最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)
去取消订阅。
示例代码
订阅消息
School.vue
<template>
<div class="school">
<h2>学校名称:{{name}}h2>
<h2>学校地址:{{address}}h2>
div>
template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'School',
data() {
return {
name:'尚硅谷',
address:'北京',
}
},
mounted() {
// console.log('School',this)
/* this.$bus.$on('hello',(data)=>{
console.log('我是School组件,收到了数据',data)
}) */
this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
console.log(this)
// console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
})
},
beforeDestroy() {
// this.$bus.$off('hello')
pubsub.unsubscribe(this.pubId)
},
}
script>
<style scoped>
.school{
background-color: skyblue;
padding: 5px;
}
style>
发布消息
Student.vue
<template>
<div class="student">
<h2>学生姓名:{{name}}h2>
<h2>学生性别:{{sex}}h2>
<button @click="sendStudentName">把学生名给School组件button>
div>
template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
}
},
mounted() {
// console.log('Student',this.x)
},
methods: {
sendStudentName(){
// this.$bus.$emit('hello',this.name)
pubsub.publish('hello',666)
}
},
}
script>
<style lang="less" scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
style>
this.$nextTick(回调函数)
具体案例
this.$nextTick(function(){
this.$refs.inputTitle.focus()
}
作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。
写法:
准备好样式:
使用
包裹要过渡的元素,并配置name属性:
<transition name="hello">
<h1 v-show="isShow">你好啊!h1>
transition>
备注:若有多个元素需要过度,则需要使用:
,且每个元素都要指定key
值。
具体案例(单个元素过渡)
<template>
<div>
<button @click="isShow = !isShow">显示/隐藏button>
<transition appear>
<h1 v-show="isShow">你好啊!h1>
transition>
div>
template>
<script>
export default {
name:'Test',
data() {
return {
isShow:true
}
},
}
script>
<style scoped>
h1{
background-color: orange;
}
.v-enter-active{
animation: move 0.5s linear;
}
.v-leave-active{
animation: move 0.5s linear reverse;
}
@keyframes move {
from{
transform: translateX(-100%);
}
to{
transform: translateX(0px);
}
}
style>
name 的作用可以让让不同的元素有不同的动画效果
<template>
<div>
<button @click="isShow = !isShow">显示/隐藏button>
<transition name="hello" appear>
<h1 v-show="isShow">你好啊!h1>
transition>
div>
template>
<script>
export default {
name:'Test',
data() {
return {
isShow:true
}
},
}
script>
<style scoped>
h1{
background-color: orange;
}
.hello-enter-active{
animation: move 0.5s linear;
}
.hello-leave-active{
animation: move 0.5s linear reverse;
}
@keyframes move {
from{
transform: translateX(-100%);
}
to{
transform: translateX(0px);
}
}
style>
具体案例(多个元素过渡)
<template>
<div>
<button @click="isShow = !isShow">显示/隐藏button>
<transition-group name="hello" appear>
<h1 v-show="!isShow" key="1">你好啊!h1>
<h1 v-show="isShow" key="2">尚硅谷!h1>
transition-group>
div>
template>
<script>
export default {
name:'Test',
data() {
return {
isShow:true
}
},
}
script>
<style scoped>
h1{
background-color: orange;
}
/* 进入的起点、离开的终点 */
.hello-enter,.hello-leave-to{
transform: translateX(-100%);
}
.hello-enter-active,.hello-leave-active{
transition: 0.5s linear;
}
/* 进入的终点、离开的起点 */
.hello-enter-to,.hello-leave{
transform: translateX(0);
}
style>
使用第三库的具体案例(随便看看,这个不重要)
库的名称:Animate.css
安装:npm i animate.css
引入:import ‘animate.css’
<template>
<div>
<button @click="isShow = !isShow">显示/隐藏button>
<transition-group
appear
name="animate__animated animate__bounce"
enter-active-class="animate__swing"
leave-active-class="animate__backOutUp"
>
<h1 v-show="!isShow" key="1">你好啊!h1>
<h1 v-show="isShow" key="2">尚硅谷!h1>
transition-group>
div>
template>
<script>
import 'animate.css'
export default {
name:'Test',
data() {
return {
isShow:true
}
},
}
script>
<style scoped>
h1{
background-color: orange;
}
style>
ajax 是前端技术,你得有浏览器,才有window对象,才有xhr,才能发ajax请求,服务器之间通信就用传统的http请求就行了。
在vue.config.js中添加如下配置:
devServer:{
proxy:"http://localhost:5000"
}
说明:
编写vue.config.js配置具体代理规则:
module.exports = {
devServer: {
proxy: {
'/api1': {// 匹配所有以 '/api1'开头的请求路径
target: 'http://localhost:5000',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api1': ''}//代理服务器将请求地址转给真实服务器时会将 /api1 去掉
},
'/api2': {// 匹配所有以 '/api2'开头的请求路径
target: 'http://localhost:5001',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api2': ''}
}
}
}
}
/*
changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
changeOrigin默认值为true
*/
说明:
作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件 。
分类:默认插槽、具名插槽、作用域插槽
使用方式:
默认插槽:
父组件中:
<Category>
<div>html结构1div>
Category>
子组件中:
<template>
<div>
<slot>插槽默认内容...slot>
div>
template>
具名插槽:
父组件中:
<Category>
<template slot="center">
<div>html结构1div>
template>
<template v-slot:footer>
<div>html结构2div>
template>
Category>
子组件中:
<template>
<div>
<slot name="center">插槽默认内容...slot>
<slot name="footer">插槽默认内容...slot>
div>
template>
作用域插槽:
理解:数据在组件的自身(子组件),但根据数据生成的结构需要组件的使用者(父组件)来决定。(games数据在Category(子)组件中,但使用数据所遍历出来的结构由App(父)组件决定)
具体编码:
父组件中:
<Category>
<template scope="scopeData">
<ul>
<li v-for="g in scopeData.games" :key="g">{{g}}li>
ul>
template>
Category>
<Category>
<template slot-scope="scopeData">
<h4 v-for="g in scopeData.games" :key="g">{{g}}h4>
template>
Category>
子组件中:
<template>
<div>
<slot :games="games">slot>
div>
template>
<script>
export default {
name:'Category',
props:['title'],
//数据在子组件自身
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽']
}
},
}
script>