vue2:scoped样式属性、nanoid、记录本小案例(基础版)

简介: vue2:scoped样式属性、nanoid、记录本小案例(基础版)

一、scoped样式属性(局部范围样式)及lang=" "的运用(默认情况下自动选择css,也不会出现lang=""让你选择语言的提示)


scoped样式属性

如果我们给两个子组件中添加的样式类名相同就会出现类名冲突的问题,
        vue显然页面的时候会最终把最后在app.vue中组测的组件的类名中的样式,
        渲染出来!

例如:

LqjSchool.vue:

<template><divclass="School"><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2></div></template>                ...
<style>.School{
background: rgb(23, 190, 241);
                        }
</style>

StudentLqj.vue:

<template><divclass="School"><h2>学生姓名:{{name}}</h2><h2>学生性别:{{msg}}</h2></div></template>                ...
<style>.School{
background: rgb(248, 120, 0);
                        }
</style>

App.vue:

importLqjSchoolfrom'./components/LqjSchool.vue'importStudentLqjfrom'./components/StudentLqj.vue'

注意:LqjSchool.vue中School的背景色为天蓝色
              StudentLqj.vue中School的背景色为橙色


结果:页面中渲染出的文字的背景颜色是StudentLqj.vue中.School的颜色:橙色


image.png

如果我们项避免出现这种情况解决方法:

       1.在不同的子组件中写不同的样式名

       2.给每一个子组件中的<style>添加scoped属性

       例如:<style scoped>   </style>

       这样我们写的样式名即使多个组件都一样,也不会出现冲突!


image.png

scoped样式属性(局部范围样式)

原理:

       原理:当我们用scoped属性来限制样式标签时,在页面渲染时会给用样式的每个<div>中的标签一个随机的id,根据此id来对应限制的标签,从而达到限制局部效果!

image.png

lang=" "的运用

此属性是供开发者在<style>标签中选择样式语言的(以css和less为例)


1.如果开发者想用css来写样式属性:

<stylelang="css"scoped>.School{
background: rgb(23, 190, 241);
                }
</style>

2.如果开发者想用less来写样式属性:

<stylelang="less"scoped>.School{
background: rgb(23, 190, 241);
                }
</style>

注意:默认情况下less是vue编译不了的我们必须借助
        (终端命令:npm i less-loader)才能正常运行。但也有可能报错:

原因你的vue脚手架调用的webpack的版本兼容问题!

image.png

查看webpack版本终端命令中输入:

npm view webpack versions

查看less-loader版本终端命令中输入:

npm view less-loader versions

安装:(我们以7版本为例)

npm i less-loader@7


二、nanoid(类型函数)直接去调用它,就能给出一个唯一的字符串


首先需要安装:

npm i nanoid

它使用分别暴露的形式,所以这样引入:

import {nanoid} from 'nanoid'


举例:

<script>import {nanoid} from'nanoid'exportdefault{
name:'Myheader',
methods:{
add(e){//e事件对象//将用户的输入包装成为一个todos对象constObj= {id:nanoid()}
                        }
                        }
                }
</script>

结果显示:

这个库会随机生成一个id


三、小案例(基础版):

app.vue:

<template><divid="root"><divclass="box"><spanclass="haizei">oen piece,记录本</span></div><divclass="todo-container"><divclass="todo-wrap"><Myheader:addTodos="addTodos"></Myheader><List:todos="todos":checkTodo="checkTodo":deleteTodo="deleteTodo"></List><Myfooter:todos="todos":checkAllTodo="checkAllTodo":clearAllTodo="clearAllTodo"></Myfooter></div></div></div></template><script>// 引入School组件 importMyheaderfrom'./components/Myheader.vue'importListfrom'./components/List.vue'// 因为List是Item的父组件,所以不用引入Item// import Item from './components/Item.vue'importMyfooterfrom'./components/Myfooter.vue'exportdefault {
name: 'App',
// msg里面要接受到的数据开始components: {Myheader,List,
// Item,Myfooter,},
data(){
return{
todos:JSON.parse(localStorage.getItem('todos')) || []
// todos:[//     // {id:'001',title:'学vue+写csdn',done:true},//     // {id:'002',title:'吃饭',done:false},//     // {id:'003',title:'学高数+四级',done:false}// ]                }
            },
methods:{
//添加一个todoObjaddTodos(Obj){
this.todos.unshift(Obj) 
      },
//勾选或取消勾选todoObjcheckTodo(id){
this.todos.forEach((todoObj)=>{
//函数体if(todoObj.id===id)  todoObj.done=!todoObj.done        })
      },
//删除一个todoObjdeleteTodo(id){
this.todos=this.todos.filter((todoObj)=>{
returntodoObj.id!==id        })
      },
//全选or全不选checkAllTodo(done){
this.todos.forEach((todoObj)=>{
todoObj.done=done        })
      },
