vue.js
12月13
Vue2中的语法糖.sync:
在父组件中的<div :title.sync="visible" ></div>
等同于: / .sync将针对于title的监听事件缩写 /<div :title="visible" @update:title="visible = $event" ></div>
在子组件的methods中使用如下将新的value传给父级:
` handleClose() { this.$emit('update:title', newValue) }`
Vue3中用v-model替代了.sync修饰符和组件的model选项 / 不兼容 /:
针对于有参数的:<div v-model:title="visible" ></div>
等同于:<div :title="visible" @update:title="visible = $event" ></div>
Vue3中还针对于没有参数的v-model:
<div v-model="visible" ></div>
没有参数但却实际上在父组件内传入modelValue,类似于:v-model:modelValue="visible" @updata:modelValue="visible =$event"
在父组件里是运用visible,在子组件里传入的props里的是modelValue.
更改参数,传入父级也是用modelValuethis.$emit('update:modelValue', newValue)
详情可以看Vue3的官方
12月12
先来看看Vue3的几种组件通信方式:
[codes=c#]
props
$emit
expose / ref
$attrs
v-model
provide / inject
Vuex
[/codes]
下面分别介绍这几种方式的写法:
1、props
[codes=c#]
父组件
子组件
[/codes]
2、$emit
父组件
[codes=c#]
子组件
[/codes]
3、expose / ref
父组件
[codes=c#]
子组件
[/codes]
4、attrs
父组件
[codes=c#]
子组件
[/codes]
5、v-model
父组件(v-model可省略)
[codes=c#]
子组件
[/codes]
6. provide / inject
父组件
[codes=c#]
子组件
[/codes]
接下来是Vue2.x 组件通信使用方法:
1、 props
父组件
[codes=c#]
子组件
export default {
props:{
msg:{
type:String,
default:'这是默认数据'
}
},
mounted(){
console.log(this.msg)
}
[/codes]
2、.sync
[codes=c#]
父组件
[/codes]
3、v-model
[codes=c#]
父组件
[/codes]
4、ref
[codes=c#]
子组件
export default {
data(){
return {
name:""
}
},
methods:{
someMethod(msg){
console.log(msg)
}
}
}
父组件
[/codes]
5、$emit / v-on
[codes=c#]
子组件
export default {
data(){
return { msg: "这是发给父组件的信息" }
},
methods: {
handleClick(){
this.$emit("sendMsg",this.msg)
}
},
}
父组件
// 或 简写
export default {
methods:{
getChildMsg(msg){
console.log(msg) // 这是父组件接收到的消息
}
}
}
6、children/parent
[codes=c#]
父组件
export default{
mounted(){
this.$children[0].someMethod() // 调用第一个子组件的方法
this.$children[0].name // 获取第一个子组件中的属性
}
}
子组件
export default{
mounted(){
this.$parent.someMethod() // 调用父组件的方法
this.$parent.name // 获取父组件中的属性
}
}
[/codes]
7、EventBus
[codes=c#]
// 方法一
// 抽离成一个单独的 js 文件 EventBus.js ,然后在需要的地方引入
// EventBus.js
import Vue from "vue"
export default new Vue()
// 方法二 直接挂载到全局
// main.js
import Vue from "vue"
Vue.prototype.$bus = new Vue()
[/codes]
8、Vuex(这个就不举例子了........懂的都懂!)
[codes=c#]
props
$emit
expose / ref
$attrs
v-model
provide / inject
Vuex
[/codes]
下面分别介绍这几种方式的写法:
1、props
[codes=c#]
父组件
子组件
[/codes]
2、$emit
父组件
[codes=c#]
子组件
[/codes]
3、expose / ref
父组件
[codes=c#]
子组件
[/codes]
4、attrs
父组件
[codes=c#]
子组件
[/codes]
5、v-model
父组件(v-model可省略)
[codes=c#]
子组件
[/codes]
6. provide / inject
父组件
[codes=c#]
子组件
[/codes]
接下来是Vue2.x 组件通信使用方法:
1、 props
父组件
[codes=c#]
子组件
export default {
props:{
msg:{
type:String,
default:'这是默认数据'
}
},
mounted(){
console.log(this.msg)
}
[/codes]
2、.sync
[codes=c#]
父组件
[/codes]
3、v-model
[codes=c#]
父组件
[/codes]
4、ref
[codes=c#]
子组件
export default {
data(){
return {
name:""
}
},
methods:{
someMethod(msg){
console.log(msg)
}
}
}
父组件
[/codes]
5、$emit / v-on
[codes=c#]
子组件
export default {
data(){
return { msg: "这是发给父组件的信息" }
},
methods: {
handleClick(){
this.$emit("sendMsg",this.msg)
}
},
}
父组件
// 或 简写
export default {
methods:{
getChildMsg(msg){
console.log(msg) // 这是父组件接收到的消息
}
}
}
6、children/parent
[codes=c#]
父组件
export default{
mounted(){
this.$children[0].someMethod() // 调用第一个子组件的方法
this.$children[0].name // 获取第一个子组件中的属性
}
}
子组件
export default{
mounted(){
this.$parent.someMethod() // 调用父组件的方法
this.$parent.name // 获取父组件中的属性
}
}
[/codes]
7、EventBus
[codes=c#]
// 方法一
// 抽离成一个单独的 js 文件 EventBus.js ,然后在需要的地方引入
// EventBus.js
import Vue from "vue"
export default new Vue()
// 方法二 直接挂载到全局
// main.js
import Vue from "vue"
Vue.prototype.$bus = new Vue()
[/codes]
8、Vuex(这个就不举例子了........懂的都懂!)
12月2
[codes=c#]
//testCp
//use testCp
[/codes]
//testCp
//use testCp
[/codes]
11月26
[codes=c#]
:columns="columns"
:data-source="list"
:rowKey="
(record, index) => {
return index;
}
">
[/codes]
:data-source="list"
:rowKey="
(record, index) => {
return index;
}
">
[/codes]
11月25
[codes=c#]
import { defineAsyncComponent } from "vue"
// simple usage
const AsyncFoo = defineAsyncComponent(() => import("./demo.vue"))
// with options
const AsyncFooWithOptions = defineAsyncComponent({
loader: () => import("./demo.vue"),
loadingComponent: LoadingComponent,
errorComponent: ErrorComponent,
delay: 200,
timeout: 3000
})
[/codes]
声明
[codes=c#]
export declare interface AsyncComponentOptions {
loader: AsyncComponentLoader;
loadingComponent?: Component;
errorComponent?: Component;
delay?: number;
timeout?: number;
suspensible?: boolean;
onError?: (error: Error, retry: () => void, fail: () => void, attempts: number) => any;
}
[/codes]
import { defineAsyncComponent } from "vue"
// simple usage
const AsyncFoo = defineAsyncComponent(() => import("./demo.vue"))
// with options
const AsyncFooWithOptions = defineAsyncComponent({
loader: () => import("./demo.vue"),
loadingComponent: LoadingComponent,
errorComponent: ErrorComponent,
delay: 200,
timeout: 3000
})
[/codes]
声明
[codes=c#]
export declare interface AsyncComponentOptions
loader: AsyncComponentLoader
loadingComponent?: Component;
errorComponent?: Component;
delay?: number;
timeout?: number;
suspensible?: boolean;
onError?: (error: Error, retry: () => void, fail: () => void, attempts: number) => any;
}
[/codes]
11月16
[@vue/compiler-sfc] defineProps is a compiler macro and no longer needs to be imported
>[@vue/compiler-sfc] `defineEmits` is a compiler macro and no longer needs to be imported.
"vite": "^2.6.4",
"vue": "^3.2.16",
新版中不需要显示引入了,
>[@vue/compiler-sfc] `defineEmits` is a compiler macro and no longer needs to be imported.
"vite": "^2.6.4",
"vue": "^3.2.16",
新版中不需要显示引入了,
9月22
Vue3.0 正式版已经发布一段时间了,除了拥抱函数式编程,还带来了新的语法糖,用以替代原本需要大量 return 的写法
基础用法
想要使用 setup 模式只要在 script 标签上面加个 setup 属性就可以了。这个模式下不需要 return 和 export 就可以在模板中使用。
[codes=c#]
按钮
[/codes]
使用 props、emit
[codes=c#]
[/codes]
使用生命周期钩子
[codes=c#]
[/codes]
setup 语法糖的缺陷
这个语法糖暂时还不支持单文件导出内容,如果使用 export 导出模块会导致编译报错。
不支持设置组件名,传统的 options 写法有个 name 属性可以设置组件名,这个在编写递归组件的时候很有用
不支持 jsx,不过如果需要使用 jsx 的话,个人还是建议直接使用传统方式,setup 函数可以直接 return 一个 jsx 函数。而且 Vue 3.0 已经默认支持 css module 了,jsx 的体验会比之前更好。
[codes=c#]
[/codes]
其他
[codes=c#]
如何导入组件 => components
在 script-setup 中导入任意的组件就可以直接在 template 中使用
如何导入指令 => directive
导入指令的用法同 导入组件
如何使用 props
通过defineProps指定当前props类型的同时,获得上下文的props对象
在script中需要props[key]引用,而template中可直接调用key
如何使用 emit
通过defineEmit指定当前组件含有的触发事件
事件通过 defineEmit 返回的上下文 emit 进行触发
如何获取 slots 和 attrs
Note
遵循 setup 函数的规则,仅在组件加载时调用一次
[/codes]
写在最后
这个特性其实还是实验性质的,可能会有不少我暂时还没遇到的奇怪 bug,所以不建议在生产环境使用。不过他确实可以精简不少的代码,特别是哪种内容比较丰富的页面,尽管可以拆成多个子组件和 hooks,但是在拆分的比较多的情况下,引入模块也不可避免地要写一堆的模板代码,相信这样的编码方式以后会成为 Vue 的标准范式。
基础用法
想要使用 setup 模式只要在 script 标签上面加个 setup 属性就可以了。这个模式下不需要 return 和 export 就可以在模板中使用。
[codes=c#]
[/codes]
使用 props、emit
[codes=c#]
[/codes]
使用生命周期钩子
[codes=c#]
[/codes]
setup 语法糖的缺陷
这个语法糖暂时还不支持单文件导出内容,如果使用 export 导出模块会导致编译报错。
不支持设置组件名,传统的 options 写法有个 name 属性可以设置组件名,这个在编写递归组件的时候很有用
不支持 jsx,不过如果需要使用 jsx 的话,个人还是建议直接使用传统方式,setup 函数可以直接 return 一个 jsx 函数。而且 Vue 3.0 已经默认支持 css module 了,jsx 的体验会比之前更好。
[codes=c#]
[/codes]
其他
[codes=c#]
如何导入组件 => components
在 script-setup 中导入任意的组件就可以直接在 template 中使用
如何导入指令 => directive
导入指令的用法同 导入组件
如何使用 props
通过defineProps指定当前props类型的同时,获得上下文的props对象
在script中需要props[key]引用,而template中可直接调用key
如何使用 emit
通过defineEmit指定当前组件含有的触发事件
事件通过 defineEmit 返回的上下文 emit 进行触发
如何获取 slots 和 attrs
Note
遵循 setup 函数的规则,仅在组件加载时调用一次
[/codes]
写在最后
这个特性其实还是实验性质的,可能会有不少我暂时还没遇到的奇怪 bug,所以不建议在生产环境使用。不过他确实可以精简不少的代码,特别是哪种内容比较丰富的页面,尽管可以拆成多个子组件和 hooks,但是在拆分的比较多的情况下,引入模块也不可避免地要写一堆的模板代码,相信这样的编码方式以后会成为 Vue 的标准范式。
6月10
首先,移除一些冷门的 feature(比如 filter、inline-template 等);
其次,引入 tree-shaking 的技术,减少打包体积。
第一点很好理解,所以这里我们来看看 tree-shaking,它的原理很简单,tree-shaking 依赖 ES2015 模块语法的静态结构(即 import 和 export),通过编译阶段的静态分析,找到没有引入的模块并打上标记。
举个例子,一个 math 模块定义了 2 个方法 square(x) 和 cube(x) :
[codes=c#]
export function square(x) {
return x * x
}
export function cube(x) {
return x * x * x
}
[/codes]
我们在这个模块外面只引入了 cube 方法:
[codes=c#]
import { cube } from './math.js'
// do something with cube
[/codes]
最终 math 模块会被 webpack 打包生成如下代码:
[codes=c#]
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
'use strict';
/* unused harmony export square */
/* harmony export (immutable) */ __webpack_exports__['a'] = cube;
function square(x) {
return x * x;
}
function cube(x) {
return x * x * x;
}
});
[/codes]
可以看到,未被引入的 square 模块被标记了, 然后压缩阶段会利用例如 uglify-js、terser 等压缩工具真正地删除这些没有用到的代码。
也就是说,利用 tree-shaking 技术,如果你在项目中没有引入 Transition、KeepAlive 等组件,那么它们对应的代码就不会打包,这样也就间接达到了减少项目引入的 Vue.js 包体积的目的。
其次,引入 tree-shaking 的技术,减少打包体积。
第一点很好理解,所以这里我们来看看 tree-shaking,它的原理很简单,tree-shaking 依赖 ES2015 模块语法的静态结构(即 import 和 export),通过编译阶段的静态分析,找到没有引入的模块并打上标记。
举个例子,一个 math 模块定义了 2 个方法 square(x) 和 cube(x) :
[codes=c#]
export function square(x) {
return x * x
}
export function cube(x) {
return x * x * x
}
[/codes]
我们在这个模块外面只引入了 cube 方法:
[codes=c#]
import { cube } from './math.js'
// do something with cube
[/codes]
最终 math 模块会被 webpack 打包生成如下代码:
[codes=c#]
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
'use strict';
/* unused harmony export square */
/* harmony export (immutable) */ __webpack_exports__['a'] = cube;
function square(x) {
return x * x;
}
function cube(x) {
return x * x * x;
}
});
[/codes]
可以看到,未被引入的 square 模块被标记了, 然后压缩阶段会利用例如 uglify-js、terser 等压缩工具真正地删除这些没有用到的代码。
也就是说,利用 tree-shaking 技术,如果你在项目中没有引入 Transition、KeepAlive 等组件,那么它们对应的代码就不会打包,这样也就间接达到了减少项目引入的 Vue.js 包体积的目的。
7月31
遇到vue一直报错assigning to rvalue解决,一直以为是js代码的问题,后面找了很久的原因,才发现是在html的模板中v-model绑定的属性并没有在data属性中定义
v-model绑定错误引起
v-model绑定错误引起