V

[Vue基础] Vue本人学习路程

RoLingG 前端学习 2023-09-17

Vue本人学习路程

为什么学Vue,因为Vue就在那。

第一章节

<!-- 第一章节:vue3的风格 -->
<template>
  <div>msg:{{ msg }}</div>
  <button @click="add">Add</button>
</template>

<script setup>
import { ref } from "vue"
 const msg = ref("RoLingG")
 // let msg = "RoLingG"
 function add() {
  console.log("ADD")
  msg.value += " Clouwer"
 }
</script>

image-20230913204448228

第二章节

V-text

渲染文本,和插值表达式类似,也是支持运算符的。

V-html

渲染标签,如果字符串是含标签的特殊字符,那么vue会将它渲染成标签。

如果是v-text或者是使用插值表达式,则会原样输出。

注意:

v-html一般是用来渲染信任的文本,例如文章的详情内容等,最好不要用在用户提交的地方

容易造成XSS攻击

<!-- 第二章:插入值表达式 -->
<template>
  <div>
  msg:{{ msg }}
  <div v-text="msg"></div>
  <div v-html="html"></div> 
 </div>
</template>

<script setup>
import { ref } from "vue"
 const msg = ref("RoLingG")
 const html = ref("<a href='http://rolingg.top' target='blank'>RoLingG's Blog</a>")
</script>

image-20230913204651270

V-bind

可以给标签动态添加内容,也可以给动态的修改标签属性,不过在属性上的操作稍微和操作内容不太一样,我们使用v-bind指令。

例如:我想动态修改img标签的src属性,希望它去读取data里面的值,但是我们不能在属性中使用插值表达式。

这样写src直接将我的内容原样输出了,所以我们需要使用v-bind,全称为动态属性。

那么我可以这么做:

<template>
  <div v-bind:data-msg="attr">
  msg:{{ msg }}
 </div>
</template>

<script setup>
    const msg = ref("RoLingG")
    const attr = ref("Hello")
</script>

当然,v-bind: 可以简写为 :

v-bind不仅可以用于HTML存在的属性,还可以应用在自定义属性上:

<!-- 动态绑定 v-bind 简写成:号,也可以是class(标签绑定属性),:class以对象的形式时,只有为true才会显示,一般不用bind一绑多 -->

<template>
  <div :data-msg="attr" :class="_class" :style="style" v-bind="bind">
  msg:{{ msg === "RoLingG" ? true : false }}
 </div>
</template>

<script setup>
import { ref } from "vue"
 const msg = ref("RoLingG")
 const attr = ref("Hello")
 // const _class = ref("active")
 const _class = {
  active:true,
  isBanner:true,
 }
 const style = {color:"blue", backgroundColor:"black"}
 const bind = {
  m1:"1",
  m2:"2",
  m3:"3",
 }
</script>

在vue所有的指令中,都是支持表达式的

<div class="name">
    {{ a.length === 0 ? '没有数据' : a }}
</div>
什么是表达式?
// 这是语句
var a = 1;

// 这是表达式
a.length === 0 ? '没有数据' : a

第三章节

v-if

v-if中的布尔值为true,则渲染这个div。

v-if如果是true,会渲染,如果是是false,不会渲染。

如果if不成立,则渲染else中的代码块。

v-show

v-show如果是false,不会显示 ,标签内会新加入style="display: none;"

<!-- 条件渲染 -->
<template>
  <!-- v-if的消失是直接消失标签,导致的消失 -->
  <!-- v-if是控制标签是否渲染 -->
  <!-- v-if是真正的控制标签本体,资源消耗多。有一个重绘重排的过程 -->
  <div class="box1" v-if="isShow" style="width: 20px; height: 20px; background-color: black;"></div>
  <!-- v-if多条件 -->
  <!-- <div class="box4" v-else-if></div> -->
  <div class="box3" v-else>你好</div>
  <!-- v-show的消失是标签新添加了display="none"的属性,才导致的消失 -->
  <!-- v-show是通过css控制标签是否显示 -->
  <!-- v-show的资源消耗少,因为是通过css控制 -->
  <div class="box2" v-show="isShow" style="width: 20px; height: 20px; background-color: black;"></div>
  <!-- isShow = !isShow,点第一次取反,点多一次再取反 -->
  <button @click="isShow = !isShow"> 显示 </button>
</template>
<script setup>
import {ref} from "vue"
const isShow = ref(true)
</script>

第四章节

循环:v-for

