Vue杂记(一)———父传子值

Vue杂记(一)———父传子值

一、在Vue中展示本地pdf文档

1、官方给出的方案,详见vue-pdf-npm

此方法仅限于展示第一页pdf,无法多张展示

//官方给出的展示
<template>
  <pdf src="./static/relativity.pdf"></pdf>
</template>
 
<script>
import pdf from 'vue-pdf'
 
export default {
  components: {
    pdf
  }
}

2、pdf文件展示全部页面

此方法可以展示一个pdf文件的所有内容,但是局限于已录入的路径,无法接收父组件传入的路径

//模板:查看多页pdf
<template>
  <div>
    <pdf 
        v-for="i in numPages" 
        :key="i" 
        :src="src" 
        :page="i" 
        style="display: inline-block; width: 80%">
    </pdf>
  </div>
</template>
<script>
import pdf from "vue-pdf";

var loadingTask = pdf.createLoadingTask("pdf文件所在路径");

export default {
  components: {
    pdf
  },

  data() {
    return {
      src: loadingTask,
      numPages: undefined
    };
  },

  mounted() {
    this.src.promise.then(pdf => {
      this.numPages = pdf.numPages;
    });
  }
};
</script>

3、接收父组件传入的路径,然后在子组件中展示出来

//父组件
<template>
  <el-container style="height:660px;border: 1px solid #eee">
    <el-aside style="height: 100% ;background-color: rgb(238, 241, 246)">
      <el-menu :default-openeds="['1', '2', '3']">      //在页面中显示1,2,3的下拉栏打开,其他的下拉栏关闭
        <el-submenu index="1">
          <template slot="title"
            ><i class="el-icon-message"></i>可行性分析</template
          >
          <el-menu-item index="1-1">
            <button v-on:click="test(1)">示例</button>   //v-on 用于绑定html事件,点击按钮,即更新count值
          </el-menu-item>
        </el-submenu>
        <el-submenu index="2">
          <template slot="title"
            ><i class="el-icon-message"></i>需求分析</template
          >
          <el-menu-item index="2-1">
            <button v-on:click="test(2)">示例</button>
          </el-menu-item>
        </el-submenu>
        <el-submenu index="3">
          <template slot="title"
            ><i class="el-icon-message"></i>总体设计</template
          >
          <el-menu-item index="3-1">
            <button v-on:click="test(3)">示例</button>
          </el-menu-item>
        </el-submenu>
        <el-submenu index="4">
          <template slot="title"
            ><i class="el-icon-message"></i>详细设计</template
          >
          <el-menu-item index="4-1">
            <button v-on:click="test(4)">示例</button>
          </el-menu-item>
        </el-submenu>
        <el-submenu index="5">
          <template slot="title"><i class="el-icon-message"></i>编程</template>
          <el-menu-item index="5-1">
            <button v-on:click="test(5)">示例</button>
          </el-menu-item>
          <el-menu-item index="5-2">作业提交</el-menu-item>
        </el-submenu>
        <el-submenu index="6">
          <template slot="title"><i class="el-icon-message"></i>编程</template>
          <el-menu-item index="6-1">
            <button v-on:click="test(6)">示例</button>
          </el-menu-item>
        </el-submenu>
      </el-menu>
    </el-aside>

     <el-main >
    <el-container >
        <test :count="count"></test>    
      //此处为向子组件绑定的值,:count中的:为v-bind的缩写,而count为任意的命名,"count"中的count为 data()中的值
      </el-container>
    </el-main>
    </el-container>
</template>

<style>
.el-header {
  background-color: #b3c0d1;
  color: #333;
  line-height: 60px;
}

.el-aside {
  color: #333;
  width: 300px;
}
</style>

<script>
import test from "./test";         //将暴露出的子组件导入

