Vue的笔记记录-----万字基础篇

指令

指令是Directives,是模板语法,用于辅助开发渲染页面的基本结构

1.内容渲染指令

v-text

<p v-text='username'></p>




const vm=new Vue({
    el:'app',
    data:{
    username:'zhangsan'
}
})

 缺点:会把标签内原有的内容覆盖调

插值语法{{}},用来解决text覆盖原有内容问题,除了可以插值还可以进行一些js里面的运算

<p >{{username}}</p>




const vm=new Vue({
    el:'app',
    data:{
    username:'zhangsan'
}
})

 v-html可以渲染带标签的字符串到页面中

2.属性绑定指令

v-bind:/:为元素属性动态绑定值还可以进行一些js里面的运算

input :placeholder="a+b"/"'gh'+b"/"username"



const vm=new Vue({
    el:'app',
    data:{
    username:'zhangsan',
    a:1,
    b:2,
}
})

3.事件绑定指令

v-on事件绑定指令简写@click

<button v-on:click="add">提交</button>









el:'#app'

data:{
},
methods:{
add(){
cl(1)
}
}

 $.event原生的dom对象e

<button @click="add(0,$event)">

事件修饰符

.prevent消除默认事件@click.prevent

事件修饰符说明
.prevent阻止默认行为
.stop阻止事件冒泡
.capture以捕获模式触发当前的事件处理函数
.once绑定的事件只触发一次
.self只有在event.target是当前元素的自身触发事件处理函数

<!-- 单击事件将停止传递 -->
<a @click.stop="doThis"></a>

<!-- 提交事件将不再重新加载页面 -->
<form @submit.prevent="onSubmit"></form>

<!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a>

<!-- 也可以只有修饰符 -->
<form @submit.prevent></form>

<!-- 仅当 event.target 是元素本身时才会触发事件处理器 -->
<!-- 例如:事件处理器不来自子元素 -->
<div @click.self="doThat">...</div>
<!-- 添加事件监听器时,使用 `capture` 捕获模式 -->
<!-- 例如:指向内部元素的事件,在被内部元素处理前,先被外部处理 -->
<div @click.capture="doThis">...</div>

<!-- 点击事件最多被触发一次 -->
<a @click.once="doThis"></a>

<!-- 滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成 -->
<!-- 以防其中包含 `event.preventDefault()` -->
<div @scroll.passive="onScroll">...</div>

 .passive 修饰符一般用于触摸事件的监听器,可以用来改善移动端的滚屏性能

按键修饰符 

@click.esc

 摁返回键触发

@keyup.enter

 向下键触发

<input @keyup.page-down="onPageDown" />
.enter
.tab
.delete (捕获“Delete”和“Backspace”两个按键)
.esc
.space
.up
.down
.left
.right

系统按键修饰符

.ctrl
.alt
.shift
.meta

 系统按键修饰符

<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

<!-- Ctrl + 点击 -->
<div @click.ctrl="doSomething">Do something</div>

.exact修饰符

<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 仅当没有按下任何系统按键时触发 -->
<button @click.exact="onClick">A</button>

鼠标按键
.left
.right
.middle

4.双向绑定指令v-model

下面这段就等价于v-model

<input
  :value="searchText"
  @input="searchText = $event.target.value"
/>

可以让程序员在不操作dom的情况下读取和修改data中的值 

v-model修饰符

.lazy input输入完之后失去焦点才更新数据

 .number 输入之后如果值是数字就转成number类型,是文字就原封不动

.trim自动去除空格

<input v-model.trim="msg" />

5.条件渲染指令

v-if

v-else

v-else-if

v-show

当这几个元素的值为true时被绑定元素内的内容从才会被显示

v-if和v-show的区别

v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。

相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display 属性会被切换。

总的来说,v-if操作dom元素的销毁于重建,v-show操作dom元素的显示与隐藏,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。