一个参数,是遍历对象的值 例如:v-for="item in list1"
二个参数,是值和键 例如:v-for="(item, key) in list1"
三个参数,是值,键,索引 例如:v-for="(item, key, index) in list2"

<!-- 循环:遍历列表、遍历对象 -->
<!-- 
  一个参数,是遍历对象的值
  二个参数,是值和键
  三个参数,是值,键,索引
  key要是唯一值
  如果需要遍历出每个元素的索引,则在遍历的时候指定index
 -->
<template>
  <div>
    <!-- 此为解构遍历。原先的id是item.id,name是item.name -->
    <ul>
      <li v-for="({id, name}, index) in list0" :key="id">{{ id }}--{{ name }}---{{ index }}</li>
    </ul>
<!-- 此时的item in lis里的item是lis里的每一个元素 -->
    <ul>
      <li v-for="item in list1" :key="item">{{ item }}</li>
    </ul>
    <ul>
      <li v-for="(item, key, index) in list2" :key="item">
        对象的值:{{ item }} --
        对象的键:{{ key }} --
        变量的索引:{{ index }}
      </li>
<!-- 此时的item in lis里的item是lis里的每一个元素 -->
      <li v-for="({id, name, address}, index) in list2" :key="item">
        --------
        对象的id:{{ id }} ---
        对象的name:{{ name }} ---
        对象的address:{{ address }} ---
        对象的index:{{ index }}
      </li>
    </ul>
<!-- 字典是很特殊的列表 -->
    <ul>
      <li v-for="val in list3" :key="val">{{ val }}</li>
      <li v-for="(val, key) in list3" :key="val">{{ key }}---{{ val }}</li>
      <li v-for="(val, key, index) in list3" :key="key">{{ index }}---{{ key }}---{{ val }}</li>
    </ul>
  </div>
</template>
<script setup>
import { ref, reactive } from "vue"
const list0 = ref([
  {id:"1", name:"RoLingG"},
  {id:"2", name:"Clouwer"},
])
const list1 = ref([
    '张三',
    '王伟',
    '张伟',
    '王五',
])
const list2 = ref([
  {id:"1", name:"RoLingG", address:"广东"},
  {id:"2", name:"Clouwer", address:"广东"},
  {id:"3", name:"Template", address:"广东"},
])
const list3 = reactive(
  {
    "name": "roling",
    "age": 23,
  }
)
</script>

第五章节

事件:v-on

<!-- 事件:全称v-on,简写为@,用来监听DOM事件,并在事件触发时执行对应的JavaScrpit函数。 -->
<!-- 用法:v-on:click="method"或@click="handler" -->
<template>
  <div>
    <!-- 按键修饰符:鼠标和键盘 -->
    <input placeholder="请输入内容" @keydown.enter="add">
    <input placeholder="请输入内容" @keydown.ctrl.enter="add">
    <div style="background-color: aquamarine; width: 20px; height: 20px" @mousedown.left="add"></div>
    <!-- ↓这个貌似不行了,鼠标中键和右键点击貌似删除了 -->
    <!-- 这种可以拿去做鼠标按下对应出现菜单等功能可用 -->
    <div style="background-color: aquamarine; width: 20px; height: 20px" @mousedown.middle="add"></div>
  </div>
  <div>count: {{ count }}</div>
  <!-- a标签的默认事件 -->
    <a @click="count++" href="https://rolingg.top">count++</a>
    <!-- 阻止a标签的默认事件 -->
    <a @click.prevent="count++" href="https://rolingg.top">count++</a>

    <!-- stop 阻止事件冒泡
    prevent 阻止默认事件
    等等 -->
    <!-- 这里先传1后传2,这叫事件的向上冒泡 -->
    <div @click="add(2)">
      <button @click="add(1)">count++</button>
    </div>
    <!-- 不想让它冒泡就用.stop进行停止,这样它就只会传个1 -->
    <div @click="add(2)">
      <button @click.stop="add(1)">count++</button>
    </div>
  <button v-on:click="count_add">点我coutn ++</button>
  <button @click="count_sub">点我coutn --</button>
  <button @click="count_addNum(10)">点我coutn+num</button>
  <!-- 即想传递参数,又想获得事件对象 使用$event进行传递-->
  <button @click="count_addNum(10, $event)">点我coutn+num</button>
</template>