//清除所有已经完成的todosclearAllTodo(){
this.todos=this.todos.filter((todoObj)=>{
return!todoObj.done        })
      }
    },
watch:{
todos:{
deep:true,
handler(value){
localStorage.setItem('todos',JSON.stringify(value))
        }
      }
    }
}
</script><style>/*base*/body {
background-image: url(../src/assets/1.png) ;
Opacity:1}
.btn {
display: inline-block;
padding: 4px12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
text-align: center;
vertical-align: middle;
cursor: pointer;
box-shadow: inset01px0rgba(0, 255, 64, 0.2), 01px2pxrgba(11, 88, 255, 0.05);
border-radius: 4px;
}
.btn-danger {
color: #fff;
background-color: #1cda45;
border: 1pxsolid#0d8fe6;
}
.btn-danger:hover {
color: #fff;
background-color: #f70ea9;
}
.btn:focus {
outline: none;
}
.todo-container {
width: 600px;
margin: 0auto;
}
.todo-container.todo-wrap {
padding: 10px;
border: 1pxsolidrgb(250, 150, 0);
border-radius: 5px;
}
.box{
display: flex;
flex-direction: row;
justify-content: space-around;
}
.haizei{
font-size: 50px;
color: rgb(245, 147, 0);
font-weight: 800;
}
</style>

Item.vue:

<template><li><label><inputtype="checkbox":checked="todoObj.done"@change="handleCheck(todoObj.id)"/><!-- <input type="checkbox" v-model="todo.done"></input> --><spanclass="ziti">{{todoObj.title}}</span><!-- <span>{{todoObj.done}}</span> --></label><buttonclass="btn btn-danger"@click="handleDelete(todoObj.id)">删除</button></li></template><script>exportdefault{
name:'Item',
//生命接受todoObj对象props:['todoObj','checkTodo','deleteTodo'],
methods:{
//勾选or取消勾选handleCheck(id){
//通知App组件将对应的todo对象done值取反this.checkTodo(id)
            },
//删除handleDelete(id){
//通知App组件将对应的todo对象done值取反if(confirm('确定删除吗?')){
this.deleteTodo(id)
                }
            },
        }
    }
</script><stylescoped>/*item*/li {
list-style: none;
height: 36px;
line-height: 36px;
padding: 05px;
border-bottom: 1pxsolid#ddd;
}
lilabel {
float: left;
cursor: pointer;
}
lilabelliinput {
vertical-align: middle;
margin-right: 6px;
position: relative;
top: -1px;
}
libutton {
float: right;
display: none;
margin-top: 3px;
}
li:before {
content: initial;
}
li:last-child {
border-bottom: none;
}
li:hover{
background: rgb(129, 3, 247);
}
li:hoverbutton{
display: block;
}
.ziti{
font-size: 15px;
color: aliceblue;
}
</style>

Myfooter.vue:

<template><divclass="todo-footer"v-show="total"><label><inputtype="checkbox":checked="isAll"@change="checkAll"/></label><spanclass="wenzi"><span>已完成{{doneTotal}}</span> / 全部{{total}}
</span><buttonclass="btn btn-danger"@click="clearAll">清除已完成任务</button></div></template><script>exportdefault{
name:'Myfooter',
props:['todos','checkAllTodo','clearAllTodo'],
computed:{
total(){
returnthis.todos.length          },
doneTotal(){
// let i = 0// this.todos.forEach((todoObj)=>{//   if(todoObj.done) i++// })// return i returnthis.todos.reduce((pre,todoObj)=>pre+ (todoObj.done?1 : 0),0)
          },
isAll(){
returnthis.doneTotal===this.total&&this.total>0          }
        },
methods:{
checkAll(e){
this.checkAllTodo(e.target.checked)
          },
clearAll(){
this.clearAllTodo()
          }
        }
    }