6.列表渲染指令v-for

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="../js-vue/vue.js"></script>
    <!-- <script src="../vuejs/antd.min.js"></script>
    <link rel="stylesheet" href="../vuejs/antd.min.css" /> -->
  </head>

  <body>
    <div id="app">
      <input type="search" value="" @keyup.esc="clearn" />
      <input v-model.lazy="searchText" />
      <input type="text" name="" id="" v-model.number="checkbox" />
      <h1 v-if="checkbox">11s</h1>
      <h1 v-else>else</h1>
      <!-- v-for -->
      <h1 v-for="(item,index) in dataBase">
        {{item.name}}-{{index}}-{{item.age?item.age:"未填写"}}-{{item.sex}}
      </h1>
      <!-- v-for 对象解构写法-->
      <h1 v-for="({name,age,sex},index) in dataBase">
        {{name}}-{{index}}-{{age?age:"未填写"}}-{{sex}}
      </h1>
      <!-- 对于多层嵌套的 v-for,作用域的工作方式和函数的作用域很类似。每个 v-for 作用域都可以访问到父级作用域: -->
      <div v-for="({name,age,sex},index) in dataBase">
        <!--也可以使用of代替in更符合js迭代-->
        <span v-for="item in jg">{{name}}-{{item}}</span>
      </div>
      <!-- 你也可以使用 v-for 来遍历一个对象的所有属性。遍历的顺序会基于对该对象调用 Object.keys() 的返回值来决定。 -->
      <div v-for="(key,value,index) in searchText">
        {{index}}-{{key}}:{{value}}
      </div>
      <!-- 直接接受一个整数值。1...n 的取值范围重复多次。从1-15包括1和 15-->
      <p v-for="n in 15">{{n}}</p>
      <!-- tem 可以在 <template> 标签上使用 v-for 来渲染一个包含多个元素的块。-->
      <ul>
        <template v-for="item in dataBase">
          <li>{{ item.name }}</li>
          <li class="divider" role="presentation"></li>
        </template>
      </ul>
    </div>
    <script>
      new Vue({
        el: '#app',
        data: {
          searchText: {
            name: 'nihao1',
            area: '云南',
          },
          checkbox: 0,
          jg: [1, 2, 3, 4, 5],
          dataBase: [
            {
              name: 'zs',
              sex: '男',
            },
            {
              name: 'ls',
              sex: '男',
            },
            {
              name: 'lt',
              sex: '男',
              age: 25,
            },
          ],
        },
        methods: {
          clearn(e) {
            console.log('触发了按键修饰符');
            e.target.value = '';
          },
        },
      });
    </script>
  </body>
</html>

同时使用 v-if 和 v-for 是不推荐的,因为这样二者的优先级不明显。

在外新包装一层 <template> 再在其上使用 v-for 可以解决这个问题 (这也更加明显易读):

 <template v-for="item in dataBase">
        <li v-if="item.age">{{ item.name }}</li>
        <li class="divider" role="presentation"></li>
      </template>

绑定Key管理vue的dom的状态:

Vue 默认按照“就地更新”的策略来更新通过 v-for 渲染的元素列表。确保他们在原本指定的位置进行渲染。

为了便于vue跟踪节点的标识,从而重新、重用对现有的元素排序,需要给对应元素加一个唯一的key属性。key是通过v-bind绑定的一个特殊的属性而不是item中的那个key属性。

值一般是一个number类型,一般用item.id。

<template v-for="todo in todos" :key="todo.name">
  <li>{{ todo.name }}</li>
</template>

key值需要是一个唯一值,不能以index当作key的值,因为没有强制的绑定方式,也不能说是个严谨的值。

例如:原来列表中有两个元素

0历史
1环境

在前面添加一个元素的时候索引值会变成

0科学
1历史
2环境

所以说是不严谨的

组件上使用v-for

可以在组件上直接使用v-for但是不会将任何数据传到组件里面,因为组件有自己独立的作用域,将数据传递到组件中需要用props

省略.....后面再说

数组变化侦测

侦听数组变化,在他们被调用时触发相关的更新:

push()向数组的末尾添加一个或多个元素,并返回新的长度。
pop()数组最后一位元素删除并返回数组的最后一个元素。
shift()数组的第一个元素从其中删除,并返回第一个元素的值。
unshift()向数组的开头添加一个或更多元素,并返回新的长度。
splice(index,howmany,item1, …, itemX)向/从数组中添加/删除项目,然后返回被删除的项目
第一个参数:表示从哪个索引位置(index)添加/删除元素
第二个参数:要删除的项目数量。如果设置为 0,则不会删除项目。
第三个参数:可选。向数组添加的新项目。
splice(1,2,‘a’,‘b’) 从索引位置(index:1)删除,删除2个元素,并添加2个新元素来替代被删除的元素
splice(1,0,‘a’)从索引位置(index:1)添加,添加两个元素
sort()正序
reverse()倒序
<label for="test">label标签</label>
<input type="text"  id="test">



