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

被折叠的 条评论
为什么被折叠?



