引入开发版本,包含命令行的警告
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<span>Message: {
{
msg }}</span>
数据只会跟新一次,渲染一次后不会再改变
<!-- 只显示一次,数据刷新不管他的事情 -->
<span v-once>This will never change: {
{
msg }}</span>
<div v-html="rawHtml"></div>
new Vue({
el:"#app",
data:{
rawHtml:"你好
"
})
我自己的认识就是:过滤器就是当你要引用一个数据时先对其进行一段处理,比如截取字符串等等操作,然后再返回数据渲染页面!
<div id="app">
<h1>{
{
msg | capitalize}}</h1>
<input type="text" v-model="msg">
</div>
<script>
new Vue({
el: "#app",
data: {
msg: "",
},
filters: {
capitalize(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})
</script>
代码意思就是:msg绑定过滤器capitalize这个函数,当这个msg有值传入时调用过滤器,对msg处理,代码中是对其进行首字母大写处理。
<h1>{
{
msg | f1 | f2 }}</h1>
// 过滤器
filters: {
f1() {
return 10;
},
f2(value) {
console.log("数据: " + value)
}
}
console:
数据: 10
{
{
message | filterA('arg1', arg2) }}
1. 这里,字符串 'arg1' 将传给过滤器作为第二个参数, arg2 表达式的值将被求值然后传给过滤器作为第三个参数。
<h1>{
{
msg | capitalize('我是第一个参数', "我是第二个参数") }}
filters: {
capitalize(value, value1, value2) {
if (!value) return ''
value = value.toString()
console.log({
value1,
value2
})
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
</h1>
console:
{
value1: "我是第一个参数", value2: "我是第二个参数"}
自我感觉就是简化了操作,原本是在模板中对数据进行处理,现在直接可以简化出来,在computed中定义函数进行处理。
<div id="example">
{
{
message.split('').reverse().join('') }}
</div>
<div id="example">
{
{
message.split('').reverse().join('') }}
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})
介绍基本的对象绑定和数组绑定两种方式
// 此例子中isActive 为 true 时 class绑定 active
<div v-bind:class="{ active: isActive }"></div>
data:{
isActive:true,
}
// 这个例子中 div 盒子绑定 active 这个类
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
进阶的使用,结合计算属性
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error, // true
'text-danger': this.error && this.error.type === 'fatal',
}
}
}
// 结果是绑定 active 这个类。
我认为对象形式的绑定是绑定了这个对象,数组形式的绑定是绑定了数组的这一个数值。
<div v-bind:class="[activeClass, errorClass]">
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
结果:
div class="active text-danger"></div>
常用的形式,三元表达式
// 此案例中是否绑定active这个类取决于isActive这个数值
<div v-bind:class="[isActive ? activeClass : '', errorClass]">
这里只介绍一种
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
条件渲染有 v-if , v-else, v-else-if, v-show
v-if 与v-show 的区别:
<p v-if="true"></p>
用 v-model 指令在表单控件元素上创建双向数据绑定
自我认识就是v-model绑定就是把输入款input的value的值绑定了,value值为多少,v-model的值就是多少。
<input
type="checkbox"
v-model="toggle"
v-bind:true-value="a"
v-bind:false-value="b"
>
// 选中时 值为a, 没有选中时值为b.
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码.
Vue.component('my-component', {
// 选项
})
对于自定义标签名,Vue.js 不强制要求遵循 W3C规则 (小写,并且包含一个短杠),尽管遵循这个规则比较好。
<div id="example">
<my-component></my-component>
</div>
// javascript 代码
// 注册
Vue.component('my-component', {
template: 'A custom component!',
data(){
return value;
// 组件开发中data必须是函数
}
})
// 创建根实例
new Vue({
el: '#example'
})
渲染结果
<div id="example">
<div>A custom component!</div>
</div>
<!-- 局部注册 -->
<div id="app">
<my-components></my-components>
</div>
<script>
var child = Vue.extend({
template: '局部注册的组件
'
})
new Vue({
el: "#app",
data: {
},
components: {
"my-components": child
}
})
</script>
通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B 。它们之间必然需要相互通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。
在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。
组件实例的作用域是孤立的。
prop 是父组件用来传递数据的一个自定义属性
注意问题一定要先注册,然后再实例化,否则会出现
Unknown custom element: <child> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
// 未知的自定义元素:-您是否正确注册了组件?对于递归组件,请确保提供“名称”选项。
Props 是单向数据流,也就是说Props绑定的数据是单向绑定的,父元素的数据改变会带动子元素的数据同时发生改变,但是子元素的数据改变不会传导给父元素
目的是防止子元素无意篡改了父组件的状态
下面给几个栗子展示props的传值
<div id="app">
<input type="text" v-model="msg">
<!-- 下面这个msg不是Js环境,msg是模板中的插值 -->
<child msg="dajiahao1"></child>
</div>
<script>
//先注册
Vue.component('child', {
// 声明 props
props: ["msg"],
template: '{
{msg}}'
});
// 再实例化
new Vue({
el: "#app",
data: {
msg: "父组件的值",
},
})
</script>
<div id="app">
<input type="text" v-model="msg">
<!-- js环境下mymsg是下面的插值,传入的是父盒子的data中变量msg -->
<child :mymsg="msg"></child>
</div>
<script>
//先注册
Vue.component('child', {
// 声明 props
props: ["mymsg"],
template: '{
{mymsg}}'
});
// 再实例化
new Vue({
el: "#app",
data: {
msg: "父组件的值",
},
})
</script>
<div id="counter-event-example">
<p>{
{
total }}</p>
<!-- 父组件通过v-on 订阅消息,这里监听子组件方法,increment方法每执行一次,父组件中方法incrementTotal就执行一次 -->
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
<script>
Vue.component('button-counter', {
// 子组件绑定increment方法
template: '',
data: function() {
return {
counter: 0
}
},
methods: {
increment: function() {
this.counter += 1
// 在子组件中用$emit发布消息
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function() {
this.total += 1
}
}
})
</script>
源码解析
1. 首先是在子组件中绑定了 increment 方法给子组件。
2. 在父组件中通过 v-on 订阅了消息事件 increment ( 也可以说是监听了子组件的 increment 方法 )v-on:increment="incrementTotal "
, 子组件的 increment 方法每执行一次,父组件的 incrementTotal 方法就执行一次 .
3. 在子组件的方法中发布消息this.$emit('increment')
, 发布的消息就是之前你订阅的消息,名称要一致!
<div id="app_first">
<button @click="add">add</button>
</div>
<div id="app_second">{
{
msg}}</div>
<body>
<script>
// 创建一个空的Vue实例
const bus = new Vue();
const first = new Vue({
el: "#app_first",
data: {
text: "我是first实例的值"
},
methods: {
add() {
bus.$emit('id-selected', {
msg: this.text,
err: 0
})
}
},
created() {
}
});
const second = new Vue({
el: "#app_second",
data: {
msg: ""
},
created() {
bus.$on('id-selected', function(obj) {
// ...
console.log("输出函数内置的对象arguments:", arguments)
console.log("输出传过来的值", obj)
console.log(obj)
// console.log(this) 此时的this指向空的bus实例对象
second.msg = obj.msg
return obj;
})
}
})
</script>
// 就是先定义一个空的全局vue实例
const bus = new Vue()
// 在一个组件中发布消息
bus.$emit("xiaoxi-mingcheng",{
msg:"你要传送的数据"
})
// 在另一个组件中订阅消息
bus.$on("xiaoxo-mingcheng",function(obj){
// 这里书写你要进行的操作,obj就是传送过来的数据对象
}
)
在我的理解就是留空位,插值进去
分为三种情况
<div id="father">
<h1>我是父亲</h1>
<children>
<h3>我是插入的元素</h3>
</children>
</div>
<script>
// 我这里就用局部注册组件
var children = Vue.extend({
template: `
我是儿子上面
我是儿子下面
`
})
new Vue({
el: "#father",
components: {
children
}
})
</script>
运行结果
<!-- 局部注册 -->
<div id="app">
<my-components>
<h1 slot="header">
我是头部
</h1>
<h2 slot="footer">
我是底部
</h2>
</my-components>
</div>
<script>
var myComponents = {
template: `
我是主体内容
`
}
new Vue({
el: "#app",
data: {
},
components: {
"my-components": myComponents,
}
})
</script>
运行结果
第三种情况
就是如果含有name属性的slot与不含与name属性的slot交叉在一起,那么有name属性的会渲染到相映的slot上,其余的如果没有设置name的slot会渲染所以的插入节点,(最后剩下插入的节点要保证是没有设置slot属性的)
一个 slot 对应一个 name
简单的说就是在 JS 的环境下 控制组件间的切换,在后面可以通过路由实现组件间的切换,这里是通过
is
属性来控制
// 这样组件切换前提是你要注册多个组件在在同一个挂载点
<component v-bind:is="currentView">
<!-- 组件在 vm.currentview 变化时改变! -->
</component>
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: {
/* ... */ },
posts: {
/* ... */ },
archive: {
/* ... */ }
}
})
如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:
<keep-alive>
<component :is="currentView">
<!-- 非活动组件将被缓存! -->
</component>
</keep-alive>
使用 ref 为子组件指定一个索引 ID
<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({
el: '#parent' })
// 访问子组件
var child = parent.$refs.profile
$refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案——应当避免在模版或计算属性中使用 $refs 。
注:此教程是个人对 Vue 官方文档的学习笔记,欢迎大家一起交流讨论学习,如发现有错误请在评论区发言讨论!