当点击label标签内的文本后,就会触发绑定的表单元素。也就是说,当用户渲染该标签时,浏览器就会自动将焦点转到绑定的表单控件上。

过滤器filter(vue3已淘汰)只能在vue2中使用

可以用在两个地方:1.插值语法2.v-bind

通过管道符进行·调用

<div :id='rawid|过滤器'>
{{message|过滤器}}
</div>

私有过滤器(在Vue不同实例中不能通用只能在当前实例使用)

<div id="app">
      <p>{{message|filterL}}</p>
    </div>
    <script>
      new Vue({
        el: '#app',
        data: {
          message: 'hellow shuaige',
        },
        filters: {
          // 过滤器函数形参永远都是管道符前面的那个值
          filterL(val) {
            // 取索引对应的字符串
            const vl = val.charAt(0).toUpperCase();
            // 截取字符串从指定索引向后截取不包括当前索引
            const ou = val.slice(1, 5);
            return vl + ou;
          },
        },
      });
    </script>
  </body>

全局过滤器挂在Vue全局指令上

  // 全局过滤器Vue.filter(过滤器名字,回调函数)
      Vue.filter('filterL', (val) => {
        const vl = val.charAt(0).toUpperCase();
        // 截取字符串从指定索引向后截取不包括当前索引
        const ou = val.slice(1, 5);
        return vl + ou;
      });

全局过滤器和私有过滤器冲突,私有过滤器优先级高

也可以通过管道符调用多个过滤器

侦听器Watch

监视数据变化时而调用的函数,在组合式 API 中,我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数:

但是学习之前需要了解一下ref声明响应式状态,主要用于组合式API中

为什么要使用ref?

在模板中使用了一个ref,改变ref时,vue会自动检测到变化,并更新相应的dom。通过依赖追踪的响应式系统实现的。当一个组件被首次渲染时,Vue会在追踪渲染的过程中使用的每一个ref,当ref被修改时,会触发追踪它的这个组件重新渲染一次。

<script setup>
import { ref, watch } from 'vue'

const question = ref('')
const answer = ref('Questions usually contain a question mark. ;-)')
const loading = ref(false)

// 可以直接侦听一个 ref
watch(question, async (newQuestion, oldQuestion) => {
  if (newQuestion.includes('?')) {//includes是查询字符串中是否包含某个字符
    loading.value = true
    answer.value = 'Thinking...'
    try {
      const res = await fetch('https://yesno.wtf/api')
      answer.value = (await res.json()).answer
    } catch (error) {
      answer.value = 'Error! Could not reach the API. ' + error
    } finally {
      loading.value = false
    }
  }
})
</script>

<template>
  <p>
    Ask a yes/no question:
    <input v-model="question" :disabled="loading" />//默认不能选中是false
  </p>
  <p>{{ answer }}</p>
</template>

侦听que's'ting,查看输入字符中是否包含问号,包含?时就让输入框不能输入,调用随机返回api

watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:

const x = ref(0)
const y = ref(0)

// 单个 ref
watch(x, (newX) => {
  console.log(`x is ${newX}`)
})

// getter 函数
watch(
  () => x.value + y.value,
  (sum) => {
    console.log(`sum of x + y is: ${sum}`)
  }
)

// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {
  console.log(`x is ${newX} and y is ${newY}`)
})

 注意,你不能直接侦听响应式对象的属性值

const obj = reactive({ count: 0 })

// 错误,因为 watch() 得到的参数是一个 number
watch(obj.count, (count) => {
  console.log(`count is: ${count}`)
})

需要返回这个属性的getter函数值

// 提供一个 getter 函数
watch(
  () => obj.count,
  (count) => {
    console.log(`count is: ${count}`)
  }
)

即时回调的侦听器(immediate:true)

页面打开先执行一次

 username: {
            handler(n, o) {
              console.log(n);
            },
            immediate: true,
          },

一次性侦听器once:true 3.4+

当数据发生变化时只触发一次

watcheffect()

简化请求远程资源的监听,不用多次调用

const todoId = ref(1)
const data = ref(null)