export default {
  data() {
    return {
      count: "/static/img/proimg/welcome.pdf",
    }
  },
  components: {
    test                        //使用子组件test
  },
  methods: {                     //上文的按钮所触发事件的函数
    test: function(n) {
      switch (n) {
        case 1:
          console.log("我是可行性分析");
          this.count = "/static/img/proimg/1.可行性分析.pdf";
          break;
        case 2:
          console.log("我是需求分析");
          this.count = "/static/img/proimg/2.需求分析.pdf";
          break;
        case 3:
          console.log("我是总体设计");
          this.count = "/static/img/proimg/3.总体设计.pdf";
          break;
        case 4:
          console.log("我是详细设计");
          this.count = "/static/img/proimg/4.详细设计.pdf";
          break;
        case 5:
          console.log("我是编程");
          this.count = "/static/img/proimg/5.编程.pdf";
          break;
        case 6:
          console.log("我是环境搭建");
          this.count = "/static/img/proimg/6.环境搭建.pdf";
          break;
      }
    }
  }
};
</script>




//子组件
<template>
  <div>
    <pdf 
        v-for="i in numPages" 
        :key="i" 
        :src="src" 
        :page="i" 
        style="display: inline-block; width: 80%">
    </pdf>
  </div>
</template>

<script>
import pdf from "vue-pdf";


export default {
  components: {
    pdf
  },
  data() {
    return {
      src: '',
      numPages: undefined
    };
  },
  watch:{
    count(n,o){                        //n为新值,o为旧值;
      this.src = n;                    //利用监听的方式去调用函数
      this.pdfTask(this.src);
    }
},
  props: ['count'],             //接收父组件传的值
   mounted() {   
     this.b=this.count;       //钩子函数,在页面加载时就运行函数
     this.pdfTask(this.b);     //调用padTask函数
   } ,
  methods: { 
      pdfTask(count) {            //由于无法将props的数据传入导script主体/script中,即以函数形式运行pdf.createLoadingTask方式
      var self = this             
      var loadingTask = pdf.createLoadingTask(count)    //解析该路径下的所有pdf页面
      loadingTask.promise.then(pdf => {
      self.src = loadingTask
      self.numPages = pdf.numPages
      })
      }
  },
};
</script>

二、杂记之传值监听

1、props传值

简单的props传值,就是父组件将某一值传入到子组件中

//父组件
<template>
<div :count="count"></div>
</template>
<script>
export default {
  data() {
    return {
      count: "/static/img/proimg/welcome.pdf",
    }
  }
}
</script>

子组件
<template>
<div>{{count}}</div>
</template>
<script>
export default {
   props: ['count'],            //此处的count无法被data接收,而methods等可通过this.count调用
  data() {
    return {
      count: "/static/img/proimg/welcome.pdf",
    }
  }
}
</script>

2、如需使data接收到props中的数据 ,详见props

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

这里有两种常见的试图变更一个 prop 的情形:

  1. **这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。**在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:

    props: ['initialCounter'],
    data: function () {
      return {
        counter: this.initialCounter
      }
    }
    
  2. **这个 prop 以一种原始的值传入且需要进行转换。**在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }
    
  3. 注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。

3、监听机制 详见监听

计算属性computed :
  1. 支持缓存,只有依赖数据发生改变,才会重新进行计算

  2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化

  3. computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props 中的数据通过计算得到的值

  4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed

  5. 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和 一个set方法,当数据变化时,调用set方法。

侦听属性watch:
  1. 不支持缓存,数据变,直接会触发相应的操作;

  2. watch支持异步;

  3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;

  4. 当一个属性发生变化时,需要执行对应的操作;一对多;

  5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,

    . immediate:组件加载立即触发回调函数执行,

    . deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要 这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

三、for循环 详见for

<template>
  <div class="content">
    <ul>

      <li v-for="(item) in list"  v-bind:key="item.id">
         {{item.name}}
         <br/>
         {{item.id}}
         <br/>
      <>
    </ul>
    <button v-on:click="add">添加新元素<tton>
  </div>

</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      list : [
        {
          id:1,
          name:'test'
        },
        {
          id:2,
          name:'test2',
        },
        {
          id:3,
          name:'test3'
        },
      ],
      newid:4,
    }
  }
  ,
  methods:{
    add:function () {
      this.list.splice(2,0,{id:this.newid++,name:"新加入元素"})
    }
  }
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值