<script setup>
import { ref } from "vue"
const count = ref(0)
function add(event) {
  console.log(event)
  count.value += event
}
 function count_add() {
   count.value += 1
 }
 function count_addNum(num) {
   count.value += num
 }
 function count_addNum1(num, event) {
   console.log(event)
   count.value += num
 }
 function count_sub() {
   count.value -= 1
 }
</script>

第六章节

计算属性

Computed:

  • 调用的时候不用加括号(只是一个属性)
  • 可以监听属性变化,属性变化,计算属性重新执行
  • 并且有缓存(多个计算属性,只执行一次)

computed和methods的区别:属性变化,methods方法全部重新获取

——————————————————

computed和methods、watch的区别

methods:可以放入函数,并且没有缓存

watch:监听,当数据发送变化时,才会触发,可以得到现在的值和过去的值还可以监听路由变化,和属性同名

<!-- 计算属性 -->
<template>
  <div>  
    count1: {{ count1 }}
    count2: {{ count2(10) }}
  </div>
</template>

<script setup>
import { ref, reactive, computed } from "vue"
const count = ref(0)
const count1 = computed(()=>{
  const v = 10086
  return v + 123 - 100
})
// ↓多次计算
const count2 = computed(()=>{
  return function(num) {
    return count.value + num
  }
})
</script>

第七章节

监听器

①ref监听

②reactive监听

③深度监听

<!-- 监听器 -->
<template>
  <div>
    msg:{{ msg }}
    <!-- v-model会双向监听,监听input的变化,实时的传入msg,立刻对msg进行数据更新。 -->
    <input type="text" v-model="msg">
    data.msg:{{ data.msg }}
    <input type="text" v-model="data.msg">
  </div>
</template>

<script setup>
import { ref,watch,reactive } from "vue"
const msg = ref("")
const data = reactive({
  msg:"",
  msg1:"",
  msg2:"",
  // ↓深度监听就是指即便这样也能监听得到,但是要像叠甲一样把上面的v-model的进行改变,但实际上直接watch监听data,数据依然和叠甲这种一样。
  data:{
    _data:{
      __data:""
    }
  }
})
// 监听msg的变化,会有新、旧数据,可用watch进行查看
watch(msg, (newdata, olddata)=>{
  console.log(newdata, olddata)
})
//监听data这一整个对象的变化,会进行一个深度监听,缺点是多属性难顶,没法监听具体是哪一个变化
//所以一般不直接监听对象的变化
// watch(data, (newdata, olddata)=>{
//   console.log(newdata, olddata)
// })
//一般监听对象用这种↓,这样还是用了深度监听
watch(()=>data.msg, (newdata, olddata)=>{
  console.log(newdata, olddata)
})
//一般都不深度监听,用这种方法阻止深度监听
//想要深度监听,把deep改成true就好了
watch(()=>data, (newdata, olddata)=>{
  console.log(newdata, olddata)
},{deep:false})
//当然,也可以精确定位进行深度监听的阻止(叠甲式写法)
watch(()=>data._data.__data, (newdata, olddata)=>{
  console.log(newdata, olddata)
})
</script>

第八章节

生命周期

<!-- 生命周期 -->
<!-- vue2的生命周期有8个,还有2个+3个,一共13个,有错误则14个 -->
<template>
  <div>

  </div>
</template>

<!-- vue2无setup,vue3有setup,且vue2和vue3部分生命周期名字有更改 -->
vue3把beforeCreate和created糅合进了setup里
 <script setup>
 import { onBeforeMount, onMounted } from "vue";
 function getData(){
  console.log("调用后端接口")
 }
//  ↓先打印setup1,后打印setup2,再打印"调用后端接口"
console.log("setup1")
// 有的后端接口要执行函数,得等标签全部渲染出来,则在↓进行执行
onBeforeMount(()=>{
  console.log("beforeMount")
})
onMounted(()=>{
  console.log("Mounted")
})
console.log("setup2")
// ↓调用后端接口一定不要这样写,可能会卡住整个网站
getData()

// vue2的生命周期
// export default {
//   //一般调用后端的api,都在setup这里完成
//   setup() {
//     console.log("setup")
//   },
//   beforeCreate() {
//     console.log("beforeCreate")
//   },
//   //在vue2里,则实在created里完成后端的api调用
//   created() {
//     console.log("Created")
//   },
//   beforeMount() {
//     console.log("beforeMount")
//   },
//   mounted() {
//     console.log("Mounted")
//   },
// }
</script>
PREV
[Golang]Gin框架 3.查询参数
NEXT
[Golang]Gin框架 6.验证器/校验器

评论(0)

发布评论