watch(
  todoId,
  async () => {
    const response = await fetch(
      `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
    )
    data.value = await response.json()
  },
  { immediate: true }
)

简写为

watchEffect(async () => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
  )
  data.value = await response.json()
})

而且回调会立即执行,不需要指定 immediate: true。在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),我们不再需要明确传递 todoId 作为源值。

watch和Watcheffect的区别

1.watch不会追踪回调函数里面访问到的东西。只有数据发生改变后才会触发回调,可以准确的控制回调函数触发时机;(可定制)

2.watcheffect可以追踪到回调函数里面的属性,代码更简洁,但是响印依赖关系不那么明确。(不可定制)

同步侦听器

import { watchSyncEffect } from 'vue'

watchSyncEffect(() => {
  /* 在响应式数据变化时同步执行 */
})

计算属性computed

通过一系列运算后得出来的值,动态计算出来的值可以被模板结构或methods方法使用

插slice、splice、split三者区别

slice 截取字符串或数组,并返回一个新的字符串或数组

splice可以对数组进行插入删除替换返回删除的数组元素

split以什么字符分割字符串返回一个数组

<div id="app">
      <div>
        <input type="text" v-model="message" />
        <p>{{messageRe}}</p>
      </div>
    </div>
    <script>
      new Vue({
        el: '#app',
        data: {
          message: 'hellow',
        },
        computed: {
          messageRe() {
            return this.message.split('').reverse().join('');
          },
        },
      });

计算属性所依赖的值发生改变时,计算属性的值也会发生改变

计算属性和侦听属性

计算属性相对于监听属性来说代码更简洁,计算属性默认只有一个getter,但是需要的时候也可以创建一个setter

computed: {
  fullName: {
    // getter
    get() {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set(newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

Axios基本使用

axios({
metnod:"请求类型",
url:"请求地址"

}).then((result)=>{

}).catch((err)=>{

})

Vue-cli脚手架

是vue.js的开发标准工具。简化webpack创建工程化项目的过程。

安装

npm i -g @vue/cli

创建项目

vue create 项目名称

通过main.js把App.vue渲染到index.html的指定区域中

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),将组件渲染到页面
}).$mount('#app')提取dom元素主要是query函数也就是queryselector查找第一个符合的dom元素,也就是··。。。。。。。。。。。。el绑定的元素,但是,el不能是body或者html,原因是vue在挂载是会将对应的dom对象替换成新的div,但body和html是不适合替换的。

 组件化开发(封装思想,一件多用)

三个组成部分:template、script、style

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue';

export default {
  name: 'App',
  components: {
    HelloWorld,
  },
};
</script>

<style lang="less">启用less
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

 组件中的data必须是一个函数,里面要return一个对象

data(){
return{
name:;;;;;;
}
}

组件中定义methods方法

 methods: {
    add() {
      alert('哇哈哈');
    },
  },

使用组件的步骤:

1.在当前组件中暴露出去,在需要用到该组件的里面导入组件

import from

2.注册组件(调入后在components中注册组件)

export default:{
compoents:{
组件名
}
}

3.在template中以标签形式直接使用该组件

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

通过components注册的是私有组件。

全局组件注册使用

main.js









import a  from b

Vue.component('A',a)

 props(自定义属性)

在自己组件中声明

props:{
name:String
}

父组件中赋值:

<zujian name='张三'><zujian>

传数字用v-bind:

<All :msg="0"></All> 传的就是数字0,不使用就是字符0

props值只读直接修改会报错,想修改需要在data中声明变量接受,从this挂载的props赋值给

props:{
num
}

data(){
return{
count:this.num
}
}

配置默认值

props:{
num:{
default:0
}
}

明确知道数据类型后可以设置接受数据的类型

props:{
num:Number/
num:{
type:Number
required:true//必填项,默认值不算必须从组件中传过来的值
}
}

样式冲突解决:scoped

.vue中的样式默认加载到全局中会发生样式冲突

给当前组件添加scoped的时候组件实例生成一个唯一标识,给组件中的每个标签对应的dom元素添加一个标签属性,但是不会在编辑页面显示

<template>
	<div class="example" data-v-49729759>hello world</div>
</template>
<style scoped>
.example[data-v-49729759] {
	color: red;
}
</style>

缺点:父元素添加了scoped的样式想修改子元素中的标签时修改不了(类似信息可以编辑但是没有网),但是没有加scoped的里面又会生效于所有组件

当在style前面添加、/deep/的时候就可以修改子元素的样式相当于后代选择器

加了scoped的样式唯一标识是在后面:

h5[data-v-3vxxxx]{

}



/deep/ h5{
}

就是
[data-v-3vxxxx] h5{
}

是
[data-v-3vxxxx] 就是父元素的唯一标识

使用第三方库的时候需要修改一些样式的时候用到/deep/

万字 基础篇结束 共10999个字

  • 36
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值