• Vue——属性监听器(面试)、自定义指令(面试)


    目录

    一、属性监听器(面试)

    二、自定义指令(面试)


    一、属性监听器(面试)

    watch:{x(){}}

    中的方法名必须跟要监听的data中的属性名一样,才代表监听指定属性

    当侦听器监听的属性发生变化时,就会调用watch中对应的方法

    侦听器属性,比计算属性计算效率消耗大

    1. new Vue({
    2. el:"",//关联界面元素
    3. data:{x:12},//vm的数据源
    4. methods:{},//方法
    5. filter:{},//过滤器
    6. computed:{xx(){}}, //xx就是一个计算属性
    7. watch:{x(){}} //x就是监听了data中的x属性的一个监听器
    8. })

     用法:

    1. <div id='app'>
    2. <p>{{n}}p>
    3. <button @click="change1">修改nbutton>
    4. <p>{{obj.age}}p>
    5. <button @click="change2">修改objbutton>
    6. div>
    7. <script>
    8. var vm = new Vue({
    9. el: '#app',
    10. data: {
    11. n: 100,
    12. obj: {
    13. age: 20
    14. }
    15. },
    16. methods: {
    17. change1() {
    18. console.log("点击事件触发了")
    19. this.n = "修改了"
    20. },
    21. change2() {
    22. // this.obj.age="修改了引用数据内部的属性值:页面会重新渲染,但是侦听器属性不会触发"
    23. // this.obj={age:"只有修改了引用数据的引用 才能触发侦听器属性"}
    24. this.obj.age = "修改了引用数据内部的属性值也想触发侦听器属性,必须深度监听"
    25. }
    26. },
    27. watch: {//侦听器属性:必须和data中的数据源同名
    28. n() {
    29. console.log(666666666)
    30. },
    31. // obj(){
    32. // console.log("obj改变了")
    33. // }
    34. obj: { //这就是深度监听,上面改变this.obj.age,这个属性监听器也会触发
    35. //其实这样设计不好
    36. deep: true,
    37. handler: () => {
    38. console.log("obj改变了")
    39. }
    40. }
    41. }
    42. })
    43. script>

    案例一:汇率换算

    1. <div id='app'>
    2. RMB:<input type="text" v-model="rmb">
    3. doller:<input type="text" v-model="doller">
    4. div>
    5. <script>
    6. var vm = new Vue({
    7. el: '#app',
    8. data: {
    9. rmb:0,
    10. doller:0
    11. },
    12. methods: {},
    13. watch:{
    14. rmb(newvalue,oldvalue){
    15. console.log(arguments) //会打印两个值,原来的值和新的值
    16. this.doller=(newvalue/6.9).toFixed(2)*100/100
    17. },
    18. doller(newvalue,oldvalue){
    19. this.rmb=newvalue*6.9
    20. }
    21. }
    22. })
    23. script>

    案例二:消费余额提示

    1. <div id='app'>
    2. <p>{{money}}p>
    3. <button @click="fn">消费button>
    4. div>
    5. <script>
    6. var vm = new Vue({
    7. el: '#app',
    8. data: {
    9. money:100
    10. },
    11. methods: {
    12. fn(){
    13. this.money-=5
    14. }
    15. },
    16. watch:{
    17. money(newv,oldv){
    18. if(newv<30){
    19. alert("发短信还给用户:只剩30了不到了")
    20. }
    21. }
    22. }
    23. })
    24. script>

    案例三:播放进度条监听

    1. <style type="text/css">
    2. .slider{
    3. width:400px;
    4. height: 20px;
    5. background-color: skyblue;
    6. position: relative;
    7. left: 100px;
    8. top: 100px;
    9. border-radius: 10px;
    10. }
    11. .sliderbar{
    12. width:30px;
    13. height: 30px;
    14. border-radius: 50%;
    15. background-color:cadetblue;
    16. position: relative;
    17. top: -5px;
    18. }
    19. style>
    20. <div id='app'>
    21. 进度条:{{total-currenttime|timerparser}}
    22. <div class="slider">
    23. <div class="sliderbar" :style="{left:x}">div>
    24. div>
    25. <button @click="start">startbutton>
    26. div>
    27. <script>
    28. var vm = new Vue({
    29. el: '#app',
    30. data: {
    31. currenttime:0,
    32. total:242,
    33. x:0,
    34. maxwidth:370
    35. },
    36. methods: {
    37. start(){
    38. this.timer=setInterval(()=>{
    39. this.currenttime+=0.1
    40. },100)
    41. }
    42. },
    43. filters:{
    44. timerparser(arg){
    45. return ` ${parseInt(arg/60).toString().padStart(2,"0")}:${parseInt(arg%60).toString().padStart(2,"0")}`
    46. }
    47. },
    48. watch:{
    49. currenttime(value){
    50. this.x=this.maxwidth*value/this.total+"px"
    51. if(value>=60){
    52. clearInterval(this.timer)
    53. alert("试听结束")
    54. }
    55. }
    56. }
    57. })
    58. script>

    二、自定义指令(面试)

    除了默认设置的核心指令( v-model 和 v-show 等),Vue 也允许注册自定义指令。

    在Vue里,代码复用的主要形式和抽象是组件。

    有的情况下,仍然需要对纯 DOM 元素进行底层操作,这时候就会用到自定义指令 。

    指令:Vue中指令就是标签中V-开始的一种自定义的标签的属性,它在Vue运行了以后,就具有封装好的功能,使用时非常简洁

    以一个input元素自动获得焦点为例,当页面加载时,使用autofocuse可以让元素将获得焦点 ,但是autofocuse在移动版Safari上不工作,现在注册一个使元素自动获取焦点的指令。

    指令注册类似于组件注册,包括全局指令和局部指令两种。

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js">script>
    7. head>
    8. <body>
    9. <div id="app">
    10. <p v-html="msg">p>
    11. <input v-red type="text" v-model="count" v-focus/>
    12. <div v-red>hellodiv>
    13. <h2 v-color="'blue'">123h2>
    14. <h2 v-color="'gold'">123h2>
    15. <p v-color="mycolor">123p>
    16. <input type="text" >
    17. div>
    18. <script>
    19. var vm = new Vue({
    20. el: "#app",
    21. data: {
    22. msg: "hello",
    23. count: 123,
    24. mycolor:"grey"
    25. },
    26. methods: {
    27. },
    28. directives: {
    29. red: {
    30. inserted(el) {
    31. console.log(el) //绑定这个指令的节点对象:DOM
    32. el.style.color = "red"
    33. }
    34. },
    35. color: {
    36. inserted(el, option) { //option是一个对象
    37. el.style.color = option.value
    38. }
    39. },
    40. focus:{
    41. inserted(el){
    42. el.focus()
    43. }
    44. }
    45. }
    46. })
    47. script>
    48. body>
    49. html>

     案例:Echarts

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. <script src='https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js'>script>
    7. <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/echarts/5.3.0-rc.1/echarts.js">script>
    8. head>
    9. <body>
    10. <style type="text/css">
    11. .box {
    12. width: 600px;
    13. height: 600px;
    14. }
    15. style>
    16. <div id='app'>
    17. <div class="box" style="width:600px;height:600px;" v-echarts>
    18. div>
    19. div>
    20. <script>
    21. var vm = new Vue({
    22. el: '#app',
    23. data: {
    24. },
    25. methods: {},
    26. directives: {
    27. echarts: {
    28. bind(el) {
    29. var myChart = echarts.init(el);
    30. let options = {
    31. title: {
    32. text: 'Referer of a Website',
    33. subtext: 'Fake Data',
    34. left: 'center'
    35. },
    36. tooltip: {
    37. trigger: 'item'
    38. },
    39. legend: {
    40. orient: 'vertical',
    41. left: 'left'
    42. },
    43. series: [{
    44. name: 'Access From',
    45. type: 'pie',
    46. radius: '50%',
    47. data: [{
    48. value: 1048,
    49. name: 'Search Engine'
    50. },
    51. {
    52. value: 735,
    53. name: 'Direct'
    54. },
    55. {
    56. value: 580,
    57. name: 'Email'
    58. },
    59. {
    60. value: 484,
    61. name: 'Union Ads'
    62. },
    63. {
    64. value: 300,
    65. name: 'Video Ads'
    66. }
    67. ],
    68. emphasis: {
    69. itemStyle: {
    70. shadowBlur: 10,
    71. shadowOffsetX: 0,
    72. shadowColor: 'rgba(0, 0, 0, 0.5)'
    73. }
    74. }
    75. }]
    76. }
    77. myChart.setOption(options)
    78. }
    79. }
    80. }
    81. })
    82. script>
    83. body>
    84. html>

    1)全局指令

    1. // 注册一个全局自定义指令 v-focus
    2. Vue.directive('focus', {
    3. // 当绑定元素插入到 DOM 中。
    4. inserted: function (el) {
    5. // 聚焦元素
    6. el.focus()
    7. }
    8. })

    2)局部指令

    1. var vm = new Vue({
    2. el: '#app',
    3. directives:{
    4. focus:{
    5. inserted: function (el) {
    6. el.focus()
    7. }
    8. }
    9. }
    10. })

    在模板中任何元素上使用新的 v-focus 属性

    3)钩子函数

    指令定义函数提供了几个钩子函数(可选) 。

    【bind】

      只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

    【inserted】

      被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

    【update】

      所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。但是可以通过比较更新前后的值来忽略不必要的模板更新。

    当前所在组件更新的时候,这个函数才运行

    【componentUpdated】

      所在组件的 VNode 及其孩子的 VNode 全部更新时调用。

    【unbind】

      只调用一次, 指令与元素解绑时调用。

    注意区别:

    bind与inserted:bind时父节点为null,inserted时父节点存在;

    update与componentUpdated:update是数据更新前,componentUpdated是数据更新后。

    4)钩子函数参数

    【el】

      指令所绑定的元素,可以用来直接操作 DOM。

    【binding】

      一个对象,包含指令名称及该指令所绑定的表达式信息。

            里面有name、value、oldvalue等等

    【vnode】

      Vue 编译生成的虚拟节点。

    【oldVnode】

      上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    注意:除了 el 之外,其它参数都是只读的,尽量不要修改他们。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

    1. <div id='app'>
    2. <p v-hqyj="red" @click="change1">hellop>
    3. div>
    4. <script>
    5. var vm = new Vue({
    6. el: '#app',
    7. data: {
    8. red:"rgb(255,0,0)"
    9. },
    10. methods: {
    11. change1(){
    12. this.red="rgb(200,0,0)"
    13. }
    14. },
    15. directives:{
    16. hqyj:{
    17. bind(){
    18. console.log("bind")
    19. },
    20. inserted(el,binding){
    21. var v=binding.value
    22. console.log(v)
    23. },
    24. update(){
    25. console.log("update")
    26. },
    27. componentUpdated(){
    28. },
    29. unbind(){
    30. }
    31. }
    32. }
    33. })
    34. script>

    5)函数简写

    大多数情况下,可能想在bind和update钩子上做重复动作,并且不想关心其它的钩子函数。可以这样写:

    1. "{ color: 'white', text: 'hello!' }">
    2. Vue.directive('demo', function (el, binding) {
    3. console.log(binding.value.color) // => "white"
    4. console.log(binding.value.text) // => "hello!"
    5. })

    三、nextTick

    学习了生命周期之后,会有一个问题:我们在写业务的时候,写的业务代码能否操作vm

    所以需要一个工具,让我们写的diamagnetic,无论在哪里写,都希望它是组件加载完了以后才运行

    这个函数的回调函数是在组件加载完了才会执行

     

    1. <div id='app'>
    2. <p>{{msg}}p>
    3. div>
    4. <script>
    5. var vm = new Vue({
    6. el: '#app',
    7. data: {
    8. msg:"hello"
    9. },
    10. methods: {},
    11. beforeCreate(){
    12. //这个函数的回调函数是在组件加载完了才会执行
    13. this.$nextTick(()=>{
    14. console.log(this.msg)
    15. })
    16. }
    17. })
    18. script>

    ==>这个函数就可以解决上面ECharts案例

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. <script src='https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js'>script>
    7. <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/echarts/5.3.0-rc.1/echarts.js">script>
    8. head>
    9. <body>
    10. <style type="text/css">
    11. .box {
    12. width: 600px;
    13. height: 600px;
    14. }
    15. style>
    16. <div id='app'>
    17. <div class="box" v-echarts>
    18. div>
    19. div>
    20. <script>
    21. var vm = new Vue({
    22. el: '#app',
    23. data: {},
    24. methods: {},
    25. directives: {
    26. echarts: {
    27. inserted(el) {
    28. Vue.nextTick(()=>{
    29. var myChart = echarts.init(el);
    30. let options={
    31. title: {
    32. text: 'Referer of a Website',
    33. subtext: 'Fake Data',
    34. left: 'center'
    35. },
    36. tooltip: {
    37. trigger: 'item'
    38. },
    39. legend: {
    40. orient: 'vertical',
    41. left: 'left'
    42. },
    43. series: [{
    44. name: 'Access From',
    45. type: 'pie',
    46. radius: '50%',
    47. data: [{
    48. value: 1048,
    49. name: 'Search Engine'
    50. },
    51. {
    52. value: 735,
    53. name: 'Direct'
    54. },
    55. {
    56. value: 580,
    57. name: 'Email'
    58. },
    59. {
    60. value: 484,
    61. name: 'Union Ads'
    62. },
    63. {
    64. value: 300,
    65. name: 'Video Ads'
    66. }
    67. ],
    68. emphasis: {
    69. itemStyle: {
    70. shadowBlur: 10,
    71. shadowOffsetX: 0,
    72. shadowColor: 'rgba(0, 0, 0, 0.5)'
    73. }
    74. }
    75. }]
    76. }
    77. myChart.setOption(options)
    78. })
    79. }
    80. }
    81. }
    82. })
    83. script>
    84. body>
    85. html>

  • 相关阅读:
    OKR在项目管理中的应用:精准化目标管理
    《可信计算技术最佳实践白皮书》发布,龙蜥助力可信计算技术应用推广(可下载)
    Python优雅遍历字典删除元素的方法
    【剑指offer】——股票的最大利润
    谁给乡镇夫妻店的数字化铺路?
    从头开始搭建Keepalived 高可用群集
    【实用工具系列之爬虫】python爬取资讯数据
    基于threejs的商品VR展示平台的设计与实现思路
    机器学习:基于Python 机器学习进行医疗保险价格预测
    9 网关的作用
  • 原文地址:https://blog.csdn.net/qq_52301431/article/details/126666500