关于sy”“nc的语法糖

本文探讨了Vue.js中sync语法糖的使用,包括自定义指令的创建和应用,如权限控制和图片加载错误处理。还介绍了Echarts在数据可视化中的角色,并给出了柱状图和饼状图的绘制示例。此外,文章提到了Vue提供的动画效果,展示了不同场景下的动画实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于sync的语法糖

语法: <子组件标签  :a.sync="b"  

父组件和子组件同步某个属性时:
以前的方法:利用单向数据流  <Son :myname="name"  @update:myname="v=>name=v" />
现在的方法:利用sync语法糖(父子之间的双向绑定)  <Son :myname.sync="name"/>
注意:update:xx 是固定的

优势:对于父组件而言:少写一个@xxx (不用授权方法给儿子,因为sync已经包含了)
使用场景:仅仅用于 父子组件关于属性的修改




# 自定义指令directive

## 指令:

1 vue提供好的指令: v-for v-if v-show v-html 等 <a v-if=“”
2 自定义指令:自己来定义指令:v-xx,以后也是被用于标签中 <a v-xx=“”


## 场景:

权限控制 :不同的账号看到的组件是不同的


## 分类:

1 全局 : 在某个js中写,能够用于所有组件
import Vue from ‘vue’
Vue.directive(‘指令名称1’,{功能1})
Vue.directive(‘指令名称2’,{功能2})