</script><stylescoped>/*footer*/.todo-footer {
height: 40px;
line-height: 40px;
padding-left: 6px;
margin-top: 5px;
}
.todo-footerlabel {
display: inline-block;
margin-right: 20px;
cursor: pointer;
}
.todo-footerlabelinput {
position: relative;
top: -1px;
vertical-align: middle;
margin-right: 5px;
}
.todo-footerbutton {
float: right;
margin-top: 5px;
}
.wenzi{
font-size: 20px;
color: azure;
}
</style>

Myheader.vue:

<template><divclass="todo-header"><inputtype="text"placeholder="请输入你的任务名称,按回车键确认"v-model="title"@keyup.enter="add"/></div></template><script>import {nanoid} from'nanoid'exportdefault{
name:'Myheader',
props:['addTodos'],
data(){
return{
title:''            }
        },
methods:{
add(){
//校验数据if(!this.title.trim()) returnalert('输入不能为空')
//将用户的输入包装成为一个todos对象constObj= {id:nanoid(),title:this.title,done:false}
//通知app组件去添加一个todos对象this.addTodos(Obj)
//清空输入框的内容this.title=" "            }
        }
    }
</script><stylescoped>/*header*/.todo-headerinput {
width: 560px;
height: 28px;
font-size: 14px;
border: 1pxsolid#ccc;
border-radius: 4px;
padding: 4px7px;
}
.todo-headerinput:focus {
outline: none;
border-color: rgba(82, 168, 236, 0.8);
box-shadow: inset01px1pxrgba(0, 0, 0, 0.075), 008pxrgba(82, 168, 236, 0.6);
}
</style>

image.png

oen piece是真是存在的!!!

目录
相关文章
|
15天前
|
JavaScript API
Vue3中的计算属性能否动态修改
【9月更文挑战第5天】Vue3中的计算属性能否动态修改
49 10
|
1天前
|
JavaScript API
vue学习(13)监视属性
vue学习(13)监视属性
10 2
|
15天前
|
JavaScript API
如何使用Vue3的可计算属性
【9月更文挑战第5天】如何使用Vue3的可计算属性
44 13
|
7天前
|
缓存 JavaScript
vue学习(12)计算属性
vue学习(12)计算属性
15 3
|
7天前
|
缓存 JavaScript
vue学习(12)计算属性
vue学习(12)计算属性
22 2
|
23天前
|
JavaScript 前端开发
vue获取元素属性
vue获取元素属性
38 3
|
1月前
|
JavaScript 开发工具 git
Vue学习之--------脚手架的分析、Ref属性、Props配置(2022/7/28)
这篇文章分析了Vue脚手架的结构,并详细讲解了`ref`属性和`Props`配置的基础知识、代码实现和测试效果,展示了如何在Vue组件中使用`ref`获取DOM元素或组件实例,以及如何通过`Props`传递和接收外部数据。
Vue学习之--------脚手架的分析、Ref属性、Props配置(2022/7/28)
|
1月前
|
缓存 JavaScript
Vue学习之--------计算属性(2022/7/9)
这篇文章通过代码实例和效果测试,详细讲解了Vue计算属性的概念、实现方式、优势以及与插值语法和methods的区别。
Vue学习之--------计算属性(2022/7/9)
|
1月前
|
JavaScript
Vue学习之--------监视属性(2022/7/10)
这篇博客文章详细介绍了Vue框架中的监视属性(watch)功能,通过天气案例展示了监视属性的基础知识、代码实例、测试效果、深度监视、监视属性简写以及在项目中的实际应用。
|
1月前
|
API
VUE3——如何挂载全局属性和方法
VUE3——如何挂载全局属性和方法
146 0