VUE
Vue是前端的一套框架,免除原生JS的DOM操作
概述:
创建VUE对象,由此对象可以控制一个HTML组件范围。
由数据驱动组件,而不直接控制组件。
VUE常用指令:
- 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中变量的引用,也可以直接写。
- 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实现双向绑定(和某个交互器)。
- 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
- 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判断显示哪个
- v-show
和v-if一样是用于决定是否显示某组件的,但区别在于,这里都会渲染进客户端浏览器,v-show的参数决定另一个参数display,由此决定是否显示。
- 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工程
-
目录结构:
-
node_modules:整个项目的依赖包(包括JS,CSS...)
-
public :存放项目的静态文件
-
src:存放源代码
-
package.json:模块的基本信息,项目开发所需要的模块,版本信息
-
vue.config.js:保存vue配置的文件,如:代理,端口的配置等
-
-
页面逻辑:
-
index.html为整个应用的入口,这个文件可以包含页面的基本结构和布局,其中声明了一个id=app的div,需要被挂载。
-
main.js是程序主要JS文件,在其中创建了Vue实例(此对象的具体实现仍需完成),并将此对象挂载在index.html中
-
App.vue是一个根组件,这个就是上面Vue对象的实现
-
xxx.vue是为了填充根组件App.vue的其余组件所在文件,可以由App.vue引入
(就像递归嵌套一样,组件构成的,也是组件)
-
-
.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>
-
-
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。
-
-
渐进式框架——学到什么程度都可以用
-
单文件组件——xxx.vue
在一个文件里封装了一个大组件的逻辑(JS),模板(HTML),样式(CSS)。
-
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的增强
- 一方面语法增强,更加方便
- 一方面引入编程语言的特性:如变量、嵌套规则、混合、函数、逻辑控制......
-
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并渲染在其中。
-
匿名插槽:
只有一个插槽,组件内所有接收的子组件都安插在此插槽内
-
具名插槽:
想要多对多,那在声明插槽时就要指定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没错也报,艹!
-
刚开始的时候如果不创建vue项目,直接导入vue.js文件就可以调用vue方法了(但也还要下载vue,只是不用配置太多)
-
在一个主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("前端真烦") } }
-
-
子组件得到父组件传入的信息:
<Son1 v-bind:todo="idd"></Son1>语法是: 子组件需要声明一个属性props:['sth1','sth2'],(在template中可以使用),然后在调用子组件的时候进行绑定:子=父;
解读: 子组件需要得到父组件的某个data,但无法直接写到子组件中,可以用此方法在写标签的时候绑定进子组件的可用属性props中,子组件相当于在启用props前先注入了数据(感觉很容易空指针)。
确实需要解耦: 如果父组件不改data里key名,那还是挺稳定的。
-
根组件的template——就是其绑定的div,子组件的template,只好手动写了
bytheway在template中最好包在一个div中
组合式API
选项式API分割了一个功能逻辑的各个部分(data在data,method在methods,提前加载的在mounted...这对维护和可读性而言不太好,于是组合式API将其写到一起)
本身是一系列API的集合
- 响应式API:例如ref(),reactive(),可以直接创建响应式状态,计算属性,侦听器
- 生命周期钩子:例如onMounted(),onUnmounted(),可以在组件各个生命周期阶段添加逻辑
- 依赖注入:例如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) } }
-
三大函数作用:
- reactive:把一个对象转化成响应式对象,返回一个proxy对象
- toRefs:把代理对象中的每一个属性都转化成响应式对象,可以配合解构
- ref:把普通数据,包装成响应式对象
- 对象可以是响应式的,其中的属性可以不是响应式,但由此对象访问此属性就可以得到类似响应式般更新的数据。
- 对象可以不是响应式的,但如果属性都是响应式,且逻辑上直接return了属性,就可以直接利用实时更新的属性。
-
前端小技巧:console.log()在控制台输出一个对象(可以展开,有许多字段),下面的大部分key都可以通过对象.属性在代码中访问到
-
而在程序中,对象往往不能直接修改,修改其内容就是改其value属性,其他属性同理。——包装成对象—传递的是地址—只能再由地址找寻别的,不能直接改地址⑧
-
ESLint
网站中用于查找ESLint问题的原因
vue 路由
-
$route:表示当前路由对象的规则(在index.js中配置,并自动添加了某些属性)
-
$router:表示全局的路由
ATTENTION
历历在目语法糖,眼泪莫名在流淌
- index.js中配置的children路由,path开头不加/。
- router-link的to属性,必须从根路由开始逐层匹配,不能直接找某层的children。
vue 过滤器(路由守卫)
目的:根据用户权力选择某些路由能否通行
分析:禁止通行某条路由似乎可以在整条线上逐点考虑截断
- 禁止点击router-link
- router-link禁止跳转
- 到达index.js,但通过配置禁止跳转
\守卫就是通过3实现
三种:
- 全局钩子:(全局守卫)beforeEach(),afterEach()
- 独享守卫:(单个路由里的钩子):beforeEnter(),beforeLeave()
- 组件内守卫:beforeRouteEnter(),beforeRouteUpdate(),BeforeRouteLeave()
每个守卫接收三个参数:
-
to:Route路由对象,表示即将进入的目标
用to.path设置对象的路径
-
from:Route对象,表示正要离开的路由
-
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的插件
前端项目注意点:
- 路由传递参数,父子组件传递参数,注意其中传递的数据类型
vue 全家桶
vue cli
-
是vue基于webpack开发的脚手架工具,内置了选项式工具来选择配置
-
npm install...
node package manager :是node.js环境下的一个包管理工具,用这个可以下载包
-
npm run server:启动项目静态资源
-
npm run build: 打包项目成一个文件夹,此文件夹可运行,和run server呈现一致,只能是打包后的。
回来吧我的VUE!
-
内置指令:
-
v-text:
向其所在节点中渲染文本内容
与插值语法的区别是:v-text会替换掉节点中的内容,{{}}不会
-
v-html:
Cookie工作流程简述:
cookie本身是一个k-v形式的字符串,在浏览器和网站服务器之间交流
-
当浏览器登录GitHub:携带用户名,密码的请求发给GitHub后台
-
GitHub返回一个成功登录的响应,此响应内嵌一个身份认证信息——cookie。
-
cookie被浏览器记录在缓存中,并标记为来自GitHub的cookie
-
接下来浏览器对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结构讲解:
-
在main.js中:
-
v2的做法:
import Vue from "vue"
vm = new Vue()...
通过导入vue.js主文件中的Vue构造函数,在main.js中创建vue实例,并用el:sth属性将vue实例接管某一块template。
-
v3的做法:
引入createApp工厂函数,相当于v2的层次再封装一层
-
-
v2中通过构造函数创建的vm对象,通过h函数控制App.vue壳组件,App.vue下调用并管理整个组件树。(接管可以用el绑定,也可以$mount)
-
v3中通过工厂函数创建app对象用来控制App壳组件,再mount到入口index.html的#app上,感觉相当于由app对象把App注入到#app中。
-
细说v3:
-
通过工厂函数传入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 响应式
-
ref包裹后,返回一个refImpl对象——reference implement引用实现对象
-
setup执行时机是:在beforeCreate之前执行,意味着vue组件还没有被创建——this是undefined
-
关于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中配置三个功能部件