动态写选项卡
vue内置组件,这个组件可以让视图动态地渲染对应的组件内容
vue内置组件不用自己定义,可以直接拿来使用。
vue内置组件component,这个组件可以让视图动态地渲染对应的组件内容
注意:
内置组件component和注册标签components只是长得像其实没有关系。
如果在component中直接使用了引入的标签,可以不用在components中注册;
如果在component中没有使用了引入的标签,则需要在components中注册。
vue内置组件keep-alive,这个组件可以缓存组件的状态
<keep-alive>
<component :is="comp"></component>
</keep-alive>
通过keepalive包裹的组件没有被销毁,也没有重新挂载,生命周期被保存了
写一个动态绑定的选项卡
<template>
<div class="tabControl">
<span @click="fn1()"> Home </span>
<span @click="fn2()"> Post </span>
<span @click="fn3()"> Archive </span>
</div>
<keep-alive>
<component :is="comp"></component>
</keep-alive>
</template>
<script>
// 导入
import Home from './components/Home.vue'
import Archive from './components/Archive.vue'
import Post from './components/Post.vue'
export default {
name: 'App',
data(){
return {
comp:Home /* 初始值为home,切换选项卡就是修改home */
},
methods:{
fn1(){
this.comp = Home
},
fn2(){
this.comp = Post
},
fn3(){
this.comp = Archive
},
},
}
</script>
新增生命周期
4组8个生命周期(create,mounte,update,destroy)
在生命周期中经常使用的是:mounted(发送http请求,进行Dom操作,连接服务器等),beforeDestroyed(清除副作用,取消连接服务器,清除全局定时器,清除一些订阅消息。)
除此之外,keepalive缓存组件中还新增两个生命周期——激活activated和失活deactivated
选项卡切换:初始挂载+激活,切换时失活——挂载——激活,再次切换失活——激活,不再重新挂载
组件通信
父子组件通信
父到子——props 既是基本属性,也可以是方法
子到父——1.自定义事件;2.接受props方法
祖先到后代——provide/inject 依赖/注入
- 在祖先中provide注入信息(provide与components同级
- 在后代组件中inject:["msg"]注入组件内容,即可在后代组件中调用
Vue获取Dom元素
vue是数据驱动视图的框架,一般情况下,操作的数据,Dom操作由框架来实现,不能用document.querySelector
在Vue中如果希望能获取Dom元素,可以使用ref属性来获取Dom元素,还可以获取组件实例
切换视图后立刻更新
在vue中,数据一变,视图会立即更新吗?不是的。
所有操作结束后,视图统一批量更新,是更合理的操作
视图还未更新时,是无法获取更新后新的值,获取该值得到undefined
调用$nextTick方法通知视图立马更新,这个方法中传入的回调函数的逻辑会在视图更新后执行
this.$nextTick(function(){})
this.$nextTick(function(){
if(this.isEdit){
this.$refs.ref1.focus();
}
});
<template>
<div class="app">
<div class="left">
<div
v-if="!isEdit"
class="t1"
>
{{ msg }}
</div>
<div
v-else
class="t2"
>
<input
ref="ref1"
v-model="msg"
type="text"
>
</div>
</div>
<div class="right">
<button @click="edit">
{{ isEdit ? "确定" : "编辑" }}
</button>
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
msg: 'hello',
isEdit: false,
}
},
methods: {
edit() {
this.isEdit = !this.isEdit
if(this.isEdit){
this.$refs.ref1.focus()
}
},
},
};
</script>
<style scoped>
.app {
background-color: #ddd;
padding: 8px;
display: flex;
}
.left {
width: 30%;
margin-right: 20px;
}
.t1 {
border: 1px solid #000;
}
.t2 input {
width: 100%;
}
</style>
name后面为项目名,最好写
el后面的为vue管理的区域,必须写
选择器,可以叫app,也可以叫别的。
插槽
如果希望child传递的一些数据(是js数据的话),通过props传递
我现在希望给child组件传递一些html结构(比如传递过去一个input框——vue插槽)
可以通过一个内置组件来接受父组件传递过来的DOM结构——slot
插槽可以分发一些视图
首先组件需要写成双标签,双标签中的内容为父组件传给子组件的内容
使用slot在子组件中接收并渲染从父组件接收过来的内容
简单父子组件插槽
<!-- 父控件内容 -->
<div id="app">
<p ref="peiqi">这是一个段落</p>
<Child>
<input />
</Child>
</div>
<!-- 子控件内容 -->
<div>
<slot></slot>
</div>
双插槽(具名插槽)
<Child>
<!-- 需要将h1放在name=h1的插槽中,将p放在name=p的插槽中 -->
<template v-slot:h1>
<h1>这是一个父组件的标题</h1>
</template>
<template v-slot:p>
<p>这是一个父组件的段落</p>
</template>
</Child>
<!-- 子控件内容 -->
<slot name="h1"></slot>
this is a child
<slot name="p"></slot>
<slot name="default"></slot>为默认插槽,只分发一个的时候,可以不写name="default"与<template v-slot:default>
<template v-slot:h1>可以简写为<template #h1>
作用域插槽
将子组件中的内容放在父组件中展示
可以使用<template #default="x">在父组件中引入子组件的内容,其中x是一个对象,使用解构语法可以导出不同的自组建中的数据
<Child>
<!-- <template #default="x"> -->
<template #default="{msg,info}">
<span>默认插槽——{{msg}}</span>
<span>{{ info }}</span>
</template>
</Child>
lint格式调整
npm run lint 可以自动检查格式错误和修改格式问题
eslint是约束提交的代码的统一格式的
可以使用eslint插件对格式进行校正。使用方法:右键使用enlint格式化
常见错误:
- 希望使用vue create出来的文件夹作为根目录(报错体现:template前报错
- template中需要基础代码,写一个div即可(报错体现:终端报错
- 安装插件后,可以使用v-css第二个快捷语法快速生成vue模板
- lint要求文件命名必须要大驼峰,可以在.eslintrc.js中关掉,在里面写'vue/multi-word-component-name': 0 ,可以通过报错看违反了那条规则,再在.eslintrc.js中关掉
- 在最后需要在留一行(报错体现:在最后一行的最后一个括号后面报错
sass嵌套选择器
<template>
<div id="app">
this is app
<div class="main">
this is main
<div class="inner">
this is inner
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
#app{
color: pink;
.main{
color: green;
.inner{
color: plum;
}
}
}
</style>
万年历
数据接口
得到的网址为—— http://v.juhe.cn/calendar/day?key=keyvalue&date=2023-13-32
(keyvalue和date根据自己的需要改
在终端安装axios
npm i axios
有可能会有依赖冲突报错,报错信息中会有解决方法,在npm i axios后面添加 --force即可
export default {
mounted () {
axios.get('http://v.juhe.cn/calendar/day?key=keyvalue&date=2023-13-32').then(res => )
console.log(res,123)
}
}
直接发送请求会出现一个网络报错问题,它是由浏览器的同源策略引起的跨域问题。
同源策略:浏览器发送http请求,必须报称协议(http)、域名(localhost)、端口号(8080)完全一致,否则这个请求发送不了,会产生跨域问题
同源策略引起的跨域问题在绝大多数情况下,都被后端接口解决了。但聚合数据的api没有在后端接口解决同源策略问题,因此需要在前端层面解决跨域问题。
在同一个域名、端口的web下启动一个服务器,再向其他服务器发起请求,即可解决同源策略。
基于Vue-cli启动一个本地服务器
vue.config.js是项目总的配置文件,在其中可以启动一个代理服务器
devServer: {
proxy: 'https://v.juhe.cn/'
}
export default {
mounted () {
// 网址的协议、域名、端口号改为与本地内容一致
axios.get('http://localhost:8080/calendar/day?key=keyvalue&date=2023').then(res => {
console.log(res, 123)
})
}
}
axios.get相当于返回了一个Promise,可以直接嗲用then方法返回resolve中的data