Day36:组件进阶和插槽

动态写选项卡

 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 依赖/注入

  1. 在祖先中provide注入信息(provide与components同级
  2. 在后代组件中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格式化

常见错误:

  1. 希望使用vue create出来的文件夹作为根目录(报错体现:template前报错
  2. template中需要基础代码,写一个div即可(报错体现:终端报错
  3. 安装插件后,可以使用v-css第二个快捷语法快速生成vue模板
  4. lint要求文件命名必须要大驼峰,可以在.eslintrc.js中关掉,在里面写'vue/multi-word-component-name': 0 ,可以通过报错看违反了那条规则,再在.eslintrc.js中关掉
  5. 在最后需要在留一行(报错体现:在最后一行的最后一个括号后面报错

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值