2 局部 :在组件中写,只能用于当前组件
export default {
directives:{
‘指令名称1’:{
//功能1
},
‘指令名称2’:{
//功能2
}
},


上课只讲全局:

## 指令中的钩子函数

1 bind: 当指令被绑定到某个元素时,才会触发, —只会触发一次
2 inserted: 当被指令绑定后的元素渲染(挂载)时,才出触发 --可能会触发多次(重点)
3 update: 当被指令绑定后的元素发生改变会触发 --可能会触发多次




## 语法:全局

Vue.directive(‘指令名称1’,{
//el能够获取被绑定的dom元素(js对象)
//binding对象.value 返回被绑定时传入的参数 v-xx=“值”
钩子函数(el,binding){}
})




## 步骤:全局

1 在src下新建directives,在该目录下新建myDirectives.js,编辑该js




2 在main.js中 使用即可

import ‘./directives/myDirectives.js’




## 场景1:通过自定义指令实现某个文本框自动获取焦点

import Vue from ‘vue’

//让某个元素能够获取焦点
Vue.directive(‘getFocus’,{
//el能够获取被绑定的dom元素(js对象)
//binding对象.value 返回被绑定时传入的参数 v-xx=“值”
inserted(el,binding){

    el.focus();
}

})

~~~

场景2: 加载多个图,如果图片加载失败,则加载默认图

//加载图片错误时显示默认图
Vue.directive('defaultImg',{
	inserted(el,binding){
        //当图片加载错误时触发
        el.onerror=function(){
            el.src=binding.value
        }
    }
})


<img  v-defaultImg="default_img" 
:src="`http://localhost:3000/img/${item}`" 
v-for="(item,index) in imgs" 
:key="index"  width="100px" height="100px"/>


export default {
  
    data(){
        return{
            imgs:[],
            default_img:require('../../assets/logo.png')
        }
    },

   async created(){
      let res=await  this.api.stus.getStus();
      this.imgs=res.stus.map(item=>item.head)
    }


场景3:通过自定义指令实现:根据不同的账号能够渲染不同的组件

aaa 111    ->只能看到编辑
bbb 111    ->只能看到删除
ccc 111    ->编辑、删除都看不到
ddd 111    ->编辑、删除都看得到

步骤1 :更新后台数据库

{
    "_id": ObjectId("62e49a53ec277e7ef863b6f4"),
    "username": "aaa",
    "password": "111",
    "privilege": [
        "upd"
    ]
}

步骤2: 更新后端的model模块

//获得model对象
let mongoose=require('mongoose');
let Schema=mongoose.Schema;
let usersSchema=new Schema({
    username:String,
    password:String,
    privilege:Array
},{versionKey:false})
let usersModel=mongoose.model("usersModel",usersSchema,"users")

//暴露 
module.exports=usersModel


步骤3:编辑自定义指令

//权限控制组件
Vue.directive('showByPrivilege',{
	inserted(el,binding){
    //    console.log(el,binding.value);
       //根据vuex获取user对象的privilege
       if(!store?.state?.users?.user?.privilege?.includes(binding.value)){
            //如果不包含,则隐藏  
            el.parentNode.removeChild(el)
       }
    }
})

步骤4: 添加自定义指令

<el-table-column label="操作">
        <template slot-scope="scope">
          <el-button v-showByPrivilege='"upd"' size="mini" @click="handleEdit(scope.$index, scope.row)"
            >编辑</el-button
          >
          <el-button
            v-showByPrivilege="'del'"
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)"
            >删除</el-button
          >
        </template>
      </el-table-column>

Echarts

数据可视化

借助图形化的手段来展示数据,好处:更直观,一目了然

可视化工具:

Echarts --百度出品  
HighCharts  --国外 收费  大公司用  
AntV --蚂蚁金服

Echarts:

百度前端团队基于canvas的js图标库(可视化数据)

安装:

npm install echarts --save

demo: 通过柱状图绘制出 姓名-年龄的关系

<template>
  <div>
    <h1>数据可视化</h1>

    <div id="d" style="width: 1000px; height: 600px"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";

export default {
  data() {
    return {
      stus: {
        names: [],
        ages: [],
      },
      myChart:null
    };
  },
  watch: {
    stus: {
      handler(newVal) {
        //绘制
         this.setOption();
      },
      deep: true,
    },
  },
  async created() {
    let res = await this.api.stus.getStus();
    this.stus.names = res.stus.map((item) => item.name);
    this.stus.ages = res.stus.map((item) => item.age);
  },
  async mounted() {
    //初始化
     this.myChart = echarts.init(document.getElementById("d"));
    //绘制
    this.setOption();
  },
  methods: {

    //绘制
    setOption() {
      this.myChart.setOption({
        title: {
          text: "姓名-年龄关系图",
        },
        tooltip: {},
        xAxis: {
          data: this.stus.names,
        },
        yAxis: {},
        series: [
          {
            name: "年龄",
            type: "bar",
            data: this.stus.ages,
          },
        ],
      });
    },
  },
};
</script>

<style>
</style>

作业:1 上面的姓名-年龄图 (柱状图) 、2 下面的班级-人数图(饼状图)

通过饼状图,绘制出  班级名-总人数 的关系图
把
stus:[
{_id: "6306dfe09b2e0000cc001007", name: "adasdad", age: 59, gender: 1, hobby: ["睡觉"], head: "2.png",…}
1: {_id: "6306dff59b2e0000cc001008", name: "女巨人", age: 11, gender: 0, hobby: ["睡觉", "吃饭", "打豆豆"],…}
2: {_id: "6306dff69b2e0000cc001009", name: "雷神3", age: 59, gender: 1, hobby: ["睡觉"], head: "2.png",…}
3: {_id: "6306dff79b2e0000cc00100a", name: "雷4", age: 24, gender: 1, hobby: ["睡觉"], head: "2.png",…}
4: {_id: "6306dff79b2e0000cc00100b", name: "雷神5", age: 14, gender: 1, hobby: ["睡觉"], head: "2.png",…}
5: {_id: "6306dff89b2e0000cc00100c", name: "雷神6", age: 34, gender: 1, hobby: ["睡觉"], head: "2.png",…}
6: {_id: "6306dff99b2e0000cc00100d", name: "雷神7", age: 59, gender: 1, hobby: ["睡觉"], head: "22222222.png",…}
7: {_id: "6306dff99b2e0000cc00100e", name: "雷8", age: 78, gender: 1, hobby: ["睡觉"], head: "2.png",…}
8: {_id: "6306dffa9b2e0000cc00100f", name: "雷神", age: 10, gender: 1, hobby: ["睡觉"], head: "11111.png",…}
]

变成:


stus2:[
     { value: 1048, name: '班级名1' },
     { value: 735, name: '班级名1' },
     { value: 580, name: '班级名1' },
     { value: 484, name: '班级名1' },
     { value: 300, name: '班级名1' }
 ]
 
 
 提示:
let str="asduasgjhasbdagdab"

let obj={}

for(let i in str){
    let k=str[i];
    if(obj[k]){
        //有
        obj[k]++;
    }else{
        //没有
        obj[k]=1
    }
}
console.log(obj);
 

vue提供的动画

关于隐藏和显示的动画

以下2种情况可以使用动画

1 条件渲染 v-if/v-show
2 动态组件 <componert :is=""

例子1:点击按钮隐藏和显示元素—完整版

<template>
    <div>

      <transition enter-active-class="xx-enter-active" leave-active-class="xx-leave-active">
        <span v-show="isb">张三</span>
      </transition>
        

        <button @click="switch1">切换</button>
    </div>
</template>

<script>
export default {
  data(){
    return{
      isb:true
    }
  },
  methods:{
    switch1(){
      this.isb=!this.isb
    }
  }
}
</script>

<style>

 @keyframes change{
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
 }


.xx-enter-active{
    animation: change 2s
}

.xx-leave-active{
     animation: change 2s reverse
}

</style>

例子2:点击按钮隐藏和显示元素—简写版

要求:

类选择器的命名必须是 .xx-enter-active .xx-leave-active

<template>
    <div>

      <transition name="xx">
        <span v-show="isb">张三</span>
      </transition>
        

        <button @click="switch1">切换</button>
    </div>
</template>

<script>
export default {
  data(){
    return{
      isb:true
    }
  },
  methods:{
    switch1(){
      this.isb=!this.isb
    }
  }
}
</script>

<style>

 @keyframes change{
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
 }


.xx-enter-active{
    animation: change 2s
}

.xx-leave-active{
     animation: change 2s reverse
}

</style>

例子3:点击按钮,以动画的形式切换内容: 张三《----》李四

<template>
    <div>

      <transition name="xx">
        <span v-if="isb" key="1">张三</span>
        <span v-else     key="2">李四</span>
      </transition>
        <button @click="switch1">切换</button>
    </div>
</template>

<script>
export default {
  data(){
    return{
       isb:true
    }
  },
  methods:{
    switch1(){
       this.isb=!this.isb
    }
  }
}
</script>

<style>

 @keyframes change{
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
 }


.xx-enter-active{
    animation: change 2s
}

.xx-leave-active{
     animation: change 0s reverse
}

</style>

例子4:动态组件实现动画 (自己写)

例子5: 以动画移动的方式来添加li,和删除li

<template>
    <div>

      <input style="margin-left:100px" type="text" @keyup.enter="add">
      <!-- <ul style="margin-left:100px"> -->
        <transition-group  tag="ul" name="xx">
                  <li v-for="item in list" :key="item.id">{{item.title}} <button @click="del(item.id)">删除</button></li>
        </transition-group>
      <!-- </ul> -->
     
    </div>
</template>

<script>
export default {
  data(){
    return{
      list:[
        {id:1,title:"java"},
        {id:2,title:"web"},
        {id:3,title:"test"}
      ],
      id:4
    }
  },
  methods:{
    add(e){
      this.list.push({
        id:this.id++,
        title:e.target.value
      })
    },
    del(id){
      this.list=this.list.filter(item=>item.id!=id)
    }
  }
}
</script>

<style>

 @keyframes change{
    0% {
      opacity: 0;
      transform: translateX(-60px);
    }
    100% {
      opacity: 1;
      transform: translateX(0px);
    }
 }


.xx-enter-active{
    animation: change 1s
}

.xx-leave-active{
     animation: change 1s reverse
}

</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值