前面我已经试过往vue的demo里面添加了vue-router和vuex。今天我就来把demo中的基础子控件增加一些动态操作。
首先vue有直接的父子数据直接引用$parent和$children。直接上例子。
//app.vue
<template>
<div id="app">
<div>这是计数{{count}}</div>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld ref="hw" msg="Welcome to Your Vue.js App"/>
<!-- 增加部分 -->
<div>
<div>这里是父控件</div>
<div><input type="button" value="子控件直接赋予数据" @click="TC" /></div>
<div v-for="item in allquestionlist.page_1[0].content" :key="item.id">
选择框是否选中:{{ item.check }}
</div>
</div>
<!-- 结束增加部分 -->
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
data(){
return {
count:this.$store.state.count, //赋予计数器的值
//增加3个变量
allquestionlist:{
"page_1":[{
content:[
{id:1,check:false},
{id:2,check:false},
{id:3,check:false}
]
}]
},
studyInfo:{
now_page:1
},
question:{
index:0,
content:[
{id:1,name:"选项1"},
{id:2,name:"选项2"},
{id:3,name:"选项3"}
]
}
};
},
methods:{
TC(){
//console.log(this.$children);
//console.log(this.$refs["hw"]);
//这里使用refs是为了快速定位到子控件,因为用children的话需要逐个判断
this.$refs["hw"].studyInfo= this.studyInfo;
this.$refs["hw"].question = this.question;
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
//helloworld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
<!-- 增加部分,此处的model使用$parent来直接引用父控件的变量 -->
<div>这里是子控件</div>
<div v-for="(item,qindex) in question.content" :key="item.id">
<input type="checkbox" v-model="$parent.allquestionlist['page_'+studyInfo.now_page][question.index].content[qindex].check" />item.name<br />
</div>
<!-- 结束增加部分,内容放在div.hello里面,模板一个根节点 -->
</div>
</template>
<script>
"use strict"
export default {
name: 'HelloWorld',
props: {
msg: String,
question:{
type:Object,
default:function () {
return { content: [] }
}
},
studyInfo:{
type:Object,
default:function () {
return { content: [] }
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style> 我在app.vue里面加了个按钮,点击按钮时,就直接修改子控件helloworld里面的变量。开始的时候,子控件的变量是默认空值,点击按钮后,就渲染出列表了。点击渲染的列表中的checkbox,因为checkbox的model是直接引用父控件的变量,所以父控件的变量会同步修改。

后面在说下按部就班的父子传递值方式,prop和$emit发起事件。这种形式一般用于组件是通用型的,以API的方式与父控件交换。当然这个情况用于prop非对象引用,传值类的使用。上代码。
//app.vue
<template>
<div id="app">
<div>这是计数{{count}}</div>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld ref="hw" msg="Welcome to Your Vue.js App" :studyInfo="studyInfo" :question="question" :checkstr="checkstr" @update:checkstr="checkstr = $event"/>
<!-- 增加部分 -->
<div>
<div>这里是父控件 </div>
<div>checkstr:{{checkstr}}</div>
</div>
<!-- 结束增加部分 -->
</div>
</template>
<script>
"use strict"
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
data(){
return {
count:this.$store.state.count, //赋予计数器的值
//增加3个变量
allquestionlist:{
"page_1":[{
content:[
{id:1,check:true},
{id:2,check:false},
{id:3,check:false}
]
}]
},
studyInfo:{
now_page:1
},
question:{
index:0,
content:[
{id:1,name:"选项1"},
{id:2,name:"选项2"},
{id:3,name:"选项3"}
]
},
checkstr:'未选中'
};
},
methods:{
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
//helloworld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
<div>这里是子控件 {{checkstr}}</div>
<div v-for="(item,qindex) in question.content" :key="item.id">
<input type="checkbox" @change="function(e){c1(e,qindex)}" />item.name<br />
</div>
</div>
</template>
<script>
"use strict"
export default {
name: 'HelloWorld',
props: {
msg: String,
question:{
type:Object,
default:function () {
return { content: [] }
}
},
studyInfo:{
type:Object,
default:function () {
return { content: [] }
}
},
checkstr:{
type:String,
default:function(){
return '';
}
}
},
methods:{
c1(e){
//console.log(e.target.checked);
this.checkstr = e.target.checked?'选中':'未选中';
this.$emit("update:checkstr",this.checkstr);
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style> 
prop传对象的话就会直接自动变化,但就容易被子控件随意修改了值。
