回来吧我的VUE

131 阅读13分钟

VUE

Vue是前端的一套框架,免除原生JS的DOM操作

概述:

创建VUE对象,由此对象可以控制一个HTML组件范围。

由数据驱动组件,而不直接控制组件。

VUE常用指令:

  1. v-bind
<div id="div1">
    <a v-bind:href="mysrc" target="_blank">
        <p>
            测试用例
        </p>
    </a>
</div>
​
​
new Vue({
        el:"#div1",
        data:{
            mysrc:"http://www.baidu.com"
        }
    })
​
//目的在于:div1中在“测试用例”上的超链接没有在源代码中写死(绑定),而是用v-bind
确定将某个属性交给vue对象。也就是说,vue对象的属性更改,v-bind绑定的内容也改。
那么怎么改vue的属性呢?

传址引用

新版本更新了语法糖,可以通过{{}}插值表达式括住变量,表示对vue中变量的引用,也可以直接写。

  1. v-model
<div id="div1">
    <a v-bind:href="mysrc" target="_blank">  //v-bind是冒号
        <p>
            测试用例
        </p>
    </a>
<input type="text" v-model="mysrc">  //v-model是等号 
</div>new Vue({
        el:"#div1",
        data:{
            mysrc:"http://www.baidu.com"
        }
    })
​
//通过在输入框中更改内容,并且由v-model接收,接收下来赋值给mysrc,就更改了
测试用例的地址。
v-model的双向绑定就是这个意思。
可用于表单<input>,输入框<textarea>,选择框<select>

理解:在vue对象中声明并初始化了变量。在操作的HTML体中,v-bind用这个变量绑定(赋值)给某个属性,v-model实现双向绑定(和某个交互器)。

  1. v-on

v-on用于给HTML组件绑定事件

<div id="div1">
<input type="button" v-on:click="dianji">    v-on也是冒号  
//原本没有click属性,只有onclick——click是vue框架内集成出来的指令  
</div>
​
​
vue({
    el: #div1,
    data:{       //属性区
​
    },
    methods:{    //方法区
    dianji:function(){
    alert(别点);
        }
    }
})

语法糖:@click=“dianji”——用@表示v-on

  1. v-if/v-else-if/v-else

用于加在某些未必显示的标签中,如果if判断是ture则显示,else组是用于组合的。

可以用于判断来自输入框的信息

既输入框v-model双绑,更改信息后 v-if决定显示与否

<input type="text" name="choice" id="choice" v-model="ccccc">
            <span v-if="ccccc==1">您选择了盖茨</span>
            <span v-else-if="ccccc==2">您选择了李在容</span>
            <span v-else-if="ccccc==3">您选择了罗永浩</span>
            <span v-else>请选择您的英雄(1/2/3)</span>

又一应用场景是:左栏是下拉列表用于选择查看哪张表,右侧主栏用v-if判断显示哪个

  1. v-show

和v-if一样是用于决定是否显示某组件的,但区别在于,这里都会渲染进客户端浏览器,v-show的参数决定另一个参数display,由此决定是否显示。

  1. v-for

用于遍历vue中data区的列表 并渲染

<div v-for="element in arr">{{element}}</div>
<div v-for="(element , index) in arr">{{index+1}}:{{element}}</div>

<ol>表示有序列表,<ul>表示无序列表。列表组件中的每个列表项使用<li>标签表示。

<ol>
  <li>第一项</li>
  <li>第二项</li>
  <li>第三项</li>
</ol>

VUE生命周期

VUE从创建到销毁共有八个生命周期,对于每个生命周期程序员们可以编写切入代码。

  • 但要注意不同时期能否对属性访问

vue工程

  1. 目录结构:

    1. node_modules:整个项目的依赖包(包括JS,CSS...)

    2. public :存放项目的静态文件

    3. src:存放源代码

      image-20230604200257803

    4. package.json:模块的基本信息,项目开发所需要的模块,版本信息

    5. vue.config.js:保存vue配置的文件,如:代理,端口的配置等

  2. 页面逻辑:

    • index.html为整个应用的入口,这个文件可以包含页面的基本结构和布局,其中声明了一个id=app的div,需要被挂载。

    • main.js是程序主要JS文件,在其中创建了Vue实例(此对象的具体实现仍需完成),并将此对象挂载在index.html中

    • App.vue是一个根组件,这个就是上面Vue对象的实现

    • xxx.vue是为了填充根组件App.vue的其余组件所在文件,可以由App.vue引入

      (就像递归嵌套一样,组件构成的,也是组件)

  3. .vue文件的结构:

    • <template>
          <div>...</div>    
      </template>
      
    • <script>
          //js语法
          export default{
              data:function(){
                  return{
                      message1:"hello world",
                      message2:"thank you"
                  }
              }
              method:{
              function f1...
          }      
       }
      </script>
      

    语法糖中糖:data:function(){}——>data(){}

    之所以把data写成函数的样子,暂不明确

    • <style>
          #idname{
              ...
          }
      </style>
      
  4. App.vue文件

    • 注意:怎么引入.vue文件?——
    <emp-view></emp-view>    //有一个文件是EmpView.vue
    <element-view></element-view>    //有一个文件是ElementView.vue
    
    export default{
        component:{EmpView},
        data(){
            ...
        }
        methods:{
            ...
        }
    }
    

重新开始VUE文档

  • vue的两个核心功能

    • 声明式渲染——可以声明式地描述最终输出的HTML和JS状态之间的关系

      由JS代码驱动HTML组件。

    • 响应式——Vue会自动更新JS状态并在其发生变化的时候响应式的更新DOM。

  • 渐进式框架——学到什么程度都可以用

  1. 单文件组件——xxx.vue

    在一个文件里封装了一个大组件的逻辑(JS),模板(HTML),样式(CSS)。

  2. API风格:选项式和组合式

    • 选项式是将JS代码区分成data,methods,mounted...
    • 组合式中各种方法,属性,钩子的调用由于不会归类,所以要更符合语法

    选项式

<script>
export default {
  // data() 返回的属性将会成为响应式的状态
  // 并且暴露在 `this` 上
  data() {
    return {
      count: 0
    }
  },

  // methods 是一些用来更改状态与触发更新的函数
  // 它们可以在模板中作为事件处理器绑定
  methods: {
    increment() {
      this.count++
    }
  },

  // 生命周期钩子会在组件生命周期的各个不同阶段被调用
  // 例如这个函数就会在组件挂载完成后被调用
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

组合式

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

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
  count.value++
}

// 生命周期钩子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>
ref 函数接受一个初始值作为参数,并返回一个响应式的引用对象。引用对象具有一个 value 属性,用于访问和修改数据。当引用对象的 value 属性发生变化时,Vue 会自动追踪这个变化,并在需要时重新渲染相关的组件。

绑定:

  • 文本差值:用于在标签内,写文本的时候像显示变量,和python的format用处一致

  • 组件标签内部绑定attribute:v-bind

    <div v-bind:id="dynamicId"></div>
    
    简写:<div :id="dynamicId"></div>
    
    • 动态绑定多个attribute:

      data() {
        return {
          objectOfAttrs: {
            id: 'container',
            class: 'wrapper'
          }
        }
      }
      
      <div v-bind="objectOfAttrs"></div>
      
  • 所有数据绑定都支持JS表达式:

    {{ number + 1 }}
    
    {{ ok ? 'YES' : 'NO' }}
    
    {{ message.split('').reverse().join('') }}
    
    <div :id="`list-${id}`"></div>
    
    在 Vue 模板内,JavaScript 表达式可以被使用在如下场景上:
    
    在文本插值中 (双大括号)
    在任何 Vue 指令 (以 v- 开头的特殊 attribute) attribute 的值中
    

组件树!

原来这才是最难的,但模块化+饿了么直接屏蔽了,感觉确实脚踏实地比直接模板好



  • 原本我的操作是,在一个单文件组件里面试图再定义一个组件

    const mytodolist:{
        <h3>nihao</h3>
    }
    

    然后认为由于此组件就在这个文件中,不用导入,直接在script中注册。

    逻辑上似乎可以但是一直有bug,猜测单文件组件里的所有(组件/样式/脚本)都是为了一个组件定义...(不明)

  • 地道的办法是把这个组件写出去,写成新的.vue,再导入,在注册,更合乎逻辑吧。

import myTodoList from "@/views/element/myTodoList";

export default {
  components: {
    "my-todo-list":myTodoList,
  }
}
  • key-value同名可以省略key,vue自动识别是myTodoList的标签

    这属于ES2015的语法标准(ES2015-ES6——是JS的一个版本,有许多新特性)



vue项目逻辑梳理:

  • 一个.vue文件是一个单页面组件,可以通过被导入的方式作为标签使用
  • 一个vue对象可以调用方法。具体而言,针对一个vue对象可以设置挂载的div,设置使用的插件,设置具体组件...
  • 一个组件转化到一个vue对象需要经过createApp(app)方法。

vue项目中,根组件App.vue被导入到main.js,在其中转化成vue对象并设置好element插件。以及关键步骤:给id为app的组件挂载上这个vue对象,表示此组件内部的元素,监听都由这个vue对象接管。(为什么可以在js文件里直接找到html里id=app的组件呢?因为js就是配套搜索html,外联嘛)。

  • 唯一的入口是index.html
  • 这个html加载的时候,项目中的JS文件为其唯一的组件(项目的根组件)绑定了一个vue对象,这个vue对象负责了三个部分:组件/规范:template,样式:style,行为:script。怎么绑呢?main.js中将根组件App.vue转化成app对象,但要注意的是:App.vue作为根组件,其下有一颗组件树DOM,具体逻辑在App.vue中完成。

狂神听课笔记

前端用于动态更改CSS样式的工具是:SASS和LESS:通过编写其特殊的,有逻辑的语法,自动转化成CSS样式。

解决的问题是:网站排版更换.......

细说SCSS和LCSS

二者都是css的增强

  1. 一方面语法增强,更加方便
  2. 一方面引入编程语言的特性:如变量、嵌套规则、混合、函数、逻辑控制......
  • webpack:用于打包整合前端文件,变成浏览器可以识别的形式(同时会考虑浏览器对ECMScript的兼容性,不满足则将文件降级)

  • typeScript:微软开发,为了解决JS语法不足

  • 为什么我的v-if失效了啊,怀疑是热部署的问题(就算是idea中启动html也会占一个线程),但是视频里却可以,而且就算在开发者工具里修改也无效

    视频里没热部署,改代码还要刷新!

  • 线程的前后思想:如果在项目运行期间安装的插件/router,idea不会给提示的

  • 项目的package.json 里面记录了所有包的版本,更改版本的方法是:先改package.json,再重新执行npm install 完成加载

vue七大属性(之computed):

  • computed 计算属性:

    • 内容和methods类似,但是其中每一个方法都仅仅是一个参与计算的属性——由属性形式调用——DemoObj.test/DemoObj.test()
    • 使用缓存思想——只有其中内容改变,此属性才会更新
    • 于是计算属性常用于得到一些不常变动的值,让出内存
  • 另一层面的讲:computed是将大量的运算逻辑从template中写到computed中,这些运算是基于原本就有的属性的

<script>
export default{
    setup(){
        let message = ref("hello")
        //试图定义一个变量:是message的反转
        //const reversedMessage = message.value.split('').reverse().join('')
        //以上没法让reversedMessage是响应式属性
        const reversedMessage = computed(() => {
            return message.value.split('').reverse().join('')
        })
        return{
            message,
            reversedMessage
        }
    }            
}
</script>

vue七大属性(之侦听器)

作用:当某个属性改变时,触发侦听器

语法:

watch(test,(value, oldValue)=>{
      console.log(value,oldValue)
    })

外层:watch()

内层接收两个参数:一个所被侦听的属性,一个是回调函数,回调函数有两个参数,分别是改变之后的value,和改变之前的value

or

watch:{
    test(value,oldValue){
    console.log(value,oldValue)
    }
}

插槽

组件能够接收任意类型的数据,是通过定义props中的参数,并在标签中进行绑定

那组件假如想接收一段模板,用于自己体内呢?

像这样:

<myDiv>
    <otherDiv></otherDiv>
</myDiv>

一般这样写在浏览器中会忽略中间的组件,因为不知道插在myDiv的哪里,但如果有确定的插槽,就完成了myDiv组件接收otherDiv并渲染在其中。

  1. 匿名插槽:

    只有一个插槽,组件内所有接收的子组件都安插在此插槽内

  2. 具名插槽:

    想要多对多,那在声明插槽时就要指定name,声明传递的组件时也要指明插槽。

路由

记录:

似乎地道的做法是:

最外层的页面切换:是根据遍历大页面所在文件夹动态生成路由

每个页面里面的小组件切换或许要写路由吧

在单页面应用中,客户端的 JavaScript 可以拦截页面的跳转请求,动态获取新的数据,然后在无需重新加载的情况下更新当前页面。

既:后端的路由是根据用户访问的URL不同而响应不同的结果,也就是常规的超链接

但前端本身对页面跳转的请求可以处理一部分,前提是所需的数据都在前端拥有。

思路:

  • 路由是决定一个坑位应该填充哪个组件的
  • 整个项目全局上配置一个路由表,表示path和组件的对应关系
  • 用给某个组件绑定类似超链接的属性,点击表示选择

注意: 在index.js里配置的路由,需要被导入到main.js文件中,由Vue对象来使用

具体做法是:在index.js文件里产生一个router对象(是集成了底层路由列表和一个历史相关的东西), export default router将此对象暴露在外,再在main.js导入此对象。

代码:

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!--使用 router-link 组件进行导航 -->
    <!--通过传递 `to` 来指定链接 -->
    <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
    <router-link to="/">Go to Home</router-link>
    <router-link to="/about">Go to About</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>
// 1. 定义路由组件.
// 也可以从其他文件导入
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }

// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
// 我们后面再讨论嵌套路由。
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]

// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
const router = VueRouter.createRouter({
  // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
  history: VueRouter.createWebHashHistory(),
  routes, // `routes: routes` 的缩写
})

// 5. 创建并挂载根实例
const app = Vue.createApp({})
//确保 _use_ 路由实例使
//整个应用支持路由。
app.use(router)

app.mount('#app')

// 现在,应用已经启动了!

动态组件

<script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>

<template>
  <component :is="Foo" />
  <component :is="someCondition ? Foo : Bar" />
</template>

通过动态修改 :is=“”的值,来调整这个组件到底显示哪个

<template>
  <div>
    <component :is="currentComponent"></component>
  </div>
</template>


<script>
data() {
  return {
    currentComponent: 'ComponentA'
  };
}
</script>


运行时可修改:(写到函数里通过调用来修改)
this.currentComponent = 'ComponentB';

子组件 - 通过事件机制 - 触发父组件钩子

  • 子组件的某个方法中,通过this.emit()方法发布一个事件

    emit两个参数:事件名+事件携带参数

  • 父组件在引用子组件时,直接@事件名绑定方法

比较和props传参的区别:

props是从上往下传

而且感觉较为静态,传递一次后,子组件对象基本不会更改

而事件机制是从下往上传



vue基础知识:

vscode有错不报,idea没错也报,艹!

  1. 刚开始的时候如果不创建vue项目,直接导入vue.js文件就可以调用vue方法了(但也还要下载vue,只是不用配置太多)

  2. 在一个主html文件下编写页面时使用vue的逻辑是:

    • 创建组件,基本参数有五:

      • template:用key:value写的一些构造函数,value是html,且需要用``包起来
      • components:用于注册此vue对象可用的子组件,注册后可在挂载的div中做标签使用
      • data:写成函数的参数组,将参数组成一组对象,作为函数的返回值
      • methods:key:value形象,value是由一组函数组成的大对象
      • 钩子:就是函数啦
    • const DemoObj={
              components:{
                  son1,
                  son2
              },
              data(){
                  return{
                  name:"bob",
                  age:"18",
                  }
              },
              methods:{
                  myToString(){
                      console.log("name"+this.name+","+"age"+this.age)
                      return("name"+this.name+","+"age"+this.age)
                  }
              },
              mounted(){
                  console.log("前端真烦")
              }
          }
      
  3. 子组件得到父组件传入的信息:

    <Son1 v-bind:todo="idd"></Son1>
    

    语法是: 子组件需要声明一个属性props:['sth1','sth2'],(在template中可以使用),然后在调用子组件的时候进行绑定:子=父;

    解读: 子组件需要得到父组件的某个data,但无法直接写到子组件中,可以用此方法在写标签的时候绑定进子组件的可用属性props中,子组件相当于在启用props前先注入了数据(感觉很容易空指针)。

确实需要解耦: 如果父组件不改data里key名,那还是挺稳定的。

  1. 根组件的template——就是其绑定的div,子组件的template,只好手动写了

    bytheway在template中最好包在一个div中

组合式API

选项式API分割了一个功能逻辑的各个部分(data在data,method在methods,提前加载的在mounted...这对维护和可读性而言不太好,于是组合式API将其写到一起)

本身是一系列API的集合

  1. 响应式API:例如ref(),reactive(),可以直接创建响应式状态,计算属性,侦听器
  2. 生命周期钩子:例如onMounted(),onUnmounted(),可以在组件各个生命周期阶段添加逻辑
  3. 依赖注入:例如provide(),inject()。。。
  • 组合式API都会配合

  • 在组合式API中,this指的是window

  • ...test中,三个点表示展开运算符,就是把一个对象的属性以此罗列=>解构

    但需要test本身是响应式的,解构后的属性才是响应式

组合式API中,需要什么类型的属性就定义什么类型,选项式API中,是先有的类型,再在其中定义属性

例如:计算属性computed

组合式:

const testComp = computed(
        function () {
          return test.data2+1
        }
    )

目标属性用computed构成

选项式:

computed: {
  fullName: {
    return this.firstName + ' ' + this.lastName;
  }
} 

略有不同

  • setup():

    在setup(){}函数中返回的对象会暴露给模板和组件实例。

    模板就是这个页面的Template

    组件实例就是由这个页面创建的对象,setup将数据注入进来

    在template中访问setup返回的ref时,会自动浅层解包——无序在template中写.value

    setup()中没有this,是因为函数自身不含对组件实例的访问权

    • setup()函数设计初衷是提供一种独立于组件实例的逻辑组合方式。

    • setup()函数的目的之一是允许在组件实例化之前进行配置和准备工作。

    • 在之前执行——有助于与组件实例解耦——函数内的逻辑不依赖于实例的状态和属性,这样可以提高逻辑的可复用性

      • 实例化vue组件时或许会传入参数等等方式调整实例,setup的解耦就是确保各个实例不会影响到setup里的逻辑
    • setup(props):参数的意思是:

      这个vue组件在上层调用时或许会传入些参数

      这个参数其实在声明组件时就明确了

      const MyComponent = { props: ['title'], setup(props) {

      console.log(props.title);
      

      } }

      setup()看来有权利在组件实例化之前操作先操作这些传来的数据。

    • setup(context):参数的意思是:

      上下文

      export default {
        setup(props, context) {
          // 透传 Attributes(非响应式的对象,等价于 $attrs)
          console.log(context.attrs)
      
          // 插槽(非响应式的对象,等价于 $slots)
          console.log(context.slots)
      
          // 触发事件(函数,等价于 $emit)
          console.log(context.emit)
      
          // 暴露公共属性(函数)
          console.log(context.expose)
        }
      }
      

三大函数作用:

  1. reactive:把一个对象转化成响应式对象,返回一个proxy对象
  2. toRefs:把代理对象中的每一个属性都转化成响应式对象,可以配合解构
  3. ref:把普通数据,包装成响应式对象
  • 对象可以是响应式的,其中的属性可以不是响应式,但由此对象访问此属性就可以得到类似响应式般更新的数据。
  • 对象可以不是响应式的,但如果属性都是响应式,且逻辑上直接return了属性,就可以直接利用实时更新的属性。

网站中用于查找ESLint问题的原因

vue 路由

  1. $route:表示当前路由对象的规则(在index.js中配置,并自动添加了某些属性)

  2. $router:表示全局的路由

ATTENTION

历历在目语法糖,眼泪莫名在流淌

  1. index.js中配置的children路由,path开头不加/。
  2. router-link的to属性,必须从根路由开始逐层匹配,不能直接找某层的children。

vue 过滤器(路由守卫)

目的:根据用户权力选择某些路由能否通行

分析:禁止通行某条路由似乎可以在整条线上逐点考虑截断

  1. 禁止点击router-link
  2. router-link禁止跳转
  3. 到达index.js,但通过配置禁止跳转

\守卫就是通过3实现

三种:

  1. 全局钩子:(全局守卫)beforeEach(),afterEach()
  2. 独享守卫:(单个路由里的钩子):beforeEnter(),beforeLeave()
  3. 组件内守卫:beforeRouteEnter(),beforeRouteUpdate(),BeforeRouteLeave()

每个守卫接收三个参数:

  1. to:Route路由对象,表示即将进入的目标

    用to.path设置对象的路径

  2. from:Route对象,表示正要离开的路由

  3. next:function,放行,类似filterChain.doFilter

  • 路由守卫写在main.js中,或者写在router的index.js下
例1 :用独享守卫
{
        path: '/',
        name: 'Home',
        component: () => import('../views/Home.vue'),
        meta: { isAuth: true },
        beforeEnter: (to, from, next) => {
            if (to.meta.isAuth) { //判断是否需要授权
                if (localStorage.getItem('school') === 'qinghuadaxue') {
                    next()  //放行
                } else {
                    alert('抱歉,您无权限查看!')
                }
            } else {
                next()  //放行
            }
        }
    }

独享路由守卫只有前置,没有后置。

例2:用全局守卫(每次,每个切换都会调用此回调函数,初始化也会调用)

  • 忘了可以log对象来查看其属性了,这确定很提高效率

    又何苦从ide找每个对象,再每个分别log

  • 于是很容易想到要根据路由对象的某些属性,进行筛选后选择是否通行。

    此属性可以是提供的API:Path,fullPath...也可以是自定义是内容

    自定义的k-v写在meta属性里(元信息——from programmer)

    因为route对象是配置对象,并不能额外添加别的属性(泛?)

常规套路:

在需要鉴权的路由下添加某boolean属性,设置为true,其他不设置即为undefined

全局守卫判断每个路由的isAuth,如果为true,进行鉴权

全局的前置和后置

后置:初始化和每次跳转之后进行调用

            后置没有next参数

            后置的to,from和前置一致,都是和一次跳跃相关

            后置的作用一般用户在确认切换后更改某些信息

            比如页面的title

            根据document.title = "sth";

bytheway:默认title也可以更改:

在main.js中

例3:用组件内守卫:

在单页面组件中写即可

设置的两个钩子是

  • beforeRouteEnter:在进入这个组件时调用(不放行进不去)
  • beforeRouteLeave:在离开这个组件时调用(不放行走不了)

与前后无关,这个守卫在一次跳跃时只触发一个

注意:两个钩子只有在通过路由规则进入组件时才会生效,直接访问不行

都是见文知意

TS+Vue

  • TS这样的类型系统可以在编译时通过静态分析检测出许多常见错误,减少了生产环境中运行时的错误,配合IDE的提示,TS整体改善了开发体验

  • 静态分析:相较于JS语法而言,TS会显性的增加些约束(像interface),来确保某些位置写法正确

  • vscode插件还是很地道的

    volar是适配v3的对TS支持的组件,vetur是适配v2的对TS支持的组件,使用volar需要禁用vetur

    vscode时常反应不过来(没扫描到已经做了某些更改,比如禁用了vetur),需要重启

  • webstorm自动配置了适配TS的插件

前端项目注意点:

  1. 路由传递参数,父子组件传递参数,注意其中传递的数据类型

vue 全家桶

vue cli

  • 是vue基于webpack开发的脚手架工具,内置了选项式工具来选择配置

  • npm install...

    node package manager :是node.js环境下的一个包管理工具,用这个可以下载包

  • npm run server:启动项目静态资源

  • npm run build: 打包项目成一个文件夹,此文件夹可运行,和run server呈现一致,只能是打包后的。

回来吧我的VUE!

  1. 内置指令:

    • v-text:

      向其所在节点中渲染文本内容

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

    • v-html:

      Cookie工作流程简述:

      cookie本身是一个k-v形式的字符串,在浏览器和网站服务器之间交流

      1. 当浏览器登录GitHub:携带用户名,密码的请求发给GitHub后台

      2. GitHub返回一个成功登录的响应,此响应内嵌一个身份认证信息——cookie。

      3. cookie被浏览器记录在缓存中,并标记为来自GitHub的cookie

      4. 接下来浏览器对GitHub的访问携带cookie,后台通过cookie识别到身份后,进行逻辑上的区分

      注意:

      • 有些网站的cookie是分批次返回的,访问到网站不同区域返回不同的cookie,可能是网站要检测,伪装成cookie。

      • 技术——利用cookie伪造身份

        谷歌插件cookie editor导入/导出Cookie

      • 记录黑客手段:避免在网站动态加载任何html格式 XSS攻击

        类似SQL注入

        • 假如v-html或者v-bind将一串html形式的字符串绑定到某标签,渲染此标签时,该字符串内的模拟标签也会被加载。

        • 如果业务上存在用户输入——且某黑客用户按照html格式输入黑客网站+获取当前cookie的JS代码,即可能悄悄更改源码,诱导其他用户进入危险网站。

        • 一般通过JS代码可以获取当前cookie,

          document.cookie

          但只要将cookie细则加上http only限制,仅限http访问使用,可以避免cookie失窃

    • v-cloak:

      通过CSS先把元素隐藏,渲染完成后再加载到页面

        

天禹老师V3结构讲解:

  1. 在main.js中:

    1. v2的做法:

      import Vue from "vue"

      vm = new Vue()...

      通过导入vue.js主文件中的Vue构造函数,在main.js中创建vue实例,并用el:sth属性将vue实例接管某一块template。

    2. v3的做法:

      引入createApp工厂函数,相当于v2的层次再封装一层

  2. v2中通过构造函数创建的vm对象,通过h函数控制App.vue壳组件,App.vue下调用并管理整个组件树。(接管可以用el绑定,也可以$mount)

  3. v3中通过工厂函数创建app对象用来控制App壳组件,再mount到入口index.html的#app上,感觉相当于由app对象把App注入到#app中。

  4. 细说v3:

    1. 通过工厂函数传入App壳组件而产生的app总控制对象

      之前vm身上许多参数,v3的app较为轻量级

      关键参数mount,unmount,有点读写一体的感觉

      直接用app.mount('#app')执行对属性的调用

      setup

      setup(){
      
          const data = '你好'
      
          function satHello(){
              alert(data)
              }
      }
       此处alert的data就可以访问到上面的data。
      
      因为!!在作用域内!!——data是setup函数的局部变量,
      可以在内部function中识别,不需要用this

老版本:

<script>
    export default{
        setup(){
    const name = "rom"
    const home = "weida"
    function say(){
       console.log("welcome back")
        }
    return{
        name:name,
        home:home,
        say:say
        }
    }
}
</script>

return内由于同名可以简写

若返回一个对象,则对象中的属性,方法,在模板中均可以直接使用。(上述return {},{}就表示对象)

..............................................................................................

选项式中,export default{}暴露到template的对象属性都可以被访问到,组合式只不过在要导出的对象中增加了一部分东西——setup(){}函数

setup函数的返回值也伴随export default 一并被保留

所以可以在setup函数体内声明属性和方法,然后return会上层大对象,接受export default

..............................................................................................

选项式内可以访问到setup函数中的属性和方法,因为setup优先执行,return的部分就和选项式同级。

组合式内访问不到选项式的属性,因为先执行setup(){}函数,还没有加载整个对象的变量。

数据劫持:

数据劫持是响应式的核心

其作用是:在某些数据执行get和set方法时插入钩子函数,钩子的内容就是改变template。

  • get:vue会对模板中调用了get方法的属性进行检测,检测其下一步是否改变(本质就是对template中调用了响应式数据的部分进行检测,毕竟调用才会用get)
  • set:响应式核心:更改模板数据

以上都是v2的做法

以下都是v3的做法

v3通过设置代理,完成对数据crud的检测

setup 响应式

  1. ref包裹后,返回一个refImpl对象——reference implement引用实现对象

  2. setup执行时机是:在beforeCreate之前执行,意味着vue组件还没有被创建——this是undefined

  3. 关于setup函数的参数

    • 如果要接收props,还得在上面先声明props:[“name”,"age"],一对一接收。此参数即为上层调用时传入的一系列参数,想必是k-v

关于$,_:

通过console.log(this)输出当下组件的实例对象,即可查看各种属性

vueX

  • 之前再组件之间的数据传递可以用vue路由传,也可以用全局事件总线传递

    全局事件总线:

    全局事件总线其实就是一个中间介质,组件间的相互通信借助于这个中间介质,通过这个中间转换介质,从而完成数据的传递与接收,实现组件间的相互通信

  • 更地道的方法是通过vueX

  • vueX:专门再Vue中实现集中式状态/数据管理的vue插件,对vue中多个组件的共享状态(数据)进行集中式的管理(读/写),也是一种组件间通信的方式。但vueX不属于任意组件。
  • 当多个组件依赖于同一状态时,或来自不同组件的行为需要改变同一状态时,使用vueX

vueX流程说明

  • 虚线是vueX功能部件
  • 实线是使用vueX的基本流程

  • State:保管各种数据状态
  • vue-Components:组件调用数据/状态
  • Actions:组件调用属性更新
  • Mutations:执行对State内数据的更新

vueX三个功能部件,都有store进行管理

有时Actions可以省略,当vue-Components不需要调用后端数据时。vue组件直接和Mutation交互。


  • 天禹@尚硅谷:

    State:菜品

    vue Components:顾客

    Actions:服务员

    Mutations:厨师

  • 步骤:

    store的index.ts中配置三个功能部件