目录
Vue 的标准开发方式是 SPA(Single Page Application):单页面web 应用,也就是收,日后的项目中只有一张页面(index.html).
为什么要使用 SPA 开发方式?
全局组件:直接注册到 Vue 根实例组件中.
定义方式:Vue.component(' ', {}) ,第一个参数是组件名,第二个参数是配置对象.
Ps:无论是使用全局组件还是局部组件,都必须在组件 template 中添加唯一根元素.
如下代码:
- <div id="app">
-
- <register>register>
- div>
-
- <script src="../js/vue.js">script>
- <script>
- //定义全局组件(生效的前提是要有 Vue 实例, 并在实例的作用域中使用)
- Vue.component('register', {
- template: `
注册
{{msg}}{{counterSqrt}} `, - data() { //组件中定义数据,必须函数的形式(和 Vue 实例定义唯一的区别)
- return { //返回值是一个对象,对象内部就是数据
- msg: "我是注册全局组件中的数据",
- count: 2
- }
- },
- methods: { //给组件定义一些方法
- test() {
- console.log("我是组件中的方法");
- }
- },
- computed: { //给组件定义一些计算属性
- counterSqrt() {
- return this.count * this.count;
- }
- },
- components: { //给组件中定义一些组件
- comp: {
- template: `我是全局组件的子组件`
- }
- },
- beforeCreate() { //组件也有自己的生命周期
- console.log("beforeCreate:", this.msg);//此时 msg 因该是 undefine
- }
- //......
- });
-
- const app = new Vue({ //没有这里,组件就不会生效
- el: "#app"
- });
效果如下:
局部组件:只能在注册组件中使用组件.
代码如下:
-
- <div id="app">
- <login>login>
- <reg>reg>
- div>
-
- <script src="../js/vue.js">script>
- <script>
-
- //定义局部组件(这是另一种方式,现在外部定义好,再到局部注册组件中引入)
- //Ps:在子组件中不可使用父组件的数据! 比如 parent 数据
- const login = {
- template: `
登录
{{ child }}{{ counterSqrt }} `, - data() {
- return {
- child: "我是注册组件的子组件 login 中的数据",
- count: 3
- }
- },
- methods: { //给组件定义一些方法
- test() {
- console.log("我是组件中的方法");
- }
- },
- computed: { //给组件定义一些计算属性
- counterSqrt() {
- return this.count * this.count;
- }
- },
- components: { //给组件中定义一些组件
- comp: {
- template: `我是子组件的子组件`
- }
- },
- beforeCreate() { //组件也有自己的生命周期
- console.log("beforeCreate:", this.child);//此时 child 因该是 undefine
- }
- //......
- }
-
- let app = new Vue({
- el: "#app",
- data: {
- parent: "我是父组件中的数据"
- },
- components: { //注册组件
- login, //也可以单独在外面定义好组件,然后引入
- reg: {
- template: `{{ child }}`,
- data() { //注意组件中数据的写法
- return {
- child: "我是子组件 reg 中的数据"
- }
- }
- }
- }
- });
- script>
效果如下:
父组件向子组件传递静态数据:在使用的组件标签上,声明静态数据 key=value (key 是自定义的),最后在子组件的 props 中声明对应的 key 即可
代码如下:
- <div id="app">
-
- <login name="hello?" count="1">login>
-
- div>
-
- <script src="../js/vue.js">script>
- <script>
-
- const login = {
- template: `
登录
{{ name }} --- {{ count }}`, - data() {
- return {
- //这里相当于添加了 name: "hello?", count="1"
- }
- },
- props: ['name', 'count'] //用来接收父组件传来的数据, 这就相当于在子组件的 data 中添加了这个静态数据
- }
-
- const app = new Vue({
- el: "#app",
- components: {
- login //注册组件
- }
- });
-
- script>
效果如下:
向子组件传递动态数据:
Ps:Vue 官方明确提出只允许单向数据流,也就是只能从父传递到子,否则会报警告
代码如下:
- <div id="app">
-
- <login :aa="count">login>
- <input type="text" v-model="count">
- div>
-
- <script src="../js/vue.js">script>
- <script>
-
- const login = {
- template: `
登录{{ aa }}
`, - data() {
- return {
-
- }
- },
- props: ['aa'],
- methods: {
- add() {
- this.aa++;//props 声明的数据,就相当于直接 data 中添加了该数据
- }
- }
-
- }
-
- const app = new Vue({
- el: "#app",
- data: {
- count: "1"
- },
- components: {
- login
- }
- });
-
- script>
最后的效果:
如下图
父向子传递事件:在组件标签上定义 @key=value (@自定义事件名=父组件中的事件名) 即可
代码如下:
- <div id="app">
-
- <login @aa="testParent()" @bb="testParent2" @cc="testParent3">login>
- div>
-
- <script src="../js/vue.js">script>
- <script>
- const login = {
- template: `
登录
点给我调用父组件中的事件 `, - data() {
- return {
- count: 10
- }
- },
- methods: {
- testChild() {
- alert("我是子组件中的事件!");
- //通过 this.$emit 来调用父组件中的事件
- //参数1:组件标签上定义的事件名
- //后续参数: 参数1 后面还可以继续传递参数,作为父组件事件中的参数
- this.$emit("aa");
- this.$emit("bb", this.count); //Vue 官方说只能单向传递(父传子),但是这种方式可以实现
- this.$emit("cc", { count: this.count, name: "cyk", isGood: true });
- }
- }
- }
-
- const app = new Vue({
- el: "#app",
- methods: {
- testParent() {
- alert("1.我是父组件中的事件!");
- },
- testParent2(count) {
- alert("2.我是父组件中的事件!");
- console.log("获取到子组件的值:" + count);
- },
- testParent3(obj) {
- alert("3.我是父组件中的事件!");
- console.log("获取到子组件的值: count=" + obj.count + ", name=" + obj.name + ", isGood=" + obj.isGood);
-
- }
- },
- components: {
- login
- }
- });
- script>
效果如下:
插槽就是用来扩展现有组件的.
代码如下:
- <div id="app">
-
-
- <login>login>
-
- <hr>
- <login><span>hellospan>login>
-
- <hr>
- <login><button slot="aa" @click="parent()">点我button>login>
- div>
-
- <script src="../js/vue.js">script>
- <script>
-
- const login = {
- template: `<div><slot name="aa">slot><h1>登录h1><slot name="bb">slot>div>`,
- }
-
- const app = new Vue({
- el: "#app",
- methods: {
- parent() {
- alert("我是父组件的事件");
- }
- },
- components: {
- login
- }
- });
-
- script>
效果如下: